X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=cpu%2Fsrc%2Fdecoder_b.vhd;h=525d408170a0b6b5bca6b12cfe42ec07f85df0e1;hb=b7b8e941c868a7ebdfcc3fbf15564dac19251ed6;hp=01c11f07b82393499d2f094f7677825b52158672;hpb=df2e395c56679967ad89ffb2911f760cf4c125e5;p=calu.git diff --git a/cpu/src/decoder_b.vhd b/cpu/src/decoder_b.vhd index 01c11f0..525d408 100644 --- a/cpu/src/decoder_b.vhd +++ b/cpu/src/decoder_b.vhd @@ -32,6 +32,7 @@ begin instr_s.bp := '0'; instr_s.op_detail := (others => '0'); instr_s.displacement := (others => '0'); + instr_s.int := '0'; instr_s.op_group := ADDSUB_OP; @@ -154,7 +155,7 @@ begin instr_s.op_detail(IMM_OPT) := '1'; instr_s.op_detail(NO_PSW_OPT) := instruction(0); - if (instr_s.opcode = "00111") then + if (instr_s.opcode = "00101") then instr_s.op_group := AND_OP; end if; @@ -184,7 +185,7 @@ begin -- instr_s.sreg_update := instruction(0); -- --================================================================= - if (instr_s.opcode = "01010" or instr_s.opcode = "01011") then + if (instr_s.opcode = "01010") then -- when "01010" => --shift instr_s.reg_dest_addr := instruction(22 downto 19); @@ -217,20 +218,26 @@ begin instr_s.reg_src1_addr := instruction(18 downto 15); instr_s.signext := instruction(2); instr_s.high_low := instruction(1); + instr_s.displacement(14 downto 0) := instruction(14 downto 0); instr_s.op_group := LDST_OP; instr_s.op_detail(NO_PSW_OPT) := '1'; + if (instr_s.displacement(14) = '1') then + instr_s.displacement(31 downto 15) := (others => '1'); + end if; + if (instr_s.opcode = "11010") then --ldi + instr_s.reg_src1_addr := instr_s.reg_dest_addr; + instr_s.op_detail(LOW_HIGH_OPT) := instr_s.high_low; + instr_s.op_detail(LDI_REPLACE_OPT) := instr_s.signext; + if (instr_s.high_low = '1') then instr_s.immediate(31 downto 16) := instruction(18 downto 3); instr_s.immediate(15 downto 0) := (others => '0'); else instr_s.immediate(15 downto 0) := instruction(18 downto 3); instr_s.immediate(31 downto 16) := (others => '0'); - - --instr_s.immediate(11 downto 0) := instruction(14 downto 3); - --instr_s.immediate(WORD_WIDTH-1 downto 12) := (others => '0'); end if; if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then @@ -239,6 +246,14 @@ begin instr_s.op_detail(IMM_OPT) := '1'; end if; + + if (instr_s.opcode = "10000") then + instr_s.op_detail(HWORD_OPT) := '1'; + end if; + + if (instr_s.opcode = "10010") then + instr_s.op_detail(BYTE_OPT) := '1'; + end if; end if; -- when "10000" => --ldh @@ -273,10 +288,47 @@ begin 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_detail(ST_OPT) := '1'; instr_s.op_group := LDST_OP; + + if (instr_s.displacement(14) = '1') then + instr_s.displacement(31 downto 15) := (others => '1'); + end if; + + if (instr_s.opcode = "10001") then + instr_s.op_detail(HWORD_OPT) := '1'; + end if; + + if (instr_s.opcode = "10011") then + instr_s.op_detail(BYTE_OPT) := '1'; + end if; + end if; + -- =============================================================== + + if (instr_s.opcode = "01011") then -- stack op + instr_s.reg_src1_addr := instruction(22 downto 19); + instr_s.reg_dest_addr := instruction(22 downto 19); + instr_s.op_group := STACK_OP; + instr_s.op_detail(NO_PSW_OPT) := '1'; + + case instruction(18 downto 17) is + when "00" => + instr_s.op_detail(PUSH_OPT) := '0'; + + when "01" => null; + + when "10" => null; + + when "11" => + instr_s.op_detail(PUSH_OPT) := '1'; + + when others => null; + end case; + + end if; + -- when "10001" => --sth -- instr_s.reg_src1_addr := instruction(22 downto 19); -- instr_s.reg_src2_addr := instruction(18 downto 15); @@ -302,7 +354,8 @@ begin instr_s.jmptype := instruction(3 downto 2); instr_s.signext := instruction(0); instr_s.op_detail(NO_PSW_OPT) := '1'; - + instr_s.op_detail(DIRECT_JUMP_OPT) := instruction(4); + instr_s.int := instruction(4); if (instr_s.opcode = "10110") then instr_s.op_detail(IMM_OPT) := '1'; @@ -316,20 +369,47 @@ begin 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; + case instr_s.jmptype is + when "00" => + instr_s.op_group := JMP_OP; + + when "01" => + instr_s.op_group := JMP_ST_OP; + + when "10" => + instr_s.op_group := JMP_ST_OP; + instr_s.op_detail(RET_OPT) := '1'; + + when "11" => + instr_s.op_group := JMP_OP; + instr_s.op_detail(JMP_REG_OPT) := '1'; + instr_s.op_detail(IMM_OPT) := '1'; + instr_s.immediate := (others => '0'); + + when others => null; + end case; - if (instr_s.jmptype = "01") then - instr_s.op_group := JMP_ST_OP; - -- instr_s.op_detail(RET_OPT) := '0'; - end if; - - if (instr_s.jmptype = "10") then - instr_s.op_group := JMP_ST_OP; - instr_s.op_detail(RET_OPT) := '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.jmptype = "01") then +-- instr_s.op_group := JMP_ST_OP; +-- -- instr_s.op_detail(RET_OPT) := '0'; +-- end if; +-- +-- if (instr_s.jmptype = "10") then +-- instr_s.op_group := JMP_ST_OP; +-- instr_s.op_detail(RET_OPT) := '1'; +-- end if; +-- +-- if (instr_s.jmptype = "11") then +-- instr_s.op_group := JMP_OP; +-- instr_s.op_detail(JMP_REG_OPT) := '1'; +-- instr_s.op_detail(IMM_OPT) := '1'; +-- instr_s.immediate := (others => '0'); +-- end if; if (instr_s.predicates = "1111" or instr_s.jmptype = "10") then instr_s.bp := '0';