Commit 30d06fe7 authored by jinbao chen's avatar jinbao chen
Browse files

finish lab3 report

parent fcd11a45
module cache_fifo #( module cache_fifo #(
parameter LINE_ADDR_LEN = 3, // line内地长度,决定了每个line具有2^3个word parameter LINE_ADDR_LEN = 3, // line内地??长度,决定了每个line具有2^3个word
parameter SET_ADDR_LEN = 3, // 组地长度,决定了共有2^3=8 parameter SET_ADDR_LEN = 3, // 组地??长度,决定了??共有2^3=8??
parameter TAG_ADDR_LEN = 6, // tag长度 parameter TAG_ADDR_LEN = 6, // tag长度
parameter WAY_CNT = 3 // 组相连度,决定了每组中有多少路line,这里是直接映射型cache,因此该参数没用 parameter WAY_CNT = 5 // 组相连度,决定了每组中有多少路line,这里是直接映射型cache,因此该参数没用??
)( )(
input clk, rst, input clk, rst,
output miss, // 对CPU发出的miss信号 output miss, // 对CPU发出的miss信号
input [31:0] addr, // 读写请求地址 input [31:0] addr, // 读写请求地址
input rd_req, // 读请求信 input rd_req, // 读请求信??
output reg [31:0] rd_data, // 读出的数据,一次读一个word output reg [31:0] rd_data, // 读出的数据,??次读??个word
input wr_req, // 写请求信 input wr_req, // 写请求信??
input [31:0] wr_data // 要写入的数据,一次写个word input [31:0] wr_data // 要写入的数据,一次写??个word
); );
localparam MEM_ADDR_LEN = TAG_ADDR_LEN + SET_ADDR_LEN ; // 计算主存地址长度 MEM_ADDR_LEN,主存大=2^MEM_ADDR_LEN个line localparam MEM_ADDR_LEN = TAG_ADDR_LEN + SET_ADDR_LEN ; // 计算主存地址长度 MEM_ADDR_LEN,主存大??=2^MEM_ADDR_LEN个line
localparam UNUSED_ADDR_LEN = 32 - TAG_ADDR_LEN - SET_ADDR_LEN - LINE_ADDR_LEN - 2 ; // 计算未使用的地址的长 localparam UNUSED_ADDR_LEN = 32 - TAG_ADDR_LEN - SET_ADDR_LEN - LINE_ADDR_LEN - 2 ; // 计算未使用的地址的长??
localparam LINE_SIZE = 1 << LINE_ADDR_LEN ; // 计算 line word 的数量, 2^LINE_ADDR_LEN 个word line localparam LINE_SIZE = 1 << LINE_ADDR_LEN ; // 计算 line ?? word 的数量,?? 2^LINE_ADDR_LEN 个word ?? line
localparam SET_SIZE = 1 << SET_ADDR_LEN ; // 计算共有多少组, 2^SET_ADDR_LEN 个组 localparam SET_SIZE = 1 << SET_ADDR_LEN ; // 计算??共有多少组,?? 2^SET_ADDR_LEN 个组
reg [ 31:0] cache_mem [SET_SIZE][WAY_CNT][LINE_SIZE]; // SET_SIZE个line,每个line有LINE_SIZE个word reg [ 31:0] cache_mem [SET_SIZE][WAY_CNT][LINE_SIZE]; // SET_SIZE个line,每个line有LINE_SIZE个word
reg [TAG_ADDR_LEN-1:0] cache_tags [SET_SIZE][WAY_CNT]; // SET_SIZE个TAG reg [TAG_ADDR_LEN-1:0] cache_tags [SET_SIZE][WAY_CNT]; // SET_SIZE个TAG
reg valid [SET_SIZE][WAY_CNT]; // SET_SIZE个valid(有效) reg valid [SET_SIZE][WAY_CNT]; // SET_SIZE个valid(有效??)
reg dirty [SET_SIZE][WAY_CNT]; // SET_SIZE个dirty(脏位) reg dirty [SET_SIZE][WAY_CNT]; // SET_SIZE个dirty(脏位)
reg [ WAY_CNT:0] cache_fifo [SET_SIZE]; reg [ WAY_CNT:0] cache_fifo [SET_SIZE];
reg [ WAY_CNT:0] way_length [SET_SIZE]; reg [ WAY_CNT:0] way_length [SET_SIZE];
wire [ 2-1:0] word_addr; // 将输入地addr拆分成这5个部 wire [ 2-1:0] word_addr; // 将输入地??addr拆分成这5个部??
wire [ LINE_ADDR_LEN-1:0] line_addr; wire [ LINE_ADDR_LEN-1:0] line_addr;
wire [ SET_ADDR_LEN-1:0] set_addr; wire [ SET_ADDR_LEN-1:0] set_addr;
wire [ TAG_ADDR_LEN-1:0] tag_addr; wire [ TAG_ADDR_LEN-1:0] tag_addr;
...@@ -36,8 +36,8 @@ wire [UNUSED_ADDR_LEN-1:0] unused_addr; ...@@ -36,8 +36,8 @@ wire [UNUSED_ADDR_LEN-1:0] unused_addr;
wire [ WAY_CNT:0] fifo_pos; wire [ WAY_CNT:0] fifo_pos;
wire [ WAY_CNT:0] queue_len; wire [ WAY_CNT:0] queue_len;
enum {IDLE, SWAP_OUT, SWAP_IN, SWAP_IN_OK} cache_stat; // cache 状机的状态定 enum {IDLE, SWAP_OUT, SWAP_IN, SWAP_IN_OK} cache_stat; // cache 状�?�机的状态定??
// IDLE代表就绪,SWAP_OUT代表正在换出,SWAP_IN代表正在换入,SWAP_IN_OK代表换入后进行一周期的写入cache操作 // IDLE代表就绪,SWAP_OUT代表正在换出,SWAP_IN代表正在换入,SWAP_IN_OK代表换入后进行一周期的写入cache操作??
reg [ SET_ADDR_LEN-1:0] mem_rd_set_addr = 0; reg [ SET_ADDR_LEN-1:0] mem_rd_set_addr = 0;
reg [ TAG_ADDR_LEN-1:0] mem_rd_tag_addr = 0; reg [ TAG_ADDR_LEN-1:0] mem_rd_tag_addr = 0;
...@@ -50,20 +50,20 @@ reg [ WAY_CNT:0] mem_fifo_len = 0; ...@@ -50,20 +50,20 @@ reg [ WAY_CNT:0] mem_fifo_len = 0;
reg [31:0] mem_wr_line [LINE_SIZE]; reg [31:0] mem_wr_line [LINE_SIZE];
wire [31:0] mem_rd_line [LINE_SIZE]; wire [31:0] mem_rd_line [LINE_SIZE];
wire mem_gnt; // 主存响应读写的握手信 wire mem_gnt; // 主存响应读写的握手信??
assign {unused_addr, tag_addr, set_addr, line_addr, word_addr} = addr; // 拆分 32bit ADDR assign {unused_addr, tag_addr, set_addr, line_addr, word_addr} = addr; // 拆分 32bit ADDR
assign fifo_pos = cache_fifo[set_addr];//queue header assign fifo_pos = cache_fifo[set_addr];//queue header
assign queue_len = way_length[set_addr];//length of the fifo queue assign queue_len = way_length[set_addr];//length of the fifo queue
reg cache_hit = 1'b0; reg cache_hit = 1'b0;
reg [WAY_CNT:0] asso_pos = 0; //hit pos in set reg [WAY_CNT:0] hit_pos = 0; //hit pos in set
always @ (*) begin // 判断 输入的address 是否 cache 中命 always @ (*) begin // 判断 输入的address 是否?? cache 中命??
for(integer i = 0;i < WAY_CNT;i++) begin for(integer i = 0;i < WAY_CNT;i++) begin
if(valid[set_addr][i] && cache_tags[set_addr][i] == tag_addr) begin if(valid[set_addr][i] && cache_tags[set_addr][i] == tag_addr) begin
cache_hit = 1'b1; cache_hit = 1'b1;
asso_pos = i; hit_pos = i;
break; break;
end end
else begin else begin
...@@ -96,18 +96,18 @@ always @ (posedge clk or posedge rst) begin // ?? cache ??? ...@@ -96,18 +96,18 @@ always @ (posedge clk or posedge rst) begin // ?? cache ???
IDLE: begin IDLE: begin
if(cache_hit) begin if(cache_hit) begin
if(rd_req) begin // 如果cache命中,并且是读请求, if(rd_req) begin // 如果cache命中,并且是读请求,
rd_data <= cache_mem[set_addr][asso_pos][line_addr]; //则直接从cache中取出要读的数据 rd_data <= cache_mem[set_addr][hit_pos][line_addr]; //则直接从cache中取出要读的数据
end else if(wr_req) begin // 如果cache命中,并且是写请求, end else if(wr_req) begin // 如果cache命中,并且是写请求,
cache_mem[set_addr][asso_pos][line_addr] <= wr_data; // 则直接向cache中写入数 cache_mem[set_addr][hit_pos][line_addr] <= wr_data; // 则直接向cache中写入数??
dirty[set_addr][asso_pos] <= 1'b1; // 写数据的同时置脏 dirty[set_addr][hit_pos] <= 1'b1; // 写数据的同时置脏??
end end
end else begin end else begin
if(wr_req | rd_req) begin // 如果 cache 未命中,并且有读写请求,则需要进行换 if(wr_req | rd_req) begin // 如果 cache 未命中,并且有读写请求,则需要进行换??
if(valid[set_addr][fifo_pos] && dirty[set_addr][fifo_pos] && queue_len!=0) begin // 如果 要换入的cache line 本来有效,且脏,则需要先将它换出 if(valid[set_addr][fifo_pos] && dirty[set_addr][fifo_pos] && queue_len!=0) begin // 如果 要换入的cache line 本来有效,且脏,则需要先将它换出
cache_stat <= SWAP_OUT; cache_stat <= SWAP_OUT;
mem_wr_addr <= {cache_tags[set_addr][fifo_pos], set_addr}; mem_wr_addr <= {cache_tags[set_addr][fifo_pos], set_addr};
mem_wr_line <= cache_mem[set_addr][fifo_pos]; mem_wr_line <= cache_mem[set_addr][fifo_pos];
end else begin // 反之,不要换出,直接换入 end else begin // 反之,不??要换出,直接换入
cache_stat <= SWAP_IN; cache_stat <= SWAP_IN;
end end
{mem_rd_tag_addr, mem_rd_set_addr} <= {tag_addr, set_addr}; {mem_rd_tag_addr, mem_rd_set_addr} <= {tag_addr, set_addr};
...@@ -117,12 +117,12 @@ always @ (posedge clk or posedge rst) begin // ?? cache ??? ...@@ -117,12 +117,12 @@ always @ (posedge clk or posedge rst) begin // ?? cache ???
end end
end end
SWAP_OUT: begin SWAP_OUT: begin
if(mem_gnt) begin // 如果主存握手信号有效,说明换出成功,跳到下一状 if(mem_gnt) begin // 如果主存握手信号有效,说明换出成功,跳到下一状�??
cache_stat <= SWAP_IN; cache_stat <= SWAP_IN;
end end
end end
SWAP_IN: begin SWAP_IN: begin
if(mem_gnt) begin // 如果主存握手信号有效,说明换入成功,跳到下一状 if(mem_gnt) begin // 如果主存握手信号有效,说明换入成功,跳到下一状�??
cache_stat <= SWAP_IN_OK; cache_stat <= SWAP_IN_OK;
end end
end end
...@@ -138,7 +138,7 @@ always @ (posedge clk or posedge rst) begin // ?? cache ??? ...@@ -138,7 +138,7 @@ always @ (posedge clk or posedge rst) begin // ?? cache ???
cache_tags[mem_rd_set_addr][mem_fifo_pos] <= mem_rd_tag_addr; cache_tags[mem_rd_set_addr][mem_fifo_pos] <= mem_rd_tag_addr;
valid [mem_rd_set_addr][mem_fifo_pos] <= 1'b1; valid [mem_rd_set_addr][mem_fifo_pos] <= 1'b1;
dirty [mem_rd_set_addr][mem_fifo_pos] <= 1'b0; dirty [mem_rd_set_addr][mem_fifo_pos] <= 1'b0;
cache_stat <= IDLE; // 回到就绪状 cache_stat <= IDLE; // 回到就绪状�??
end end
endcase endcase
end end
...@@ -148,9 +148,9 @@ wire mem_rd_req = (cache_stat == SWAP_IN ); ...@@ -148,9 +148,9 @@ wire mem_rd_req = (cache_stat == SWAP_IN );
wire mem_wr_req = (cache_stat == SWAP_OUT); wire mem_wr_req = (cache_stat == SWAP_OUT);
wire [ MEM_ADDR_LEN-1 :0] mem_addr = mem_rd_req ? mem_rd_addr : ( mem_wr_req ? mem_wr_addr : 0); wire [ MEM_ADDR_LEN-1 :0] mem_addr = mem_rd_req ? mem_rd_addr : ( mem_wr_req ? mem_wr_addr : 0);
assign miss = (rd_req | wr_req) & ~(cache_hit && cache_stat==IDLE) ; // 有读写请求时,如果cache不处于就(IDLE)状态,或者未命中,则miss=1 assign miss = (rd_req | wr_req) & ~(cache_hit && cache_stat==IDLE) ; // ?? 有读写请求时,如果cache不处于就??(IDLE)状�?�,或�?�未命中,则miss=1
main_mem #( // 主存,每次读写以line 为单 main_mem #( // 主存,每次读写以line 为单??
.LINE_ADDR_LEN ( LINE_ADDR_LEN ), .LINE_ADDR_LEN ( LINE_ADDR_LEN ),
.ADDR_LEN ( MEM_ADDR_LEN ) .ADDR_LEN ( MEM_ADDR_LEN )
) main_mem_instance ( ) main_mem_instance (
......
module cache_lru #( module cache_lru #(
parameter LINE_ADDR_LEN = 3, // line内地长度,决定了每个line具有2^3个word parameter LINE_ADDR_LEN = 3, // line内地??长度,决定了每个line具有2^3个word
parameter SET_ADDR_LEN = 3, // 组地长度,决定了共有2^3=8 parameter SET_ADDR_LEN = 3, // 组地??长度,决定了??共有2^3=8??
parameter TAG_ADDR_LEN = 6, // tag长度 parameter TAG_ADDR_LEN = 6, // tag长度
parameter WAY_CNT = 3 // 组相连度,决定了每组中有多少路line,这里是直接映射型cache,因此该参数没用 parameter WAY_CNT = 5 // 组相连度,决定了每组中有多少路line,这里是直接映射型cache,因此该参数没用??
)( )(
input clk, rst, input clk, rst,
output miss, // 对CPU发出的miss信号 output miss, // 对CPU发出的miss信号
input [31:0] addr, // 读写请求地址 input [31:0] addr, // 读写请求地址
input rd_req, // 读请求信 input rd_req, // 读请求信??
output reg [31:0] rd_data, // 读出的数据,一次读一个word output reg [31:0] rd_data, // 读出的数据,??次读??个word
input wr_req, // 写请求信 input wr_req, // 写请求信??
input [31:0] wr_data // 要写入的数据,一次写个word input [31:0] wr_data // 要写入的数据,一次写??个word
); );
localparam MEM_ADDR_LEN = TAG_ADDR_LEN + SET_ADDR_LEN ; // 计算主存地址长度 MEM_ADDR_LEN,主存大=2^MEM_ADDR_LEN个line localparam MEM_ADDR_LEN = TAG_ADDR_LEN + SET_ADDR_LEN ; // 计算主存地址长度 MEM_ADDR_LEN,主存大??=2^MEM_ADDR_LEN个line
localparam UNUSED_ADDR_LEN = 32 - TAG_ADDR_LEN - SET_ADDR_LEN - LINE_ADDR_LEN - 2 ; // 计算未使用的地址的长 localparam UNUSED_ADDR_LEN = 32 - TAG_ADDR_LEN - SET_ADDR_LEN - LINE_ADDR_LEN - 2 ; // 计算未使用的地址的长??
localparam LINE_SIZE = 1 << LINE_ADDR_LEN ; // 计算 line word 的数量, 2^LINE_ADDR_LEN 个word line localparam LINE_SIZE = 1 << LINE_ADDR_LEN ; // 计算 line ?? word 的数量,?? 2^LINE_ADDR_LEN 个word ?? line
localparam SET_SIZE = 1 << SET_ADDR_LEN ; // 计算共有多少组, 2^SET_ADDR_LEN 个组 localparam SET_SIZE = 1 << SET_ADDR_LEN ; // 计算??共有多少组,?? 2^SET_ADDR_LEN 个组
reg [ 31:0] cache_mem [SET_SIZE][WAY_CNT][LINE_SIZE]; // SET_SIZE个line,每个line有LINE_SIZE个word reg [ 31:0] cache_mem [SET_SIZE][WAY_CNT][LINE_SIZE]; // SET_SIZE个line,每个line有LINE_SIZE个word
reg [TAG_ADDR_LEN-1:0] cache_tags [SET_SIZE][WAY_CNT]; // SET_SIZE个TAG reg [TAG_ADDR_LEN-1:0] cache_tags [SET_SIZE][WAY_CNT]; // SET_SIZE个TAG
reg valid [SET_SIZE][WAY_CNT]; // SET_SIZE个valid(有效) reg valid [SET_SIZE][WAY_CNT]; // SET_SIZE个valid(有效??)
reg dirty [SET_SIZE][WAY_CNT]; // SET_SIZE个dirty(脏位) reg dirty [SET_SIZE][WAY_CNT]; // SET_SIZE个dirty(脏位)
reg [ WAY_CNT:0] lru_stack [SET_SIZE][WAY_CNT]; reg [ WAY_CNT:0] lru_stack [SET_SIZE][WAY_CNT];
reg [ WAY_CNT:0] way_length [SET_SIZE]; reg [ WAY_CNT:0] way_length [SET_SIZE];
wire [ 2-1:0] word_addr; // 将输入地addr拆分成这5个部 wire [ 2-1:0] word_addr; // 将输入地??addr拆分成这5个部??
wire [ LINE_ADDR_LEN-1:0] line_addr; wire [ LINE_ADDR_LEN-1:0] line_addr;
wire [ SET_ADDR_LEN-1:0] set_addr; wire [ SET_ADDR_LEN-1:0] set_addr;
wire [ TAG_ADDR_LEN-1:0] tag_addr; wire [ TAG_ADDR_LEN-1:0] tag_addr;
...@@ -36,8 +36,8 @@ wire [UNUSED_ADDR_LEN-1:0] unused_addr; ...@@ -36,8 +36,8 @@ wire [UNUSED_ADDR_LEN-1:0] unused_addr;
wire [ WAY_CNT:0] lru_pos; wire [ WAY_CNT:0] lru_pos;
wire [ WAY_CNT:0] stack_len; wire [ WAY_CNT:0] stack_len;
enum {IDLE, SWAP_OUT, SWAP_IN, SWAP_IN_OK} cache_stat; // cache 状机的状态定 enum {IDLE, SWAP_OUT, SWAP_IN, SWAP_IN_OK} cache_stat; // cache 状�?�机的状态定??
// IDLE代表就绪,SWAP_OUT代表正在换出,SWAP_IN代表正在换入,SWAP_IN_OK代表换入后进行一周期的写入cache操作 // IDLE代表就绪,SWAP_OUT代表正在换出,SWAP_IN代表正在换入,SWAP_IN_OK代表换入后进行一周期的写入cache操作??
reg [ SET_ADDR_LEN-1:0] mem_rd_set_addr = 0; reg [ SET_ADDR_LEN-1:0] mem_rd_set_addr = 0;
reg [ TAG_ADDR_LEN-1:0] mem_rd_tag_addr = 0; reg [ TAG_ADDR_LEN-1:0] mem_rd_tag_addr = 0;
...@@ -50,7 +50,7 @@ reg [ WAY_CNT:0] mem_lru_len = 0; ...@@ -50,7 +50,7 @@ reg [ WAY_CNT:0] mem_lru_len = 0;
reg [31:0] mem_wr_line [LINE_SIZE]; reg [31:0] mem_wr_line [LINE_SIZE];
wire [31:0] mem_rd_line [LINE_SIZE]; wire [31:0] mem_rd_line [LINE_SIZE];
wire mem_gnt; // 主存响应读写的握手信 wire mem_gnt; // 主存响应读写的握手信??
assign {unused_addr, tag_addr, set_addr, line_addr, word_addr} = addr; // 拆分 32bit ADDR assign {unused_addr, tag_addr, set_addr, line_addr, word_addr} = addr; // 拆分 32bit ADDR
...@@ -58,13 +58,13 @@ assign stack_len = way_length[set_addr];//length of the lru stack ...@@ -58,13 +58,13 @@ assign stack_len = way_length[set_addr];//length of the lru stack
assign lru_pos = lru_stack[set_addr][WAY_CNT-1]; assign lru_pos = lru_stack[set_addr][WAY_CNT-1];
reg cache_hit = 1'b0; reg cache_hit = 1'b0;
reg [WAY_CNT:0] asso_pos = 0; //hit pos in set reg [WAY_CNT:0] hit_pos = 0; //hit pos in set
always @ (*) begin // 判断 输入的address 是否 cache 中命 always @ (*) begin // 判断 输入的address 是否?? cache 中命??
for(integer i = 0;i < WAY_CNT;i++) begin for(integer i = 0;i < WAY_CNT;i++) begin
if(valid[set_addr][i] && cache_tags[set_addr][i] == tag_addr) begin if(valid[set_addr][i] && cache_tags[set_addr][i] == tag_addr) begin
cache_hit = 1'b1; cache_hit = 1'b1;
asso_pos = i; hit_pos = i;
break; break;
end end
else begin else begin
...@@ -97,36 +97,36 @@ always @ (posedge clk or posedge rst) begin // ?? cache ??? ...@@ -97,36 +97,36 @@ always @ (posedge clk or posedge rst) begin // ?? cache ???
IDLE: begin IDLE: begin
if(cache_hit) begin if(cache_hit) begin
if(rd_req) begin // 如果cache命中,并且是读请求, if(rd_req) begin // 如果cache命中,并且是读请求,
rd_data <= cache_mem[set_addr][asso_pos][line_addr]; //则直接从cache中取出要读的数据 rd_data <= cache_mem[set_addr][hit_pos][line_addr]; //则直接从cache中取出要读的数据
for(integer i=1;i<WAY_CNT;i++)begin//update stack for(integer i=1;i<WAY_CNT;i++)begin//update stack
if(i>asso_pos)begin if(i>hit_pos)begin
break; break;
end end
else begin else begin
lru_stack[set_addr][i] <= lru_stack[set_addr][i-1]; lru_stack[set_addr][i] <= lru_stack[set_addr][i-1];
end end
end end
lru_stack[set_addr][0] <= asso_pos; lru_stack[set_addr][0] <= hit_pos;
end else if(wr_req) begin // 如果cache命中,并且是写请求, end else if(wr_req) begin // 如果cache命中,并且是写请求,
cache_mem[set_addr][asso_pos][line_addr] <= wr_data; // 则直接向cache中写入数 cache_mem[set_addr][hit_pos][line_addr] <= wr_data; // 则直接向cache中写入数??
dirty[set_addr][asso_pos] <= 1'b1; // 写数据的同时置脏 dirty[set_addr][hit_pos] <= 1'b1; // 写数据的同时置脏??
for(integer i=1;i<WAY_CNT;i++)begin for(integer i=1;i<WAY_CNT;i++)begin
if(i>asso_pos)begin if(i>hit_pos)begin
break; break;
end end
else begin else begin
lru_stack[set_addr][i] <= lru_stack[set_addr][i-1]; lru_stack[set_addr][i] <= lru_stack[set_addr][i-1];
end end
end end
lru_stack[set_addr][0] <= asso_pos; lru_stack[set_addr][0] <= hit_pos;
end end
end else begin end else begin
if(wr_req | rd_req) begin // 如果 cache 未命中,并且有读写请求,则需要进行换 if(wr_req | rd_req) begin // 如果 cache 未命中,并且有读写请求,则需要进行换??
if(valid[set_addr][lru_pos] && dirty[set_addr][lru_pos] && stack_len!=0) begin // 如果 要换入的cache line 本来有效,且脏,则需要先将它换出 if(valid[set_addr][lru_pos] && dirty[set_addr][lru_pos] && stack_len!=0) begin // 如果 要换入的cache line 本来有效,且脏,则需要先将它换出
cache_stat <= SWAP_OUT; cache_stat <= SWAP_OUT;
mem_wr_addr <= {cache_tags[set_addr][lru_pos], set_addr}; mem_wr_addr <= {cache_tags[set_addr][lru_pos], set_addr};
mem_wr_line <= cache_mem[set_addr][lru_pos]; mem_wr_line <= cache_mem[set_addr][lru_pos];
end else begin // 反之,不要换出,直接换入 end else begin // 反之,不??要换出,直接换入
cache_stat <= SWAP_IN; cache_stat <= SWAP_IN;
end end
{mem_rd_tag_addr, mem_rd_set_addr} <= {tag_addr, set_addr}; {mem_rd_tag_addr, mem_rd_set_addr} <= {tag_addr, set_addr};
...@@ -136,12 +136,12 @@ always @ (posedge clk or posedge rst) begin // ?? cache ??? ...@@ -136,12 +136,12 @@ always @ (posedge clk or posedge rst) begin // ?? cache ???
end end
end end
SWAP_OUT: begin SWAP_OUT: begin
if(mem_gnt) begin // 如果主存握手信号有效,说明换出成功,跳到下一状 if(mem_gnt) begin // 如果主存握手信号有效,说明换出成功,跳到下一状�??
cache_stat <= SWAP_IN; cache_stat <= SWAP_IN;
end end
end end
SWAP_IN: begin SWAP_IN: begin
if(mem_gnt) begin // 如果主存握手信号有效,说明换入成功,跳到下一状 if(mem_gnt) begin // 如果主存握手信号有效,说明换入成功,跳到下一状�??
cache_stat <= SWAP_IN_OK; cache_stat <= SWAP_IN_OK;
end end
end end
...@@ -156,7 +156,7 @@ always @ (posedge clk or posedge rst) begin // ?? cache ??? ...@@ -156,7 +156,7 @@ always @ (posedge clk or posedge rst) begin // ?? cache ???
cache_tags[mem_rd_set_addr][mem_lru_pos] <= mem_rd_tag_addr; cache_tags[mem_rd_set_addr][mem_lru_pos] <= mem_rd_tag_addr;
valid [mem_rd_set_addr][mem_lru_pos] <= 1'b1; valid [mem_rd_set_addr][mem_lru_pos] <= 1'b1;
dirty [mem_rd_set_addr][mem_lru_pos] <= 1'b0; dirty [mem_rd_set_addr][mem_lru_pos] <= 1'b0;
cache_stat <= IDLE; // 回到就绪状 cache_stat <= IDLE; // 回到就绪状�??
end end
endcase endcase
end end
...@@ -166,9 +166,9 @@ wire mem_rd_req = (cache_stat == SWAP_IN ); ...@@ -166,9 +166,9 @@ wire mem_rd_req = (cache_stat == SWAP_IN );
wire mem_wr_req = (cache_stat == SWAP_OUT); wire mem_wr_req = (cache_stat == SWAP_OUT);
wire [ MEM_ADDR_LEN-1 :0] mem_addr = mem_rd_req ? mem_rd_addr : ( mem_wr_req ? mem_wr_addr : 0); wire [ MEM_ADDR_LEN-1 :0] mem_addr = mem_rd_req ? mem_rd_addr : ( mem_wr_req ? mem_wr_addr : 0);
assign miss = (rd_req | wr_req) & ~(cache_hit && cache_stat==IDLE) ; // 有读写请求时,如果cache不处于就(IDLE)状态,或者未命中,则miss=1 assign miss = (rd_req | wr_req) & ~(cache_hit && cache_stat==IDLE) ; // ?? 有读写请求时,如果cache不处于就??(IDLE)状�?�,或�?�未命中,则miss=1
main_mem #( // 主存,每次读写以line 为单 main_mem #( // 主存,每次读写以line 为单??
.LINE_ADDR_LEN ( LINE_ADDR_LEN ), .LINE_ADDR_LEN ( LINE_ADDR_LEN ),
.ADDR_LEN ( MEM_ADDR_LEN ) .ADDR_LEN ( MEM_ADDR_LEN )
) main_mem_instance ( ) main_mem_instance (
......
...@@ -1889,7 +1889,7 @@ always @ (posedge clk or posedge rst) ...@@ -1889,7 +1889,7 @@ always @ (posedge clk or posedge rst)
end end
end end
cache #( cache_fifo #(
.LINE_ADDR_LEN ( 3 ), .LINE_ADDR_LEN ( 3 ),
.SET_ADDR_LEN ( 2 ), .SET_ADDR_LEN ( 2 ),
.TAG_ADDR_LEN ( 12 ), .TAG_ADDR_LEN ( 12 ),
......
module main_mem #( // 每次读取个line module main_mem #( // 每次读取?个line
parameter LINE_ADDR_LEN = 3, // line内地长度,决定了每个line具有 2^LINE_ADDR_LEN 个word parameter LINE_ADDR_LEN = 3, // line内地?长度,决定了每个line具有 2^LINE_ADDR_LEN 个word
parameter ADDR_LEN = 8 // 决定了mem中包 2^ADDR_LEN 个line parameter ADDR_LEN = 8 // 决定了mem中包? 2^ADDR_LEN 个line
)( )(
input clk, rst, input clk, rst,
output gnt, // read or write grant output gnt, // read or write grant
input [ADDR_LEN-1:0] addr, // line的地 input [ADDR_LEN-1:0] addr, // line的地?
input rd_req, input rd_req,
output reg [31:0] rd_line [1 << LINE_ADDR_LEN], output reg [31:0] rd_line [1 << LINE_ADDR_LEN],
input wr_req, input wr_req,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment