[ICache] Idle & Lookup

This commit is contained in:
Paul Pan 2021-07-07 16:07:49 +08:00
parent 9f48a9ccd2
commit ccfbbe3c1b
6 changed files with 170 additions and 72 deletions

View File

@ -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]`|

View File

@ -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

24
src/Cache/status.dot Normal file
View File

@ -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
}

View File

@ -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

View File

@ -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;

View File

@ -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