From 1587d9e6eb284a4fa8ead86abef3be719ba8cf6f Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 21 Feb 2020 12:34:23 +1100 Subject: [PATCH] dcache: Fix obscure bug and minor cleanups The obscure bug is that a non-cacheable load with update would never do the update and would never complete the instruction. This is fixed by making state NC_LOAD_WAIT_ACK go to LOAD_UPDATE2 if r1.req.update is set. The slow load forms with update can go to LOAD_UPDATE2 at the end rather than LOAD_UPDATE, thus saving a cycle. Loads with a cache hit need the LOAD_UPDATE state in the third cycle since they are not writing back until the 4th cycle, when the state is LOAD_UPDATE2. Slow loads (cacheable loads that miss and non-cacheable loads) currently go to LOAD_UPDATE in the cycle after they see r1.wb.ack = 1 for the last time, but that cycle is the cycle where they write back, and the following cycle does nothing. Going to LOAD_UPDATE2 in those cases saves a cycle and makes them consistent with the load hit case. The logic in the RELOAD_WAIT_ACK case doesn't need to check r1.req.load = '1' since we only ever use RELOAD_WAIT_ACK for loads. There are also some whitespace fixes and a typo fix. Signed-off-by: Paul Mackerras --- dcache.vhdl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/dcache.vhdl b/dcache.vhdl index df54c95..ddc4769 100644 --- a/dcache.vhdl +++ b/dcache.vhdl @@ -500,7 +500,7 @@ begin -- If it's not a load with update, complete it now if r2.load_is_update = '0' then d_out.valid <= '1'; - end if; + end if; end if; -- Slow ops (load miss, NC, stores) @@ -508,7 +508,7 @@ begin -- If it's a load, enable register writeback and switch -- mux accordingly -- - if r1.req.load then + if r1.req.load then d_out.write_reg <= r1.req.write_reg; d_out.write_enable <= '1'; @@ -679,7 +679,7 @@ begin end process; -- - -- Every other case is handled by this stage machine: + -- Every other case is handled by this state machine: -- -- * Cache load miss/reload (in conjunction with "rams") -- * Load hits for update forms @@ -835,8 +835,8 @@ begin -- we also need to do the deferred update cycle. -- r1.slow_valid <= '1'; - if r1.req.load = '1' and r1.req.update = '1' then - r1.state <= LOAD_UPDATE; + if r1.req.update = '1' then + r1.state <= LOAD_UPDATE2; report "completing miss with load-update !"; else r1.state <= IDLE; @@ -864,13 +864,16 @@ begin -- Got ack ? complete. if wishbone_in.ack = '1' then + r1.state <= IDLE; if r1.state = NC_LOAD_WAIT_ACK then r1.slow_data <= wishbone_in.dat; + if r1.req.update = '1' then + r1.state <= LOAD_UPDATE2; + end if; end if; r1.slow_valid <= '1'; r1.wb.cyc <= '0'; r1.wb.stb <= '0'; - r1.state <= IDLE; end if; end case; end if;