From fb4cad6eaf91a9a13dac31e2d4ea6bbb88abe903 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 9 Sep 2019 15:18:09 +1000 Subject: [PATCH] Remove second write port We only need two write ports for load with update instructions. Having two write ports just for this instruction is expensive. For now we will force them to be the only instruction in the pipeline, and take two cycles of writeback. Signed-off-by: Anton Blanchard --- common.vhdl | 5 +---- loadstore2.vhdl | 17 +++++++++++------ writeback.vhdl | 46 +++++++++++++++++++--------------------------- 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/common.vhdl b/common.vhdl index 6c0963f..29c37be 100644 --- a/common.vhdl +++ b/common.vhdl @@ -128,11 +128,8 @@ package common is write_enable: std_ulogic; write_reg : std_ulogic_vector(4 downto 0); write_data : std_ulogic_vector(63 downto 0); - write_enable2: std_ulogic; - write_reg2 : std_ulogic_vector(4 downto 0); - write_data2 : std_ulogic_vector(63 downto 0); end record; - constant Loadstore2ToWritebackInit : Loadstore2ToWritebackType := (valid => '0', write_enable => '0', write_enable2 => '0', others => (others => '0')); + constant Loadstore2ToWritebackInit : Loadstore2ToWritebackType := (valid => '0', write_enable => '0', others => (others => '0')); type Execute1ToExecute2Type is record valid: std_ulogic; diff --git a/loadstore2.vhdl b/loadstore2.vhdl index 9ac8c7b..dcf406f 100644 --- a/loadstore2.vhdl +++ b/loadstore2.vhdl @@ -86,6 +86,17 @@ begin if l_in.load = '1' then m_tmp.we <= '0'; + -- Load with update instructions write two GPR destinations. + -- We don't want the expense of two write ports, so make it + -- single in the pipeline and write back the update GPR now + -- and the load once we get the data back. We'll have to + -- revisit this when loads can take exceptions. + if l_in.update = '1' then + w_tmp.write_enable <= '1'; + w_tmp.write_reg <= l_in.update_reg; + w_tmp.write_data <= l_in.addr; + end if; + state <= WAITING_FOR_READ_ACK; else m_tmp.we <= '1'; @@ -135,12 +146,6 @@ begin w_tmp.write_enable <= '1'; w_tmp.write_reg <= l_saved.write_reg; - if l_saved.update = '1' then - w_tmp.write_enable2 <= '1'; - w_tmp.write_reg2 <= l_saved.update_reg; - w_tmp.write_data2 <= l_saved.addr; - end if; - m_tmp <= wishbone_master_out_init; state <= IDLE; end if; diff --git a/writeback.vhdl b/writeback.vhdl index 03174f7..e3e76e8 100644 --- a/writeback.vhdl +++ b/writeback.vhdl @@ -48,42 +48,34 @@ begin w_tmp <= WritebackToRegisterFileInit; c_tmp <= WritebackToCrFileInit; - if e.valid = '1' then - if e.write_enable = '1' then - w_tmp.write_reg <= e.write_reg; - w_tmp.write_data <= e.write_data; - w_tmp.write_enable <= '1'; - end if; + if e.write_enable = '1' then + w_tmp.write_reg <= e.write_reg; + w_tmp.write_data <= e.write_data; + w_tmp.write_enable <= '1'; + end if; - if e.write_cr_enable = '1' then - c_tmp.write_cr_enable <= '1'; - c_tmp.write_cr_mask <= e.write_cr_mask; - c_tmp.write_cr_data <= e.write_cr_data; - end if; + if e.write_cr_enable = '1' then + c_tmp.write_cr_enable <= '1'; + c_tmp.write_cr_mask <= e.write_cr_mask; + c_tmp.write_cr_data <= e.write_cr_data; end if; - if l.valid = '1' and l.write_enable = '1' then + if l.write_enable = '1' then w_tmp.write_reg <= l.write_reg; w_tmp.write_data <= l.write_data; w_tmp.write_enable <= '1'; end if; - if l.valid = '1' and l.write_enable2 = '1' then - w_tmp.write_reg2 <= l.write_reg2; - w_tmp.write_data2 <= l.write_data2; - w_tmp.write_enable2 <= '1'; + + if m.write_reg_enable = '1' then + w_tmp.write_enable <= '1'; + w_tmp.write_reg <= m.write_reg_nr; + w_tmp.write_data <= m.write_reg_data; end if; - if m.valid = '1' then - if m.write_reg_enable = '1' then - w_tmp.write_enable <= '1'; - w_tmp.write_reg <= m.write_reg_nr; - w_tmp.write_data <= m.write_reg_data; - end if; - if m.write_cr_enable = '1' then - c_tmp.write_cr_enable <= '1'; - c_tmp.write_cr_mask <= m.write_cr_mask; - c_tmp.write_cr_data <= m.write_cr_data; - end if; + if m.write_cr_enable = '1' then + c_tmp.write_cr_enable <= '1'; + c_tmp.write_cr_mask <= m.write_cr_mask; + c_tmp.write_cr_data <= m.write_cr_data; end if; end process; end;