From ccfbbe3c1b5d4a31265f9189215d2bcce149af48 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Wed, 7 Jul 2021 16:07:49 +0800 Subject: [PATCH] [ICache] Idle & Lookup --- src/Cache/Design.md | 13 --- src/Cache/ICache.sv | 180 ++++++++++++++++++++++++++++++---------- src/Cache/status.dot | 24 ++++++ src/include/ICache.svh | 16 +--- src/include/defines.svh | 2 +- src/include/sram.svh | 7 +- 6 files changed, 170 insertions(+), 72 deletions(-) delete mode 100644 src/Cache/Design.md create mode 100644 src/Cache/status.dot diff --git a/src/Cache/Design.md b/src/Cache/Design.md deleted file mode 100644 index 3b375f4..0000000 --- a/src/Cache/Design.md +++ /dev/null @@ -1,13 +0,0 @@ -# Cache - -I-Cache with D-Cache - -## I-CACHE - -四路组相联,行大小`16Bytes`,每路`1KBytes`,共`4KBytes` - -|Tag|Index|Offset| -|:-:|:-:|:-:| -|x|$\log_2{64}=6$|$\log_2{16}=4$| -|`[31:10]`|组索引:`[9:4]`|行内索引:`[3:0]`| - diff --git a/src/Cache/ICache.sv b/src/Cache/ICache.sv index 14944e5..1220d05 100644 --- a/src/Cache/ICache.sv +++ b/src/Cache/ICache.sv @@ -1,4 +1,5 @@ `include "defines.svh" +`include "sram.svh" `include "ICache.svh" module ICache ( @@ -7,21 +8,150 @@ module ICache ( // TODO add AXI interface - HandShake.prev handshake, - ICPipeline.ICache cacheInfo + sramro_i.slave sram // Core + ); - // Four way assoc + // Four way assoc bram controller: ICTagRAM_t TagRAM0, TagRAM1, TagRAM2, TagRAM3; ICDataRAM_t DataRAM0, DataRAM1, DataRAM2, DataRAM3; - // Block RAM + // Vars: + ICacheStatus_t status, nextStatus; + + logic [31:0] PC; + wire [4:0] cacheAddress; // PC[9:4] + + logic [`IC_DATA_LENGTH-1:0] cacheLine; // Cache Line + logic [31:0] cacheLineData[4]; // Map Cache Line into 4 Cache Data + + logic hit; // Cache hit or not + logic hitWay[4]; // Cache Line hit or not + logic [21:0] tag; // PC[31:10] + + // Init: + initial begin + status = ICIdle; + TagRAM0.wen = 0; + TagRAM1.wen = 0; + TagRAM2.wen = 0; + TagRAM3.wen = 0; + DataRAM0.wen = 0; + DataRAM1.wen = 0; + DataRAM2.wen = 0; + DataRAM3.wen = 0; + end + + // Main: + always_ff @(posedge clk) begin + sram.data_ok = 0; + sram.addr_ok = 0; + + case (status) + ICIdle: begin + if (sram.req == 1) begin + PC <= sram.addr; + sram.addr_ok = 1; + end + end + + ICLookup: begin + if (hit) begin + sram.data_ok <= 1; + if (sram.req == 1) begin + PC <= sram.addr; + sram.addr_ok = 1; + end + end else begin + // TBD + end + end + + ICMiss: begin + end + + ICReplace: begin + end + + ICRefill: begin + end + + default: begin + end + endcase + + end + + // Next Status Generator: + always_comb begin + case (status) + ICIdle: begin // IDLE or LOOKUP + if (sram.req) nextStatus = ICLookup; + else nextStatus = ICIdle; + end + ICLookup: begin // IDLE or LOOKUP or MISS + if (hit) begin + if (sram.req) nextStatus = ICLookup; + else nextStatus = ICIdle; + end else nextStatus = ICMiss; + end + ICMiss: begin // REPLACE + end + ICReplace: begin // REFILL + end + ICRefill: begin // IDLE or LOOKUP + end + default: nextStatus = ICIdle; + endcase + end + + always_ff @(posedge clk) begin + status <= nextStatus; + end + + // SRAM: + assign cacheAddress = PC[9:4]; + assign tag = PC[31:10]; + + + // Hit Check: + assign hitWay[0] = TagRAM0.rdata[0] & TagRAM0.rdata[`IC_TAG_LENGTH-1:1] == tag; + assign hitWay[1] = TagRAM1.rdata[0] & TagRAM1.rdata[`IC_TAG_LENGTH-1:1] == tag; + assign hitWay[2] = TagRAM2.rdata[0] & TagRAM2.rdata[`IC_TAG_LENGTH-1:1] == tag; + assign hitWay[3] = TagRAM3.rdata[0] & TagRAM3.rdata[`IC_TAG_LENGTH-1:1] == tag; + assign hit = hitWay[0] | hitWay[1] | hitWay[2] | hitWay[3]; + + assign cacheLine = (hitWay[0] ? DataRAM0.rdata : 32'b0) | + (hitWay[1] ? DataRAM1.rdata : 32'b0) | + (hitWay[2] ? DataRAM2.rdata : 32'b0) | + (hitWay[3] ? DataRAM3.rdata : 32'b0); + + assign cacheLineData[0] = cacheLine[31:0]; + assign cacheLineData[1] = cacheLine[63:32]; + assign cacheLineData[2] = cacheLine[95:64]; + assign cacheLineData[3] = cacheLine[127:96]; + + assign sram.rdata0 = cacheLineData[PC[3]]; + assign sram.rdata1 = cacheLineData[PC[3]+1]; + + + + // Block RAM: + assign TagRam0.addr = cacheAddress; + assign TagRam1.addr = cacheAddress; + assign TagRam2.addr = cacheAddress; + assign TagRam3.addr = cacheAddress; + assign DataRam0.addr = cacheAddress; + assign DataRam1.addr = cacheAddress; + assign DataRam2.addr = cacheAddress; + assign DataRam3.addr = cacheAddress; + cache_tag_bram tag_ram0 ( - .addra(TagRAM2.addr), + .addra(TagRAM0.addr), .clka (clk), - .dina (TagRAM2.wdata), - .douta(TagRAM2.rdata), - .wea (TagRAM2.wen) + .dina (TagRAM0.wdata), + .douta(TagRAM0.rdata), + .wea (TagRAM0.wen) ); cache_tag_bram tag_ram1 ( .addra(TagRAM1.addr), @@ -74,40 +204,6 @@ module ICache ( .wea (DataRAM3.wen) ); - // Static - - // Lookup Stage - logic cacheAddress = cacheInfo.PC[9:4]; // TODO: move cacheInfo.PC into a local reg and update it via ff - - - // Hit Check Stage - logic [`IC_DATA_LENGTH-1:0] cacheLine; // Cache Line - logic [31:0] cacheLineData[4]; // Map Cache Line into 4 Cache Data - - assign cacheLineData[0] = cacheLine[31:0]; - assign cacheLineData[1] = cacheLine[63:32]; - assign cacheLineData[1] = cacheLine[95:64]; - assign cacheLineData[1] = cacheLine[127:96]; - - logic hit; // Cache hit or not - logic hitPart[4]; // Cache Line hit or not - logic [21:0] tag; - - assign tag = cacheInfo.PC[31:10]; // TODO: move cacheInfo.PC into a local reg and update it via ff - assign hitPart[0] = TagRAM0.rdata[0] && TagRAM0.rdata[`IC_TAG_LENGTH-1:1] == tag; - assign hitPart[1] = TagRAM1.rdata[0] && TagRAM1.rdata[`IC_TAG_LENGTH-1:1] == tag; - assign hitPart[2] = TagRAM2.rdata[0] && TagRAM2.rdata[`IC_TAG_LENGTH-1:1] == tag; - assign hitPart[3] = TagRAM3.rdata[0] && TagRAM3.rdata[`IC_TAG_LENGTH-1:1] == tag; - assign hit = hitPart[0] | hitPart[1] | hitPart[2] | hitPart[3]; - - assign cacheLine = // TODO: AXI Data ? : - hitPart[0] ? DataRAM0.rdata : - hitPart[1] ? DataRAM1.rdata : - hitPart[2] ? DataRAM2.rdata : - hitPart[3] ? DataRAM3.rdata : - 0; - - endmodule diff --git a/src/Cache/status.dot b/src/Cache/status.dot new file mode 100644 index 0000000..a5d13d1 --- /dev/null +++ b/src/Cache/status.dot @@ -0,0 +1,24 @@ +digraph action { + IDLE [label="IDLE"] + LOOKUP [label="LOOKUP"] + MISS [label="MISS"] + REPLACE [label="REPLACE"] + REFILL [label="REFILL"] + + # IDLE + IDLE -> IDLE [label = "req = 0"] + IDLE -> LOOKUP [label = "req = 1"] + + # LOOKUP + LOOKUP -> MISS [label = "hit = 0"] + LOOKUP -> LOOKUP [label = "hit = 1 & req = 1"] + LOOKUP -> IDLE [label = "hit = 1 & req = 0"] + + # TBD + MISS -> REPLACE + MISS -> MISS + REPLACE -> REFILL + REPLACE -> REPLACE + REFILL -> IDLE + REFILL -> REFILL +} \ No newline at end of file diff --git a/src/include/ICache.svh b/src/include/ICache.svh index 8009e91..47afefd 100644 --- a/src/include/ICache.svh +++ b/src/include/ICache.svh @@ -22,22 +22,12 @@ typedef struct packed { logic [`IC_DATA_LENGTH-1:0] rdata; } ICDataRAM_t; // 64 * 128 -typedef enum { +typedef enum bit [2:0] { + ICIdle, ICLookup, - ICHitUpdate, - ICMissHandle, - ICSelect, + ICMiss, ICReplace, ICRefill } ICacheStatus_t; -interface ICPipeline; - logic [31:0] PC; - logic [31:0] inst; - - modport ICache(input PC, output inst); - modport Pipe(input inst, output PC); - -endinterface //ICPipeline - `endif diff --git a/src/include/defines.svh b/src/include/defines.svh index 17f63d1..88ab76b 100644 --- a/src/include/defines.svh +++ b/src/include/defines.svh @@ -6,7 +6,7 @@ typedef logic [15:0] hfwd_t; typedef logic [7:0] byte_t; typedef struct packed { - logic v; // readygo + logic v; // readygo logic [31:0] i; } instr; diff --git a/src/include/sram.svh b/src/include/sram.svh index b5c1c29..d1fff28 100644 --- a/src/include/sram.svh +++ b/src/include/sram.svh @@ -23,10 +23,11 @@ interface sramro_i (); word_t addr; logic addr_ok; logic data_ok; - word_t rdata; + word_t rdata0; + word_t rdata1; - modport master(output req, addr, input addr_ok, data_ok, rdata); - modport slave(input req, addr, output addr_ok, data_ok, rdata); + modport master(output req, addr, input addr_ok, data_ok, rdata0, rdata1); + modport slave(input req, addr, output addr_ok, data_ok, rdata0, rdata1); endinterface