- simplified instruction decoder and removed genrom functions

Committed on the Free edition of March Hare Software CVSNT Server.
Upgrade to CVS Suite for more features and support:
http://march-hare.com/cvsnt/


git-svn-id: http://moon:8086/svn/vhdl/trunk@394 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2009-03-16 11:31:51 +00:00
parent e465dc860b
commit 81c8bf1897
+356 -324
View File
@@ -43,12 +43,7 @@ package mips_instr is
function extract_bimm18(instr, pc : word_t) return word_t;
function decode_op(instr : word_t) return op_t;
function ctrl_lines_default return ctrl_lines_t;
function special_ctrl_lines(func : func_t) return ctrl_lines_t;
function regimm_ctrl_lines(rt : reg_ptr_t) return ctrl_lines_t;
function opcode_ctrl_lines(opc : opcode_t) return ctrl_lines_t;
function gen_rom_opcode return rom_opcode_t;
function gen_rom_regimm return rom_regimm_t;
function gen_rom_special return rom_special_t;
function opcode_ctrl_lines(instr : word_t) return ctrl_lines_t;
end mips_instr;
@@ -153,12 +148,14 @@ package body mips_instr is
variable opc : natural range 0 to 63;
variable func : natural range 0 to 63;
variable rt : natural range 0 to 31;
variable rs : natural range 0 to 31;
begin
opc := to_integer(extract_opc(instr));
func := to_integer(extract_func(instr));
rt := to_integer(extract_rt(instr));
rs := to_integer(extract_rs(instr));
result := op_sll;
@@ -317,16 +314,100 @@ package body mips_instr is
result := op_lui;
when 16 =>
result := op_cop0;
case rs is
when 0 =>
result := op_mfc0;
when 2 =>
result := op_cfc0; -- illegal
when 4 =>
result := op_mtc0;
when 6 =>
result := op_ctc0; -- illegal
when 8 =>
case rt is
when 0 =>
result := op_bcf0; -- illegal
when 1 =>
result := op_bct0; -- illegal
when others => null; -- undef
end case;
when others => null; -- undef
end case;
when 17 =>
result := op_cop1;
case rs is
when 0 =>
result := op_mfc1;
when 2 =>
result := op_cfc1;
when 4 =>
result := op_mtc1;
when 6 =>
result := op_ctc1;
when 8 =>
case rt is
when 0 =>
result := op_bcf1;
when 1 =>
result := op_bct1;
when others => null; -- undef
end case;
when others => null; -- undef
end case;
when 18 =>
result := op_cop2;
case rs is
when 0 =>
result := op_mfc2;
when 2 =>
result := op_cfc2;
when 4 =>
result := op_mtc2;
when 6 =>
result := op_ctc2;
when 8 =>
case rt is
when 0 =>
result := op_bcf2;
when 1 =>
result := op_bct2;
when others => null; -- undef
end case;
when others => null; -- undef
end case;
when 19 =>
result := op_cop3;
case rs is
when 0 =>
result := op_mfc3;
when 2 =>
result := op_cfc3;
when 4 =>
result := op_mtc3;
when 6 =>
result := op_ctc3;
when 8 =>
case rt is
when 0 =>
result := op_bcf3;
when 1 =>
result := op_bct3;
when others => null; -- undef
end case;
when others => null; -- undef
end case;
when 32 =>
result := op_lb;
@@ -364,6 +445,9 @@ package body mips_instr is
when 46 =>
result := op_swr;
when 48 =>
result := op_lwc0; -- illegal
when 49 =>
result := op_lwc1;
@@ -373,6 +457,9 @@ package body mips_instr is
when 51 =>
result := op_lwc3;
when 56 =>
result := op_swc0; -- illegal
when 57 =>
result := op_swc1;
@@ -436,312 +523,274 @@ package body mips_instr is
end ctrl_lines_default;
function special_ctrl_lines(func : func_t) return ctrl_lines_t is
function opcode_ctrl_lines(instr : word_t) return ctrl_lines_t is
variable result : ctrl_lines_t;
variable op : integer range 0 to 2**func_t'length-1;
variable opc : integer range 0 to 2**opcode_t'length-1;
variable func : integer range 0 to 2**func_t'length-1;
variable rt : integer range 0 to 2**reg_ptr_t'length-1;
variable rs : integer range 0 to 2**reg_ptr_t'length-1;
begin
result := ctrl_lines_default;
op := to_integer(func);
case op is
result := ctrl_lines_default;
opc := to_integer(extract_opc(instr));
func := to_integer(extract_func(instr));
rt := to_integer(extract_rt(instr));
rs := to_integer(extract_rs(instr));
-- when op_add =>
when 32 =>
result.alu.outsel := alu_adder;
result.alu.add := '1';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
result.alu_exc_en := '1';
case opc is
-- SPECIAL
when 0 =>
case func is
-- when op_addu =>
when 33 =>
result.alu.outsel := alu_adder;
result.alu.add := '1';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_add =>
when 32 =>
result.alu.outsel := alu_adder;
result.alu.add := '1';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
result.alu_exc_en := '1';
-- when op_and =>
when 36 =>
result.alu.outsel := alu_and;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_addu =>
when 33 =>
result.alu.outsel := alu_adder;
result.alu.add := '1';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_break =>
when 13 =>
result.exc_break := '1';
result.except_en := '1';
-- when op_and =>
when 36 =>
result.alu.outsel := alu_and;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_div =>
when 26 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '1';
result.mul_mul_divn := '0';
-- when op_break =>
when 13 =>
result.exc_break := '1';
result.except_en := '1';
-- when op_div =>
when 26 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '1';
result.mul_mul_divn := '0';
-- when op_divu =>
when 27 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '0';
result.mul_mul_divn := '0';
-- when op_jalr =>
when 9 =>
result.jump_long := '1';
result.wptr_srcsel := wptr_src_imm;
result.reg_write := '1';
result.reg_link := '1';
-- when op_jr =>
when 8 =>
result.jump_long := '1';
-- when op_mfhi =>
when 16 =>
result.reg_write := '1';
result.mul_access := '1';
result.mul_hilo_sel := '1';
-- when op_mflo =>
when 18 =>
result.reg_write := '1';
result.mul_access := '1';
result.mul_hilo_sel := '0';
-- when op_mthi =>
when 17 =>
result.mul_hilo_we := '1';
result.mul_hilo_sel := '1';
-- when op_mtlo =>
when 19 =>
result.mul_hilo_we := '1';
result.mul_hilo_sel := '0';
-- when op_mult =>
when 24 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '1';
result.mul_mul_divn := '1';
-- when op_multu =>
when 25 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '0';
result.mul_mul_divn := '1';
-- when op_or =>
when 37 =>
result.alu.outsel := alu_or;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_nor =>
when 39 =>
result.alu.outsel := alu_nor;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sll =>
when 0 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '0';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_sllv =>
when 4 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '0';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_slt =>
when 42 =>
result.alu.outsel := alu_lts;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sltu =>
when 43 =>
result.alu.outsel := alu_ltu;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sra =>
when 3 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '1';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_srav =>
when 7 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '1';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_srl =>
when 2 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '0';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_srlv =>
when 6 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '0';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_sub =>
when 34 =>
result.alu.outsel := alu_adder;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
result.alu_exc_en := '1';
-- when op_subu =>
when 35 =>
result.alu.outsel := alu_adder;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_syscall =>
when 12 =>
result.exc_syscall := '1';
result.except_en := '1';
-- when op_xor =>
when 38 =>
result.alu.outsel := alu_xor;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
when others =>
result.exc_illegal := '1';
end case;
-- REGIMM
when 1 =>
case rt is
-- when op_bgez =>
when 1 =>
result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '1';
-- when op_bgezal =>
when 17 =>
result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '1';
result.wptr_srcsel := wptr_src_const;
result.reg_write := '1';
result.reg_link := '1';
-- when op_bltz =>
when 0 =>
result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '0';
-- when op_bltzal =>
when 16 =>
result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '0';
result.wptr_srcsel := wptr_src_const;
result.reg_write := '1';
result.reg_link := '1';
when others =>
result.exc_illegal := '1';
end case;
-- when COPz =>
when 16 | 17 | 18 | 19 =>
result.cop_instr_en := '1';
-- when op_divu =>
when 27 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '0';
result.mul_mul_divn := '0';
-- when op_jalr =>
when 9 =>
result.jump_long := '1';
result.wptr_srcsel := wptr_src_imm;
result.reg_write := '1';
result.reg_link := '1';
-- when op_jr =>
when 8 =>
result.jump_long := '1';
-- when op_mfhi =>
when 16 =>
result.reg_write := '1';
result.mul_access := '1';
result.mul_hilo_sel := '1';
-- when op_mflo =>
when 18 =>
result.reg_write := '1';
result.mul_access := '1';
result.mul_hilo_sel := '0';
-- when op_mthi =>
when 17 =>
result.mul_hilo_we := '1';
result.mul_hilo_sel := '1';
-- when op_mtlo =>
when 19 =>
result.mul_hilo_we := '1';
result.mul_hilo_sel := '0';
-- when op_mult =>
when 24 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '1';
result.mul_mul_divn := '1';
-- when op_multu =>
when 25 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '0';
result.mul_mul_divn := '1';
-- when op_or =>
when 37 =>
result.alu.outsel := alu_or;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_nor =>
when 39 =>
result.alu.outsel := alu_nor;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sll =>
when 0 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '0';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_sllv =>
when 4 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '0';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_slt =>
when 42 =>
result.alu.outsel := alu_lts;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sltu =>
when 43 =>
result.alu.outsel := alu_ltu;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sra =>
when 3 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '1';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_srav =>
when 7 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '1';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_srl =>
when 2 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '0';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_srlv =>
when 6 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '0';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_sub =>
when 34 =>
result.alu.outsel := alu_adder;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
result.alu_exc_en := '1';
-- when op_subu =>
when 35 =>
result.alu.outsel := alu_adder;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_syscall =>
when 12 =>
result.exc_syscall := '1';
result.except_en := '1';
-- when op_xor =>
when 38 =>
result.alu.outsel := alu_xor;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
when others =>
result.exc_illegal := '1';
end case;
return result;
end special_ctrl_lines;
function gen_rom_special return rom_special_t is
variable result : rom_special_t;
variable func : func_t;
begin
for i in 0 to 2**func_t'length-1 loop
func := to_unsigned(i, func_t'length);
result(i) := special_ctrl_lines(func);
end loop;
return result;
end gen_rom_special;
function regimm_ctrl_lines(rt : reg_ptr_t) return ctrl_lines_t is
variable result : ctrl_lines_t;
variable op : integer range 0 to 2**reg_ptr_t'length-1;
begin
result := ctrl_lines_default;
op := to_integer(rt);
case op is
-- when op_bgez =>
when 1 =>
result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '1';
-- when op_bgezal =>
when 17 =>
result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '1';
result.wptr_srcsel := wptr_src_const;
result.reg_write := '1';
result.reg_link := '1';
-- when op_bltz =>
when 0 =>
result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '0';
-- when op_bltzal =>
when 16 =>
result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '0';
result.wptr_srcsel := wptr_src_const;
result.reg_write := '1';
result.reg_link := '1';
when others =>
result.exc_illegal := '1';
end case;
return result;
end regimm_ctrl_lines;
function gen_rom_regimm return rom_regimm_t is
variable result : rom_regimm_t;
variable rt : reg_ptr_t;
begin
for i in 0 to 2**reg_ptr_t'length-1 loop
rt := to_unsigned(i, reg_ptr_t'length);
result(i) := regimm_ctrl_lines(rt);
end loop;
return result;
end gen_rom_regimm;
function opcode_ctrl_lines(opc : opcode_t) return ctrl_lines_t is
variable result : ctrl_lines_t;
variable op : integer range 0 to 2**opcode_t'length-1;
begin
result := ctrl_lines_default;
op := to_integer(opc);
case op is
-- when op_addi =>
when 8 =>
result.imm_src := src_imm32;
@@ -793,10 +842,6 @@ package body mips_instr is
result.bc_src := bc_eq_ne;
result.bc_not := '1';
-- when op_cop =>
when 16 | 17 | 18 | 19 =>
result.cop_instr_en := '1';
-- when op_j =>
when 2 =>
result.jump := '1';
@@ -977,19 +1022,6 @@ package body mips_instr is
end opcode_ctrl_lines;
function gen_rom_opcode return rom_opcode_t is
variable result : rom_opcode_t;
variable opc : opcode_t;
begin
for i in 0 to 2**opcode_t'length-1 loop
opc := to_unsigned(i, opcode_t'length);
result(i) := opcode_ctrl_lines(opc);
end loop;
return result;
end gen_rom_opcode;
end mips_instr;
--------------------------------------------------------------------------