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

View File

@ -55,33 +55,22 @@ module MMU (
typedef enum bit [3:0] { typedef enum bit [3:0] {
I_IDLE, I_IDLE,
I_WA, I_WA,
I_WD1, I_WD1, I_WD2, I_WD3, I_WD4, I_WD5, I_WD6, I_WD7, I_WD8,
I_WD2, I_REFILL,
I_WD3, I_CACHE
I_WD4,
I_WD5,
I_WD6,
I_WD7,
I_WD8,
I_REFILL
} istate_t; } istate_t;
typedef enum bit [2:0] { typedef enum bit [2:0] {
DR_IDLE, DR_IDLE,
DR_WA, DR_WA,
DR_WD1, DR_WD1, DR_WD2, DR_WD3, DR_WD4,
DR_WD2, DR_REFILL,
DR_WD3, DR_CACHE
DR_WD4,
DR_REFILL
} drstate_t; } drstate_t;
typedef enum bit [2:0] { typedef enum bit [2:0] {
DW_IDLE, DW_IDLE,
DW_WD1, DW_WD1, DW_WD2, DW_WD3, DW_WD4,
DW_WD2,
DW_WD3,
DW_WD4,
DW_WB, DW_WB,
DW_WAITR DW_WAITR
} dwstate_t; } dwstate_t;
@ -121,14 +110,17 @@ module MMU (
end end
always_comb begin always_comb begin
iEn = 0; iEn = 0;
iEn2 = 0; iEn2 = 0;
iNextState = iState; iNextState = iState;
inst.data_ok = 0; inst.data_ok = 0;
inst_axi.req = 0; inst_axi.req = 0;
ic.clear = 0;
case (iState) case (iState)
I_IDLE: begin I_IDLE: begin
if (~iValid1) iEn = 1; if (diReq & ~iValid1) begin
iNextState = I_CACHE;
end else if (~iValid1) iEn = 1;
else begin else begin
iEn2 = 1; iEn2 = 1;
if (iCached1 & ic.hit) begin if (iCached1 & ic.hit) begin
@ -155,6 +147,7 @@ module MMU (
if (inst_axi.rvalid) begin if (inst_axi.rvalid) begin
inst.data_ok = 1; inst.data_ok = 1;
if (iCached2) iNextState = I_WD3; if (iCached2) iNextState = I_WD3;
else if (diReq) iNextState = I_CACHE;
else begin else begin
iEn = 1; iEn = 1;
iNextState = I_IDLE; iNextState = I_IDLE;
@ -180,7 +173,27 @@ module MMU (
if (inst_axi.rvalid) iNextState = I_REFILL; if (inst_axi.rvalid) iNextState = I_REFILL;
end end
I_REFILL: begin I_REFILL: begin
iEn = 1; 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; iNextState = I_IDLE;
end end
endcase endcase
@ -190,74 +203,23 @@ module MMU (
// ======== iFlip-Flop ======== // ======== iFlip-Flop ========
// ============================ // ============================
ffenr #(1) ivalid_ff ( ffenr #(1) ivalid_ff (clk, rst, inst.req, iEn, iReq1);
clk, ffen #(32) iPA_ff (clk, iPA1, iEn2, iPA2);
rst, ffen #(1) iCached_ff (clk, iCached1, iEn2, iCached2);
inst.req,
iEn,
iReq1
);
ffen #(32) iPA_ff (
clk,
iPA1,
iEn2,
iPA2
);
ffen #(1) iCached_ff (
clk,
iCached1,
iEn2,
iCached2
);
ffen #(32) id1_ff ( ffen #(32) id1_ff (clk, inst_axi.rdata, iState == I_WA | iState == I_WD1, iD1);
clk, ffen #(32) id2_ff (clk, inst_axi.rdata, iState == I_WD2, iD2);
inst_axi.rdata, ffen #(32) id3_ff (clk, inst_axi.rdata, iState == I_WD3, iD3);
iState == I_WA | iState == I_WD1, ffen #(32) id4_ff (clk, inst_axi.rdata, iState == I_WD4, iD4);
iD1 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) id2_ff ( ffen #(32) id7_ff (clk, inst_axi.rdata, iState == I_WD7, iD7);
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 ========== // ========== iFunction ==========
// =============================== // ===============================
assign iVA = inst.addr; assign iVA = iNextState == I_CACHE ? data.addr : inst.addr;
assign iValid1 = iReq1 & iHit1 & iMValid1 & (in_kernel | iUser1); assign iValid1 = iReq1 & iHit1 & iMValid1 & (in_kernel | iUser1);
assign inst.addr_ok = iEn; assign inst.addr_ok = iEn;
@ -271,11 +233,13 @@ module MMU (
{inst.rdata1, inst.rdata0} {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.valid = iValid1 & iCached1;
assign ic.index = iVA[`IC_TAGL-1:`IC_INDEXL]; assign ic.index = iVA[`IC_TAGL-1:`IC_INDEXL];
assign ic.tag1 = iEn2 ? iPA1[31:`IC_TAGL] : iPA2[31:`IC_TAGL]; assign ic.tag1 = iEn2 ? iPA1[31:`IC_TAGL] : iPA2[31:`IC_TAGL];
assign ic.rvalid = inst_axi.rvalid & inst_axi.data_ok; 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 ( mux4 #(256) ic_rdata_mux (
{inst_axi.rdata, iD7, iD6, iD5, iD4, iD3, iD2, iD1}, {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.len = (iEn2 ? iCached1 : iCached2) ? 4'b0111 : 4'b0001;
assign inst_axi.size = 3'b010; assign inst_axi.size = 3'b010;
assign iTLBRefill = (iState == I_IDLE) & iReq1 & ~iHit1; assign iTLBRefill = (iState == I_IDLE & iReq1 | iState == I_CACHE & ~cacheOp[1]) & ~iHit1;
assign iTLBInvalid = (iState == I_IDLE) & iReq1 & ~iMValid1; assign iTLBInvalid = (iState == I_IDLE & iReq1 | iState == I_CACHE & ~cacheOp[1]) & ~iMValid1;
assign iAddressError = (iState == I_IDLE) & iReq1 & ~in_kernel & ~iUser1; assign iAddressError = (iState == I_IDLE) & iReq1 & ~in_kernel & ~iUser1;
// ====================== // ======================
@ -301,7 +265,7 @@ module MMU (
word_t dVA; word_t dVA;
logic dEn; logic dEn;
logic dReq1; logic dReq1, dcReq1, diReq;
logic dHit1; logic dHit1;
logic dCached1, dCached2; logic dCached1, dCached2;
logic dDirty1; logic dDirty1;
@ -328,15 +292,15 @@ module MMU (
// ======== dFlip-Flop ======== // ======== dFlip-Flop ========
// ============================ // ============================
ffenr #(1) dvalid_ff (clk, rst, data.req, dEn, dReq1); ffenr #(1) dvalid_ff (clk, rst, data.req, dEn, dReq1);
ffen #(2) dsize_ff (clk, data.size, dEn, dSize1); ffen #(2) dsize_ff (clk, data.size, dEn, dSize1);
ffen #(32) dPA_ff (clk, dPA1, dEn2, dPA2); ffen #(32) dPA_ff (clk, dPA1, dEn2, dPA2);
ffen #(1) dCached_ff (clk, dCached1, dEn2, dCached2); ffen #(1) dCached_ff (clk, dCached1, dEn2, dCached2);
ffen #(1) dwr_ff (clk, data.wr, dEn2, dwr1); ffen #(1) dwr_ff (clk, data.wr, dEn2, dwr1);
ffen #(4) dwstrb_ff (clk, data.wstrb, dEn2, dWstrb1); ffen #(4) dwstrb_ff (clk, data.wstrb, dEn2, dWstrb1);
ffen #(32) dwdata_ff (clk, data.wdata, dEn2, dWdata1); ffen #(32) dwdata_ff (clk, data.wdata, dEn2, dWdata1);
ffen #(3) cache_op_ff (clk, cacheOp[2:0], dEn, cacheOp1[2:0]); ffen #(3) cache_op_ff (clk, cacheOp[2:0], dEn, cacheOp1[2:0]);
ffen #(3) cache_op2_ff (clk, cacheOp1[2:0], dEn2, cacheOp2[2:0]); ffen #(3) cache_op2_ff (clk, cacheOp1[2:0], dEn2, cacheOp2[2:0]);
// ================================= // =================================
// ======== drState Machine ======== // ======== drState Machine ========
@ -359,6 +323,7 @@ module MMU (
case (drState) case (drState)
DR_IDLE: begin DR_IDLE: begin
if (~dValid1) dEn = 1; if (~dValid1) dEn = 1;
else if (~dcReq1) drNextState = DR_CACHE;
else begin else begin
dEn2 = 1; dEn2 = 1;
if (data.wr) data.data_ok = 1; if (data.wr) data.data_ok = 1;
@ -412,6 +377,17 @@ module MMU (
drNextState = DR_IDLE; drNextState = DR_IDLE;
end end
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 endcase
end end
@ -419,13 +395,27 @@ module MMU (
// ========== dFunction ========== // ========== dFunction ==========
// ================================ // ================================
assign dVA = data.addr; /*
assign dValid1 = dReq1 & dHit1 & dMValid1 & (~data.wr | dDirty1) & (in_kernel | dUser1); * 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 dTLBRefill = (drState == DR_IDLE) & dReq1 & ~cacheOp1[1] & ~dHit1; assign dVA = data.addr;
assign dTLBInvalid = (drState == DR_IDLE) & dReq1 & ~cacheOp1[1] & ~dMValid1; assign diReq = dEn ? data.req & ~cacheOp[2] & |cacheOp[1:0]
assign dTLBModified = (drState == DR_IDLE) & dReq1 & ~cacheOp1[1] & data.wr & ~dDirty1; : dReq1 & ~cacheOp1[2] & |cacheOp1[1:0];
assign dAddressError = (drState == DR_IDLE) & dReq1 & ~cacheOp1[1] & ~in_kernel & ~dUser1; 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 & 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 ======== // ======== drFlip-Flop ========
@ -465,7 +455,8 @@ module MMU (
data.rdata 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.valid = dValid1 & dCached1 & (~cacheOp1[2] | cacheOp1[1] | dc.hit);
assign dc.index = dVA[`DC_TAGL-1:`DC_INDEXL]; assign dc.index = dVA[`DC_TAGL-1:`DC_INDEXL];
assign dc.tag1 = dEn2 ? dPA1[31:`DC_TAGL] : dPA2[31:`DC_TAGL]; assign dc.tag1 = dEn2 ? dPA1[31:`DC_TAGL] : dPA2[31:`DC_TAGL];