Configurable Cache
This commit is contained in:
parent
bab898db60
commit
31030d6a84
15
src/Gadgets/onehot_bin.sv
Normal file
15
src/Gadgets/onehot_bin.sv
Normal file
@ -0,0 +1,15 @@
|
||||
module onehot_bin #(
|
||||
parameter WIDTH = 4
|
||||
) (
|
||||
input logic [ WIDTH-1:0] onehot,
|
||||
output logic [$clog2(WIDTH)-1:0] bin
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < $clog2(WIDTH); i++) begin
|
||||
logic [WIDTH-1:0] bin_mask;
|
||||
for (genvar j = 0; j < WIDTH; j++)
|
||||
assign bin_mask[j] = j[i];
|
||||
assign bin[i] = |(bin_mask & onehot);
|
||||
end
|
||||
|
||||
endmodule
|
180
src/MU/DCache.sv
180
src/MU/DCache.sv
@ -11,78 +11,74 @@ module DCache (
|
||||
// ============ Vars ============
|
||||
// ==============================
|
||||
|
||||
DCTagRAM_t TagRAM0/*verilator split_var*/, TagRAM1/*verilator split_var*/, TagRAM2/*verilator split_var*/, TagRAM3/*verilator split_var*/;
|
||||
DCDataRAM_t DataRAM0/*verilator split_var*/, DataRAM1/*verilator split_var*/, DataRAM2/*verilator split_var*/, DataRAM3/*verilator split_var*/;
|
||||
DCTagRAM_t TagRAM[`DC_WAYS]/*verilator split_var*/;
|
||||
DCDataRAM_t DataRAM[`DC_WAYS]/*verilator split_var*/;
|
||||
|
||||
(* RAM_STYLE="distributed" *)
|
||||
logic [3:0] LRU[`DC_INDEX_DEPTH];
|
||||
logic [3:0] nowLRU;
|
||||
logic [3:0] nxtLRU;
|
||||
logic [`DC_WAYS-1:0] LRU[`DC_INDEX_DEPTH];
|
||||
logic [`DC_WAYS-1:0] nowLRU;
|
||||
logic [`DC_WAYS-1:0] nxtLRU;
|
||||
|
||||
logic setLRU_valid;
|
||||
logic [3:0] setLRU;
|
||||
logic [3:0] nxtsetLRU;
|
||||
logic [`DC_WAYS-1:0] setLRU;
|
||||
logic [`DC_WAYS-1:0] nxtsetLRU;
|
||||
|
||||
logic clrLRU_valid;
|
||||
logic [3:0] clrLRU;
|
||||
logic [3:0] nxtclrLRU;
|
||||
logic [`DC_WAYS-1:0] clrLRU;
|
||||
logic [`DC_WAYS-1:0] nxtclrLRU;
|
||||
|
||||
DCTag_t tag[4];
|
||||
DCData_t data[4];
|
||||
DCTag_t tag[`DC_WAYS];
|
||||
DCData_t data[`DC_WAYS];
|
||||
|
||||
logic [3:0] hitway;
|
||||
logic [3:0] victim;
|
||||
logic [`DC_WAYS-1:0] hitway;
|
||||
logic [`DC_WAYS-1:0] victim;
|
||||
DCTagL_t dirt_tag;
|
||||
logic [3:0] wen;
|
||||
logic [`DC_WAYS-1:0] wen;
|
||||
|
||||
|
||||
// ==============================
|
||||
// =========== Lookup ===========
|
||||
// ==============================
|
||||
|
||||
assign tag[0] = TagRAM0.rdata;
|
||||
assign tag[1] = TagRAM1.rdata;
|
||||
assign tag[2] = TagRAM2.rdata;
|
||||
assign tag[3] = TagRAM3.rdata;
|
||||
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 data[0] = DataRAM0.rdata;
|
||||
assign data[1] = DataRAM1.rdata;
|
||||
assign data[2] = DataRAM2.rdata;
|
||||
assign data[3] = DataRAM3.rdata;
|
||||
|
||||
assign hitway[0] = tag[0].valid & tag[0].tag == port.tag;
|
||||
assign hitway[1] = tag[1].valid & tag[1].tag == port.tag;
|
||||
assign hitway[2] = tag[2].valid & tag[2].tag == port.tag;
|
||||
assign hitway[3] = tag[3].valid & tag[3].tag == port.tag;
|
||||
logic [$clog2(`DC_WAYS)-1:0] hitway_bin;
|
||||
onehot_bin #(`DC_WAYS) hitway_conv (.onehot(hitway), .bin(hitway_bin));
|
||||
|
||||
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}})
|
||||
| (hitway[2] ? data[2] : {`DC_DATA_LENGTH{1'b0}})
|
||||
| (hitway[3] ? data[3] : {`DC_DATA_LENGTH{1'b0}});
|
||||
assign port.hit_row = data[hitway_bin];
|
||||
|
||||
// ==============================
|
||||
// ========== Replace ===========
|
||||
// ==============================
|
||||
|
||||
// TODO: use lowbit 1 to avoid != 0 judge
|
||||
|
||||
logic [`DC_WAYS-1:0] victim_dirt, victim_dirt_collect;
|
||||
logic [`DC_WAYS-1:0] victim_valid, victim_valid_collect;
|
||||
logic [`DC_WAYS-1:0] victim_lrud, victim_lrud_collect;
|
||||
logic [`DC_WAYS-1:0] victim_lru;
|
||||
|
||||
for (genvar i = 0; i < `DC_WAYS; i++) begin
|
||||
assign victim_dirt_collect[i] = tag[i].dirty;
|
||||
assign victim_valid_collect[i] = tag[i].valid;
|
||||
assign victim_lrud_collect[i] = nowLRU[i] == 0 & ~tag[i].dirty;
|
||||
end
|
||||
|
||||
assign victim_dirt = (victim_dirt_collect) & (-victim_dirt_collect);
|
||||
assign victim_valid = (~victim_valid_collect) & (-~victim_valid_collect);
|
||||
assign victim_lrud = (victim_lrud_collect) & (-victim_lrud_collect);
|
||||
assign victim_lru = (~nowLRU) & (-~nowLRU);
|
||||
|
||||
assign victim = port.ctrl.cache_hit_writeback ? hitway
|
||||
: port.ctrl.cache_index_writeback & tag[0].dirty ? 4'b0001
|
||||
: port.ctrl.cache_index_writeback & tag[1].dirty ? 4'b0010
|
||||
: port.ctrl.cache_index_writeback & tag[2].dirty ? 4'b0100
|
||||
: port.ctrl.cache_index_writeback & tag[3].dirty ? 4'b1000
|
||||
: port.ctrl.cache_index_writeback ? 4'b1111 // NOTE: <----
|
||||
: tag[0].valid == 0 ? 4'b0001
|
||||
: tag[1].valid == 0 ? 4'b0010
|
||||
: tag[2].valid == 0 ? 4'b0100
|
||||
: tag[3].valid == 0 ? 4'b1000
|
||||
: nowLRU[0] == 0 & ~tag[0].dirty ? 4'b0001
|
||||
: nowLRU[1] == 0 & ~tag[1].dirty ? 4'b0010
|
||||
: nowLRU[2] == 0 & ~tag[2].dirty ? 4'b0100
|
||||
: nowLRU[3] == 0 & ~tag[3].dirty ? 4'b1000
|
||||
: nowLRU[0] == 0 ? 4'b0001
|
||||
: nowLRU[1] == 0 ? 4'b0010
|
||||
: nowLRU[2] == 0 ? 4'b0100
|
||||
: 4'b1000;
|
||||
: port.ctrl.cache_index_writeback ? (victim_dirt == `DC_WAYS'b0 ? ~`DC_WAYS'b0 : victim_dirt)
|
||||
: victim_valid != `DC_WAYS'b0 ? victim_valid
|
||||
: victim_lrud != `DC_WAYS'b0 ? victim_lrud
|
||||
: victim_lru;
|
||||
|
||||
assign port.dirt = |{victim & {tag[3].dirty, tag[2].dirty, tag[1].dirty, tag[0].dirty}};
|
||||
assign dirt_tag = (victim[0] ? tag[0].tag : {(32-`DC_TAGL){1'b0}})
|
||||
@ -96,24 +92,24 @@ module DCache (
|
||||
| (victim[3] ? data[3] : {`DC_DATA_LENGTH{1'b0}});
|
||||
|
||||
assign setLRU_valid = port.ctrl.read_and_hit | port.ctrl.read_but_replace | port.ctrl.write_and_hit | port.ctrl.write_but_replace;
|
||||
assign setLRU = (port.ctrl.read_and_hit ? hitway : 4'b0000)
|
||||
| (port.ctrl.read_but_replace ? victim : 4'b0000)
|
||||
| (port.ctrl.write_and_hit ? hitway : 4'b0000)
|
||||
| (port.ctrl.write_but_replace ? victim : 4'b0000);
|
||||
assign nxtsetLRU = setLRU | nowLRU & {4{~&{nowLRU | setLRU}}};
|
||||
assign setLRU = (port.ctrl.read_and_hit ? hitway : `DC_WAYS'b0)
|
||||
| (port.ctrl.read_but_replace ? victim : `DC_WAYS'b0)
|
||||
| (port.ctrl.write_and_hit ? hitway : `DC_WAYS'b0)
|
||||
| (port.ctrl.write_but_replace ? victim : `DC_WAYS'b0);
|
||||
assign nxtsetLRU = setLRU | nowLRU & {`DC_WAYS{~&{nowLRU | setLRU}}};
|
||||
|
||||
assign clrLRU_valid = port.ctrl.cache_index_invalidate | port.ctrl.cache_hit_invalidate | port.ctrl.cache_index_writeback | port.ctrl.cache_hit_writeback;
|
||||
assign clrLRU = (port.ctrl.cache_index_invalidate ? 4'b1111 : 4'b0000)
|
||||
| (port.ctrl.cache_hit_invalidate ? hitway : 4'b0000)
|
||||
| (port.ctrl.cache_index_writeback ? 4'b1111 : 4'b0000)
|
||||
| (port.ctrl.cache_hit_writeback ? hitway : 4'b0000);
|
||||
assign clrLRU = (port.ctrl.cache_index_invalidate ? ~`DC_WAYS'b0 : `DC_WAYS'b0)
|
||||
| (port.ctrl.cache_hit_invalidate ? hitway : `DC_WAYS'b0)
|
||||
| (port.ctrl.cache_index_writeback ? ~`DC_WAYS'b0 : `DC_WAYS'b0)
|
||||
| (port.ctrl.cache_hit_writeback ? hitway : `DC_WAYS'b0);
|
||||
assign nxtclrLRU = ~clrLRU & nowLRU;
|
||||
|
||||
assign nxtLRU = (setLRU_valid ? nxtsetLRU : 4'b0000)
|
||||
| (clrLRU_valid ? nxtclrLRU : 4'b0000);
|
||||
assign nxtLRU = (setLRU_valid ? nxtsetLRU : `DC_WAYS'b0)
|
||||
| (clrLRU_valid ? nxtclrLRU : `DC_WAYS'b0);
|
||||
|
||||
for (genvar i = 0; i < `DC_INDEX_DEPTH; i++)
|
||||
initial LRU[i] = 4'b0;
|
||||
initial LRU[i] = `DC_WAYS'b0;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (~rst) begin
|
||||
@ -128,56 +124,40 @@ module DCache (
|
||||
// ==============================
|
||||
|
||||
// 地址
|
||||
assign TagRAM0.addr = port.index_for_lookup;
|
||||
assign TagRAM1.addr = port.index_for_lookup;
|
||||
assign TagRAM2.addr = port.index_for_lookup;
|
||||
assign TagRAM3.addr = port.index_for_lookup;
|
||||
assign DataRAM0.addr = port.index_for_lookup;
|
||||
assign DataRAM1.addr = port.index_for_lookup;
|
||||
assign DataRAM2.addr = port.index_for_lookup;
|
||||
assign DataRAM3.addr = port.index_for_lookup;
|
||||
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 = ({4{port.ctrl.read_but_replace}} & victim)
|
||||
| ({4{port.ctrl.write_and_hit}} & hitway)
|
||||
| ({4{port.ctrl.write_but_replace}} & victim)
|
||||
| ({4{port.ctrl.cache_index_invalidate}} )
|
||||
| ({4{port.ctrl.cache_index_writeback}} & victim)
|
||||
| ({4{port.ctrl.cache_hit_invalidate}} & hitway)
|
||||
| ({4{port.ctrl.cache_hit_writeback}} & hitway);
|
||||
assign wen = ({`DC_WAYS{port.ctrl.read_but_replace}} & victim)
|
||||
| ({`DC_WAYS{port.ctrl.write_and_hit}} & hitway)
|
||||
| ({`DC_WAYS{port.ctrl.write_but_replace}} & victim)
|
||||
| ({`DC_WAYS{port.ctrl.cache_index_invalidate}} )
|
||||
| ({`DC_WAYS{port.ctrl.cache_index_writeback}} & victim)
|
||||
| ({`DC_WAYS{port.ctrl.cache_hit_invalidate}} & hitway)
|
||||
| ({`DC_WAYS{port.ctrl.cache_hit_writeback}} & hitway);
|
||||
|
||||
assign {TagRAM3.wen, TagRAM2.wen, TagRAM1.wen, TagRAM0.wen} = wen;
|
||||
assign {DataRAM3.wen, DataRAM2.wen, DataRAM1.wen, DataRAM0.wen} = wen;
|
||||
for (genvar i = 0; i < `IC_WAYS; i++) begin
|
||||
assign TagRAM[i].wen = wen[i];
|
||||
assign DataRAM[i].wen = wen[i];
|
||||
end
|
||||
|
||||
// 写数据
|
||||
assign TagRAM0.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 TagRAM1.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 TagRAM2.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 TagRAM3.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};
|
||||
for (genvar i = 0; i < `IC_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
|
||||
|
||||
assign DataRAM0.wdata = port.update_row;
|
||||
assign DataRAM1.wdata = port.update_row;
|
||||
assign DataRAM2.wdata = port.update_row;
|
||||
assign DataRAM3.wdata = port.update_row;
|
||||
|
||||
// bram
|
||||
// BRAM 实例
|
||||
for (genvar i = 0; i < `IC_WAYS; i++) begin : dbram
|
||||
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||
tag_ram0 (.rst(rst), .addra(TagRAM0.addr), .clka(clk), .dina(TagRAM0.wdata), .douta(TagRAM0.rdata), .wea(TagRAM0.wen));
|
||||
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||
tag_ram1 (.rst(rst), .addra(TagRAM1.addr), .clka(clk), .dina(TagRAM1.wdata), .douta(TagRAM1.rdata), .wea(TagRAM1.wen));
|
||||
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||
tag_ram2 (.rst(rst), .addra(TagRAM2.addr), .clka(clk), .dina(TagRAM2.wdata), .douta(TagRAM2.rdata), .wea(TagRAM2.wen));
|
||||
bram #(.DATA_WIDTH(32-`DC_TAGL+2), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||
tag_ram3 (.rst(rst), .addra(TagRAM3.addr), .clka(clk), .dina(TagRAM3.wdata), .douta(TagRAM3.rdata), .wea(TagRAM3.wen));
|
||||
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_ram0 (.rst(rst), .addra(DataRAM0.addr), .clka(clk), .dina(DataRAM0.wdata), .douta(DataRAM0.rdata), .wea(DataRAM0.wen));
|
||||
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||
data_ram1 (.rst(rst), .addra(DataRAM1.addr), .clka(clk), .dina(DataRAM1.wdata), .douta(DataRAM1.rdata), .wea(DataRAM1.wen));
|
||||
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||
data_ram2 (.rst(rst), .addra(DataRAM2.addr), .clka(clk), .dina(DataRAM2.wdata), .douta(DataRAM2.rdata), .wea(DataRAM2.wen));
|
||||
bram #(.DATA_WIDTH(`DC_DATA_LENGTH), .DATA_DEPTH(2 ** (`DC_TAGL-`DC_INDEXL)))
|
||||
data_ram3 (.rst(rst), .addra(DataRAM3.addr), .clka(clk), .dina(DataRAM3.wdata), .douta(DataRAM3.rdata), .wea(DataRAM3.wen));
|
||||
data_ram (.rst(rst), .addra(DataRAM[i].addr), .clka(clk), .dina(DataRAM[i].wdata), .douta(DataRAM[i].rdata), .wea(DataRAM[i].wen));
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
140
src/MU/ICache.sv
140
src/MU/ICache.sv
@ -11,78 +11,67 @@ module ICache (
|
||||
// ============ Vars ============
|
||||
// ==============================
|
||||
|
||||
ICTagRAM_t TagRAM0/*verilator split_var*/, TagRAM1/*verilator split_var*/, TagRAM2/*verilator split_var*/, TagRAM3/*verilator split_var*/;
|
||||
ICDataRAM_t DataRAM0/*verilator split_var*/, DataRAM1/*verilator split_var*/, DataRAM2/*verilator split_var*/, DataRAM3/*verilator split_var*/;
|
||||
ICTagRAM_t TagRAM[`IC_WAYS]/*verilator split_var*/;
|
||||
ICDataRAM_t DataRAM[`IC_WAYS]/*verilator split_var*/;
|
||||
|
||||
(* RAM_STYLE="distributed" *)
|
||||
logic [3:0] LRU[`IC_INDEX_DEPTH];
|
||||
logic [3:0] nowLRU;
|
||||
logic [3:0] nxtLRU;
|
||||
logic [`IC_WAYS-1:0] LRU[`IC_INDEX_DEPTH];
|
||||
logic [`IC_WAYS-1:0] nowLRU;
|
||||
logic [`IC_WAYS-1:0] nxtLRU;
|
||||
|
||||
logic setLRU_valid;
|
||||
logic [3:0] setLRU;
|
||||
logic [3:0] nxtsetLRU;
|
||||
logic [`IC_WAYS-1:0] setLRU;
|
||||
logic [`IC_WAYS-1:0] nxtsetLRU;
|
||||
|
||||
logic clrLRU_valid;
|
||||
logic [3:0] clrLRU;
|
||||
logic [3:0] nxtclrLRU;
|
||||
logic [`IC_WAYS-1:0] clrLRU;
|
||||
logic [`IC_WAYS-1:0] nxtclrLRU;
|
||||
|
||||
ICTag_t tag[4];
|
||||
ICData_t data[4];
|
||||
ICTag_t tag[`IC_WAYS];
|
||||
ICData_t data[`IC_WAYS];
|
||||
|
||||
logic [3:0] hitway;
|
||||
logic [3:0] victim;
|
||||
logic [3:0] wen;
|
||||
logic [`IC_WAYS-1:0] hitway;
|
||||
logic [`IC_WAYS-1:0] victim;
|
||||
logic [`IC_WAYS-1:0] wen;
|
||||
|
||||
// ==============================
|
||||
// =========== Lookup ===========
|
||||
// ==============================
|
||||
|
||||
assign tag[0] = TagRAM0.rdata;
|
||||
assign tag[1] = TagRAM1.rdata;
|
||||
assign tag[2] = TagRAM2.rdata;
|
||||
assign tag[3] = TagRAM3.rdata;
|
||||
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 data[0] = DataRAM0.rdata;
|
||||
assign data[1] = DataRAM1.rdata;
|
||||
assign data[2] = DataRAM2.rdata;
|
||||
assign data[3] = DataRAM3.rdata;
|
||||
|
||||
assign hitway[0] = tag[0].valid & tag[0].tag == port.tag;
|
||||
assign hitway[1] = tag[1].valid & tag[1].tag == port.tag;
|
||||
assign hitway[2] = tag[2].valid & tag[2].tag == port.tag;
|
||||
assign hitway[3] = tag[3].valid & tag[3].tag == port.tag;
|
||||
logic [$clog2(`IC_WAYS)-1:0] hitway_bin;
|
||||
onehot_bin #(`IC_WAYS) hitway_conv (.onehot(hitway), .bin(hitway_bin));
|
||||
|
||||
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}})
|
||||
| (hitway[2] ? data[2] : {`IC_DATA_LENGTH{1'b0}})
|
||||
| (hitway[3] ? data[3] : {`IC_DATA_LENGTH{1'b0}});
|
||||
assign port.hit_row = data[hitway_bin];
|
||||
|
||||
assign victim = tag[0].valid == 0 ? 4'b0001
|
||||
: tag[1].valid == 0 ? 4'b0010
|
||||
: tag[2].valid == 0 ? 4'b0100
|
||||
: tag[3].valid == 0 ? 4'b1000
|
||||
: nowLRU[0] == 0 ? 4'b0001
|
||||
: nowLRU[1] == 0 ? 4'b0010
|
||||
: nowLRU[2] == 0 ? 4'b0100
|
||||
: 4'b1000;
|
||||
logic [`IC_WAYS-1:0] victim_tag, victim_tag_collect;
|
||||
logic [`IC_WAYS-1:0] victim_lru;
|
||||
for (genvar i = 0; i < `IC_WAYS; i++) assign victim_tag_collect[i] = tag[i].valid;
|
||||
assign victim_tag = (~victim_tag_collect) & (-~victim_tag_collect);
|
||||
assign victim_lru = (~nowLRU) & (-~nowLRU);
|
||||
assign victim = victim_tag != `IC_WAYS'b0 ? victim_tag : victim_lru;
|
||||
|
||||
assign setLRU_valid = port.ctrl.read_and_hit | port.ctrl.read_but_replace;
|
||||
assign setLRU = (port.ctrl.read_and_hit ? hitway : 4'b0000)
|
||||
| (port.ctrl.read_but_replace ? victim : 4'b0000);
|
||||
assign nxtsetLRU = setLRU | nowLRU & {4{~&{nowLRU | setLRU}}};
|
||||
assign setLRU = (port.ctrl.read_and_hit ? hitway : `IC_WAYS'b0)
|
||||
| (port.ctrl.read_but_replace ? victim : `IC_WAYS'b0);
|
||||
assign nxtsetLRU = setLRU | nowLRU & {`IC_WAYS{~&{nowLRU | setLRU}}};
|
||||
|
||||
assign clrLRU_valid = port.ctrl.cache_index_invalidate | port.ctrl.cache_hit_invalidate;
|
||||
assign clrLRU = (port.ctrl.cache_index_invalidate ? 4'b1111 : 4'b0000)
|
||||
| (port.ctrl.cache_hit_invalidate ? hitway : 4'b0000);
|
||||
assign clrLRU = (port.ctrl.cache_index_invalidate ? ~`IC_WAYS'b0 : `IC_WAYS'b0)
|
||||
| (port.ctrl.cache_hit_invalidate ? hitway : `IC_WAYS'b0);
|
||||
assign nxtclrLRU = ~clrLRU & nowLRU;
|
||||
|
||||
assign nxtLRU = (setLRU_valid ? nxtsetLRU : 4'b0000)
|
||||
| (clrLRU_valid ? nxtclrLRU : 4'b0000);
|
||||
assign nxtLRU = (setLRU_valid ? nxtsetLRU : `IC_WAYS'b0)
|
||||
| (clrLRU_valid ? nxtclrLRU : `IC_WAYS'b0);
|
||||
|
||||
for (genvar i = 0; i < `IC_INDEX_DEPTH; i++)
|
||||
initial LRU[i] = 4'b0;
|
||||
initial LRU[i] = `IC_WAYS'b0;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (~rst) begin
|
||||
@ -97,47 +86,34 @@ module ICache (
|
||||
// ==============================
|
||||
|
||||
// 地址
|
||||
assign TagRAM0.addr = port.index_for_lookup;
|
||||
assign TagRAM1.addr = port.index_for_lookup;
|
||||
assign TagRAM2.addr = port.index_for_lookup;
|
||||
assign TagRAM3.addr = port.index_for_lookup;
|
||||
assign DataRAM0.addr = port.index_for_lookup;
|
||||
assign DataRAM1.addr = port.index_for_lookup;
|
||||
assign DataRAM2.addr = port.index_for_lookup;
|
||||
assign DataRAM3.addr = port.index_for_lookup;
|
||||
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 = ({4{port.ctrl.read_but_replace}} & victim)
|
||||
| ({4{port.ctrl.cache_index_invalidate}} )
|
||||
| ({4{port.ctrl.cache_hit_invalidate}} & hitway);
|
||||
assign wen = ({`IC_WAYS{port.ctrl.read_but_replace}} & victim)
|
||||
| ({`IC_WAYS{port.ctrl.cache_index_invalidate}} )
|
||||
| ({`IC_WAYS{port.ctrl.cache_hit_invalidate}} & hitway);
|
||||
|
||||
for (genvar i = 0; i < `IC_WAYS; i++) begin
|
||||
assign TagRAM[i].wen = wen[i];
|
||||
assign DataRAM[i].wen = wen[i];
|
||||
end
|
||||
|
||||
assign {TagRAM3.wen, TagRAM2.wen, TagRAM1.wen, TagRAM0.wen} = wen;
|
||||
assign {DataRAM3.wen, DataRAM2.wen, DataRAM1.wen, DataRAM0.wen} = wen;
|
||||
// 写数据
|
||||
assign TagRAM0.wdata = {port.tag, port.ctrl.read_but_replace};
|
||||
assign TagRAM1.wdata = {port.tag, port.ctrl.read_but_replace};
|
||||
assign TagRAM2.wdata = {port.tag, port.ctrl.read_but_replace};
|
||||
assign TagRAM3.wdata = {port.tag, port.ctrl.read_but_replace};
|
||||
assign DataRAM0.wdata = port.update_row;
|
||||
assign DataRAM1.wdata = port.update_row;
|
||||
assign DataRAM2.wdata = port.update_row;
|
||||
assign DataRAM3.wdata = port.update_row;
|
||||
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_ram0 (.rst(rst), .addra(TagRAM0.addr), .clka(clk), .dina(TagRAM0.wdata), .douta(TagRAM0.rdata), .wea(TagRAM0.wen));
|
||||
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||
tag_ram1 (.rst(rst), .addra(TagRAM1.addr), .clka(clk), .dina(TagRAM1.wdata), .douta(TagRAM1.rdata), .wea(TagRAM1.wen));
|
||||
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||
tag_ram2 (.rst(rst), .addra(TagRAM2.addr), .clka(clk), .dina(TagRAM2.wdata), .douta(TagRAM2.rdata), .wea(TagRAM2.wen));
|
||||
bram #(.DATA_WIDTH(32-`IC_TAGL+1), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||
tag_ram3 (.rst(rst), .addra(TagRAM3.addr), .clka(clk), .dina(TagRAM3.wdata), .douta(TagRAM3.rdata), .wea(TagRAM3.wen));
|
||||
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_ram0 (.rst(rst), .addra(DataRAM0.addr), .clka(clk), .dina(DataRAM0.wdata), .douta(DataRAM0.rdata), .wea(DataRAM0.wen));
|
||||
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||
data_ram1 (.rst(rst), .addra(DataRAM1.addr), .clka(clk), .dina(DataRAM1.wdata), .douta(DataRAM1.rdata), .wea(DataRAM1.wen));
|
||||
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||
data_ram2 (.rst(rst), .addra(DataRAM2.addr), .clka(clk), .dina(DataRAM2.wdata), .douta(DataRAM2.rdata), .wea(DataRAM2.wen));
|
||||
bram #(.DATA_WIDTH(`IC_DATA_LENGTH), .DATA_DEPTH(2 ** (`IC_TAGL-`IC_INDEXL)))
|
||||
data_ram3 (.rst(rst), .addra(DataRAM3.addr), .clka(clk), .dina(DataRAM3.wdata), .douta(DataRAM3.rdata), .wea(DataRAM3.wen));
|
||||
data_ram (.rst(rst), .addra(DataRAM[i].addr), .clka(clk), .dina(DataRAM[i].wdata), .douta(DataRAM[i].rdata), .wea(DataRAM[i].wen));
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
// `define ILA_DEBUG
|
||||
|
||||
// `define ENABLE_CACHEOP
|
||||
// `define ENABLE_TLB
|
||||
// `define ENABLE_CpU
|
||||
// `define ENABLE_TRAP
|
||||
`define ENABLE_CACHEOP
|
||||
`define ENABLE_TLB
|
||||
`define ENABLE_CpU
|
||||
`define ENABLE_TRAP
|
||||
|
||||
`ifdef SIMULATION_VERILATOR
|
||||
`undef ENABLE_CpU
|
||||
|
Loading…
Reference in New Issue
Block a user