Files
OpenExSys_NoC/rtl/util/plru.sv
2023-11-26 14:59:34 +01:00

121 lines
4.5 KiB
Systemverilog

`ifndef __PLRU_SV__
`define __PLRU_SV__
module plru
#(
parameter int unsigned N_WAYS = 2,
parameter int unsigned N_SETS = 2
)
(
input logic touch_valid_i,
input logic [$clog2(N_SETS)-1:0] touch_addr_i,
input logic [$clog2(N_WAYS)-1:0] touch_way_i,
output logic [$clog2(N_WAYS)-1:0] alloc_way_o,
input logic clk,
input logic rst
);
logic [N_SETS-1:0][N_WAYS-2:0] plru_regs;
generate
if(N_WAYS == 2) begin
assign alloc_way_o = plru_regs[touch_addr_i][0];
end
else if (N_WAYS == 4) begin
assign alloc_way_o = plru_regs[touch_addr_i][0] ?
{plru_regs[touch_addr_i][0], plru_regs[touch_addr_i][2]} :
{plru_regs[touch_addr_i][0], plru_regs[touch_addr_i][1]};
end
else if (N_WAYS == 8) begin
always_comb begin
if (plru_regs[touch_addr_i][0]) begin
if (plru_regs[touch_addr_i][2]) begin
alloc_way_o = {plru_regs[touch_addr_i][0], plru_regs[touch_addr_i][2], plru_regs[touch_addr_i][6]};
end
else begin
alloc_way_o = {plru_regs[touch_addr_i][0], plru_regs[touch_addr_i][2], plru_regs[touch_addr_i][5]};
end
end
else begin
if (plru_regs[touch_addr_i][1]) begin
alloc_way_o = {plru_regs[touch_addr_i][0], plru_regs[touch_addr_i][1], plru_regs[touch_addr_i][4]};
end
else begin
alloc_way_o = {plru_regs[touch_addr_i][0], plru_regs[touch_addr_i][1], plru_regs[touch_addr_i][3]};
end
end
end
end
endgenerate
generate
if(N_WAYS == 2) begin
always_ff @(posedge clk) begin
if (rst) begin
plru_regs <= 0;
end
else if (touch_valid_i) begin
if (touch_way_i == alloc_way_o) begin
plru_regs[touch_addr_i] <= ~plru_regs[touch_addr_i];
end
end
end
end
else if (N_WAYS == 4) begin
always_ff @(posedge clk) begin
if (rst) begin
plru_regs <= 0;
end
else if (touch_valid_i & (alloc_way_o == touch_way_i)) begin
if (plru_regs[touch_addr_i][0]) begin
plru_regs[touch_addr_i][0] <= ~plru_regs[touch_addr_i][0];
plru_regs[touch_addr_i][2] <= ~plru_regs[touch_addr_i][2];
end
else begin
plru_regs[touch_addr_i][0] <= ~plru_regs[touch_addr_i][0];
plru_regs[touch_addr_i][1] <= ~plru_regs[touch_addr_i][1];
end
end
end
end
else if (N_WAYS == 8) begin
always_ff @(posedge clk) begin
if (rst) begin
plru_regs <= 0;
end
else if (touch_valid_i & (alloc_way_o == touch_way_i)) begin
if (plru_regs[touch_addr_i][0]) begin
if (plru_regs[touch_addr_i][2]) begin
plru_regs[touch_addr_i][0] <= ~plru_regs[touch_addr_i][0];
plru_regs[touch_addr_i][2] <= ~plru_regs[touch_addr_i][2];
plru_regs[touch_addr_i][6] <= ~plru_regs[touch_addr_i][6];
end
else begin
plru_regs[touch_addr_i][0] <= ~plru_regs[touch_addr_i][0];
plru_regs[touch_addr_i][2] <= ~plru_regs[touch_addr_i][2];
plru_regs[touch_addr_i][5] <= ~plru_regs[touch_addr_i][5];
end
end
else begin
if (plru_regs[touch_addr_i][1]) begin
plru_regs[touch_addr_i][0] <= ~plru_regs[touch_addr_i][0];
plru_regs[touch_addr_i][2] <= ~plru_regs[touch_addr_i][2];
plru_regs[touch_addr_i][4] <= ~plru_regs[touch_addr_i][4];
end
else begin
plru_regs[touch_addr_i][0] <= ~plru_regs[touch_addr_i][0];
plru_regs[touch_addr_i][2] <= ~plru_regs[touch_addr_i][2];
plru_regs[touch_addr_i][3] <= ~plru_regs[touch_addr_i][3];
end
end
end
end
end
endgenerate
endmodule
`endif