forked from Github_Repos/cvw
added page table walker fault exit for icache.
This commit is contained in:
parent
61027f650c
commit
118dfa9cec
1
wally-pipelined/src/cache/icache.sv
vendored
1
wally-pipelined/src/cache/icache.sv
vendored
@ -45,6 +45,7 @@ module icache
|
|||||||
output logic ICacheStallF,
|
output logic ICacheStallF,
|
||||||
input logic ITLBMissF,
|
input logic ITLBMissF,
|
||||||
input logic ITLBWriteF,
|
input logic ITLBWriteF,
|
||||||
|
input logic WalkerInstrPageFaultF,
|
||||||
|
|
||||||
// The raw (not decompressed) instruction that was requested
|
// The raw (not decompressed) instruction that was requested
|
||||||
// If this instruction is compressed, upper 16 bits may be the next 16 bits or may be zeros
|
// If this instruction is compressed, upper 16 bits may be the next 16 bits or may be zeros
|
||||||
|
@ -72,6 +72,8 @@ module ifu (
|
|||||||
input logic [`XLEN-1:0] SATP_REGW,
|
input logic [`XLEN-1:0] SATP_REGW,
|
||||||
input logic STATUS_MXR, STATUS_SUM,
|
input logic STATUS_MXR, STATUS_SUM,
|
||||||
input logic ITLBWriteF, ITLBFlushF,
|
input logic ITLBWriteF, ITLBFlushF,
|
||||||
|
input logic WalkerInstrPageFaultF,
|
||||||
|
|
||||||
output logic ITLBMissF, ITLBHitF,
|
output logic ITLBMissF, ITLBHitF,
|
||||||
|
|
||||||
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
|
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
|
||||||
@ -105,7 +107,6 @@ module ifu (
|
|||||||
// if you're allowed to parameterize outputs/ inputs existence, these are an easy delete.
|
// if you're allowed to parameterize outputs/ inputs existence, these are an easy delete.
|
||||||
|
|
||||||
logic [`PA_BITS-1:0] PCPFmmu, PCNextFPhys; // used to either truncate or expand PCPF and PCNextF into `PA_BITS width.
|
logic [`PA_BITS-1:0] PCPFmmu, PCNextFPhys; // used to either truncate or expand PCPF and PCNextF into `PA_BITS width.
|
||||||
;
|
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if (`XLEN==32) begin
|
if (`XLEN==32) begin
|
||||||
@ -152,7 +153,8 @@ module ifu (
|
|||||||
|
|
||||||
icache icache(.*,
|
icache icache(.*,
|
||||||
.PCNextF(PCNextFPhys),
|
.PCNextF(PCNextFPhys),
|
||||||
.PCPF(PCPFmmu));
|
.PCPF(PCPFmmu),
|
||||||
|
.WalkerInstrPageFaultF(WalkerInstrPageFaultF));
|
||||||
|
|
||||||
flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FlushD ? nop : FinalInstrRawF, nop, InstrRawD);
|
flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FlushD ? nop : FinalInstrRawF, nop, InstrRawD);
|
||||||
|
|
||||||
|
@ -181,31 +181,106 @@ module pagetablewalker
|
|||||||
|
|
||||||
flopenl #(.TYPE(statetype)) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
|
flopenl #(.TYPE(statetype)) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
|
||||||
|
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
assign PRegEn = (WalkerState == LEVEL1_WDV || WalkerState == LEVEL0_WDV) && ~HPTWStall;
|
assign PRegEn = (WalkerState == LEVEL1_WDV || WalkerState == LEVEL0_WDV) && ~HPTWStall;
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
// State transition logic
|
// State transition logic
|
||||||
always_comb begin
|
always_comb begin
|
||||||
|
PRegEn = 1'b0;
|
||||||
|
TranslationPAdr = '0;
|
||||||
|
HPTWRead = 1'b0;
|
||||||
|
MMUStall = 1'b1;
|
||||||
|
PageTableEntry = '0;
|
||||||
|
PageType = '0;
|
||||||
|
DTLBWriteM = '0;
|
||||||
|
ITLBWriteF = '0;
|
||||||
|
|
||||||
|
WalkerInstrPageFaultF = 1'b0;
|
||||||
|
WalkerLoadPageFaultM = 1'b0;
|
||||||
|
WalkerStorePageFaultM = 1'b0;
|
||||||
|
|
||||||
case (WalkerState)
|
case (WalkerState)
|
||||||
IDLE: if (MMUTranslate) NextWalkerState = LEVEL1_WDV;
|
IDLE: begin
|
||||||
else NextWalkerState = IDLE;
|
if (MMUTranslate && SvMode == `SV32) begin // *** Added SvMode
|
||||||
LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV;
|
NextWalkerState = LEVEL1_WDV;
|
||||||
else NextWalkerState = LEVEL1;
|
TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
|
||||||
LEVEL1:
|
HPTWRead = 1'b1;
|
||||||
|
end else begin
|
||||||
|
NextWalkerState = IDLE;
|
||||||
|
TranslationPAdr = '0;
|
||||||
|
MMUStall = 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LEVEL1_WDV: begin
|
||||||
|
TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
|
||||||
|
if (HPTWStall) begin
|
||||||
|
NextWalkerState = LEVEL1_WDV;
|
||||||
|
end else begin
|
||||||
|
NextWalkerState = LEVEL1;
|
||||||
|
PRegEn = 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LEVEL1: begin
|
||||||
// *** <FUTURE WORK> According to the architecture, we should
|
// *** <FUTURE WORK> According to the architecture, we should
|
||||||
// fault upon finding a superpage that is misaligned or has 0
|
// fault upon finding a superpage that is misaligned or has 0
|
||||||
// access bit. The following commented line of code is
|
// access bit. The following commented line of code is
|
||||||
// supposed to perform that check. However, it is untested.
|
// supposed to perform that check. However, it is untested.
|
||||||
if (ValidPTE && LeafPTE && ~BadMegapage) NextWalkerState = LEAF;
|
if (ValidPTE && LeafPTE && ~BadMegapage) begin
|
||||||
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
|
|
||||||
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_WDV;
|
|
||||||
else NextWalkerState = FAULT;
|
|
||||||
LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV;
|
|
||||||
else NextWalkerState = LEVEL0;
|
|
||||||
LEVEL0: if (ValidPTE & LeafPTE & ~AccessAlert)
|
|
||||||
NextWalkerState = LEAF;
|
NextWalkerState = LEAF;
|
||||||
else NextWalkerState = FAULT;
|
PageTableEntry = CurrentPTE;
|
||||||
LEAF: NextWalkerState = IDLE;
|
PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux?
|
||||||
FAULT: NextWalkerState = IDLE;
|
DTLBWriteM = DTLBMissMQ;
|
||||||
|
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||||
|
TranslationPAdr = TranslationVAdrQ[`PA_BITS-1:0];
|
||||||
|
end
|
||||||
|
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
|
||||||
|
else if (ValidPTE && ~LeafPTE) begin
|
||||||
|
NextWalkerState = LEVEL0_WDV;
|
||||||
|
TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
||||||
|
HPTWRead = 1'b1;
|
||||||
|
end else begin
|
||||||
|
NextWalkerState = FAULT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LEVEL0_WDV: begin
|
||||||
|
TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
||||||
|
if (HPTWStall) begin
|
||||||
|
NextWalkerState = LEVEL0_WDV;
|
||||||
|
end else begin
|
||||||
|
NextWalkerState = LEVEL0;
|
||||||
|
PRegEn = 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LEVEL0: begin
|
||||||
|
if (ValidPTE & LeafPTE & ~AccessAlert) begin
|
||||||
|
NextWalkerState = LEAF;
|
||||||
|
PageTableEntry = CurrentPTE;
|
||||||
|
PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00;
|
||||||
|
DTLBWriteM = DTLBMissMQ;
|
||||||
|
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||||
|
TranslationPAdr = TranslationVAdrQ[`PA_BITS-1:0];
|
||||||
|
end else begin
|
||||||
|
NextWalkerState = FAULT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LEAF: begin
|
||||||
|
NextWalkerState = IDLE;
|
||||||
|
MMUStall = 1'b0;
|
||||||
|
end
|
||||||
|
FAULT: begin
|
||||||
|
NextWalkerState = IDLE;
|
||||||
|
WalkerInstrPageFaultF = ~DTLBMissMQ;
|
||||||
|
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
|
||||||
|
WalkerStorePageFaultM = DTLBMissMQ && MemStore;
|
||||||
|
MMUStall = 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
// Default case should never happen, but is included for linter.
|
// Default case should never happen, but is included for linter.
|
||||||
default: NextWalkerState = IDLE;
|
default: NextWalkerState = IDLE;
|
||||||
endcase
|
endcase
|
||||||
@ -221,55 +296,6 @@ module pagetablewalker
|
|||||||
//assign HPTWRead = (WalkerState == IDLE && MMUTranslate) ||
|
//assign HPTWRead = (WalkerState == IDLE && MMUTranslate) ||
|
||||||
// WalkerState == LEVEL2 || WalkerState == LEVEL1;
|
// WalkerState == LEVEL2 || WalkerState == LEVEL1;
|
||||||
|
|
||||||
// Assign combinational outputs
|
|
||||||
always_comb begin
|
|
||||||
// default values
|
|
||||||
//TranslationPAdr = '0;
|
|
||||||
PageTableEntry = '0;
|
|
||||||
PageType ='0;
|
|
||||||
DTLBWriteM = '0;
|
|
||||||
ITLBWriteF = '0;
|
|
||||||
WalkerInstrPageFaultF = '0;
|
|
||||||
WalkerLoadPageFaultM = '0;
|
|
||||||
WalkerStorePageFaultM = '0;
|
|
||||||
//MMUStall = '1;
|
|
||||||
|
|
||||||
case (NextWalkerState)
|
|
||||||
IDLE: begin
|
|
||||||
//MMUStall = '0;
|
|
||||||
end
|
|
||||||
LEVEL1: begin
|
|
||||||
//TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
|
|
||||||
end
|
|
||||||
LEVEL1_WDV: begin
|
|
||||||
//TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
|
|
||||||
end
|
|
||||||
LEVEL0: begin
|
|
||||||
//TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
|
||||||
end
|
|
||||||
LEVEL0_WDV: begin
|
|
||||||
//TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
|
||||||
end
|
|
||||||
LEAF: begin
|
|
||||||
// Keep physical address alive to prevent HADDR dropping to 0
|
|
||||||
//TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
|
||||||
PageTableEntry = CurrentPTE;
|
|
||||||
PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00;
|
|
||||||
DTLBWriteM = DTLBMissMQ;
|
|
||||||
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
|
||||||
end
|
|
||||||
FAULT: begin
|
|
||||||
//TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
|
||||||
WalkerInstrPageFaultF = ~DTLBMissMQ;
|
|
||||||
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
|
|
||||||
WalkerStorePageFaultM = DTLBMissMQ && MemStore;
|
|
||||||
// MMUStall = '0; // Drop the stall early to enter trap handling code
|
|
||||||
end
|
|
||||||
default: begin
|
|
||||||
// nothing
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
// Capture page table entry from data cache
|
// Capture page table entry from data cache
|
||||||
// *** may need to delay reading this value until the next clock cycle.
|
// *** may need to delay reading this value until the next clock cycle.
|
||||||
@ -338,7 +364,6 @@ module pagetablewalker
|
|||||||
|
|
||||||
LEVEL3_WDV: begin
|
LEVEL3_WDV: begin
|
||||||
TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
|
TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
|
||||||
//HPTWRead = 1'b1;
|
|
||||||
if (HPTWStall) begin
|
if (HPTWStall) begin
|
||||||
NextWalkerState = LEVEL3_WDV;
|
NextWalkerState = LEVEL3_WDV;
|
||||||
end else begin
|
end else begin
|
||||||
@ -355,12 +380,12 @@ module pagetablewalker
|
|||||||
if (ValidPTE && LeafPTE && ~BadTerapage) begin
|
if (ValidPTE && LeafPTE && ~BadTerapage) begin
|
||||||
NextWalkerState = LEAF;
|
NextWalkerState = LEAF;
|
||||||
PageTableEntry = CurrentPTE;
|
PageTableEntry = CurrentPTE;
|
||||||
PageType = (WalkerState == LEVEL3) ? 2'b11 :
|
PageType = (WalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux?
|
||||||
((WalkerState == LEVEL2) ? 2'b10 :
|
((WalkerState == LEVEL2) ? 2'b10 :
|
||||||
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
||||||
DTLBWriteM = DTLBMissMQ;
|
DTLBWriteM = DTLBMissMQ;
|
||||||
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||||
TranslationPAdr = TranslationVAdrQ;
|
TranslationPAdr = TranslationVAdrQ[`PA_BITS-1:0];
|
||||||
end
|
end
|
||||||
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
|
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
|
||||||
else if (ValidPTE && ~LeafPTE) begin
|
else if (ValidPTE && ~LeafPTE) begin
|
||||||
@ -397,7 +422,7 @@ module pagetablewalker
|
|||||||
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
||||||
DTLBWriteM = DTLBMissMQ;
|
DTLBWriteM = DTLBMissMQ;
|
||||||
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||||
TranslationPAdr = TranslationVAdrQ;
|
TranslationPAdr = TranslationVAdrQ[`PA_BITS-1:0];
|
||||||
end
|
end
|
||||||
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
|
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
|
||||||
else if (ValidPTE && ~LeafPTE) begin
|
else if (ValidPTE && ~LeafPTE) begin
|
||||||
@ -434,7 +459,7 @@ module pagetablewalker
|
|||||||
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
||||||
DTLBWriteM = DTLBMissMQ;
|
DTLBWriteM = DTLBMissMQ;
|
||||||
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||||
TranslationPAdr = TranslationVAdrQ;
|
TranslationPAdr = TranslationVAdrQ[`PA_BITS-1:0];
|
||||||
|
|
||||||
end
|
end
|
||||||
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
|
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
|
||||||
@ -449,7 +474,6 @@ module pagetablewalker
|
|||||||
|
|
||||||
LEVEL0_WDV: begin
|
LEVEL0_WDV: begin
|
||||||
TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
||||||
//HPTWRead = 1'b1;
|
|
||||||
if (HPTWStall) begin
|
if (HPTWStall) begin
|
||||||
NextWalkerState = LEVEL0_WDV;
|
NextWalkerState = LEVEL0_WDV;
|
||||||
end else begin
|
end else begin
|
||||||
@ -467,7 +491,7 @@ module pagetablewalker
|
|||||||
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
||||||
DTLBWriteM = DTLBMissMQ;
|
DTLBWriteM = DTLBMissMQ;
|
||||||
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||||
TranslationPAdr = TranslationVAdrQ;
|
TranslationPAdr = TranslationVAdrQ[`PA_BITS-1:0];
|
||||||
end else begin
|
end else begin
|
||||||
NextWalkerState = FAULT;
|
NextWalkerState = FAULT;
|
||||||
end
|
end
|
||||||
|
@ -178,9 +178,9 @@ module wallypipelinedhart
|
|||||||
logic [2:0] Funct3MfromLSU;
|
logic [2:0] Funct3MfromLSU;
|
||||||
|
|
||||||
|
|
||||||
|
ifu ifu(.InstrInF(InstrRData),
|
||||||
|
.WalkerInstrPageFaultF(WalkerInstrPageFaultF),
|
||||||
ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache
|
.*); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||||
|
|
||||||
ieu ieu(.*); // integer execution unit: integer register file, datapath and controller
|
ieu ieu(.*); // integer execution unit: integer register file, datapath and controller
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user