X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=cpu%2Fsrc%2Fdecoder_b.vhd;h=339d11d1af28ff04ba55bbf8b6cc7667d26f2711;hb=6750eea5f750d928426114047ff342256a4fccc6;hp=1804811a9efac1583bd20e450b6c0d1afe32b734;hpb=5356e3e07b4c3f16d4f2494100e2c4e937cb0e5b;p=calu.git diff --git a/cpu/src/decoder_b.vhd b/cpu/src/decoder_b.vhd index 1804811..339d11d 100644 --- a/cpu/src/decoder_b.vhd +++ b/cpu/src/decoder_b.vhd @@ -25,15 +25,17 @@ begin instr_s.reg_src2_addr := (others => '0'); instr_s.immediate := (others => '0'); - instr_s.displacement := (others => '0'); instr_s.jmptype := (others => '0'); - instr_s.carry := '0'; - instr_s.sreg_update := '0'; instr_s.high_low := '0'; instr_s.fill := '0'; instr_s.signext := '0'; instr_s.bp := '0'; - instr_s.arith := '0'; + instr_s.op_detail := (others => '0'); + instr_s.displacement := (others => '0'); + + instr_s.op_group := ADDSUB_OP; + +-- type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP); -- special function register operations missing @@ -44,8 +46,32 @@ begin instr_s.reg_dest_addr := instruction(22 downto 19); instr_s.reg_src1_addr := instruction(18 downto 15); instr_s.reg_src2_addr := instruction(14 downto 11); - instr_s.carry := instruction(1); - instr_s.sreg_update := instruction(0); + + instr_s.op_detail(NO_PSW_OPT) := instruction(0); --instr_s.sreg_update; + + instr_s.op_group := ADDSUB_OP; + + if (instr_s.opcode = "00000") then + instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry; + end if; + + if (instr_s.opcode = "00001") then + instr_s.op_detail(SUB_OPT) := '1'; + instr_s.op_detail(CARRY_OPT) := instruction(1); --instr_s.carry; + end if; + + if (instr_s.opcode = "00100") then + instr_s.op_group := AND_OP; + end if; + + if (instr_s.opcode = "00110") then + instr_s.op_group := OR_OP; + end if; + + if (instr_s.opcode = "01000") then + instr_s.op_group := XOR_OP; + end if; + end if; -- when "00001" => --sub -- instr_s.reg_dest_addr := instruction(22 downto 19); @@ -84,14 +110,21 @@ begin instr_s.reg_src1_addr := instruction(18 downto 15); instr_s.immediate(11 downto 0) := instruction(14 downto 3); instr_s.signext := instruction(2); - instr_s.carry := instruction(1); - instr_s.sreg_update := instruction(0); if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then instr_s.immediate(31 downto 12) := (others => '1'); end if; - end if; + instr_s.op_detail(IMM_OPT) := '1'; + instr_s.op_detail(CARRY_OPT) := instruction(1); + instr_s.op_detail(NO_PSW_OPT) := instruction(0); + + instr_s.op_group := ADDSUB_OP; + + if (instr_s.opcode = "00011") then + instr_s.op_detail(SUB_OPT) := '1'; + end if; + end if; -- when "00011" => --subi -- instr_s.reg_dest_addr := instruction(22 downto 19); @@ -113,7 +146,25 @@ begin instr_s.immediate(15 downto 0) := instruction(18 downto 3); instr_s.high_low := instruction(2); instr_s.fill := instruction(1); - instr_s.sreg_update := instruction(0); + + if (instr_s.fill = '1') then + instr_s.immediate(31 downto 16) := (others => '1'); + end if; + + instr_s.op_detail(IMM_OPT) := '1'; + instr_s.op_detail(NO_PSW_OPT) := instruction(0); + + if (instr_s.opcode = "00111") then + instr_s.op_group := AND_OP; + end if; + + if (instr_s.opcode = "00111") then + instr_s.op_group := OR_OP; + end if; + + if (instr_s.opcode = "01001") then + instr_s.op_group := XOR_OP; + end if; end if; -- when "00111" => --orx @@ -139,10 +190,14 @@ begin instr_s.reg_dest_addr := instruction(22 downto 19); instr_s.reg_src1_addr := instruction(18 downto 15); instr_s.immediate(4 downto 0) := instruction(14 downto 10); - instr_s.left_right := instruction(3); - instr_s.arith := instruction(2); - instr_s.carry := instruction(1); - instr_s.sreg_update := instruction(0); + + instr_s.op_detail(RIGHT_OPT) := instruction(3); + instr_s.op_detail(NO_PSW_OPT) := instruction(0); + instr_s.op_detail(CARRY_OPT) := instruction(1); + instr_s.op_detail(ARITH_OPT) := instruction(2); + instr_s.op_detail(IMM_OPT) := '1'; + + instr_s.op_group := SHIFT_OP; end if; -- when "01011" => --stackop @@ -160,13 +215,20 @@ begin -- when "01110" => --ldw instr_s.reg_dest_addr := instruction(22 downto 19); instr_s.reg_src1_addr := instruction(18 downto 15); - instr_s.displacement(14 downto 0) := instruction(14 downto 0); instr_s.immediate(15 downto 0) := instruction(18 downto 3); instr_s.signext := instruction(2); instr_s.high_low := instruction(1); - if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then - instr_s.immediate(31 downto 16) := (others => '1'); + instr_s.op_group := LDST_OP; + instr_s.op_detail(NO_PSW_OPT) := '1'; + + if (instr_s.opcode = "11010") then + if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then + instr_s.immediate(31 downto 16) := (others => '1'); + end if; + instr_s.immediate(11 downto 0) := instruction(14 downto 3); + instr_s.immediate(WORD_WIDTH-1 downto 12) := (others => '0'); + instr_s.op_detail(IMM_OPT) := '1'; end if; end if; @@ -198,9 +260,12 @@ begin if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then --when "01111" => --stw - instr_s.reg_src1_addr := instruction(22 downto 19); -- register value - instr_s.reg_src2_addr := instruction(18 downto 15); -- mem addr + instr_s.reg_src2_addr := instruction(22 downto 19); -- register value + instr_s.reg_src1_addr := instruction(18 downto 15); -- mem addr instr_s.displacement(14 downto 0) := instruction(14 downto 0); + instr_s.op_detail(NO_PSW_OPT) := '1'; + instr_s.op_detail(ST_OPT) := '1'; + instr_s.op_group := LDST_OP; end if; -- when "10001" => --sth @@ -227,6 +292,29 @@ begin instr_s.bp := instruction(1); instr_s.jmptype := instruction(3 downto 2); instr_s.signext := instruction(0); + instr_s.op_detail(NO_PSW_OPT) := '1'; + + + if (instr_s.opcode = "10110") then + instr_s.op_detail(IMM_OPT) := '1'; + else + instr_s.immediate(31 downto 0) := (others => '0'); + instr_s.op_detail(JMP_REG_OPT) := '1'; + instr_s.op_detail(IMM_OPT) := '1'; + end if; + + if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then + instr_s.immediate(31 downto 16) := (others => '1'); + end if; + + if (instr_s.jmptype = "00") then +-- instr_s.op_detail(SUB_OPT) := not instr_s.opcode(0); + instr_s.op_group := JMP_OP; + end if; + + if (instr_s.predicates = "1111") then + instr_s.bp := '0'; + end if; end if; -- when "10111" => --brreg @@ -242,7 +330,21 @@ begin -- when "11000" => --cmp instr_s.reg_src1_addr := instruction(22 downto 19); instr_s.reg_src2_addr := instruction(18 downto 15); - instr_s.immediate(15 downto 0) := instruction(18 downto 3); + + if (instr_s.opcode = "11001") then + instr_s.immediate(15 downto 0) := instruction(18 downto 3); + instr_s.signext := instruction(2); + + if (instr_s.signext = '1' and instr_s.immediate(15) = '1') then + instr_s.immediate(31 downto 16) := (others => '1'); + end if; + + instr_s.op_detail(IMM_OPT) := '1'; + end if; + instr_s.op_detail(NO_DST_OPT) := '1'; + instr_s.op_group := ADDSUB_OP; + instr_s.op_detail(SUB_OPT) := '1'; + end if; -- when "11001" => --cmpi