From b930136793b80b6a3a79a9b97864ab9ff3957472 Mon Sep 17 00:00:00 2001 From: Stefan Rebernig Date: Mon, 15 Nov 2010 20:28:45 +0100 Subject: [PATCH] pipeline erste version mit 31bit shifter (kostet 7MHz und viele LEs) --- cpu/create_project.tcl | 26 +++ cpu/src/alu_pkg.vhd | 390 +++++++++++++++++----------------- cpu/src/core_top.vhd | 38 +++- cpu/src/execute_stage_b.vhd | 2 +- cpu/src/gpm_b.vhd | 2 +- cpu/src/writeback_stage_b.vhd | 12 +- 6 files changed, 260 insertions(+), 210 deletions(-) diff --git a/cpu/create_project.tcl b/cpu/create_project.tcl index 6419c5a..0b13c22 100755 --- a/cpu/create_project.tcl +++ b/cpu/create_project.tcl @@ -46,6 +46,32 @@ if {$make_assignments} { set_global_assignment -name VHDL_FILE ../src/decoder_b.vhd set_global_assignment -name VHDL_FILE ../src/decode_stage.vhd set_global_assignment -name VHDL_FILE ../src/decode_stage_b.vhd + + set_global_assignment -name VHDL_FILE ../src/alu_pkg.vhd + + set_global_assignment -name VHDL_FILE ../src/extension_pkg.vhd + set_global_assignment -name VHDL_FILE ../src/gpm_pkg.vhd + + set_global_assignment -name VHDL_FILE ../src/exec_op.vhd + set_global_assignment -name VHDL_FILE ../src/exec_op/add_op_b.vhd + set_global_assignment -name VHDL_FILE ../src/exec_op/and_op_b.vhd + set_global_assignment -name VHDL_FILE ../src/exec_op/or_op_b.vhd + set_global_assignment -name VHDL_FILE ../src/exec_op/xor_op_b.vhd + set_global_assignment -name VHDL_FILE ../src/exec_op/shift_op_b.vhd + + set_global_assignment -name VHDL_FILE ../src/alu.vhd + set_global_assignment -name VHDL_FILE ../src/alu_b.vhd + + set_global_assignment -name VHDL_FILE ../src/gpm.vhd + set_global_assignment -name VHDL_FILE ../src/gpm_b.vhd + + set_global_assignment -name VHDL_FILE ../src/execute_stage.vhd + set_global_assignment -name VHDL_FILE ../src/execute_stage_b.vhd + + + set_global_assignment -name VHDL_FILE ../src/writeback_stage.vhd + set_global_assignment -name VHDL_FILE ../src/writeback_stage_b.vhd + set_location_assignment PIN_L1 -to sys_clk set_location_assignment PIN_R22 -to sys_res diff --git a/cpu/src/alu_pkg.vhd b/cpu/src/alu_pkg.vhd index cc085c7..99b4655 100755 --- a/cpu/src/alu_pkg.vhd +++ b/cpu/src/alu_pkg.vhd @@ -1,195 +1,195 @@ -library IEEE; - -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -use work.common_pkg.all; ---use work.core_extension.all; - - -package alu_pkg is - - type status_rec is record - zero : std_logic; - oflo : std_logic; - sign : std_logic; - carry : std_logic; - end record; - - subtype status_t is byte_t; - --type alu_interal_rec is record - -- - --end record alu_internal_rec; - - type alu_result_rec is record - result : gp_register_t; - result_addr : gp_addr_t; - - status : status_rec; - --stackpointer : gp_register_t; - - alu_jump : std_logic; - brpr : std_logic; - reg_op : std_logic; - mem_op : std_logic; - - --new_val : std_logic; - mem_en : std_logic; - - hw_op : std_logic; - byte_op : std_logic; - sign_xt : std_logic; - - end record alu_result_rec; - - constant SHIFT_WIDTH : integer := log2c(gp_register_t'length); - - constant COND_ZERO : condition_t := "0001"; - constant COND_NZERO : condition_t := "0000"; - constant COND_NOFLO : condition_t := "0010"; - constant COND_OFLO : condition_t := "0011"; - constant COND_NCARRY : condition_t := "0100"; - constant COND_CARRY : condition_t := "0101"; - constant COND_NSIGN : condition_t := "0110"; - constant COND_SIGN : condition_t := "0111"; - - constant COND_ABOVE : condition_t := "1000"; - constant COND_BEQ: condition_t := "1001"; - constant COND_GEQ : condition_t := "1010"; - constant COND_LT : condition_t := "1011"; - constant COND_GT : condition_t := "1100"; - - constant COND_LEQ : condition_t := "1101"; - constant COND_ALWAYS : condition_t := "1110"; - constant COND_NEVER : condition_t := "1111"; - - function add_oflo(l_neg, r_neg, res_neg : std_logic) return std_logic; - -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec; - - -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; - -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; - -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; - - -- function shift_op(left_operand, right_operand : gp_register_t; arith,sleft,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec; - - component alu is - --some modules won't need all inputs - port( - --System inputs - - clk : in std_logic; - reset : in std_logic; - --operation inputs - cond : in condition_t; - op_group : in op_info_t; - left_operand : in gp_register_t; - right_operand : in gp_register_t; - op_detail : in op_opt_t; - alu_state : in alu_result_rec; - alu_result : out alu_result_rec; - addr : out gp_register_t; - data : out gp_register_t - ); - end component alu; - -end package alu_pkg; - -package body alu_pkg is - - function add_oflo(l_neg, r_neg , res_neg: std_logic) return std_logic is - begin - return (l_neg AND r_neg AND not(res_neg)) OR - (not(l_neg) AND not(r_neg) AND res_neg); - end function add_oflo; - - -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec is - -- variable alu_result_out : 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_out := alu_result; - - -- addcarry := (others =>'0'); - -- addcarry(0) := unsigned(alu_result.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_out.result := std_logic_vector(carry_res)(gp_register_t'range); - -- alu_result_out.status.carry := std_logic_vector(carry_res)(carry_res'high); - - - -- alu_result_out.status.carry := oflo1 or oflo2; - - -- --sign will be set globally. - -- --zero will be set globally. - - -- return alu_result_out; - -- end function addsub_op; - - -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is - -- variable alu_result_out : alu_result_rec; - -- begin - -- alu_result_out := alu_result; - -- alu_result_out.result := left_operand and right_operand; - -- end function and_op; - - -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is - -- variable alu_result_out : alu_result_rec; - -- begin - -- alu_result_out := alu_result; - -- alu_result_out.result := left_operand or right_operand; - -- end function or_op; - - -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is - -- variable alu_result_out : alu_result_rec; - -- begin - -- alu_result_out := alu_result; - -- alu_result_out.result := left_operand xor right_operand; - -- end function xor_op; - - -- function shift_op(left_operand, right_operand : gp_register_t; arith,rs,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec is - -- variable alu_result_out : alu_result_rec; - -- variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0); - -- variable tmp_sb : std_logic; - -- begin - -- alu_result_out := alu_result; - - -- if rs = '1' then - -- tmp_sb := (carry and alu_result.status.carry and not(arith)) or (arith and left_operand(gp_register_t'high)); - -- tmp_shift := bit_vector(tmp_sb & left_operand & alu_result.status.carry); - -- tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); - - -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(0); - -- else - -- tmp_sb := (carry and alu_result.status.carry and not(arith)); - -- tmp_shift := bit_vector(alu_result.status.carry & left_operand & tmp_sb); - -- tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); - - -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(tmp_shift'high); - -- end if; - - -- alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1); - - -- end function shift_op; - -end package body alu_pkg; +library IEEE; + +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +--use work.core_extension.all; + + +package alu_pkg is + + type status_rec is record + zero : std_logic; + oflo : std_logic; + sign : std_logic; + carry : std_logic; + end record; + + subtype status_t is byte_t; + --type alu_interal_rec is record + -- + --end record alu_internal_rec; + + type alu_result_rec is record + result : gp_register_t; + result_addr : gp_addr_t; + + status : status_rec; + --stackpointer : gp_register_t; + + alu_jump : std_logic; + brpr : std_logic; + reg_op : std_logic; + mem_op : std_logic; + + --new_val : std_logic; + mem_en : std_logic; + + hw_op : std_logic; + byte_op : std_logic; + sign_xt : std_logic; + + end record alu_result_rec; + + constant SHIFT_WIDTH : integer := log2c(gp_register_t'length); + + constant COND_ZERO : condition_t := "0001"; + constant COND_NZERO : condition_t := "0000"; + constant COND_NOFLO : condition_t := "0010"; + constant COND_OFLO : condition_t := "0011"; + constant COND_NCARRY : condition_t := "0100"; + constant COND_CARRY : condition_t := "0101"; + constant COND_NSIGN : condition_t := "0110"; + constant COND_SIGN : condition_t := "0111"; + + constant COND_ABOVE : condition_t := "1000"; + constant COND_BEQ: condition_t := "1001"; + constant COND_GEQ : condition_t := "1010"; + constant COND_LT : condition_t := "1011"; + constant COND_GT : condition_t := "1100"; + + constant COND_LEQ : condition_t := "1101"; + constant COND_ALWAYS : condition_t := "1110"; + constant COND_NEVER : condition_t := "1111"; + + function add_oflo(l_neg, r_neg, res_neg : std_logic) return std_logic; + -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec; + + -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; + -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; + -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; + + -- function shift_op(left_operand, right_operand : gp_register_t; arith,sleft,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec; + + component alu is + --some modules won't need all inputs + port( + --System inputs + + clk : in std_logic; + reset : in std_logic; + --operation inputs + cond : in condition_t; + op_group : in op_info_t; + left_operand : in gp_register_t; + right_operand : in gp_register_t; + op_detail : in op_opt_t; + alu_state : in alu_result_rec; + alu_result : out alu_result_rec; + addr : out gp_register_t; + data : out gp_register_t + ); + end component alu; + +end package alu_pkg; + +package body alu_pkg is + + function add_oflo(l_neg, r_neg , res_neg: std_logic) return std_logic is + begin + return (l_neg AND r_neg AND not(res_neg)) OR + (not(l_neg) AND not(r_neg) AND res_neg); + end function add_oflo; + + -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec is + -- variable alu_result_out : 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_out := alu_result; + + -- addcarry := (others =>'0'); + -- addcarry(0) := unsigned(alu_result.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_out.result := std_logic_vector(carry_res)(gp_register_t'range); + -- alu_result_out.status.carry := std_logic_vector(carry_res)(carry_res'high); + + + -- alu_result_out.status.carry := oflo1 or oflo2; + + -- --sign will be set globally. + -- --zero will be set globally. + + -- return alu_result_out; + -- end function addsub_op; + + -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is + -- variable alu_result_out : alu_result_rec; + -- begin + -- alu_result_out := alu_result; + -- alu_result_out.result := left_operand and right_operand; + -- end function and_op; + + -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is + -- variable alu_result_out : alu_result_rec; + -- begin + -- alu_result_out := alu_result; + -- alu_result_out.result := left_operand or right_operand; + -- end function or_op; + + -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is + -- variable alu_result_out : alu_result_rec; + -- begin + -- alu_result_out := alu_result; + -- alu_result_out.result := left_operand xor right_operand; + -- end function xor_op; + + -- function shift_op(left_operand, right_operand : gp_register_t; arith,rs,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec is + -- variable alu_result_out : alu_result_rec; + -- variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0); + -- variable tmp_sb : std_logic; + -- begin + -- alu_result_out := alu_result; + + -- if rs = '1' then + -- tmp_sb := (carry and alu_result.status.carry and not(arith)) or (arith and left_operand(gp_register_t'high)); + -- tmp_shift := bit_vector(tmp_sb & left_operand & alu_result.status.carry); + -- tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); + + -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(0); + -- else + -- tmp_sb := (carry and alu_result.status.carry and not(arith)); + -- tmp_shift := bit_vector(alu_result.status.carry & left_operand & tmp_sb); + -- tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); + + -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(tmp_shift'high); + -- end if; + + -- alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1); + + -- end function shift_op; + +end package body alu_pkg; diff --git a/cpu/src/core_top.vhd b/cpu/src/core_top.vhd index 7ec0743..f146d8d 100644 --- a/cpu/src/core_top.vhd +++ b/cpu/src/core_top.vhd @@ -11,8 +11,7 @@ entity core_top is --System input pins sys_clk : in std_logic; sys_res : in std_logic; - - to_next_stage : out dec_op + result : out gp_register_t ); @@ -29,10 +28,23 @@ architecture behav of core_top is signal reg_w_addr_pin : std_logic_vector(REG_ADDR_WIDTH-1 downto 0); signal reg_wr_data_pin : gp_register_t; signal reg_we_pin : std_logic; + signal to_next_stage : dec_op; -- signal reg1_rd_data_pin : gp_register_t; -- signal reg2_rd_data_pin : gp_register_t; + signal result_pin : gp_register_t;--reg + signal result_addr_pin : gp_addr_t;--reg + signal addr_pin : word_t; --memaddr + signal data_pin : gp_register_t; --mem data --ureg + signal alu_jump_pin : std_logic;--reg + signal brpr_pin : std_logic; --reg + signal wr_en_pin : std_logic;--regop --reg + signal dmem_pin : std_logic;--memop + signal dmem_wr_en_pin : std_logic; + signal hword_pin : std_logic; + signal byte_s_pin : std_logic; + begin @@ -83,17 +95,29 @@ begin to_next_stage => to_next_stage ); + exec_st : execute_stage + generic map('0') + port map(sys_clk, sys_res,to_next_stage, result_pin, result_addr_pin,addr_pin, + data_pin, alu_jump_pin,brpr_pin, wr_en_pin, dmem_pin,dmem_wr_en_pin,hword_pin,byte_s_pin); + + writeback_st : writeback_stage + generic map('0', '1') + port map(sys_clk, sys_res, result_pin, result_addr_pin, addr_pin, data_pin, alu_jump_pin, brpr_pin, + wr_en_pin, dmem_pin, dmem_wr_en_pin, hword_pin, byte_s_pin, + reg_wr_data_pin, reg_we_pin, reg_w_addr_pin, jump_result_pin, alu_jump_bit_pin); + --init : process(all) --begin - jump_result_pin <= (others => '0'); - alu_jump_bit_pin <= '0'; - reg_w_addr_pin <= (others => '0'); - reg_wr_data_pin <= (others => '0'); - reg_we_pin <= '0'; +-- jump_result_pin <= (others => '0'); +-- alu_jump_bit_pin <= '0'; +-- reg_w_addr_pin <= (others => '0'); +-- reg_wr_data_pin <= (others => '0'); +-- reg_we_pin <= '0'; --end process; + result <= result_pin; end behav; diff --git a/cpu/src/execute_stage_b.vhd b/cpu/src/execute_stage_b.vhd index 1f2c194..5979a8b 100644 --- a/cpu/src/execute_stage_b.vhd +++ b/cpu/src/execute_stage_b.vhd @@ -51,7 +51,7 @@ begin end process; -asyn: process(reset,dec_instr, alu_nxt, psw) +asyn: process(reset,dec_instr, alu_nxt, psw, reg) begin condition <= dec_instr.condition; diff --git a/cpu/src/gpm_b.vhd b/cpu/src/gpm_b.vhd index 7327a9f..1fbc2ec 100644 --- a/cpu/src/gpm_b.vhd +++ b/cpu/src/gpm_b.vhd @@ -22,7 +22,7 @@ begin end if; end process syn; -asyn : process (clk, reset) +asyn : process (clk, reset, alu_nxt) begin reg_nxt.status <= alu_nxt.status; end process asyn; diff --git a/cpu/src/writeback_stage_b.vhd b/cpu/src/writeback_stage_b.vhd index 94af88c..9d8fdde 100644 --- a/cpu/src/writeback_stage_b.vhd +++ b/cpu/src/writeback_stage_b.vhd @@ -38,11 +38,11 @@ syn: process(clk, reset) begin if (reset = RESET_VALUE) then - wb_reg_nxt.address <= (others => '0'); - wb_reg_nxt.dmem_en <= '0'; - wb_reg_nxt.dmem_write_en <= '0'; - wb_reg_nxt.hword <= '0'; - wb_reg_nxt.byte_s <= '0'; + wb_reg.address <= (others => '0'); + wb_reg.dmem_en <= '0'; + wb_reg.dmem_write_en <= '0'; + wb_reg.hword <= '0'; + wb_reg.byte_s <= '0'; elsif rising_edge(clk) then wb_reg <= wb_reg_nxt; end if; @@ -58,7 +58,7 @@ end process; -shift_input: process(data_ram_read, address, dmem_en, dmem_write_en, hword, wb_reg, result) +shift_input: process(data_ram_read, address, dmem_en, dmem_write_en, hword, wb_reg, result, byte_s, alu_jmp, br_pred) begin wb_reg_nxt.address <= address; -- 2.25.1