From: Paul Mackerras Date: Mon, 19 Sep 2022 08:05:30 +0000 (+1000) Subject: litedram: Split L2 PLRU into storage and logic X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b8f9c833f85a13514f61b64895fa9ae6f7c2d671;p=microwatt.git litedram: Split L2 PLRU into storage and logic As has been done for the L1 dcache and icache, this puts the L2 cache PLRU state into a little RAM and has a single copy of the logic to calculate the pseudo-LRU way and update the PLRU state. Signed-off-by: Paul Mackerras --- diff --git a/litedram/extras/litedram-wrapper-l2.vhdl b/litedram/extras/litedram-wrapper-l2.vhdl index 6c0967b..4bea293 100644 --- a/litedram/extras/litedram-wrapper-l2.vhdl +++ b/litedram/extras/litedram-wrapper-l2.vhdl @@ -305,8 +305,7 @@ architecture behaviour of litedram_wrapper is signal cache_out : cache_ram_out_t; -- PLRU output interface - type plru_out_t is array(index_t) of std_ulogic_vector(WAY_BITS-1 downto 0); - signal plru_victim : plru_out_t; + signal plru_victim : way_t; -- -- Helper functions to decode incoming requests @@ -565,39 +564,44 @@ begin end generate; -- Generate PLRUs - maybe_plrus: if NUM_WAYS > 1 generate + maybe_plrus : if NUM_WAYS > 1 generate + type plru_array is array(index_t) of std_ulogic_vector(NUM_WAYS - 2 downto 0); + signal plru_ram : plru_array; + signal plru_cur : std_ulogic_vector(NUM_WAYS - 2 downto 0); + signal plru_upd : std_ulogic_vector(NUM_WAYS - 2 downto 0); + signal plru_acc : std_ulogic_vector(WAY_BITS-1 downto 0); + signal plru_out : std_ulogic_vector(WAY_BITS-1 downto 0); begin - plrus: for i in 0 to NUM_LINES-1 generate + plru : entity work.plrufn + generic map ( + BITS => WAY_BITS + ) + port map ( + acc => plru_acc, + tree_in => plru_cur, + tree_out => plru_upd, + lru => plru_out + ); + + process(all) + begin + -- Read PLRU bits from array + plru_cur <= plru_ram(req_index); + -- PLRU interface - signal plru_acc : std_ulogic_vector(WAY_BITS-1 downto 0); - signal plru_acc_en : std_ulogic; - signal plru_out : std_ulogic_vector(WAY_BITS-1 downto 0); + plru_acc <= std_ulogic_vector(to_unsigned(req_hit_way, WAY_BITS)); + plru_victim <= to_integer(unsigned(plru_out)); + end process; + + -- synchronous writes to PLRU array + process(system_clk) begin - plru : entity work.plru - generic map ( - BITS => WAY_BITS - ) - port map ( - clk => system_clk, - rst => system_reset, - acc => plru_acc, - acc_en => plru_acc_en, - lru => plru_out - ); - - process(req_index, req_op, req_hit_way, plru_out) - begin - -- PLRU interface - if (req_op = OP_LOAD_HIT or - req_op = OP_STORE_HIT) and req_index = i then - plru_acc_en <= '1'; - else - plru_acc_en <= '0'; + if rising_edge(system_clk) then + if (req_op = OP_LOAD_HIT or req_op = OP_STORE_HIT) then + plru_ram(req_index) <= plru_upd; end if; - plru_acc <= std_ulogic_vector(to_unsigned(req_hit_way, WAY_BITS)); - plru_victim(i) <= plru_out; - end process; - end generate; + end if; + end process; end generate; -- @@ -1019,7 +1023,7 @@ begin -- We need to read a cache line if req_op = OP_LOAD_MISS and not wait_qdrain then -- Grab way to replace - refill_way <= to_integer(unsigned(plru_victim(req_index))); + refill_way <= plru_victim; -- Keep track of our index and way for subsequent stores refill_index <= req_index;