[ICache] Idle & Lookup
This commit is contained in:
parent
9f48a9ccd2
commit
ccfbbe3c1b
@ -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]`|
|
||||
|
@ -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
24
src/Cache/status.dot
Normal 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
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user