一、LRU算法是什么?
LRU:Least Recrntly Used,近期最少使用;
LRU算法用于cache管理或者任何需要对访问权进行周期更新的场景;基于时间和空间考虑,cache中存储着近期将会使用到的数据。当cache满后,如果有新的数据到来,需要将某个现有的数据从cache中清除,为新数据提供空间。LRU算法可以找到最久未被使用过的数据,cache将此数据清除,并将新数据写入到此处。
二、LRU算法实现
1.LRU算法原理
在RTL中实现LRU算法的方法有很多种。一种采用硬件实现LRU的方法是矩阵法。
- 构建一个存储单元矩阵(每个存储单元是一个寄存器);
- 将所有寄存器初始化为0;
- 无论何时,当有一个表项被访问,其对应的行全部置为1,其对应的列全部置为0(核心操作);
- 只要某个表项被访问,就重复步骤3;
- 全零的一行对应的表项是近期最少使用者,是需要被替换的对象;
2.代码实现
module MATRIX_LRU #(
paramater SIZE = 8
)
(
input clk,
input rst_n,
input update_the_entry,
input [2:0] update_the_index,
output reg [2:0] lru_index
)
reg [SIZE-1 : 0] matrix [SIZE-1 : 0];
reg [SIZE-1 : 0] matrix_nxt [SIZE-1 : 0];
reg [2 : 0] lru_index_nxt ;
generate //后面不能加begin
genvar i; //使用genvar定义循环变量
//generate中的for循环必须加begin...end;并且,begin后面必须有名字,用大写字母表示;
for (i=0; i<SIZE; i=i+1) begin: INITIAL_AND_REFRESH
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0) begin
matrix[i] <= {SIZE{1'b0}};
end
else begin
matrix[i] <= matrix_nxt[i];
end
end
end
endgenerate
generate
genvar j,k; //注意名字不要和上面的重复
for (j=0; j<SIZE; j=j+1) begin: ROW_OPERATE
for(k=0; k<SIZE; k=k+1) begin: COLUMN_OPERATE
always @(*) begin
if( update_the_entry && (j == update_index) &&(k != update_index)) begin
matrix_nxt[j][k] = 1'b1;
end
else if(update_the_entry && (k == update_index)) begin
matrix_nxt[j][k] = 1'b0;
end
else begin
martix_nxt[j][k] = matrix[j][k];
end
end
end
end
endgenarate
always @(*) begin
if(matrix[0] == 8'b0) begin
lru_index_nxt = 3'd0;
end
else if(matrix[1] == 8'b0) begin
lru_index_nxt = 3'd1;
end
else if(matrix[2] == 8'b0) begin
lru_index_nxt = 3'd2;
end
else if(matrix[3] == 8'b0) begin
lru_index_nxt = 3'd3;
end
else if(matrix[4] == 8'b0) begin
lru_index_nxt = 3'd4;
end
else if(matrix[5] == 8'b0) begin
lru_index_nxt = 3'd5;
end
else if(matrix[6] == 8'b0) begin
lru_index_nxt = 3'd6;
end
else if(matrix[7] == 8'b0) begin
lru_index_nxt = 3'd7;
end
else begin
lru_index_nxt = lru_index;
end
end
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0) begin
lru_index <= 3'd0;
else begin
lru_index <= lru_index_nxt;
end
end
endmodule