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 type mem_access_request_t is record
op : op_t; op : op_t;
valid : std_ulogic;
dcbz : std_ulogic; dcbz : std_ulogic;
real_addr : std_ulogic_vector(REAL_ADDR_BITS - 1 downto 0); real_addr : std_ulogic_vector(REAL_ADDR_BITS - 1 downto 0);
data : std_ulogic_vector(63 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_op : op_t;
signal req_data : std_ulogic_vector(63 downto 0); signal req_data : std_ulogic_vector(63 downto 0);
signal req_same_tag : std_ulogic; signal req_same_tag : std_ulogic;
signal req_go : std_ulogic;


signal early_req_row : row_t; signal early_req_row : row_t;


@ -856,6 +858,7 @@ begin
end if; end if;
end if; end if;
req_op <= op; req_op <= op;
req_go <= go;


-- Version of the row number that is valid one cycle earlier -- Version of the row number that is valid one cycle earlier
-- in the cases where we need to read the cache data BRAM. -- in the cases where we need to read the cache data BRAM.
@ -1240,6 +1243,7 @@ begin
req := r1.req; req := r1.req;
else else
req.op := req_op; req.op := req_op;
req.valid := req_go;
req.dcbz := r0.req.dcbz; req.dcbz := r0.req.dcbz;
req.real_addr := ra; req.real_addr := ra;
req.data := r0.req.data; req.data := r0.req.data;
@ -1402,11 +1406,14 @@ begin
if wishbone_in.stall = '0' then if wishbone_in.stall = '0' then
-- See if there is another store waiting to be done -- See if there is another store waiting to be done
-- which is in the same real page. -- which is in the same real page.
if acks < 7 and req.same_tag = '1' and if req.valid = '1' then
(req.op = OP_STORE_MISS or req.op = OP_STORE_HIT) then r1.wb.adr(SET_SIZE_BITS - 1 downto 0) <=
r1.wb.adr <= req.real_addr(r1.wb.adr'left downto 0); req.real_addr(SET_SIZE_BITS - 1 downto 0);
r1.wb.dat <= req.data; r1.wb.dat <= req.data;
r1.wb.sel <= req.byte_sel; 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'; r1.wb.stb <= '1';
stbs_done := false; stbs_done := false;
if req.op = OP_STORE_HIT then if req.op = OP_STORE_HIT then

Loading…
Cancel
Save