try add I-Cache's CACHE inst
This commit is contained in:
parent
17f64e1f2f
commit
2143cbe630
@ -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),
|
||||
|
201
src/MMU/MMU.sv
201
src/MMU/MMU.sv
@ -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;
|
||||
@ -121,14 +110,17 @@ module MMU (
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
iEn = 0;
|
||||
iEn2 = 0;
|
||||
iNextState = iState;
|
||||
iEn = 0;
|
||||
iEn2 = 0;
|
||||
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,7 +173,27 @@ module MMU (
|
||||
if (inst_axi.rvalid) iNextState = I_REFILL;
|
||||
end
|
||||
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;
|
||||
end
|
||||
endcase
|
||||
@ -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;
|
||||
@ -328,15 +292,15 @@ module MMU (
|
||||
// ======== dFlip-Flop ========
|
||||
// ============================
|
||||
|
||||
ffenr #(1) dvalid_ff (clk, rst, data.req, dEn, dReq1);
|
||||
ffen #(2) dsize_ff (clk, data.size, dEn, dSize1);
|
||||
ffen #(32) dPA_ff (clk, dPA1, dEn2, dPA2);
|
||||
ffen #(1) dCached_ff (clk, dCached1, dEn2, dCached2);
|
||||
ffen #(1) dwr_ff (clk, data.wr, dEn2, dwr1);
|
||||
ffen #(4) dwstrb_ff (clk, data.wstrb, dEn2, dWstrb1);
|
||||
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_op2_ff (clk, cacheOp1[2:0], dEn2, cacheOp2[2:0]);
|
||||
ffenr #(1) dvalid_ff (clk, rst, data.req, dEn, dReq1);
|
||||
ffen #(2) dsize_ff (clk, data.size, dEn, dSize1);
|
||||
ffen #(32) dPA_ff (clk, dPA1, dEn2, dPA2);
|
||||
ffen #(1) dCached_ff (clk, dCached1, dEn2, dCached2);
|
||||
ffen #(1) dwr_ff (clk, data.wr, dEn2, dwr1);
|
||||
ffen #(4) dwstrb_ff (clk, data.wstrb, dEn2, dWstrb1);
|
||||
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_op2_ff (clk, cacheOp1[2:0], dEn2, cacheOp2[2:0]);
|
||||
|
||||
// =================================
|
||||
// ======== drState Machine ========
|
||||
@ -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 ==========
|
||||
// ================================
|
||||
|
||||
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 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 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 & 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];
|
||||
|
Loading…
Reference in New Issue
Block a user