try add I-Cache's CACHE inst

This commit is contained in:
Paul Pan 2021-09-03 21:23:32 +08:00
parent 17f64e1f2f
commit 2143cbe630
2 changed files with 102 additions and 111 deletions

View File

@ -68,7 +68,7 @@ module ICache (
end
end
LOOKUP: begin
if (~port.valid | hit) begin
if (~port.valid | hit | port.clear) begin
if (~port.req) begin
nextState = IDLE;
end
@ -164,7 +164,7 @@ module ICache (
port.req,
baddr
);
assign bwe = (state == REPLACE) & port.rvalid;
assign bwe = (state == REPLACE) & port.rvalid | port.clear;
// 地址
assign TagRAM0.addr = baddr;
@ -189,10 +189,10 @@ module ICache (
assign TagRAM1.wdata = {port.tag1, 1'b1};
assign TagRAM2.wdata = {port.tag1, 1'b1};
assign TagRAM3.wdata = {port.tag1, 1'b1};
assign DataRAM0.wdata = port.rdata;
assign DataRAM1.wdata = port.rdata;
assign DataRAM2.wdata = port.rdata;
assign DataRAM3.wdata = port.rdata;
assign DataRAM0.wdata = port.clear ? `IC_TAG_LENGTH'b0 : port.rdata;
assign DataRAM1.wdata = port.clear ? `IC_TAG_LENGTH'b0 : port.rdata;
assign DataRAM2.wdata = port.clear ? `IC_TAG_LENGTH'b0 : port.rdata;
assign DataRAM3.wdata = port.clear ? `IC_TAG_LENGTH'b0 : port.rdata;
ICTag_bram tag_ram0 (
.addra(TagRAM0.addr),

View File

@ -55,33 +55,22 @@ module MMU (
typedef enum bit [3:0] {
I_IDLE,
I_WA,
I_WD1,
I_WD2,
I_WD3,
I_WD4,
I_WD5,
I_WD6,
I_WD7,
I_WD8,
I_REFILL
I_WD1, I_WD2, I_WD3, I_WD4, I_WD5, I_WD6, I_WD7, I_WD8,
I_REFILL,
I_CACHE
} istate_t;
typedef enum bit [2:0] {
DR_IDLE,
DR_WA,
DR_WD1,
DR_WD2,
DR_WD3,
DR_WD4,
DR_REFILL
DR_WD1, DR_WD2, DR_WD3, DR_WD4,
DR_REFILL,
DR_CACHE
} drstate_t;
typedef enum bit [2:0] {
DW_IDLE,
DW_WD1,
DW_WD2,
DW_WD3,
DW_WD4,
DW_WD1, DW_WD2, DW_WD3, DW_WD4,
DW_WB,
DW_WAITR
} dwstate_t;
@ -126,9 +115,12 @@ module MMU (
iNextState = iState;
inst.data_ok = 0;
inst_axi.req = 0;
ic.clear = 0;
case (iState)
I_IDLE: begin
if (~iValid1) iEn = 1;
if (diReq & ~iValid1) begin
iNextState = I_CACHE;
end else if (~iValid1) iEn = 1;
else begin
iEn2 = 1;
if (iCached1 & ic.hit) begin
@ -155,6 +147,7 @@ module MMU (
if (inst_axi.rvalid) begin
inst.data_ok = 1;
if (iCached2) iNextState = I_WD3;
else if (diReq) iNextState = I_CACHE;
else begin
iEn = 1;
iNextState = I_IDLE;
@ -180,6 +173,26 @@ module MMU (
if (inst_axi.rvalid) iNextState = I_REFILL;
end
I_REFILL: begin
if (diReq) iNextState = I_CACHE;
else begin
iEn = 1;
iNextState = I_IDLE;
end
end
I_CACHE: begin
/*
* I-Cache Cache指令实现备注:
* I_CACHE iEn == 0
* I_CACHE iEn = 1
* Exceptions
* TLB iNextState == I_CACHE时发送
* I-Cache iNextState == I_CACHE时发送
* I_CACHE iAddressError Address TLBRefill TLBInvalid
* I_CACHE I_CACHE clear
* drState
*/
if (~iTLBRefill & ~iTLBInvalid & iCached1 & (ic.hit | cacheOp1[1])) ic.clear = 1;
iEn = 1;
iNextState = I_IDLE;
end
@ -190,74 +203,23 @@ module MMU (
// ======== iFlip-Flop ========
// ============================
ffenr #(1) ivalid_ff (
clk,
rst,
inst.req,
iEn,
iReq1
);
ffen #(32) iPA_ff (
clk,
iPA1,
iEn2,
iPA2
);
ffen #(1) iCached_ff (
clk,
iCached1,
iEn2,
iCached2
);
ffenr #(1) ivalid_ff (clk, rst, inst.req, iEn, iReq1);
ffen #(32) iPA_ff (clk, iPA1, iEn2, iPA2);
ffen #(1) iCached_ff (clk, iCached1, iEn2, iCached2);
ffen #(32) id1_ff (
clk,
inst_axi.rdata,
iState == I_WA | iState == I_WD1,
iD1
);
ffen #(32) id2_ff (
clk,
inst_axi.rdata,
iState == I_WD2,
iD2
);
ffen #(32) id3_ff (
clk,
inst_axi.rdata,
iState == I_WD3,
iD3
);
ffen #(32) id4_ff (
clk,
inst_axi.rdata,
iState == I_WD4,
iD4
);
ffen #(32) id5_ff (
clk,
inst_axi.rdata,
iState == I_WD5,
iD5
);
ffen #(32) id6_ff (
clk,
inst_axi.rdata,
iState == I_WD6,
iD6
);
ffen #(32) id7_ff (
clk,
inst_axi.rdata,
iState == I_WD7,
iD7
);
ffen #(32) id1_ff (clk, inst_axi.rdata, iState == I_WA | iState == I_WD1, iD1);
ffen #(32) id2_ff (clk, inst_axi.rdata, iState == I_WD2, iD2);
ffen #(32) id3_ff (clk, inst_axi.rdata, iState == I_WD3, iD3);
ffen #(32) id4_ff (clk, inst_axi.rdata, iState == I_WD4, iD4);
ffen #(32) id5_ff (clk, inst_axi.rdata, iState == I_WD5, iD5);
ffen #(32) id6_ff (clk, inst_axi.rdata, iState == I_WD6, iD6);
ffen #(32) id7_ff (clk, inst_axi.rdata, iState == I_WD7, iD7);
// ===============================
// ========== iFunction ==========
// ===============================
assign iVA = inst.addr;
assign iVA = iNextState == I_CACHE ? data.addr : inst.addr;
assign iValid1 = iReq1 & iHit1 & iMValid1 & (in_kernel | iUser1);
assign inst.addr_ok = iEn;
@ -271,11 +233,13 @@ module MMU (
{inst.rdata1, inst.rdata0}
);
assign ic.req = iEn;
// I-Cache req on inst query or cache instruction
assign ic.req = iEn | iNextState == I_CACHE;
assign ic.valid = iValid1 & iCached1;
assign ic.index = iVA[`IC_TAGL-1:`IC_INDEXL];
assign ic.tag1 = iEn2 ? iPA1[31:`IC_TAGL] : iPA2[31:`IC_TAGL];
assign ic.rvalid = inst_axi.rvalid & inst_axi.data_ok;
assign ic.clear = iState == I_CACHE & ~cacheOp1[2] & iCached1 & (ic.hit | cacheOp1[1]);
mux4 #(256) ic_rdata_mux (
{inst_axi.rdata, iD7, iD6, iD5, iD4, iD3, iD2, iD1},
@ -290,8 +254,8 @@ module MMU (
assign inst_axi.len = (iEn2 ? iCached1 : iCached2) ? 4'b0111 : 4'b0001;
assign inst_axi.size = 3'b010;
assign iTLBRefill = (iState == I_IDLE) & iReq1 & ~iHit1;
assign iTLBInvalid = (iState == I_IDLE) & iReq1 & ~iMValid1;
assign iTLBRefill = (iState == I_IDLE & iReq1 | iState == I_CACHE & ~cacheOp[1]) & ~iHit1;
assign iTLBInvalid = (iState == I_IDLE & iReq1 | iState == I_CACHE & ~cacheOp[1]) & ~iMValid1;
assign iAddressError = (iState == I_IDLE) & iReq1 & ~in_kernel & ~iUser1;
// ======================
@ -301,7 +265,7 @@ module MMU (
word_t dVA;
logic dEn;
logic dReq1;
logic dReq1, dcReq1, diReq;
logic dHit1;
logic dCached1, dCached2;
logic dDirty1;
@ -359,6 +323,7 @@ module MMU (
case (drState)
DR_IDLE: begin
if (~dValid1) dEn = 1;
else if (~dcReq1) drNextState = DR_CACHE;
else begin
dEn2 = 1;
if (data.wr) data.data_ok = 1;
@ -412,6 +377,17 @@ module MMU (
drNextState = DR_IDLE;
end
end
DR_CACHE: begin
/*
* I-CACHE
* iState == I_CACHE
*/
if (iState == I_CACHE) begin
data.data_ok = 1;
dEn = 1;
drNextState = DR_IDLE;
end
end
endcase
end
@ -419,13 +395,27 @@ module MMU (
// ========== dFunction ==========
// ================================
/*
* D-Cache Cache
* Cache
* TLB D-Cache 访
* dc.req I-Cache Cache 0
* drState DR_REFILL DW_STATE
* dwState dwaState CACHE
* dAddressError TLBModified Address TLBRefill TLBInvalid
* dc.clear
*/
assign dVA = data.addr;
assign diReq = dEn ? data.req & ~cacheOp[2] & |cacheOp[1:0]
: dReq1 & ~cacheOp1[2] & |cacheOp1[1:0];
assign dcReq1 = dReq1 & (cacheOp1 == CNOP | cacheOp[2]); // exclude I-Cache clear
assign dValid1 = dReq1 & dHit1 & dMValid1 & (~data.wr | dDirty1) & (in_kernel | dUser1);
assign dTLBRefill = (drState == DR_IDLE) & dReq1 & ~cacheOp1[1] & ~dHit1;
assign dTLBInvalid = (drState == DR_IDLE) & dReq1 & ~cacheOp1[1] & ~dMValid1;
assign dTLBModified = (drState == DR_IDLE) & dReq1 & ~cacheOp1[1] & data.wr & ~dDirty1;
assign dAddressError = (drState == DR_IDLE) & dReq1 & ~cacheOp1[1] & ~in_kernel & ~dUser1;
assign dTLBRefill = drState == DR_IDLE & dcReq1 & (cacheOp1 == CNOP | ~cacheOp1[1]) & ~dHit1;
assign dTLBInvalid = drState == DR_IDLE & dcReq1 & (cacheOp1 == CNOP | ~cacheOp1[1]) & ~dMValid1;
assign dTLBModified = drState == DR_IDLE & dcReq1 & data.wr & ~dDirty1;
assign dAddressError = drState == DR_IDLE & dcReq1 & ~in_kernel & ~dUser1;
// =============================
// ======== drFlip-Flop ========
@ -465,7 +455,8 @@ module MMU (
data.rdata
);
assign dc.req = dEn;
// do not request when handling CACHE instruction on I-Cache
assign dc.req = dEn & (cacheOp[2] | ~|cacheOp[1:0]);
assign dc.valid = dValid1 & dCached1 & (~cacheOp1[2] | cacheOp1[1] | dc.hit);
assign dc.index = dVA[`DC_TAGL-1:`DC_INDEXL];
assign dc.tag1 = dEn2 ? dPA1[31:`DC_TAGL] : dPA2[31:`DC_TAGL];