litedram: Add stash buffer to the L2 cache wishbone interface

This breaks the long stall signal coming back to the processor
and helps improve overall timing.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
jtag-port
Benjamin Herrenschmidt 4 years ago
parent b23fd6c5f1
commit b58ff724f6

@ -239,8 +239,10 @@ architecture behaviour of litedram_wrapper is
REFILL_WAIT_ACK); -- Cache refill wait ack REFILL_WAIT_ACK); -- Cache refill wait ack
signal state : state_t; signal state : state_t;


-- Latched WB request. -- Latched WB request
signal wb_req : wishbone_master_out := wishbone_master_out_init; signal wb_req : wishbone_master_out := wishbone_master_out_init;
-- Stashed WB request
signal wb_stash : wishbone_master_out := wishbone_master_out_init;


-- Read pipeline (to handle cache RAM latency) -- Read pipeline (to handle cache RAM latency)
signal read_ack_0 : std_ulogic; signal read_ack_0 : std_ulogic;
@ -267,6 +269,7 @@ architecture behaviour of litedram_wrapper is
signal req_we : std_ulogic_vector(DRAM_SBITS-1 downto 0); signal req_we : std_ulogic_vector(DRAM_SBITS-1 downto 0);
signal req_wdata : std_ulogic_vector(DRAM_DBITS-1 downto 0); signal req_wdata : std_ulogic_vector(DRAM_DBITS-1 downto 0);
signal accept_store : std_ulogic; signal accept_store : std_ulogic;
signal stall : std_ulogic;


-- Line refill command signals and latches -- Line refill command signals and latches
signal refill_cmd_valid : std_ulogic; signal refill_cmd_valid : std_ulogic;
@ -574,30 +577,54 @@ begin
request_latch: process(system_clk) request_latch: process(system_clk)
begin begin
if rising_edge(system_clk) then if rising_edge(system_clk) then
-- We can latch a new request if we are idle (for now). We also
-- latch the absence of request. This is a pipeline that takes -- Implement a stash buffer. If we are stalled and stash is
-- one per-cycle unless non-IDLE. -- free, fill it up. This will generate a WB stall on the
-- -- next cycle.
if wb_out.stall = '0' then if stall = '1' and wb_out.stall = '0' and wb_in.cyc = '1' and wb_in.stb = '1' then
-- Avoid constantly updating addr/data for unrelated requests wb_stash <= wb_in;
if wb_in.cyc = '1' then if TRACE then
wb_req <= wb_in; report "stashed wb req ! addr:" & to_hstring(wb_in.adr) &
" we:" & std_ulogic'image(wb_in.we) &
" sel:" & to_hstring(wb_in.sel);
end if;
end if;

-- We aren't stalled, see what we can do
if stall = '0' then
if wb_stash.cyc = '1' then
-- Something in stash ! use it and clear stash
wb_req <= wb_stash;
wb_stash.cyc <= '0';
if TRACE then
report "unstashed wb req ! addr:" & to_hstring(wb_stash.adr) &
" we:" & std_ulogic'image(wb_stash.we) &
" sel:" & to_hstring(wb_stash.sel);
end if;
else else
wb_req.cyc <= wb_in.cyc; -- Grab request from WB
wb_req.stb <= wb_in.stb; if wb_in.cyc = '1' then
end if; wb_req <= wb_in;
else
wb_req.cyc <= wb_in.cyc;
wb_req.stb <= wb_in.stb;
end if;


if TRACE then if TRACE then
if wb_in.cyc = '1' and wb_in.stb = '1' then if wb_in.cyc = '1' and wb_in.stb = '1' then
report "latch new wb req ! addr:" & to_hstring(wb_in.adr) & report "latch new wb req ! addr:" & to_hstring(wb_in.adr) &
" we:" & std_ulogic'image(wb_in.we) & " we:" & std_ulogic'image(wb_in.we) &
" sel:" & to_hstring(wb_in.sel); " sel:" & to_hstring(wb_in.sel);
end if;
end if; end if;
end if; end if;
end if; end if;
end if; end if;
end process; end process;


-- Stall when stash is full
wb_out.stall <= wb_stash.cyc;

-- --
-- --
-- Read response pipeline -- Read response pipeline
@ -669,14 +696,14 @@ begin
when IDLE => when IDLE =>
case req_op is case req_op is
when OP_LOAD_MISS => when OP_LOAD_MISS =>
wb_out.stall <= '1'; stall <= '1';
when OP_STORE_MISS | OP_STORE_HIT => when OP_STORE_MISS | OP_STORE_HIT =>
wb_out.stall <= not accept_store; stall <= not accept_store;
when others => when others =>
wb_out.stall <= '0'; stall <= '0';
end case; end case;
when others => when others =>
wb_out.stall <= '1'; stall <= '1';
end case; end case;
-- Data out mux -- Data out mux

Loading…
Cancel
Save