- 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
+148 -116
View File
@@ -43,12 +43,7 @@ package mips_instr is
function extract_bimm18(instr, pc : word_t) return word_t; function extract_bimm18(instr, pc : word_t) return word_t;
function decode_op(instr : word_t) return op_t; function decode_op(instr : word_t) return op_t;
function ctrl_lines_default return ctrl_lines_t; function ctrl_lines_default return ctrl_lines_t;
function special_ctrl_lines(func : func_t) return ctrl_lines_t; function opcode_ctrl_lines(instr : word_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;
end mips_instr; end mips_instr;
@@ -153,12 +148,14 @@ package body mips_instr is
variable opc : natural range 0 to 63; variable opc : natural range 0 to 63;
variable func : natural range 0 to 63; variable func : natural range 0 to 63;
variable rt : natural range 0 to 31; variable rt : natural range 0 to 31;
variable rs : natural range 0 to 31;
begin begin
opc := to_integer(extract_opc(instr)); opc := to_integer(extract_opc(instr));
func := to_integer(extract_func(instr)); func := to_integer(extract_func(instr));
rt := to_integer(extract_rt(instr)); rt := to_integer(extract_rt(instr));
rs := to_integer(extract_rs(instr));
result := op_sll; result := op_sll;
@@ -317,16 +314,100 @@ package body mips_instr is
result := op_lui; result := op_lui;
when 16 => 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 => 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 => 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 => 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 => when 32 =>
result := op_lb; result := op_lb;
@@ -364,6 +445,9 @@ package body mips_instr is
when 46 => when 46 =>
result := op_swr; result := op_swr;
when 48 =>
result := op_lwc0; -- illegal
when 49 => when 49 =>
result := op_lwc1; result := op_lwc1;
@@ -373,6 +457,9 @@ package body mips_instr is
when 51 => when 51 =>
result := op_lwc3; result := op_lwc3;
when 56 =>
result := op_swc0; -- illegal
when 57 => when 57 =>
result := op_swc1; result := op_swc1;
@@ -436,18 +523,26 @@ package body mips_instr is
end ctrl_lines_default; end ctrl_lines_default;
function opcode_ctrl_lines(instr : word_t) return ctrl_lines_t is
function special_ctrl_lines(func : func_t) return ctrl_lines_t is
variable result : ctrl_lines_t; 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 begin
result := ctrl_lines_default; 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));
op := to_integer(func); case opc is
case op is -- SPECIAL
when 0 =>
case func is
-- when op_add => -- when op_add =>
when 32 => when 32 =>
result.alu.outsel := alu_adder; result.alu.outsel := alu_adder;
result.alu.add := '1'; result.alu.add := '1';
@@ -456,7 +551,7 @@ package body mips_instr is
result.reg_write := '1'; result.reg_write := '1';
result.alu_exc_en := '1'; result.alu_exc_en := '1';
-- when op_addu => -- when op_addu =>
when 33 => when 33 =>
result.alu.outsel := alu_adder; result.alu.outsel := alu_adder;
result.alu.add := '1'; result.alu.add := '1';
@@ -464,94 +559,94 @@ package body mips_instr is
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_and => -- when op_and =>
when 36 => when 36 =>
result.alu.outsel := alu_and; result.alu.outsel := alu_and;
result.alu.op1_src := alu_src_reg; result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_break => -- when op_break =>
when 13 => when 13 =>
result.exc_break := '1'; result.exc_break := '1';
result.except_en := '1'; result.except_en := '1';
-- when op_div => -- when op_div =>
when 26 => when 26 =>
result.mul_access := '1'; result.mul_access := '1';
result.mul_start := '1'; result.mul_start := '1';
result.mul_s_un := '1'; result.mul_s_un := '1';
result.mul_mul_divn := '0'; result.mul_mul_divn := '0';
-- when op_divu => -- when op_divu =>
when 27 => when 27 =>
result.mul_access := '1'; result.mul_access := '1';
result.mul_start := '1'; result.mul_start := '1';
result.mul_s_un := '0'; result.mul_s_un := '0';
result.mul_mul_divn := '0'; result.mul_mul_divn := '0';
-- when op_jalr => -- when op_jalr =>
when 9 => when 9 =>
result.jump_long := '1'; result.jump_long := '1';
result.wptr_srcsel := wptr_src_imm; result.wptr_srcsel := wptr_src_imm;
result.reg_write := '1'; result.reg_write := '1';
result.reg_link := '1'; result.reg_link := '1';
-- when op_jr => -- when op_jr =>
when 8 => when 8 =>
result.jump_long := '1'; result.jump_long := '1';
-- when op_mfhi => -- when op_mfhi =>
when 16 => when 16 =>
result.reg_write := '1'; result.reg_write := '1';
result.mul_access := '1'; result.mul_access := '1';
result.mul_hilo_sel := '1'; result.mul_hilo_sel := '1';
-- when op_mflo => -- when op_mflo =>
when 18 => when 18 =>
result.reg_write := '1'; result.reg_write := '1';
result.mul_access := '1'; result.mul_access := '1';
result.mul_hilo_sel := '0'; result.mul_hilo_sel := '0';
-- when op_mthi => -- when op_mthi =>
when 17 => when 17 =>
result.mul_hilo_we := '1'; result.mul_hilo_we := '1';
result.mul_hilo_sel := '1'; result.mul_hilo_sel := '1';
-- when op_mtlo => -- when op_mtlo =>
when 19 => when 19 =>
result.mul_hilo_we := '1'; result.mul_hilo_we := '1';
result.mul_hilo_sel := '0'; result.mul_hilo_sel := '0';
-- when op_mult => -- when op_mult =>
when 24 => when 24 =>
result.mul_access := '1'; result.mul_access := '1';
result.mul_start := '1'; result.mul_start := '1';
result.mul_s_un := '1'; result.mul_s_un := '1';
result.mul_mul_divn := '1'; result.mul_mul_divn := '1';
-- when op_multu => -- when op_multu =>
when 25 => when 25 =>
result.mul_access := '1'; result.mul_access := '1';
result.mul_start := '1'; result.mul_start := '1';
result.mul_s_un := '0'; result.mul_s_un := '0';
result.mul_mul_divn := '1'; result.mul_mul_divn := '1';
-- when op_or => -- when op_or =>
when 37 => when 37 =>
result.alu.outsel := alu_or; result.alu.outsel := alu_or;
result.alu.op1_src := alu_src_reg; result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_nor => -- when op_nor =>
when 39 => when 39 =>
result.alu.outsel := alu_nor; result.alu.outsel := alu_nor;
result.alu.op1_src := alu_src_reg; result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_sll => -- when op_sll =>
when 0 => when 0 =>
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2; result.alu.outsel := alu_shift2;
@@ -559,7 +654,7 @@ package body mips_instr is
result.shamt2_srcsel := sa_src_imm; result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1'; result.reg_write := '1';
-- when op_sllv => -- when op_sllv =>
when 4 => when 4 =>
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2; result.alu.outsel := alu_shift2;
@@ -567,7 +662,7 @@ package body mips_instr is
result.shamt2_srcsel := sa_src_reg; result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_slt => -- when op_slt =>
when 42 => when 42 =>
result.alu.outsel := alu_lts; result.alu.outsel := alu_lts;
result.alu.add := '0'; result.alu.add := '0';
@@ -575,7 +670,7 @@ package body mips_instr is
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_sltu => -- when op_sltu =>
when 43 => when 43 =>
result.alu.outsel := alu_ltu; result.alu.outsel := alu_ltu;
result.alu.add := '0'; result.alu.add := '0';
@@ -583,7 +678,7 @@ package body mips_instr is
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_sra => -- when op_sra =>
when 3 => when 3 =>
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2; result.alu.outsel := alu_shift2;
@@ -592,7 +687,7 @@ package body mips_instr is
result.shamt2_srcsel := sa_src_imm; result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1'; result.reg_write := '1';
-- when op_srav => -- when op_srav =>
when 7 => when 7 =>
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2; result.alu.outsel := alu_shift2;
@@ -601,7 +696,7 @@ package body mips_instr is
result.shamt2_srcsel := sa_src_reg; result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_srl => -- when op_srl =>
when 2 => when 2 =>
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2; result.alu.outsel := alu_shift2;
@@ -610,7 +705,7 @@ package body mips_instr is
result.shamt2_srcsel := sa_src_imm; result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1'; result.reg_write := '1';
-- when op_srlv => -- when op_srlv =>
when 6 => when 6 =>
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2; result.alu.outsel := alu_shift2;
@@ -619,7 +714,7 @@ package body mips_instr is
result.shamt2_srcsel := sa_src_reg; result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_sub => -- when op_sub =>
when 34 => when 34 =>
result.alu.outsel := alu_adder; result.alu.outsel := alu_adder;
result.alu.add := '0'; result.alu.add := '0';
@@ -628,7 +723,7 @@ package body mips_instr is
result.reg_write := '1'; result.reg_write := '1';
result.alu_exc_en := '1'; result.alu_exc_en := '1';
-- when op_subu => -- when op_subu =>
when 35 => when 35 =>
result.alu.outsel := alu_adder; result.alu.outsel := alu_adder;
result.alu.add := '0'; result.alu.add := '0';
@@ -636,12 +731,12 @@ package body mips_instr is
result.alu.op2_src := alu_src_reg; result.alu.op2_src := alu_src_reg;
result.reg_write := '1'; result.reg_write := '1';
-- when op_syscall => -- when op_syscall =>
when 12 => when 12 =>
result.exc_syscall := '1'; result.exc_syscall := '1';
result.except_en := '1'; result.except_en := '1';
-- when op_xor => -- when op_xor =>
when 38 => when 38 =>
result.alu.outsel := alu_xor; result.alu.outsel := alu_xor;
result.alu.op1_src := alu_src_reg; result.alu.op1_src := alu_src_reg;
@@ -653,40 +748,17 @@ package body mips_instr is
end case; end case;
return result; -- REGIMM
when 1 =>
case rt is
end special_ctrl_lines; -- when op_bgez =>
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 => when 1 =>
result.branch := '1'; result.branch := '1';
result.bc_src := bc_ltz_gez; result.bc_src := bc_ltz_gez;
result.bc_not := '1'; result.bc_not := '1';
-- when op_bgezal => -- when op_bgezal =>
when 17 => when 17 =>
result.branch := '1'; result.branch := '1';
result.bc_src := bc_ltz_gez; result.bc_src := bc_ltz_gez;
@@ -695,13 +767,13 @@ package body mips_instr is
result.reg_write := '1'; result.reg_write := '1';
result.reg_link := '1'; result.reg_link := '1';
-- when op_bltz => -- when op_bltz =>
when 0 => when 0 =>
result.branch := '1'; result.branch := '1';
result.bc_src := bc_ltz_gez; result.bc_src := bc_ltz_gez;
result.bc_not := '0'; result.bc_not := '0';
-- when op_bltzal => -- when op_bltzal =>
when 16 => when 16 =>
result.branch := '1'; result.branch := '1';
result.bc_src := bc_ltz_gez; result.bc_src := bc_ltz_gez;
@@ -715,32 +787,9 @@ package body mips_instr is
end case; end case;
return result; -- when COPz =>
when 16 | 17 | 18 | 19 =>
end regimm_ctrl_lines; result.cop_instr_en := '1';
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 op_addi =>
when 8 => when 8 =>
@@ -793,10 +842,6 @@ package body mips_instr is
result.bc_src := bc_eq_ne; result.bc_src := bc_eq_ne;
result.bc_not := '1'; result.bc_not := '1';
-- when op_cop =>
when 16 | 17 | 18 | 19 =>
result.cop_instr_en := '1';
-- when op_j => -- when op_j =>
when 2 => when 2 =>
result.jump := '1'; result.jump := '1';
@@ -977,19 +1022,6 @@ package body mips_instr is
end opcode_ctrl_lines; 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; end mips_instr;
-------------------------------------------------------------------------- --------------------------------------------------------------------------