dcache: Ease timing on wishbone data and byte selects

This eliminates a path where the inputs to r1.wb.dat and r1.wb.sel
depend on req_op, which depends on the TLB and cache hit detection.
In fact they only need to depend on the nature of the request in
r0.req (i.e. DCBZ, store, cacheable load, or non-cacheable load).
This sets them at the beginning of the code for IDLE state rather
than inside the req_op case statement.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/233/head
Paul Mackerras 4 years ago
parent 36297d35f8
commit 128fe8ac26

@ -1250,8 +1250,18 @@ begin
req.mmu_req := r0.mmu_req; req.mmu_req := r0.mmu_req;
req.dcbz := r0.req.dcbz; req.dcbz := r0.req.dcbz;
req.real_addr := ra; req.real_addr := ra;
req.data := r0.req.data; -- Force data to 0 for dcbz
req.byte_sel := r0.req.byte_sel; if r0.req.dcbz = '0' then
req.data := r0.req.data;
else
req.data := (others => '0');
end if;
-- Select all bytes for dcbz and for cacheable loads
if r0.req.dcbz = '1' or (r0.req.load = '1' and r0.req.nc = '0') then
req.byte_sel := (others => '1');
else
req.byte_sel := r0.req.byte_sel;
end if;
req.hit_way := req_hit_way; req.hit_way := req_hit_way;
req.same_tag := req_same_tag; req.same_tag := req_same_tag;


@ -1268,7 +1278,9 @@ begin
case r1.state is case r1.state is
when IDLE => when IDLE =>
r1.wb.adr <= req.real_addr(r1.wb.adr'left downto 0); r1.wb.adr <= req.real_addr(r1.wb.adr'left downto 0);
r1.dcbz <= '0'; r1.wb.sel <= req.byte_sel;
r1.wb.dat <= req.data;
r1.dcbz <= req.dcbz;


-- Keep track of our index and way for subsequent stores. -- Keep track of our index and way for subsequent stores.
r1.store_index <= get_index(req.real_addr); r1.store_index <= get_index(req.real_addr);
@ -1298,7 +1310,6 @@ begin
" tag:" & to_hstring(get_tag(req.real_addr)); " tag:" & to_hstring(get_tag(req.real_addr));


-- Start the wishbone cycle -- Start the wishbone cycle
r1.wb.sel <= (others => '1');
r1.wb.we <= '0'; r1.wb.we <= '0';
r1.wb.cyc <= '1'; r1.wb.cyc <= '1';
r1.wb.stb <= '1'; r1.wb.stb <= '1';
@ -1308,7 +1319,6 @@ begin
r1.write_tag <= '1'; r1.write_tag <= '1';


when OP_LOAD_NC => when OP_LOAD_NC =>
r1.wb.sel <= req.byte_sel;
r1.wb.cyc <= '1'; r1.wb.cyc <= '1';
r1.wb.stb <= '1'; r1.wb.stb <= '1';
r1.wb.we <= '0'; r1.wb.we <= '0';
@ -1316,8 +1326,6 @@ begin


when OP_STORE_HIT | OP_STORE_MISS => when OP_STORE_HIT | OP_STORE_MISS =>
if req.dcbz = '0' then if req.dcbz = '0' then
r1.wb.sel <= req.byte_sel;
r1.wb.dat <= req.data;
r1.state <= STORE_WAIT_ACK; r1.state <= STORE_WAIT_ACK;
r1.acks_pending <= to_unsigned(1, 3); r1.acks_pending <= to_unsigned(1, 3);
r1.full <= '0'; r1.full <= '0';
@ -1333,17 +1341,10 @@ begin
else else
-- dcbz is handled much like a load miss except -- dcbz is handled much like a load miss except
-- that we are writing to memory instead of reading -- that we are writing to memory instead of reading

-- Start the wishbone writes
r1.wb.sel <= (others => '1');
r1.wb.dat <= (others => '0');

-- Handle the rest like a load miss
r1.state <= RELOAD_WAIT_ACK; r1.state <= RELOAD_WAIT_ACK;
if req.op = OP_STORE_MISS then if req.op = OP_STORE_MISS then
r1.write_tag <= '1'; r1.write_tag <= '1';
end if; end if;
r1.dcbz <= '1';
end if; end if;
r1.wb.we <= '1'; r1.wb.we <= '1';
r1.wb.cyc <= '1'; r1.wb.cyc <= '1';

Loading…
Cancel
Save