parent
fa0f195d17
commit
24613eeade
@ -36,7 +36,7 @@ module DCache (
|
|||||||
|
|
||||||
DCIndexL_t index1;
|
DCIndexL_t index1;
|
||||||
|
|
||||||
logic hit, hit2;
|
logic hit;
|
||||||
logic [3:0] hitWay;
|
logic [3:0] hitWay;
|
||||||
DCData_t cacheLine;
|
DCData_t cacheLine;
|
||||||
|
|
||||||
@ -141,14 +141,13 @@ module DCache (
|
|||||||
assign hitWay[3] = tagV[3] & tagOut[3].tag == port.tag1;
|
assign hitWay[3] = tagV[3] & tagOut[3].tag == port.tag1;
|
||||||
// 在 clearWb状态下确保命中
|
// 在 clearWb状态下确保命中
|
||||||
assign hit = |{hitWay} | port.clear & port.clearWb;
|
assign hit = |{hitWay} | port.clear & port.clearWb;
|
||||||
assign hit2 = |{hitWay};
|
|
||||||
|
|
||||||
assign cacheLine = (hitWay[0] ? dataOut[0] : `DC_DATA_LENGTH'b0)
|
assign cacheLine = (hitWay[0] ? dataOut[0] : `DC_DATA_LENGTH'b0)
|
||||||
| (hitWay[1] ? dataOut[1] : `DC_DATA_LENGTH'b0)
|
| (hitWay[1] ? dataOut[1] : `DC_DATA_LENGTH'b0)
|
||||||
| (hitWay[2] ? dataOut[2] : `DC_DATA_LENGTH'b0)
|
| (hitWay[2] ? dataOut[2] : `DC_DATA_LENGTH'b0)
|
||||||
| (hitWay[3] ? dataOut[3] : `DC_DATA_LENGTH'b0);
|
| (hitWay[3] ? dataOut[3] : `DC_DATA_LENGTH'b0);
|
||||||
|
|
||||||
assign port.hit = hit2;
|
assign port.hit = hit;
|
||||||
assign port.row = cacheLine;
|
assign port.row = cacheLine;
|
||||||
|
|
||||||
// ==============================
|
// ==============================
|
||||||
|
173
src/MMU/MMU.sv
173
src/MMU/MMU.sv
@ -56,7 +56,7 @@ module MMU (
|
|||||||
I_WA,
|
I_WA,
|
||||||
I_WD1, I_WD2, I_WD3, I_WD4, I_WD5, I_WD6, I_WD7, I_WD8,
|
I_WD1, I_WD2, I_WD3, I_WD4, I_WD5, I_WD6, I_WD7, I_WD8,
|
||||||
I_REFILL,
|
I_REFILL,
|
||||||
I_CACHE_PREPARE, I_CACHE_DISPATCH, I_CACHE_REFILL
|
I_CACHE, I_CACHE_DISPATCH, I_CACHE_REFILL
|
||||||
} istate_t;
|
} istate_t;
|
||||||
|
|
||||||
typedef enum bit [3:0] {
|
typedef enum bit [3:0] {
|
||||||
@ -64,7 +64,7 @@ module MMU (
|
|||||||
DR_WA,
|
DR_WA,
|
||||||
DR_WD1, DR_WD2, DR_WD3, DR_WD4,
|
DR_WD1, DR_WD2, DR_WD3, DR_WD4,
|
||||||
DR_REFILL,
|
DR_REFILL,
|
||||||
DR_ICACHE, DR_CACHE_PREPARE, DR_CACHE_DISPATCH, DR_CACHE_REFILL, DR_CACHE_REQ
|
DR_ICACHE, DR_CACHE, DR_CACHE_REFILL, DR_CACHE_REQ
|
||||||
} drstate_t;
|
} drstate_t;
|
||||||
|
|
||||||
typedef enum bit [2:0] {
|
typedef enum bit [2:0] {
|
||||||
@ -83,23 +83,12 @@ module MMU (
|
|||||||
// ======== CacheVar ========
|
// ======== CacheVar ========
|
||||||
// ==========================
|
// ==========================
|
||||||
|
|
||||||
logic icReq; // whether there is an i-cache request
|
logic icReq; // whether there is a i-cache request
|
||||||
logic icReqV; // whether i-cache req is valid (I_CACHE_DISPATCH)
|
logic icvReq; // whether the i-cache req is valid (I_CACHE_DISPATCH)
|
||||||
|
|
||||||
CacheOp_t cacheOp1; // cacheOp piped for a cycle
|
CacheOp_t cacheOp1; // cacheOp piped for a cycle
|
||||||
word_t dVA1; // data.addr
|
word_t dVA1;
|
||||||
|
|
||||||
logic dcReq; // whether there is a d-cache request
|
|
||||||
logic dClrRv; // dc.rvalid
|
|
||||||
logic dClrReq; // dc.req
|
|
||||||
logic dClrInv; // make dc.valid false
|
|
||||||
logic dDirtValid; // whether it is still dirty
|
|
||||||
|
|
||||||
logic dcReqV; // whether d-cache req is valid
|
|
||||||
logic dcCEn; // dCached1 en
|
|
||||||
logic dCClear; // clear dcCached1
|
|
||||||
logic dcCached1; // dCached1 pipe
|
|
||||||
logic dc2nd; // dcache cache write
|
|
||||||
// ======================
|
// ======================
|
||||||
// ======== iVar ========
|
// ======== iVar ========
|
||||||
// ======================
|
// ======================
|
||||||
@ -147,7 +136,7 @@ module MMU (
|
|||||||
* deadlock , or else the request will be handled when
|
* deadlock , or else the request will be handled when
|
||||||
* current request is finished at I-REFILL or I-WD2
|
* current request is finished at I-REFILL or I-WD2
|
||||||
*/
|
*/
|
||||||
iNextState = I_CACHE_PREPARE;
|
iNextState = I_CACHE;
|
||||||
end else if (~iValid1) iEn = 1;
|
end else if (~iValid1) iEn = 1;
|
||||||
else begin
|
else begin
|
||||||
iEn2 = 1;
|
iEn2 = 1;
|
||||||
@ -176,7 +165,7 @@ module MMU (
|
|||||||
inst.data_ok = 1;
|
inst.data_ok = 1;
|
||||||
if (iCached2) iNextState = I_WD3;
|
if (iCached2) iNextState = I_WD3;
|
||||||
// make sure icReq is handled
|
// make sure icReq is handled
|
||||||
else if (icReq) iNextState = I_CACHE_PREPARE;
|
else if (icReq) iNextState = I_CACHE;
|
||||||
else begin
|
else begin
|
||||||
iEn = 1;
|
iEn = 1;
|
||||||
iNextState = I_IDLE;
|
iNextState = I_IDLE;
|
||||||
@ -203,13 +192,13 @@ module MMU (
|
|||||||
end
|
end
|
||||||
I_REFILL: begin
|
I_REFILL: begin
|
||||||
// make sure icReq is handled
|
// make sure icReq is handled
|
||||||
if (icReq) iNextState = I_CACHE_PREPARE;
|
if (icReq) iNextState = I_CACHE;
|
||||||
else begin
|
else begin
|
||||||
iEn = 1;
|
iEn = 1;
|
||||||
iNextState = I_IDLE;
|
iNextState = I_IDLE;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
I_CACHE_PREPARE: begin
|
I_CACHE: begin
|
||||||
/* For "I-Cache Hit Invalid":
|
/* For "I-Cache Hit Invalid":
|
||||||
* send TLB translation request here to reduce logic on critical path
|
* send TLB translation request here to reduce logic on critical path
|
||||||
* For "I-Cache Index Invalid" or "I-Cache Index Store Tag":
|
* For "I-Cache Index Invalid" or "I-Cache Index Store Tag":
|
||||||
@ -234,7 +223,7 @@ module MMU (
|
|||||||
* 3. ic.clear & ic.clearIdx
|
* 3. ic.clear & ic.clearIdx
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (icReqV) ic.clear = 1;
|
if (icvReq) ic.clear = 1;
|
||||||
|
|
||||||
ic.clearIdx = cacheOp1[1];
|
ic.clearIdx = cacheOp1[1];
|
||||||
iEn2 = 1; // use iPA1 as tag
|
iEn2 = 1; // use iPA1 as tag
|
||||||
@ -269,9 +258,9 @@ module MMU (
|
|||||||
// ========== iFunction ==========
|
// ========== iFunction ==========
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
// On I_CACHE_PREPARE: sending cache request
|
// On I_CACHE: sending cache request
|
||||||
// On I_CACHE_DISPATCH: using the same addr to clear
|
// On I_CACHE_DISPATCH: using the same addr to clear
|
||||||
assign iVA = (iState == I_CACHE_PREPARE | iState == I_CACHE_DISPATCH) ? dVA1 : inst.addr;
|
assign iVA = (iState == I_CACHE | iState == I_CACHE_DISPATCH) ? dVA1 : 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;
|
||||||
@ -286,7 +275,7 @@ module MMU (
|
|||||||
);
|
);
|
||||||
|
|
||||||
// I-Cache req on inst query or cache instruction
|
// I-Cache req on inst query or cache instruction
|
||||||
assign ic.req = iEn | iState == I_CACHE_PREPARE;
|
assign ic.req = iEn | iState == 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];
|
||||||
@ -316,7 +305,7 @@ module MMU (
|
|||||||
word_t dVA;
|
word_t dVA;
|
||||||
|
|
||||||
logic dEn;
|
logic dEn;
|
||||||
logic dReq1;
|
logic dReq1, dcReq1;
|
||||||
logic dHit1;
|
logic dHit1;
|
||||||
logic dCached1, dCached2;
|
logic dCached1, dCached2;
|
||||||
logic dDirty1;
|
logic dDirty1;
|
||||||
@ -337,6 +326,11 @@ module MMU (
|
|||||||
word_t ddAddr1;
|
word_t ddAddr1;
|
||||||
logic [127:0] ddData1;
|
logic [127:0] ddData1;
|
||||||
|
|
||||||
|
// D-Cache Clear
|
||||||
|
logic dClrRv, dClrReq;
|
||||||
|
logic dDirtValid;
|
||||||
|
logic dCEn, dCClear, dCCached;
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
// ======== dFlip-Flop ========
|
// ======== dFlip-Flop ========
|
||||||
// ============================
|
// ============================
|
||||||
@ -349,6 +343,9 @@ module MMU (
|
|||||||
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 #(1) dDirtValid_ff (clk, dc.dirt_valid, dEn2, dDirtValid);
|
||||||
|
ffenr #(1) dCCached_ff (clk, dCClear | rst, 1'b1, dCEn, dCCached);
|
||||||
|
|
||||||
// =================================
|
// =================================
|
||||||
// ======== drState Machine ========
|
// ======== drState Machine ========
|
||||||
// =================================
|
// =================================
|
||||||
@ -364,37 +361,44 @@ module MMU (
|
|||||||
always_comb begin
|
always_comb begin
|
||||||
dEn = 0;
|
dEn = 0;
|
||||||
dEn2 = 0;
|
dEn2 = 0;
|
||||||
|
dCEn = 0;
|
||||||
|
dCClear = 0;
|
||||||
drNextState = drState;
|
drNextState = drState;
|
||||||
data.data_ok = 0;
|
data.data_ok = 0;
|
||||||
rdata_axi.req = 0;
|
rdata_axi.req = 0;
|
||||||
|
|
||||||
// D-Cache 清除功能 (与 req 一起发送)
|
// D-Cache 清除功能 (与 req 一起发送)
|
||||||
dc.clear = 0; // dc.valid = ... (dc.clear | ...) ...
|
dc.clear = 0;
|
||||||
dc.clearIdx = 0;
|
dc.clearIdx = 0;
|
||||||
dc.clearWb = 0;
|
dc.clearWb = 0;
|
||||||
|
|
||||||
// 直接发送 dc.rvalid
|
// 直接发送 dc.rvalid
|
||||||
dClrRv = 0;
|
dClrRv = 0;
|
||||||
// 直接发送 dc.req
|
// 直接发送 dc.req
|
||||||
dClrReq = 0;
|
dClrReq = 0;
|
||||||
// 清除 dc.valid
|
|
||||||
dClrInv = 0;
|
|
||||||
// 记录 dCached1
|
|
||||||
dcCEn = 0;
|
|
||||||
// 清除 dcCached1
|
|
||||||
dCClear = 0;
|
|
||||||
// CACHE 指令二阶段
|
|
||||||
dc2nd = 0;
|
|
||||||
|
|
||||||
case (drState)
|
case (drState)
|
||||||
DR_IDLE: begin
|
DR_IDLE: begin
|
||||||
if (icReq) drNextState = DR_ICACHE;
|
if (icReq) drNextState = DR_ICACHE;
|
||||||
else if (dcReq & ~dTLBRefill & ~dTLBInvalid) begin
|
else if (dReq1 & cacheOp1[2] & (dCached1 | dCCached | cacheOp1[1])) begin
|
||||||
dcCEn = 1'b1; // Store dCached1
|
if (cacheOp1[0]) begin
|
||||||
dEn2 = 1'b1; // Store dPA1
|
// 不需要写回的情况
|
||||||
dClrInv = 1'b1; // clear dc.valid
|
// D-Cache 状态机处于 Lookup 阶段
|
||||||
drNextState = DR_CACHE_REQ;
|
dc.clear = 1; // 发送清除
|
||||||
|
dc.clearIdx = cacheOp1[1]; // 清除时清除整行或者命中对象
|
||||||
|
drNextState = DR_CACHE_REFILL; // 进入 REFILL 等候写入完成
|
||||||
|
end else begin
|
||||||
|
// 需要写回
|
||||||
|
// 此时 D-Cache 状态机处于 Lookup 状态
|
||||||
|
// 可能是: 1. CACHE 请求第一次发送
|
||||||
|
// 2. Index Writeback 清除一路后返回
|
||||||
|
dc.clear = 1; // 发送清除
|
||||||
|
dc.clearIdx = cacheOp1[1]; // 清除时清除整行或者命中对象
|
||||||
|
dc.clearWb = 1; // 需要写回的清除
|
||||||
|
drNextState = DR_CACHE; // 进入 DR_CACHE 等候写入完成
|
||||||
|
dEn2 = 1; // 二阶段
|
||||||
|
dCEn = 1; // 缓存 dCached1
|
||||||
|
end
|
||||||
|
end else if (dReq1 & cacheOp1[2]) begin
|
||||||
|
// avoid deadlock when address is uncached
|
||||||
|
drNextState = DR_CACHE_REFILL;
|
||||||
end else if (~dValid1) dEn = 1;
|
end else if (~dValid1) dEn = 1;
|
||||||
else begin
|
else begin
|
||||||
dEn2 = 1;
|
dEn2 = 1;
|
||||||
@ -460,36 +464,7 @@ module MMU (
|
|||||||
drNextState = DR_IDLE;
|
drNextState = DR_IDLE;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
DR_CACHE_PREPARE: begin
|
DR_CACHE: begin
|
||||||
if (~dcReqV) begin
|
|
||||||
/*
|
|
||||||
* Jump back when
|
|
||||||
* 1. Request is invalid
|
|
||||||
* 2. finished
|
|
||||||
*/
|
|
||||||
dc.clear = 1; // Let D-Cache state machine went back to IDLE
|
|
||||||
drNextState = DR_CACHE_REFILL;
|
|
||||||
end else if (dcCached1 | cacheOp1[1]) begin
|
|
||||||
if (cacheOp1[0]) begin
|
|
||||||
// 不需要写回的情况
|
|
||||||
// D-Cache 状态机处于 Lookup 阶段
|
|
||||||
dc.clear = 1; // 发送清除
|
|
||||||
dc.clearIdx = cacheOp1[1]; // 清除时清除整行或者命中对象
|
|
||||||
drNextState = DR_CACHE_REFILL; // 进入 REFILL 等候写入完成
|
|
||||||
end else begin
|
|
||||||
// 需要写回
|
|
||||||
// 此时 D-Cache 状态机处于 Lookup 状态
|
|
||||||
// 可能是: 1. CACHE 请求第一次发送
|
|
||||||
// 2. Index Writeback 清除一路后返回
|
|
||||||
dc.clear = 1; // 发送清除
|
|
||||||
dc.clearIdx = cacheOp1[1]; // 清除时清除整行或者命中对象
|
|
||||||
dc.clearWb = 1; // 需要写回的清除
|
|
||||||
drNextState = DR_CACHE_DISPATCH; // 进入 DR_CACHE_DISPATCH 等候写入完成
|
|
||||||
dc2nd = 1; // 二阶段
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
DR_CACHE_DISPATCH: begin
|
|
||||||
// WriteBack
|
// WriteBack
|
||||||
// D-Cache: state == REPLACE
|
// D-Cache: state == REPLACE
|
||||||
if (wdata_ok) begin
|
if (wdata_ok) begin
|
||||||
@ -498,8 +473,10 @@ module MMU (
|
|||||||
// dc.clear = 1;
|
// dc.clear = 1;
|
||||||
if (cacheOp1[1]) begin
|
if (cacheOp1[1]) begin
|
||||||
// Clear by Index
|
// Clear by Index
|
||||||
if (dDirtValid) drNextState = DR_CACHE_REQ; // 重新进入准备其它路的清除
|
if (dDirtValid)
|
||||||
else drNextState = DR_CACHE_REFILL; // 清除完了
|
drNextState = DR_CACHE_REQ; // 重新进入准备其它路的清除
|
||||||
|
else
|
||||||
|
drNextState = DR_CACHE_REFILL; // 清除完了
|
||||||
end else begin
|
end else begin
|
||||||
// Clear by Address
|
// Clear by Address
|
||||||
drNextState = DR_CACHE_REFILL; // 进入 REFILL 等候写入完成
|
drNextState = DR_CACHE_REFILL; // 进入 REFILL 等候写入完成
|
||||||
@ -513,9 +490,8 @@ module MMU (
|
|||||||
data.data_ok = 1;
|
data.data_ok = 1;
|
||||||
end
|
end
|
||||||
DR_CACHE_REQ: begin
|
DR_CACHE_REQ: begin
|
||||||
// From DR_IDLE or DR_CACHE_DISPATCH
|
|
||||||
dClrReq = 1;
|
dClrReq = 1;
|
||||||
drNextState = DR_CACHE_PREPARE;
|
drNextState = DR_IDLE;
|
||||||
end
|
end
|
||||||
default: begin drNextState = DR_IDLE; end
|
default: begin drNextState = DR_IDLE; end
|
||||||
endcase
|
endcase
|
||||||
@ -526,10 +502,11 @@ module MMU (
|
|||||||
// ================================
|
// ================================
|
||||||
|
|
||||||
assign dVA = data.addr;
|
assign dVA = data.addr;
|
||||||
|
assign dcReq1 = dReq1 & (cacheOp1 == CNOP | cacheOp1[2]); // exclude I-Cache clear
|
||||||
assign dValid1 = dReq1 & dHit1 & dMValid1 & (~data.wr | dDirty1) & (in_kernel | dUser1);
|
assign dValid1 = dReq1 & dHit1 & dMValid1 & (~data.wr | dDirty1) & (in_kernel | dUser1);
|
||||||
|
|
||||||
assign dTLBRefill = drState == DR_IDLE & dReq1 & (cacheOp1 == CNOP | ~cacheOp1[1]) & ~dHit1;
|
assign dTLBRefill = drState == DR_IDLE & dcReq1 & (cacheOp1 == CNOP | ~cacheOp1[1]) & ~dHit1;
|
||||||
assign dTLBInvalid = drState == DR_IDLE & dReq1 & (cacheOp1 == CNOP | ~cacheOp1[1]) & ~dMValid1;
|
assign dTLBInvalid = drState == DR_IDLE & dcReq1 & (cacheOp1 == CNOP | ~cacheOp1[1]) & ~dMValid1;
|
||||||
assign dTLBModified = drState == DR_IDLE & dReq1 & cacheOp1 == CNOP & data.wr & ~dDirty1;
|
assign dTLBModified = drState == DR_IDLE & dReq1 & cacheOp1 == CNOP & data.wr & ~dDirty1;
|
||||||
assign dAddressError = drState == DR_IDLE & dReq1 & cacheOp1 == CNOP & ~in_kernel & ~dUser1;
|
assign dAddressError = drState == DR_IDLE & dReq1 & cacheOp1 == CNOP & ~in_kernel & ~dUser1;
|
||||||
|
|
||||||
@ -573,7 +550,7 @@ module MMU (
|
|||||||
|
|
||||||
// do not request when handling CACHE instruction on I-Cache
|
// do not request when handling CACHE instruction on I-Cache
|
||||||
assign dc.req = dClrReq | dEn & (cacheOp[2] | ~|cacheOp[1:0]);
|
assign dc.req = dClrReq | dEn & (cacheOp[2] | ~|cacheOp[1:0]);
|
||||||
assign dc.valid = ~dClrInv & (dValid1 & dCached1 | dc.clear);
|
assign dc.valid = dValid1 & dCached1 | dc.clear;
|
||||||
assign dc.index = dEn ? dVA[`DC_TAGL-1:`DC_INDEXL] : dVA1[`DC_TAGL-1:`DC_INDEXL];
|
assign dc.index = dEn ? dVA[`DC_TAGL-1:`DC_INDEXL] : dVA1[`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];
|
||||||
assign dc.sel1 = dEn2 ? dPA1[3:2] : dPA2[3:2];
|
assign dc.sel1 = dEn2 ? dPA1[3:2] : dPA2[3:2];
|
||||||
@ -613,13 +590,12 @@ module MMU (
|
|||||||
|
|
||||||
case (dwState)
|
case (dwState)
|
||||||
DW_IDLE: begin
|
DW_IDLE: begin
|
||||||
if ( (dEn2 & ~dcReq | dc2nd)
|
if (dEn2 & (~(dCached1 | dCEn) & data.wr
|
||||||
& (~(dCached1 | dcCached1) ? data.wr
|
| (dCached1 | dCEn) & dc.dirt_valid
|
||||||
: dc.dirt_valid
|
|
||||||
& (~cacheOp1[2] | ~cacheOp1[0]) // WriteOnly 不允许写回
|
& (~cacheOp1[2] | ~cacheOp1[0]) // WriteOnly 不允许写回
|
||||||
& (~dc.hit | cacheOp1[2] & ~cacheOp1[0]) // Writeback 或一般情况
|
& (~dc.hit | cacheOp1[2] & ~cacheOp1[0]) // Writeback 或一般情况
|
||||||
)) begin
|
)) begin
|
||||||
if (dCached1 | dcCached1) begin
|
if (dCached1 | dCEn) begin
|
||||||
wdata_axi.wdata = dc.dirt_data[31:0];
|
wdata_axi.wdata = dc.dirt_data[31:0];
|
||||||
wdata_axi.wstrb = 4'b1111;
|
wdata_axi.wstrb = 4'b1111;
|
||||||
wdata_axi.wvalid = 1'b1;
|
wdata_axi.wvalid = 1'b1;
|
||||||
@ -632,7 +608,7 @@ module MMU (
|
|||||||
|
|
||||||
if (~wdata_axi.wready) dwNextState = DW_WD1;
|
if (~wdata_axi.wready) dwNextState = DW_WD1;
|
||||||
else begin
|
else begin
|
||||||
if (dCached1 | dcCached1) dwNextState = DW_WD2;
|
if (dCached1 | dCEn) dwNextState = DW_WD2;
|
||||||
else begin
|
else begin
|
||||||
if (~wdata_axi.data_ok) dwNextState = DW_WB;
|
if (~wdata_axi.data_ok) dwNextState = DW_WB;
|
||||||
else begin
|
else begin
|
||||||
@ -645,7 +621,7 @@ module MMU (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
DW_WD1: begin
|
DW_WD1: begin
|
||||||
if (dCached2 | dcCached1) begin
|
if (dCached2 | dCCached) begin
|
||||||
wdata_axi.wdata = ddData1[31:0];
|
wdata_axi.wdata = ddData1[31:0];
|
||||||
wdata_axi.wstrb = 4'b1111;
|
wdata_axi.wstrb = 4'b1111;
|
||||||
wdata_axi.wvalid = 1'b1;
|
wdata_axi.wvalid = 1'b1;
|
||||||
@ -657,7 +633,7 @@ module MMU (
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (wdata_axi.wready) begin
|
if (wdata_axi.wready) begin
|
||||||
if (dCached2 | dcCached1) dwNextState = DW_WD2;
|
if (dCached2 | dCCached) dwNextState = DW_WD2;
|
||||||
else begin
|
else begin
|
||||||
if (~wdata_axi.data_ok) dwNextState = DW_WB;
|
if (~wdata_axi.data_ok) dwNextState = DW_WB;
|
||||||
else begin
|
else begin
|
||||||
@ -728,9 +704,8 @@ module MMU (
|
|||||||
|
|
||||||
case (dwaState)
|
case (dwaState)
|
||||||
DWA_IDLE: begin
|
DWA_IDLE: begin
|
||||||
if ( (dEn2 & ~dcReq | dc2nd)
|
if (dEn2 & (~(dCached1 | dCEn) & data.wr
|
||||||
& (~(dCached1 | dcCached1) ? data.wr
|
| (dCached1 | dCEn) & dc.dirt_valid
|
||||||
: dc.dirt_valid
|
|
||||||
& (~cacheOp1[2] | ~cacheOp1[0]) // WriteOnly 不允许写回
|
& (~cacheOp1[2] | ~cacheOp1[0]) // WriteOnly 不允许写回
|
||||||
& (~dc.hit | cacheOp1[2] & ~cacheOp1[0]) // Writeback 或一般情况
|
& (~dc.hit | cacheOp1[2] & ~cacheOp1[0]) // Writeback 或一般情况
|
||||||
)) begin
|
)) begin
|
||||||
@ -767,9 +742,9 @@ module MMU (
|
|||||||
// ========== dwFunction ==========
|
// ========== dwFunction ==========
|
||||||
// ================================
|
// ================================
|
||||||
|
|
||||||
assign wdata_axi.addr = ((dEn2 ? dCached1 : dCached2) | dcCached1) ? (dwaState == DWA_IDLE) ? dc.dirt_addr : ddAddr1 : dEn2 ? dPA1 : dPA2;
|
assign wdata_axi.addr = ((dEn2 ? dCached1 : dCached2) | dCEn) ? (dwaState == DWA_IDLE) ? dc.dirt_addr : ddAddr1 : dEn2 ? dPA1 : dPA2;
|
||||||
assign wdata_axi.len = ((dEn2 ? dCached1 : dCached2) | dcCached1) ? 4'b0011 : 4'b0000;
|
assign wdata_axi.len = ((dEn2 ? dCached1 : dCached2) | dCEn) ? 4'b0011 : 4'b0000;
|
||||||
assign wdata_axi.size = ((dEn2 ? dCached1 : dCached2) | dcCached1) ? 3'b010 : {1'b0, dSize1};
|
assign wdata_axi.size = ((dEn2 ? dCached1 : dCached2) | dCEn) ? 3'b010 : {1'b0, dSize1};
|
||||||
assign dc.wvalid = dEn2 ? data.wr : dwr1;
|
assign dc.wvalid = dEn2 ? data.wr : dwr1;
|
||||||
assign dc.wdata = dEn2 ? data.wdata : dWdata1;
|
assign dc.wdata = dEn2 ? data.wdata : dWdata1;
|
||||||
assign dc.wstrb = dEn2 ? data.wstrb : dWstrb1;
|
assign dc.wstrb = dEn2 ? data.wstrb : dWstrb1;
|
||||||
@ -780,21 +755,11 @@ module MMU (
|
|||||||
|
|
||||||
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 #(32) dVA1_ff (clk, data.addr, dEn, dVA1);
|
ffen #(32) dVA1_ff (clk, data.addr, dEn, dVA1);
|
||||||
ffen #(1) dDirtValid_ff (clk, dc.dirt_valid, dc.clear, dDirtValid);
|
|
||||||
|
|
||||||
ffenr #(1) dcCached1_ff (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst | dCClear),
|
|
||||||
.d(dCached1 | &cacheOp1[2:1]),
|
|
||||||
.en(dcCEn),
|
|
||||||
.q(dcCached1)
|
|
||||||
);
|
|
||||||
|
|
||||||
assign icReq = dReq1 & ~cacheOp1[2] & |cacheOp1[1:0];
|
assign icReq = dReq1 & ~cacheOp1[2] & |cacheOp1[1:0];
|
||||||
assign icReqV = ~iTLBRefill & ~iTLBInvalid & (iCached1 & ic.hit | cacheOp1[1]);
|
assign icvReq = ~iTLBRefill & ~iTLBInvalid & (iCached1 & ic.hit | cacheOp1[1]);
|
||||||
|
|
||||||
assign dcReq = dReq1 & cacheOp1[2];
|
|
||||||
assign dcReqV = ~dTLBRefill & ~dTLBInvalid & (dcCached1 & dc.hit | cacheOp1[1]);
|
|
||||||
|
|
||||||
// ==============================
|
// ==============================
|
||||||
// ========== VA -> PA ==========
|
// ========== VA -> PA ==========
|
||||||
|
Loading…
Reference in New Issue
Block a user