This commit is contained in:
cxy004 2022-08-05 14:48:55 +08:00
parent 9048a4749d
commit 429f7e55cb
4 changed files with 370 additions and 1 deletions

View File

@ -1,6 +1,10 @@
`include "defines.svh"
`include "Cache.svh"
`ifndef DC_SPEC_2WAY
`ifndef DC_SPEC_1WAY
module DCache (
input clk,
input rst,
@ -158,3 +162,202 @@ module DCache (
endmodule
`else // 1way
module DCache (
input clk,
input rst,
DCache_i.cache port
);
// ==============================
// ============ Vars ============
// ==============================
DCTagRAM_t TagRAM/*verilator split_var*/;
DCDataRAM_t DataRAM/*verilator split_var*/;
DCTag_t tag;
DCData_t data;
logic hit;
DCTagL_t dirt_tag;
logic wen;
// ==============================
// =========== Lookup ===========
// ==============================
assign tag = TagRAM.rdata;
assign data = DataRAM.rdata;
assign hit = tag.valid & tag.tag == port.tag;
assign port.hit = hit;
assign port.hit_row = data;
// ==============================
// ========== Replace ===========
// ==============================
assign port.dirt = tag.dirty;
assign dirt_tag = tag.tag;
assign port.dirt_addr = {dirt_tag, port.index, `DC_INDEXL'b0};
assign port.dirt_row = data;
// ==============================
// ========= Block RAM ==========
// ==============================
// 地址
assign TagRAM.addr = port.index_for_lookup;
assign DataRAM.addr = port.index_for_lookup;
// 写使能
assign wen = port.ctrl.read_but_replace
| port.ctrl.write_and_hit
| port.ctrl.write_but_replace
| port.ctrl.cache_index_invalidate
| port.ctrl.cache_index_writeback
| port.ctrl.cache_hit_invalidate & hit
| port.ctrl.cache_hit_writeback & hit;
assign TagRAM.wen = wen;
assign DataRAM.wen = wen;
// 写数据
assign TagRAM.wdata = {port.tag, port.ctrl.write_and_hit | port.ctrl.write_but_replace, port.ctrl.read_but_replace | port.ctrl.write_and_hit | port.ctrl.write_but_replace};
assign DataRAM.wdata = port.update_row;
// BRAM 实例
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
tag_ram (.rst(rst), .addra(TagRAM.addr), .clka(clk), .dina(TagRAM.wdata), .douta(TagRAM.rdata), .wea(TagRAM.wen));
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
data_ram (.rst(rst), .addra(DataRAM.addr), .clka(clk), .dina(DataRAM.wdata), .douta(DataRAM.rdata), .wea(DataRAM.wen));
endmodule
`endif
`else // 2way
module DCache (
input clk,
input rst,
DCache_i.cache port
);
// ==============================
// ============ Vars ============
// ==============================
DCTagRAM_t TagRAM[2]/*verilator split_var*/;
DCDataRAM_t DataRAM[2]/*verilator split_var*/;
logic LRU[`DC_INDEX_DEPTH];
logic nowLRU;
logic nxtLRU;
DCTag_t tag[2];
DCData_t data[2];
logic [1:0] hitway;
logic victim;
DCTagL_t dirt_tag;
logic [1:0] wen;
// ==============================
// =========== Lookup ===========
// ==============================
for (genvar i = 0; i < `DC_WAYS; i++) begin
assign tag[i] = TagRAM[i].rdata;
assign data[i] = DataRAM[i].rdata;
assign hitway[i] = tag[i].valid & tag[i].tag == port.tag;
end
assign port.hit = |{hitway};
assign port.hit_row = (hitway[0] ? data[0] : {`DC_DATA_LENGTH{1'b0}})
| (hitway[1] ? data[1] : {`DC_DATA_LENGTH{1'b0}});
// ==============================
// ========== Replace ===========
// ==============================
assign victim = port.ctrl.cache_hit_writeback ? hitway[1]
: port.ctrl.cache_index_writeback & tag[0].dirty ? 1'b0
: port.ctrl.cache_index_writeback & tag[1].dirty ? 1'b1
: tag[0].valid == 0 ? 1'b0
: tag[1].valid == 0 ? 1'b1
: ~nowLRU;
assign port.dirt = tag[victim].dirty;
assign dirt_tag = tag[victim].tag;
assign port.dirt_addr = {dirt_tag, port.index, `DC_INDEXL'b0};
assign port.dirt_row = data[victim];
assign nxtLRU = (port.ctrl.read_and_hit ? hitway[1] : 1'b0)
| (port.ctrl.read_but_replace ? victim : 1'b0)
| (port.ctrl.write_and_hit ? hitway[1] : 1'b0)
| (port.ctrl.write_but_replace ? victim : 1'b0);
for (genvar i = 0; i < `DC_INDEX_DEPTH; i++)
initial LRU[i] = 1'b0;
always_ff @(posedge clk) begin
if (~rst) begin
if (port.ctrl.read_and_hit | port.ctrl.read_but_replace
| port.ctrl.write_and_hit | port.ctrl.write_but_replace)
LRU[port.index] <= nxtLRU;
nowLRU <= LRU[port.index_for_lookup];
end
end
// ==============================
// ========= Block RAM ==========
// ==============================
// 地址
for (genvar i = 0; i < `DC_WAYS; i++) begin
assign TagRAM[i].addr = port.index_for_lookup;
assign DataRAM[i].addr = port.index_for_lookup;
end
// 写使能
assign wen = (port.ctrl.read_but_replace ? {victim, ~victim} : 2'b00)
| (port.ctrl.write_and_hit ? hitway : 2'b00)
| (port.ctrl.write_but_replace ? {victim, ~victim} : 2'b00)
| (port.ctrl.cache_index_invalidate ? 2'b11 : 2'b00)
| (port.ctrl.cache_index_writeback ? port.dirt ? {victim, ~victim} : 2'b11 : 2'b00)
| (port.ctrl.cache_hit_invalidate ? hitway : 2'b00)
| (port.ctrl.cache_hit_writeback ? hitway : 2'b00);
for (genvar i = 0; i < `DC_WAYS; i++) begin
assign TagRAM[i].wen = wen[i];
assign DataRAM[i].wen = wen[i];
end
// 写数据
for (genvar i = 0; i < `DC_WAYS; i++) begin
assign TagRAM[i].wdata = {port.tag, port.ctrl.write_and_hit | port.ctrl.write_but_replace, port.ctrl.read_but_replace | port.ctrl.write_and_hit | port.ctrl.write_but_replace};
assign DataRAM[i].wdata = port.update_row;
end
// BRAM 实例
for (genvar i = 0; i < `DC_WAYS; i++) begin : dbram
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
tag_ram (.rst(rst), .addra(TagRAM[i].addr), .clka(clk), .dina(TagRAM[i].wdata), .douta(TagRAM[i].rdata), .wea(TagRAM[i].wen));
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
data_ram (.rst(rst), .addra(DataRAM[i].addr), .clka(clk), .dina(DataRAM[i].wdata), .douta(DataRAM[i].rdata), .wea(DataRAM[i].wen));
end
endmodule
`endif

View File

@ -1,6 +1,10 @@
`include "defines.svh"
`include "Cache.svh"
`ifndef IC_SPEC_2WAY
`ifndef IC_SPEC_1WAY
module ICache (
input clk,
input rst,
@ -117,3 +121,161 @@ module ICache (
end
endmodule
`else // 1way
module ICache (
input clk,
input rst,
ICache_i.cache port
);
// ==============================
// ============ Vars ============
// ==============================
ICTagRAM_t TagRAM/*verilator split_var*/;
ICDataRAM_t DataRAM/*verilator split_var*/;
ICTag_t tag;
ICData_t data;
logic hit;
logic wen;
// ==============================
// =========== Lookup ===========
// ==============================
assign tag = TagRAM.rdata;
assign data = DataRAM.rdata;
assign hit = tag.valid & tag.tag == port.tag;
assign port.hit = hit;
assign port.hit_row = data;
// ==============================
// ========= Block RAM ==========
// ==============================
// 地址
assign TagRAM.addr = port.index_for_lookup;
assign DataRAM.addr = port.index_for_lookup;
// 写使能
assign wen = port.ctrl.read_but_replace | port.ctrl.cache_index_invalidate | port.ctrl.cache_hit_invalidate & hit;
assign TagRAM.wen = wen;
assign DataRAM.wen = wen;
// 写数据
assign TagRAM.wdata = {port.tag, port.ctrl.read_but_replace};
assign DataRAM.wdata = port.update_row;
// BRAM 实例
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
tag_ram (.rst(rst), .addra(TagRAM.addr), .clka(clk), .dina(TagRAM.wdata), .douta(TagRAM.rdata), .wea(TagRAM.wen));
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
data_ram (.rst(rst), .addra(DataRAM.addr), .clka(clk), .dina(DataRAM.wdata), .douta(DataRAM.rdata), .wea(DataRAM.wen));
endmodule
`endif
`else // 2way
module ICache (
input clk,
input rst,
ICache_i.cache port
);
// ==============================
// ============ Vars ============
// ==============================
ICTagRAM_t TagRAM[2]/*verilator split_var*/;
ICDataRAM_t DataRAM[2]/*verilator split_var*/;
logic LRU[`IC_INDEX_DEPTH];
logic nowLRU;
logic nxtLRU;
ICTag_t tag[2];
ICData_t data[2];
logic [1:0] hitway;
logic victim;
logic [1:0] wen;
// ==============================
// =========== Lookup ===========
// ==============================
for (genvar i = 0; i < `IC_WAYS; i++) begin
assign tag[i] = TagRAM[i].rdata;
assign data[i] = DataRAM[i].rdata;
assign hitway[i] = tag[i].valid & tag[i].tag == port.tag;
end
assign port.hit = |{hitway};
assign port.hit_row = (hitway[0] ? data[0] : {`IC_DATA_LENGTH{1'b0}})
| (hitway[1] ? data[1] : {`IC_DATA_LENGTH{1'b0}});
assign victim = tag[0].valid == 0 ? 1'b0
: tag[1].valid == 0 ? 1'b1
: ~nowLRU;
assign nxtLRU = (port.ctrl.read_and_hit ? hitway[1] : 1'b0)
| (port.ctrl.read_but_replace ? victim : 1'b0);
for (genvar i = 0; i < `IC_INDEX_DEPTH; i++)
initial LRU[i] = 1'b0;
always_ff @(posedge clk) begin
if (~rst) begin
if (port.ctrl.read_and_hit | port.ctrl.read_but_replace)
LRU[port.index] <= nxtLRU;
nowLRU <= LRU[port.index_for_lookup];
end
end
// ==============================
// ========= Block RAM ==========
// ==============================
// 地址
for (genvar i = 0; i < `IC_WAYS; i++) begin
assign TagRAM[i].addr = port.index_for_lookup;
assign DataRAM[i].addr = port.index_for_lookup;
end
// 写使能
assign wen = (port.ctrl.read_but_replace ? {victim, ~victim} : 2'b00)
| (port.ctrl.cache_index_invalidate ? 2'b11 : 2'b00)
| (port.ctrl.cache_hit_invalidate ? hitway : 2'b00);
for (genvar i = 0; i < `IC_WAYS; i++) begin
assign TagRAM[i].wen = wen[i];
assign DataRAM[i].wen = wen[i];
end
// 写数据
for (genvar i = 0; i < `IC_WAYS; i++) begin
assign TagRAM[i].wdata = {port.tag, port.ctrl.read_but_replace};
assign DataRAM[i].wdata = port.update_row;
end
// BRAM 实例
for (genvar i = 0; i < `IC_WAYS; i++) begin : ibram
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
tag_ram (.rst(rst), .addra(TagRAM[i].addr), .clka(clk), .dina(TagRAM[i].wdata), .douta(TagRAM[i].rdata), .wea(TagRAM[i].wen));
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
data_ram (.rst(rst), .addra(DataRAM[i].addr), .clka(clk), .dina(DataRAM[i].wdata), .douta(DataRAM[i].rdata), .wea(DataRAM[i].wen));
end
endmodule
`endif

View File

@ -14,6 +14,8 @@
`define IC_ROW_LENGTH (`IC_DATA_LENGTH / `XLEN - 1)
`define IC_INDEX_DEPTH (2 ** (`IC_TAGL - `IC_INDEXL))
`define IC_WAYS 2
// `define IC_SPEC_1WAY
`define IC_SPEC_2WAY
typedef logic [`IC_DATA_LENGTH-1:0] ICData_t;
typedef logic [32-`IC_TAGL-1:0] ICTagL_t;
@ -53,6 +55,8 @@ typedef struct packed {
`define DC_ROW_LENGTH (`DC_DATA_LENGTH / `XLEN - 1)
`define DC_INDEX_DEPTH (2 ** (`DC_TAGL - `DC_INDEXL))
`define DC_WAYS 2
// `define DC_SPEC_1WAY
`define DC_SPEC_2WAY
typedef logic [`DC_DATA_LENGTH-1:0] DCData_t;
typedef logic [32-`DC_TAGL-1:0] DCTagL_t;

View File

@ -18,7 +18,7 @@
`undef ENABLE_TLB
`endif
`define MUL_PIPE_STAGES 3
`define MUL_PIPE_STAGES 6
`define XLEN 32
`define PCRST 32'hBFC00000