121 lines
4.5 KiB
Systemverilog
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 |