@@ -242,19 +242,62 @@ module snitch_icache_handler #(
242242 end
243243 end
244244
245- // The cache line eviction LFSR is responsible for picking a cache line for
246- // replacement at random. Note that we assume that the entire cache is full,
247- // so no empty cache lines are available. This is the common case since we
248- // do not support flushing of the cache.
249245 logic [CFG .SET_ALIGN - 1 : 0 ] evict_index;
250246 logic evict_enable;
251247
252- snitch_icache_lfsr # (CFG .SET_ALIGN ) i_evict_lfsr (
253- .clk_i ( clk_i ),
254- .rst_ni ( rst_ni ),
255- .value_o ( evict_index ),
256- .enable_i ( evict_enable )
257- );
248+ if ( CFG .L1_PLRU ) begin : gen_plru
249+
250+ logic [CFG .LINE_COUNT - 1 : 0 ][CFG .SET_COUNT - 1 : 0 ] used_masks;
251+ logic [CFG .LINE_COUNT - 1 : 0 ][CFG .SET_COUNT - 1 : 0 ] evict_masks;
252+
253+ always_comb begin
254+ used_masks = '0 ;
255+ if (in_req_valid_i && in_req_hit_i) begin
256+ // hit update
257+ used_masks[in_req_addr_i >> CFG .LINE_ALIGN ][in_req_set_i] = 1'b1 ;
258+ end else if (write_valid_o) begin
259+ // refill update
260+ used_masks[write_addr_o][write_set_o] = 1'b1 ;
261+ end
262+ end
263+
264+ for (genvar i = 0 ; i < CFG .LINE_COUNT ; i++ ) begin : gen_plru_tree
265+
266+ plru_tree # (
267+ .ENTRIES ( CFG .SET_COUNT )
268+ ) i_plru_tree (
269+ .clk_i,
270+ .rst_ni,
271+
272+ .used_i ( used_masks [i] ),
273+ .plru_o ( evict_masks[i] )
274+ );
275+
276+ end
277+
278+ onehot_to_bin # (
279+ .ONEHOT_WIDTH ( CFG .SET_COUNT )
280+ ) i_evict_mask_to_index (
281+ .onehot ( evict_masks[write_addr_o] ),
282+ .bin ( evict_index )
283+ );
284+
285+ end else begin : gen_lfsr
286+
287+ // The cache line eviction LFSR is responsible for picking a cache line for
288+ // replacement at random. Note that we assume that the entire cache is full,
289+ // so no empty cache lines are available. This is the common case since we
290+ // do not support flushing of the cache.
291+ snitch_icache_lfsr # (
292+ .N (CFG .SET_ALIGN )
293+ ) i_evict_lfsr (
294+ .clk_i ( clk_i ),
295+ .rst_ni ( rst_ni ),
296+ .value_o ( evict_index ),
297+ .enable_i ( evict_enable )
298+ );
299+
300+ end
258301
259302 // The response handler deals with incoming refill responses. It queries and
260303 // clears the corresponding entry in the pending table, stores the data in
0 commit comments