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 <paulus@ozlabs.org>
pull/233/head
Paul Mackerras 4 years ago
parent c01e1c7b91
commit 1be6fbac33

@ -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

Loading…
Cancel
Save