From df7d337b1f8769f7546d49efea4202d8fc3ddf75 Mon Sep 17 00:00:00 2001 From: Stefan Date: Mon, 15 Nov 2010 11:37:06 +0100 Subject: [PATCH] pipe2 --- cpu/src/common_pkg.vhd | 5 +- cpu/src/decode_stage_b.vhd | 26 ++++++- cpu/src/decoder_b.vhd | 53 ++++++++++++-- cpu/src/exec_op/add_op_b.vhd | 122 ++++++++++++++++----------------- cpu/src/exec_op/and_op_b.vhd | 44 ++++++------ cpu/src/exec_op/or_op_b.vhd | 44 ++++++------ cpu/src/exec_op/shift_op_b.vhd | 92 ++++++++++++------------- cpu/src/exec_op/xor_op_b.vhd | 44 ++++++------ 8 files changed, 251 insertions(+), 179 deletions(-) diff --git a/cpu/src/common_pkg.vhd b/cpu/src/common_pkg.vhd index 9398fb2..1dca196 100755 --- a/cpu/src/common_pkg.vhd +++ b/cpu/src/common_pkg.vhd @@ -35,7 +35,7 @@ package common_pkg is subtype instruction_word_t is std_logic_vector(WORD_WIDTH-1 downto 0); subtype instruction_addr_t is std_logic_vector(INSTR_ADDR_WIDTH-1 downto 0); - subtype gp_addr_t is unsigned(REG_ADDR_WIDTH-1 downto 0); + subtype gp_addr_t is std_logic_vector(REG_ADDR_WIDTH-1 downto 0); subtype data_ram_word_t is std_logic_vector(WORD_WIDTH-1 downto 0); subtype data_ram_addr_t is std_logic_vector(DATA_ADDR_WIDTH-1 downto 0); @@ -79,6 +79,8 @@ package common_pkg is carry, sreg_update, high_low, fill, signext, bp, arith, left_right : std_logic; + op_detail : op_pot_t; + end record; @@ -87,6 +89,7 @@ package common_pkg is rtw_reg : gp_register_t; rtw_reg1 : std_logic; rtw_reg2 : std_logic; + immediate : gp_register_t; end record; diff --git a/cpu/src/decode_stage_b.vhd b/cpu/src/decode_stage_b.vhd index 28c04c3..54cf728 100644 --- a/cpu/src/decode_stage_b.vhd +++ b/cpu/src/decode_stage_b.vhd @@ -8,7 +8,6 @@ use work.core_pkg.all; use work.common_pkg.all; - architecture behav of decode_stage is signal instr_spl : instruction_rec; @@ -60,6 +59,29 @@ begin end process; +-- type dec_op is record +-- condition : condition_t; +-- op_group : op_info_t; +-- op_detail : op_opt_t; +-- brpr : std_logic; +-- +-- src1 : gp_register_t; +-- src2 : gp_register_t; +-- +-- saddr1 : gp_addr_t; +-- saddr2 : gp_addr_t; +-- +-- daddr : gp_addr_t; +-- +-- end record; + +to_alu: process(instr_spl) + +begin + + +end process; + -- async process: decides between memory and read-through-write buffer on output output: process(rtw_rec, reg1_mem_data, reg2_mem_data) @@ -87,6 +109,8 @@ begin rtw_rec_nxt.rtw_reg1 <= '0'; rtw_rec_nxt.rtw_reg2 <= '0'; + rtw_rec_nxt.immediate <= instr_spl.immediate; + if (reg_w_addr = instr_spl.reg_src1_addr) then rtw_rec_nxt.rtw_reg1 <= '1'; end if; diff --git a/cpu/src/decoder_b.vhd b/cpu/src/decoder_b.vhd index 1804811..9e043b2 100644 --- a/cpu/src/decoder_b.vhd +++ b/cpu/src/decoder_b.vhd @@ -34,6 +34,7 @@ begin instr_s.signext := '0'; instr_s.bp := '0'; instr_s.arith := '0'; + instr_s.op_detail := (others => '0'); -- special function register operations missing @@ -46,6 +47,17 @@ begin 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; + + 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; end if; -- when "00001" => --sub -- instr_s.reg_dest_addr := instruction(22 downto 19); @@ -90,8 +102,15 @@ begin 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); + + 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); @@ -114,6 +133,13 @@ begin 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); end if; -- when "00111" => --orx @@ -143,6 +169,11 @@ begin 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); end if; -- when "01011" => --stackop @@ -165,8 +196,11 @@ begin 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'); + 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.op_detail(IMM_OPT) := '1'; end if; end if; @@ -242,7 +276,18 @@ 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; + end if; -- when "11001" => --cmpi diff --git a/cpu/src/exec_op/add_op_b.vhd b/cpu/src/exec_op/add_op_b.vhd index e3d62c6..919c795 100755 --- a/cpu/src/exec_op/add_op_b.vhd +++ b/cpu/src/exec_op/add_op_b.vhd @@ -1,61 +1,61 @@ -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -use work.common_pkg.all; -use work.alu_pkg.all; - -architecture add_op of exec_op is - -signal sub, addc : std_logic; - -begin - -sub <= op_detail(SUB_OPT); -addc <= op_detail(CARRY_OPT); - -calc: process(left_operand, right_operand, alu_state, sub, addc) - variable alu_result_v : alu_result_rec; - variable complement : gp_register_t; - variable carry_res : unsigned(gp_register_t'length downto 0); - variable tmp_right_operand : unsigned(gp_register_t'length downto 0); - variable oflo1, oflo2, l_neg, r_neg : std_logic; - variable addcarry : unsigned(carry_res'range); -begin - alu_result_v := alu_state; - - addcarry := (others =>'0'); - addcarry(0) := alu_state.status.carry and addc; - - complement := inc(not(right_operand)); - l_neg := left_operand(gp_register_t'high); - - carry_res := unsigned('0' & left_operand)+addcarry; - oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high)); - - if sub = '1' then - tmp_right_operand := unsigned('0' & complement); - else - tmp_right_operand := unsigned('0' & right_operand); - end if; - - l_neg := std_logic_vector(carry_res)(gp_register_t'high); - r_neg := std_logic_vector(tmp_right_operand)(gp_register_t'high); - - carry_res := carry_res + tmp_right_operand; - oflo2 := add_oflo(l_neg,r_neg,std_logic_vector(carry_res)(gp_register_t'high)); - - - alu_result_v.result := std_logic_vector(carry_res)(gp_register_t'range); - alu_result_v.status.carry := std_logic_vector(carry_res)(carry_res'high); - - - alu_result_v.status.carry := oflo1 or oflo2; - - --sign will be set globally. - --zero will be set globally. - - alu_result <= alu_result_v; -end process; - -end architecture add_op; +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture add_op of exec_op is + +signal sub, addc : std_logic; + +begin + +sub <= op_detail(SUB_OPT); +addc <= op_detail(CARRY_OPT); + +calc: process(left_operand, right_operand, alu_state, sub, addc) + variable alu_result_v : alu_result_rec; + variable complement : gp_register_t; + variable carry_res : unsigned(gp_register_t'length downto 0); + variable tmp_right_operand : unsigned(gp_register_t'length downto 0); + variable oflo1, oflo2, l_neg, r_neg : std_logic; + variable addcarry : unsigned(carry_res'range); +begin + alu_result_v := alu_state; + + addcarry := (others =>'0'); + addcarry(0) := alu_state.status.carry and addc; + + complement := inc(not(right_operand)); + l_neg := left_operand(gp_register_t'high); + + carry_res := unsigned('0' & left_operand)+addcarry; + oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high)); + + if sub = '1' then + tmp_right_operand := unsigned('0' & complement); + else + tmp_right_operand := unsigned('0' & right_operand); + end if; + + l_neg := std_logic_vector(carry_res)(gp_register_t'high); + r_neg := std_logic_vector(tmp_right_operand)(gp_register_t'high); + + carry_res := carry_res + tmp_right_operand; + oflo2 := add_oflo(l_neg,r_neg,std_logic_vector(carry_res)(gp_register_t'high)); + + + alu_result_v.result := std_logic_vector(carry_res)(gp_register_t'range); + alu_result_v.status.carry := std_logic_vector(carry_res)(carry_res'high); + + + alu_result_v.status.carry := oflo1 or oflo2; + + --sign will be set globally. + --zero will be set globally. + + alu_result <= alu_result_v; +end process; + +end architecture add_op; diff --git a/cpu/src/exec_op/and_op_b.vhd b/cpu/src/exec_op/and_op_b.vhd index 05c8f3e..6cacc78 100755 --- a/cpu/src/exec_op/and_op_b.vhd +++ b/cpu/src/exec_op/and_op_b.vhd @@ -1,22 +1,22 @@ -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -use work.common_pkg.all; -use work.alu_pkg.all; - -architecture and_op of exec_op is -begin - -calc: process(left_operand, right_operand, alu_state) - variable alu_result_v : alu_result_rec; - -begin - alu_result_v := alu_state; - - alu_result_v.result := left_operand and right_operand; - - alu_result <= alu_result_v; -end process; - -end architecture and_op; +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture and_op of exec_op is +begin + +calc: process(left_operand, right_operand, alu_state) + variable alu_result_v : alu_result_rec; + +begin + alu_result_v := alu_state; + + alu_result_v.result := left_operand and right_operand; + + alu_result <= alu_result_v; +end process; + +end architecture and_op; diff --git a/cpu/src/exec_op/or_op_b.vhd b/cpu/src/exec_op/or_op_b.vhd index fbe1ec8..bc6784d 100755 --- a/cpu/src/exec_op/or_op_b.vhd +++ b/cpu/src/exec_op/or_op_b.vhd @@ -1,22 +1,22 @@ -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -use work.common_pkg.all; -use work.alu_pkg.all; - -architecture or_op of exec_op is -begin - -calc: process(left_operand, right_operand, alu_state) - variable alu_result_v : alu_result_rec; - -begin - alu_result_v := alu_state; - - alu_result_v.result := left_operand or right_operand; - - alu_result <= alu_result_v; -end process; - -end architecture or_op; +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture or_op of exec_op is +begin + +calc: process(left_operand, right_operand, alu_state) + variable alu_result_v : alu_result_rec; + +begin + alu_result_v := alu_state; + + alu_result_v.result := left_operand or right_operand; + + alu_result <= alu_result_v; +end process; + +end architecture or_op; diff --git a/cpu/src/exec_op/shift_op_b.vhd b/cpu/src/exec_op/shift_op_b.vhd index 291b590..0b5a73c 100755 --- a/cpu/src/exec_op/shift_op_b.vhd +++ b/cpu/src/exec_op/shift_op_b.vhd @@ -1,46 +1,46 @@ -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -use work.common_pkg.all; -use work.alu_pkg.all; - -architecture shift_op of exec_op is - - signal logic, ls, carry : std_logic; - -begin - - logic <= op_detail(LOG_OPT); - ls <= op_detail(LEFT_OPT); - carry <= op_detail(CARRY_OPT); - -calc: process(left_operand, right_operand, logic,ls, carry, alu_state) - variable alu_result_v : alu_result_rec; - variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0); - variable tmp_sb : std_logic; - begin - alu_result_v := alu_state; - - if ls = '1' then - tmp_sb := (carry and alu_state.status.carry and logic); - tmp_shift := to_bitvector(alu_state.status.carry & left_operand & tmp_sb); - tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); - - alu_result_v.status.carry := to_stdlogicvector(tmp_shift)(tmp_shift'high); - - else - tmp_sb := (carry and alu_state.status.carry and logic) or (not(logic) and left_operand(gp_register_t'high)); - tmp_shift := to_bitvector(tmp_sb & left_operand & alu_state.status.carry); - tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); - - alu_result_v.status.carry := to_stdlogicvector(tmp_shift)(0); - end if; - - alu_result_v.result := to_stdlogicvector(tmp_shift)(gp_register_t'length downto 1); - - alu_result <= alu_result_v; - -end process; - -end architecture shift_op; +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture shift_op of exec_op is + + signal logic, ls, carry : std_logic; + +begin + + logic <= op_detail(LOG_OPT); + ls <= op_detail(LEFT_OPT); + carry <= op_detail(CARRY_OPT); + +calc: process(left_operand, right_operand, logic,ls, carry, alu_state) + variable alu_result_v : alu_result_rec; + variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0); + variable tmp_sb : std_logic; + begin + alu_result_v := alu_state; + + if ls = '1' then + tmp_sb := (carry and alu_state.status.carry and logic); + tmp_shift := to_bitvector(alu_state.status.carry & left_operand & tmp_sb); + tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); + + alu_result_v.status.carry := to_stdlogicvector(tmp_shift)(tmp_shift'high); + + else + tmp_sb := (carry and alu_state.status.carry and logic) or (not(logic) and left_operand(gp_register_t'high)); + tmp_shift := to_bitvector(tmp_sb & left_operand & alu_state.status.carry); + tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); + + alu_result_v.status.carry := to_stdlogicvector(tmp_shift)(0); + end if; + + alu_result_v.result := to_stdlogicvector(tmp_shift)(gp_register_t'length downto 1); + + alu_result <= alu_result_v; + +end process; + +end architecture shift_op; diff --git a/cpu/src/exec_op/xor_op_b.vhd b/cpu/src/exec_op/xor_op_b.vhd index 62c7db8..8d4089c 100755 --- a/cpu/src/exec_op/xor_op_b.vhd +++ b/cpu/src/exec_op/xor_op_b.vhd @@ -1,22 +1,22 @@ -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -use work.common_pkg.all; -use work.alu_pkg.all; - -architecture xor_op of exec_op is -begin - -calc: process(left_operand, right_operand, alu_state) - variable alu_result_v : alu_result_rec; - -begin - alu_result_v := alu_state; - - alu_result_v.result := left_operand xor right_operand; - - alu_result <= alu_result_v; -end process; - -end architecture xor_op; +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture xor_op of exec_op is +begin + +calc: process(left_operand, right_operand, alu_state) + variable alu_result_v : alu_result_rec; + +begin + alu_result_v := alu_state; + + alu_result_v.result := left_operand xor right_operand; + + alu_result <= alu_result_v; +end process; + +end architecture xor_op; -- 2.25.1