[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 "defines.svh"
|
||||||
|
`include "sram.svh"
|
||||||
`include "ICache.svh"
|
`include "ICache.svh"
|
||||||
|
|
||||||
module ICache (
|
module ICache (
|
||||||
@ -7,21 +8,150 @@ module ICache (
|
|||||||
|
|
||||||
// TODO add AXI interface
|
// TODO add AXI interface
|
||||||
|
|
||||||
HandShake.prev handshake,
|
sramro_i.slave sram // Core
|
||||||
ICPipeline.ICache cacheInfo
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Four way assoc
|
// Four way assoc bram controller:
|
||||||
ICTagRAM_t TagRAM0, TagRAM1, TagRAM2, TagRAM3;
|
ICTagRAM_t TagRAM0, TagRAM1, TagRAM2, TagRAM3;
|
||||||
ICDataRAM_t DataRAM0, DataRAM1, DataRAM2, DataRAM3;
|
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 (
|
cache_tag_bram tag_ram0 (
|
||||||
.addra(TagRAM2.addr),
|
.addra(TagRAM0.addr),
|
||||||
.clka (clk),
|
.clka (clk),
|
||||||
.dina (TagRAM2.wdata),
|
.dina (TagRAM0.wdata),
|
||||||
.douta(TagRAM2.rdata),
|
.douta(TagRAM0.rdata),
|
||||||
.wea (TagRAM2.wen)
|
.wea (TagRAM0.wen)
|
||||||
);
|
);
|
||||||
cache_tag_bram tag_ram1 (
|
cache_tag_bram tag_ram1 (
|
||||||
.addra(TagRAM1.addr),
|
.addra(TagRAM1.addr),
|
||||||
@ -74,40 +204,6 @@ module ICache (
|
|||||||
.wea (DataRAM3.wen)
|
.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
|
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;
|
logic [`IC_DATA_LENGTH-1:0] rdata;
|
||||||
} ICDataRAM_t; // 64 * 128
|
} ICDataRAM_t; // 64 * 128
|
||||||
|
|
||||||
typedef enum {
|
typedef enum bit [2:0] {
|
||||||
|
ICIdle,
|
||||||
ICLookup,
|
ICLookup,
|
||||||
ICHitUpdate,
|
ICMiss,
|
||||||
ICMissHandle,
|
|
||||||
ICSelect,
|
|
||||||
ICReplace,
|
ICReplace,
|
||||||
ICRefill
|
ICRefill
|
||||||
} ICacheStatus_t;
|
} 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
|
`endif
|
||||||
|
@ -6,7 +6,7 @@ typedef logic [15:0] hfwd_t;
|
|||||||
typedef logic [7:0] byte_t;
|
typedef logic [7:0] byte_t;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic v; // readygo
|
logic v; // readygo
|
||||||
logic [31:0] i;
|
logic [31:0] i;
|
||||||
} instr;
|
} instr;
|
||||||
|
|
||||||
|
@ -23,10 +23,11 @@ interface sramro_i ();
|
|||||||
word_t addr;
|
word_t addr;
|
||||||
logic addr_ok;
|
logic addr_ok;
|
||||||
logic data_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 master(output req, addr, input addr_ok, data_ok, rdata0, rdata1);
|
||||||
modport slave(input req, addr, output addr_ok, data_ok, rdata);
|
modport slave(input req, addr, output addr_ok, data_ok, rdata0, rdata1);
|
||||||
|
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user