Remove second write port
authorAnton Blanchard <anton@linux.ibm.com>
Mon, 9 Sep 2019 05:18:09 +0000 (15:18 +1000)
committerAnton Blanchard <anton@ozlabs.org>
Mon, 9 Sep 2019 05:18:09 +0000 (15:18 +1000)
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 <anton@linux.ibm.com>
common.vhdl
loadstore2.vhdl
writeback.vhdl

index 6c0963f9de006a85f0046fb6060102a7406000ff..29c37bef18150c0e408cf5025063a86b995048b5 100644 (file)
@@ -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;
index 9ac8c7bbd0fe78628cda6b899dff7b3c08de9b74..dcf406f081dfac4514314172f1477d91ef2a4861 100644 (file)
@@ -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;
index 03174f7b16b8d07214fe12ca673e957886dda2e2..e3e76e8b467b23ab347b5586037e278c95b5655b 100644 (file)
@@ -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;