From 429f7e55cb114b7b94697479265766bc83410762 Mon Sep 17 00:00:00 2001 From: cxy004 Date: Fri, 5 Aug 2022 14:48:55 +0800 Subject: [PATCH] spec --- src/MU/DCache.sv | 203 ++++++++++++++++++++++++++++++++++++++++ src/MU/ICache.sv | 162 ++++++++++++++++++++++++++++++++ src/include/Cache.svh | 4 + src/include/defines.svh | 2 +- 4 files changed, 370 insertions(+), 1 deletion(-) diff --git a/src/MU/DCache.sv b/src/MU/DCache.sv index 7a9246e..cb5a602 100644 --- a/src/MU/DCache.sv +++ b/src/MU/DCache.sv @@ -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 diff --git a/src/MU/ICache.sv b/src/MU/ICache.sv index a3c51c5..bdb0082 100644 --- a/src/MU/ICache.sv +++ b/src/MU/ICache.sv @@ -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 diff --git a/src/include/Cache.svh b/src/include/Cache.svh index 0a8e680..1edd2f9 100644 --- a/src/include/Cache.svh +++ b/src/include/Cache.svh @@ -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; diff --git a/src/include/defines.svh b/src/include/defines.svh index 53f34d6..1dd43ff 100644 --- a/src/include/defines.svh +++ b/src/include/defines.svh @@ -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