mirror of
https://github.com/openhwgroup/cvw
synced 2025-01-30 00:14:28 +00:00
added page table walker fault exit for icache.
This commit is contained in:
parent
3dae02818c
commit
386193de00
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,
|
||||
input logic ITLBMissF,
|
||||
input logic ITLBWriteF,
|
||||
input logic WalkerInstrPageFaultF,
|
||||
|
||||
// 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
|
||||
|
@ -27,62 +27,64 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module ifu (
|
||||
input logic clk, reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
|
||||
input logic clk, reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
|
||||
// Fetch
|
||||
input logic [`XLEN-1:0] InstrInF,
|
||||
input logic InstrAckF,
|
||||
output logic [`XLEN-1:0] PCF,
|
||||
input logic [`XLEN-1:0] InstrInF,
|
||||
input logic InstrAckF,
|
||||
output logic [`XLEN-1:0] PCF,
|
||||
output logic [`PA_BITS-1:0] InstrPAdrF,
|
||||
output logic InstrReadF,
|
||||
output logic ICacheStallF,
|
||||
output logic InstrReadF,
|
||||
output logic ICacheStallF,
|
||||
// Decode
|
||||
output logic [`XLEN-1:0] PCD,
|
||||
output logic [`XLEN-1:0] PCD,
|
||||
// Execute
|
||||
output logic [`XLEN-1:0] PCLinkE,
|
||||
input logic PCSrcE,
|
||||
input logic [`XLEN-1:0] PCTargetE,
|
||||
output logic [`XLEN-1:0] PCE,
|
||||
output logic BPPredWrongE,
|
||||
output logic [`XLEN-1:0] PCLinkE,
|
||||
input logic PCSrcE,
|
||||
input logic [`XLEN-1:0] PCTargetE,
|
||||
output logic [`XLEN-1:0] PCE,
|
||||
output logic BPPredWrongE,
|
||||
// Mem
|
||||
input logic RetM, TrapM,
|
||||
input logic [`XLEN-1:0] PrivilegedNextPCM,
|
||||
output logic [31:0] InstrD, InstrE, InstrM, InstrW,
|
||||
output logic [`XLEN-1:0] PCM,
|
||||
output logic [4:0] InstrClassM,
|
||||
output logic BPPredDirWrongM,
|
||||
output logic BTBPredPCWrongM,
|
||||
output logic RASPredPCWrongM,
|
||||
output logic BPPredClassNonCFIWrongM,
|
||||
input logic RetM, TrapM,
|
||||
input logic [`XLEN-1:0] PrivilegedNextPCM,
|
||||
output logic [31:0] InstrD, InstrE, InstrM, InstrW,
|
||||
output logic [`XLEN-1:0] PCM,
|
||||
output logic [4:0] InstrClassM,
|
||||
output logic BPPredDirWrongM,
|
||||
output logic BTBPredPCWrongM,
|
||||
output logic RASPredPCWrongM,
|
||||
output logic BPPredClassNonCFIWrongM,
|
||||
// Writeback
|
||||
// output logic [`XLEN-1:0] PCLinkW,
|
||||
// Faults
|
||||
input logic IllegalBaseInstrFaultD,
|
||||
output logic ITLBInstrPageFaultF,
|
||||
output logic IllegalIEUInstrFaultD,
|
||||
output logic InstrMisalignedFaultM,
|
||||
output logic [`XLEN-1:0] InstrMisalignedAdrM,
|
||||
input logic IllegalBaseInstrFaultD,
|
||||
output logic ITLBInstrPageFaultF,
|
||||
output logic IllegalIEUInstrFaultD,
|
||||
output logic InstrMisalignedFaultM,
|
||||
output logic [`XLEN-1:0] InstrMisalignedAdrM,
|
||||
|
||||
|
||||
// mmu management
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [`XLEN-1:0] PageTableEntryF,
|
||||
input logic [1:0] PageTypeF,
|
||||
input logic [`XLEN-1:0] SATP_REGW,
|
||||
input logic STATUS_MXR, STATUS_SUM,
|
||||
input logic ITLBWriteF, ITLBFlushF,
|
||||
output logic ITLBMissF, ITLBHitF,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [`XLEN-1:0] PageTableEntryF,
|
||||
input logic [1:0] PageTypeF,
|
||||
input logic [`XLEN-1:0] SATP_REGW,
|
||||
input logic STATUS_MXR, STATUS_SUM,
|
||||
input logic ITLBWriteF, ITLBFlushF,
|
||||
input logic WalkerInstrPageFaultF,
|
||||
|
||||
output logic ITLBMissF, ITLBHitF,
|
||||
|
||||
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
|
||||
// input logic [31:0] HADDR,
|
||||
// input logic [2:0] HSIZE,
|
||||
// input logic HWRITE,
|
||||
input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so they're gonna have to come over into ifu and dmem
|
||||
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
|
||||
input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so they're gonna have to come over into ifu and dmem
|
||||
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
|
||||
|
||||
output logic PMPInstrAccessFaultF, PMAInstrAccessFaultF,
|
||||
output logic ISquashBusAccessF
|
||||
output logic PMPInstrAccessFaultF, PMAInstrAccessFaultF,
|
||||
output logic ISquashBusAccessF
|
||||
// output logic [5:0] IHSELRegionsF
|
||||
|
||||
);
|
||||
@ -105,7 +107,6 @@ module ifu (
|
||||
// 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.
|
||||
;
|
||||
|
||||
generate
|
||||
if (`XLEN==32) begin
|
||||
@ -152,7 +153,8 @@ module ifu (
|
||||
|
||||
icache icache(.*,
|
||||
.PCNextF(PCNextFPhys),
|
||||
.PCPF(PCPFmmu));
|
||||
.PCPF(PCPFmmu),
|
||||
.WalkerInstrPageFaultF(WalkerInstrPageFaultF));
|
||||
|
||||
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);
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
assign PRegEn = (WalkerState == LEVEL1_WDV || WalkerState == LEVEL0_WDV) && ~HPTWStall;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
// State transition logic
|
||||
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)
|
||||
IDLE: if (MMUTranslate) NextWalkerState = LEVEL1_WDV;
|
||||
else NextWalkerState = IDLE;
|
||||
LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV;
|
||||
else NextWalkerState = LEVEL1;
|
||||
LEVEL1:
|
||||
IDLE: begin
|
||||
if (MMUTranslate && SvMode == `SV32) begin // *** Added SvMode
|
||||
NextWalkerState = LEVEL1_WDV;
|
||||
TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
|
||||
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
|
||||
// fault upon finding a superpage that is misaligned or has 0
|
||||
// access bit. The following commented line of code is
|
||||
// supposed to perform that check. However, it is untested.
|
||||
if (ValidPTE && LeafPTE && ~BadMegapage) NextWalkerState = LEAF;
|
||||
// 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;
|
||||
else NextWalkerState = FAULT;
|
||||
LEAF: NextWalkerState = IDLE;
|
||||
FAULT: NextWalkerState = IDLE;
|
||||
if (ValidPTE && LeafPTE && ~BadMegapage) begin
|
||||
NextWalkerState = LEAF;
|
||||
PageTableEntry = CurrentPTE;
|
||||
PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux?
|
||||
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: NextWalkerState = IDLE;
|
||||
endcase
|
||||
@ -221,55 +296,6 @@ module pagetablewalker
|
||||
//assign HPTWRead = (WalkerState == IDLE && MMUTranslate) ||
|
||||
// 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
|
||||
// *** may need to delay reading this value until the next clock cycle.
|
||||
@ -338,7 +364,6 @@ module pagetablewalker
|
||||
|
||||
LEVEL3_WDV: begin
|
||||
TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
|
||||
//HPTWRead = 1'b1;
|
||||
if (HPTWStall) begin
|
||||
NextWalkerState = LEVEL3_WDV;
|
||||
end else begin
|
||||
@ -355,12 +380,12 @@ module pagetablewalker
|
||||
if (ValidPTE && LeafPTE && ~BadTerapage) begin
|
||||
NextWalkerState = LEAF;
|
||||
PageTableEntry = CurrentPTE;
|
||||
PageType = (WalkerState == LEVEL3) ? 2'b11 :
|
||||
PageType = (WalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux?
|
||||
((WalkerState == LEVEL2) ? 2'b10 :
|
||||
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
||||
DTLBWriteM = DTLBMissMQ;
|
||||
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||
TranslationPAdr = TranslationVAdrQ;
|
||||
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
|
||||
@ -397,7 +422,7 @@ module pagetablewalker
|
||||
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
||||
DTLBWriteM = DTLBMissMQ;
|
||||
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||
TranslationPAdr = TranslationVAdrQ;
|
||||
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
|
||||
@ -434,7 +459,7 @@ module pagetablewalker
|
||||
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
||||
DTLBWriteM = DTLBMissMQ;
|
||||
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||
TranslationPAdr = TranslationVAdrQ;
|
||||
TranslationPAdr = TranslationVAdrQ[`PA_BITS-1:0];
|
||||
|
||||
end
|
||||
// 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
|
||||
TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
||||
//HPTWRead = 1'b1;
|
||||
if (HPTWStall) begin
|
||||
NextWalkerState = LEVEL0_WDV;
|
||||
end else begin
|
||||
@ -467,7 +491,7 @@ module pagetablewalker
|
||||
((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
||||
DTLBWriteM = DTLBMissMQ;
|
||||
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||
TranslationPAdr = TranslationVAdrQ;
|
||||
TranslationPAdr = TranslationVAdrQ[`PA_BITS-1:0];
|
||||
end else begin
|
||||
NextWalkerState = FAULT;
|
||||
end
|
||||
|
@ -176,11 +176,11 @@ module wallypipelinedhart
|
||||
logic StallWtoLSU;
|
||||
logic StallWfromLSU;
|
||||
logic [2:0] Funct3MfromLSU;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||
ifu ifu(.InstrInF(InstrRData),
|
||||
.WalkerInstrPageFaultF(WalkerInstrPageFaultF),
|
||||
.*); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||
|
||||
ieu ieu(.*); // integer execution unit: integer register file, datapath and controller
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user