From 1be6fbac3333a7f99c0cf7151100e8032f4cea50 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 11 Jul 2020 09:10:24 +1000 Subject: [PATCH] dcache: Remove dependency of r1.wb.adr/dat/sel on req_op This improves timing by setting r1.wb.{adr,dat,sel} to the next request when doing a write cycle on the wishbone before we know whether the next request has a TLB and cache hit or not, i.e. without depending on req_op. r1.wb.stb still depends on req_op. This contains a workaround for what is probably a bug elsewhere, in that changing r1.wb.sel unconditionally once we see stall=0 from the wishbone causes incorrect behaviour. Making it conditional on there being a valid following request appears to fix the problem. Signed-off-by: Paul Mackerras --- dcache.vhdl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dcache.vhdl b/dcache.vhdl index 4d9843e..4c1db9b 100644 --- a/dcache.vhdl +++ b/dcache.vhdl @@ -226,6 +226,7 @@ architecture rtl of dcache is type mem_access_request_t is record op : op_t; + valid : std_ulogic; dcbz : std_ulogic; real_addr : std_ulogic_vector(REAL_ADDR_BITS - 1 downto 0); data : std_ulogic_vector(63 downto 0); @@ -309,6 +310,7 @@ architecture rtl of dcache is signal req_op : op_t; signal req_data : std_ulogic_vector(63 downto 0); signal req_same_tag : std_ulogic; + signal req_go : std_ulogic; signal early_req_row : row_t; @@ -856,6 +858,7 @@ begin end if; end if; req_op <= op; + req_go <= go; -- Version of the row number that is valid one cycle earlier -- in the cases where we need to read the cache data BRAM. @@ -1240,6 +1243,7 @@ begin req := r1.req; else req.op := req_op; + req.valid := req_go; req.dcbz := r0.req.dcbz; req.real_addr := ra; req.data := r0.req.data; @@ -1402,11 +1406,14 @@ begin if wishbone_in.stall = '0' then -- See if there is another store waiting to be done -- which is in the same real page. - if acks < 7 and req.same_tag = '1' and - (req.op = OP_STORE_MISS or req.op = OP_STORE_HIT) then - r1.wb.adr <= req.real_addr(r1.wb.adr'left downto 0); + if req.valid = '1' then + r1.wb.adr(SET_SIZE_BITS - 1 downto 0) <= + req.real_addr(SET_SIZE_BITS - 1 downto 0); r1.wb.dat <= req.data; r1.wb.sel <= req.byte_sel; + end if; + if acks < 7 and req.same_tag = '1' and + (req.op = OP_STORE_MISS or req.op = OP_STORE_HIT) then r1.wb.stb <= '1'; stbs_done := false; if req.op = OP_STORE_HIT then