litedram: Pipeline store acks in L2

There is a long timing path to generate the ack signal from
the L2 cache as it's fully combinational for stores, including
signals coming from litedram.

Instead, pipeline the store acks. This will introduce a cycle
latency but should improve timing. Also the core will eventually
be smart enough not to wait for store acks to complete them anyway.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
jtag-port
Benjamin Herrenschmidt 4 years ago
parent 5ae5f76558
commit 05bbbf0772

@ -245,13 +245,17 @@ architecture behaviour of litedram_wrapper is
signal wb_stash : wishbone_master_out := wishbone_master_out_init;

-- Read pipeline (to handle cache RAM latency)
signal read_ack_0 : std_ulogic;
signal read_ack_1 : std_ulogic;
signal read_ack_0 : std_ulogic := '0';
signal read_ack_1 : std_ulogic := '0';
signal read_ad3_0 : std_ulogic;
signal read_ad3_1 : std_ulogic;
signal read_way_0 : way_t;
signal read_way_1 : way_t;

-- Store ack pipeline
signal store_ack_0 : std_ulogic := '0';
signal store_ack_1 : std_ulogic := '0';

-- Async signals decoding latched request
type req_op_t is (OP_NONE,
OP_LOAD_HIT,
@ -625,7 +629,6 @@ begin
-- Stall when stash is full
wb_out.stall <= wb_stash.cyc;

--
--
-- Read response pipeline
--
@ -657,6 +660,16 @@ begin
end if;
end process;

--
-- Store acks pipeline
--
store_ack_pipe: process(system_clk)
begin
if rising_edge(system_clk) then
store_ack_1 <= store_ack_0;
end if;
end process;

wb_reponse: process(all)
variable rdata : std_ulogic_vector(DRAM_DBITS-1 downto 0);
variable store_done : std_ulogic;
@ -717,15 +730,16 @@ begin
store_done := '0';
end if;

-- Generate ACKs on read hits and store complete
-- Pipeline store acks
store_ack_0 <= store_done;

-- Generate Wishbone ACKs on read hits and store complete
--
-- XXXX TODO: This can happen on store right behind loads !
-- This probably need to be fixed by putting store acks in
-- the same pipeline as the read acks. TOOD: Create a testbench
-- to exercise those corner cases as the core can't yet.
-- This can happen on store right behind loads ! This is why
-- we don't accept a new store right behind a load ack above.
--
wb_out.ack <= read_ack_1 or store_done;
assert read_ack_0 = '0' or store_done = '0' report
wb_out.ack <= read_ack_1 or store_ack_1;
assert read_ack_1 = '0' or store_ack_1 = '0' report
"Read ack and store ack collision !"
severity failure;
end process;

Loading…
Cancel
Save