Finish finite state machines for page table walker

This commit is contained in:
Thomas Fleming 2021-03-25 02:48:40 -04:00
parent 7367052e76
commit e3900bd0fa
4 changed files with 270 additions and 75 deletions

View File

@ -48,7 +48,7 @@ module ahblite (
input logic [1:0] MemSizeM, input logic [1:0] MemSizeM,
// Signals from MMU // Signals from MMU
input logic [`XLEN-1:0] MMUPAdr, input logic [`XLEN-1:0] MMUPAdr,
input logic MMUTranslate, input logic MMUTranslate, MMUTranslationComplete,
output logic [`XLEN-1:0] MMUReadPTE, output logic [`XLEN-1:0] MMUReadPTE,
output logic MMUReady, output logic MMUReady,
// Return from bus // Return from bus
@ -75,7 +75,8 @@ module ahblite (
); );
logic GrantData; logic GrantData;
logic [2:0] ISize; logic [31:0] AccessAddress;
logic [2:0] AccessSize, PTESize, ISize;
logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataNewW, ReadDataOldW, WriteData; logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataNewW, ReadDataOldW, WriteData;
logic IReady, DReady; logic IReady, DReady;
logic CaptureDataM; logic CaptureDataM;
@ -89,47 +90,69 @@ module ahblite (
// Data accesses have priority over instructions. However, if a data access comes // Data accesses have priority over instructions. However, if a data access comes
// while an instruction read is occuring, the instruction read finishes before // while an instruction read is occuring, the instruction read finishes before
// the data access can take place. // the data access can take place.
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADC, ATOMICREAD, ATOMICWRITE} statetype; typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADC, ATOMICREAD, ATOMICWRITE, MMUTRANSLATE, MMUIDLE} statetype;
statetype BusState, NextBusState; statetype BusState, NextBusState;
flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState); flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState);
always_comb always_comb
case (BusState) case (BusState)
IDLE: if (AtomicM[1]) NextBusState = ATOMICREAD; IDLE: if (MMUTranslate) NextBusState = MMUTRANSLATE;
else if (MemReadM) NextBusState = MEMREAD; // Memory has pirority over instructions else if (AtomicM[1]) NextBusState = ATOMICREAD;
else if (MemWriteM) NextBusState = MEMWRITE; else if (MemReadM) NextBusState = MEMREAD; // Memory has priority over instructions
else if (InstrReadF) NextBusState = INSTRREAD; else if (MemWriteM) NextBusState = MEMWRITE;
else NextBusState = IDLE; else if (InstrReadF) NextBusState = INSTRREAD;
ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD; else NextBusState = IDLE;
else NextBusState = ATOMICWRITE; MMUTRANSLATE: if (~HREADY) NextBusState = MMUTRANSLATE;
ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE; else NextBusState = MMUIDLE;
else if (InstrReadF) NextBusState = INSTRREAD; // *** Could the MMUIDLE state just be the normal idle state?
else NextBusState = IDLE; // Do we trust MMUTranslate to be high exactly when we need translation?
MEMREAD: if (~HREADY) NextBusState = MEMREAD; MMUIDLE: if (~MMUTranslationComplete)
else if (InstrReadF) NextBusState = INSTRREADC; NextBusState = MMUTRANSLATE;
else NextBusState = IDLE; else if (AtomicM[1]) NextBusState = ATOMICREAD;
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE; else if (MemReadM) NextBusState = MEMREAD; // Memory has priority over instructions
else if (InstrReadF) NextBusState = INSTRREAD; else if (MemWriteM) NextBusState = MEMWRITE;
else NextBusState = IDLE; else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE;
ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD;
else NextBusState = ATOMICWRITE;
ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE;
else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE;
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
else if (InstrReadF) NextBusState = INSTRREADC;
else NextBusState = IDLE;
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE;
INSTRREAD: INSTRREAD:
if (~HREADY) NextBusState = INSTRREAD; if (~HREADY) NextBusState = INSTRREAD;
else NextBusState = IDLE; // if (InstrReadF still high) else NextBusState = IDLE; // if (InstrReadF still high)
INSTRREADC: if (~HREADY) NextBusState = INSTRREADC; // "C" for "competing", meaning please don't mess up the memread in the W stage. INSTRREADC: if (~HREADY) NextBusState = INSTRREADC; // "C" for "competing", meaning please don't mess up the memread in the W stage.
else NextBusState = IDLE; else NextBusState = IDLE;
endcase endcase
// stall signals // stall signals
assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE); (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
assign #1 InstrStall = (NextBusState == INSTRREAD) || (NextBusState == INSTRREADC); (NextBusState == MMUTRANSLATE) || (NextBusState == MMUIDLE);
// *** Could get finer grained stalling if we distinguish between MMU
// instruction address translation and data address translation
assign #1 InstrStall = (NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
(NextBusState == MMUTRANSLATE) || (NextBusState == MMUIDLE);
// bus outputs // bus outputs
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE); (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE);
assign #1 HADDR = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0]; assign #1 AccessAddress = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0];
assign #1 HADDR = (MMUTranslate) ? MMUPAdr[31:0] : AccessAddress;
generate
if (`XLEN == 32) assign PTESize = 3'b010; // in rv32, PTEs are 4 bytes
else assign PTESize = 3'b011; // in rv64, PTEs are 8 bytes
endgenerate
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway
assign #1 HSIZE = GrantData ? {1'b0, MemSizeM} : ISize; assign #1 AccessSize = (GrantData) ? {1'b0, MemSizeM} : ISize;
assign #1 HSIZE = (MMUTranslate) ? PTESize : AccessSize;
assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH
assign HPROT = 4'b0011; // not used; see Section 3.7 assign HPROT = 4'b0011; // not used; see Section 3.7
assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise
@ -145,7 +168,10 @@ module ahblite (
// Route signals to Instruction and Data Caches // Route signals to Instruction and Data Caches
// *** assumes AHBW = XLEN // *** assumes AHBW = XLEN
assign #1 MMUReady = (NextBusState == MMUIDLE);
assign InstrRData = HRDATA; assign InstrRData = HRDATA;
assign MMUReadPTE = HRDATA;
assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021 assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021
assign CaptureDataM = ((BusState == MEMREAD) && (NextBusState != MEMREAD)) || assign CaptureDataM = ((BusState == MEMREAD) && (NextBusState != MEMREAD)) ||
((BusState == ATOMICREAD) && (NextBusState == ATOMICWRITE)); ((BusState == ATOMICREAD) && (NextBusState == ATOMICWRITE));

View File

@ -32,25 +32,29 @@ module pagetablewalker (
input logic [`XLEN-1:0] SATP_REGW, input logic [`XLEN-1:0] SATP_REGW,
input logic MemWriteM,
input logic ITLBMissF, DTLBMissM, input logic ITLBMissF, DTLBMissM,
input logic [`XLEN-1:0] PCF, MemAdrM, input logic [`XLEN-1:0] PCF, MemAdrM,
output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM, output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM,
output logic ITLBWriteF, DTLBWriteM, output logic ITLBWriteF, DTLBWriteM,
// *** handshake to tlbs probably not needed, since stalls take effect // *** handshake to tlbs probably not needed, since stalls take effect
// output logic TranslationComplete output logic MMUTranslationComplete,
// Signals from and to ahblite // Signals from and to ahblite
input logic [`XLEN-1:0] MMUReadPTE, input logic [`XLEN-1:0] MMUReadPTE,
input logic MMUReady, input logic MMUReady,
output logic [`XLEN-1:0] MMUPAdr, output logic [`XLEN-1:0] MMUPAdr,
output logic MMUTranslate output logic MMUTranslate,
// Faults
output logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM
); );
logic SvMode; logic SvMode;
logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`XLEN-1:0] DirectInstrPTE, DirectMemPTE; logic [`XLEN-1:0] DirectInstrPTE, DirectMemPTE, TranslationVAdr;
logic [9:0] DirectPTEFlags = {2'b0, 8'b00001111}; logic [9:0] DirectPTEFlags = {2'b0, 8'b00001111};
@ -73,71 +77,233 @@ module pagetablewalker (
end end
endgenerate endgenerate
flopenr #(`XLEN) instrpte(clk, reset, ITLBMissF, DirectInstrPTE, PageTableEntryF); //flopenr #(`XLEN) instrpte(clk, reset, ITLBMissF, DirectInstrPTE, PageTableEntryF);
flopenr #(`XLEN) datapte(clk, reset, DTLBMissM, DirectMemPTE, PageTableEntryM); //flopenr #(`XLEN) datapte(clk, reset, DTLBMissM, DirectMemPTE, PageTableEntryM);
flopr #(1) iwritesignal(clk, reset, ITLBMissF, ITLBWriteF); //flopr #(1) iwritesignal(clk, reset, ITLBMissF, ITLBWriteF);
flopr #(1) dwritesignal(clk, reset, DTLBMissM, DTLBWriteM); //flopr #(1) dwritesignal(clk, reset, DTLBMissM, DTLBWriteM);
// Prefer data address translations over instruction address translations
assign TranslationVAdr = (DTLBMissM) ? MemAdrM : PCF;
assign MMUTranslate = DTLBMissM || ITLBMissF;
/*
generate generate
if (`XLEN == 32) begin if (`XLEN == 32) begin
assign SvMode = SATP_REGW[31]; assign SvMode = SATP_REGW[31];
logic VPN1 [9:0] = TranslationVAdr[31:22]; logic [9:0] VPN1 = TranslationVAdr[31:22];
logic VPN0 [9:0] = TranslationVAdr[21:12]; // *** could optimize by not passing offset? logic [9:0] VPN0 = TranslationVAdr[21:12]; // *** could optimize by not passing offset?
logic TranslationPAdr [33:0]; logic [33:0] TranslationPAdr;
logic [21:0] CurrentPPN;
typedef enum {IDLE, DATA_LEVEL1, DATA_LEVEL0, DATA_LEAF, DATA FAULT} statetype; logic Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid;
logic ValidPTE, AccessAlert, MegapageMisaligned, BadMegapage, LeafPTE;
typedef enum {IDLE, LEVEL1, LEVEL0, LEAF, FAULT} statetype;
statetype WalkerState, NextWalkerState; statetype WalkerState, NextWalkerState;
always_ff @(posedge HCLK, negedge HRESETn) // *** Do we need a synchronizer here for walker to talk to ahblite?
if (~HRESETn) WalkerState <= #1 IDLE; flopenl #(.TYPE(statetype)) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
else WalkerState <= #1 NextWalkerState;
always_comb begin always_comb begin
NextWalkerState = 'X;
case (WalkerState) case (WalkerState)
IDLE: if (TLBMissM) NextWalkerState = LEVEL1; IDLE: if (MMUTranslate) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
LEVEL1: if (HREADY && ValidEntry) NextWalkerState = LEVEL0; LEVEL1: if (~MMUReady) NextWalkerState = LEVEL1;
else if (HREADY) NextWalkerState = FAULT; // else if (~ValidPTE || (LeafPTE && BadMegapage))
else NextWalkerState = LEVEL1; // NextWalkerState = FAULT;
LEVEL2: if (HREADY && ValidEntry) NextWalkerState = LEAF; // *** Leave megapage implementation for later
else if (HREADY) NextWalkerState = FAULT; // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF;
else NextWalkerState = LEVEL2; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0;
LEAF: NextWalkerState = IDLE; else NextWalkerState = FAULT;
LEVEL0: if (~MMUReady) NextWalkerState = LEVEL0;
else if (ValidPTE && LeafPTE && ~AccessAlert)
NextWalkerState = LEAF;
else NextWalkerState = FAULT;
LEAF: if (MMUTranslate) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
FAULT: if (MMUTranslate) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
endcase endcase
end end
always_ff @(posedge HCLK, negedge HRESETn) // unswizzle PTE bits
if (~HRESETn) begin assign {Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid} = MMUReadPTE[7:0];
// A megapage is a Level 1 leaf page. This page must have zero PPN[0].
assign MegapageMisaligned = |(CurrentPPN[9:0]);
assign LeafPTE = Executable | Writable | Readable;
assign ValidPTE = Valid && ~(Writable && ~Readable);
assign AccessAlert = ~Accessed || (MemWriteM && ~Dirty);
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
// *** Should translate this flop block into our flop module notation
always_ff @(posedge clk, negedge reset)
if (reset) begin
TranslationPAdr <= '0; TranslationPAdr <= '0;
PageTableEntryF <= '0; PageTableEntryF <= '0;
TranslationComplete <= '0; MMUTranslationComplete <= '0;
DTLBWriteM <= '0;
ITLBWriteF <= '0;
InstrPageFaultM <= '0;
LoadPageFaultM <= '0;
StorePageFaultM <= '0;
end else begin end else begin
// default values // default values
TranslationPAdr <= '0;
PageTableEntryF <= '0;
MMUTranslationComplete <= '0;
DTLBWriteM <= '0;
ITLBWriteF <= '0;
InstrPageFaultM <= '0;
LoadPageFaultM <= '0;
StorePageFaultM <= '0;
case (NextWalkerState) case (NextWalkerState)
LEVEL1: TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00}; LEVEL1: begin
LEVEL2: TranslationPAdr <= {CurrentPPN, VPN0, 2'b00}; TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00};
end
LEVEL0: begin
TranslationPAdr <= {CurrentPPN, VPN0, 2'b00};
end
LEAF: begin LEAF: begin
PageTableEntryF <= CurrentPageTableEntry; PageTableEntryF <= MMUReadPTE;
TranslationComplete <= '1; PageTableEntryM <= MMUReadPTE;
end MMUTranslationComplete <= '1;
DTLBWriteM <= DTLBMissM;
ITLBWriteF <= ~DTLBMissM; // Prefer data over instructions
end
FAULT: begin
InstrPageFaultM <= ~DTLBMissM;
LoadPageFaultM <= DTLBMissM && ~MemWriteM;
StorePageFaultM <= DTLBMissM && MemWriteM;
end
endcase endcase
end end
assign #1 Translate = (NextWalkerState == LEVEL1); // Interpret inputs from ahblite
assign CurrentPPN = MMUReadPTE[31:10];
// Assign outputs to ahblite
// *** Currently truncate address to 32 bits. This must be changed if
// we support larger physical address spaces
assign MMUPAdr = TranslationPAdr[31:0];
end else begin end else begin
// sv39 not yet implemented
assign SvMode = SATP_REGW[63]; assign SvMode = SATP_REGW[63];
logic [8:0] VPN2 = TranslationVAdr[38:30];
logic [8:0] VPN1 = TranslationVAdr[29:21];
logic [8:0] VPN0 = TranslationVAdr[20:12]; // *** could optimize by not passing offset?
logic [55:0] TranslationPAdr;
logic [43:0] CurrentPPN;
logic Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid;
logic ValidPTE, AccessAlert, GigapageMisaligned, MegapageMisaligned,
BadGigapage, BadMegapage, LeafPTE;
typedef enum {IDLE, LEVEL2, LEVEL1, LEVEL0, LEAF, FAULT} statetype;
statetype WalkerState, NextWalkerState;
// *** Do we need a synchronizer here for walker to talk to ahblite?
flopenl #(.TYPE(statetype)) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
always_comb begin
case (WalkerState)
IDLE: if (MMUTranslate) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
LEVEL2: if (~MMUReady) NextWalkerState = LEVEL2;
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1;
else NextWalkerState = FAULT;
LEVEL1: if (~MMUReady) NextWalkerState = LEVEL1;
// else if (~ValidPTE || (LeafPTE && BadMegapage))
// NextWalkerState = FAULT;
// *** Leave megapage implementation for later
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF;
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0;
else NextWalkerState = FAULT;
LEVEL0: if (~MMUReady) NextWalkerState = LEVEL0;
else if (ValidPTE && LeafPTE && ~AccessAlert)
NextWalkerState = LEAF;
else NextWalkerState = FAULT;
LEAF: if (MMUTranslate) NextWalkerState = LEVEL2;
else NextWalkerState = IDLE;
FAULT: if (MMUTranslate) NextWalkerState = LEVEL2;
else NextWalkerState = IDLE;
endcase
end
// unswizzle PTE bits
assign {Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid} = MMUReadPTE[7:0];
// A megapage is a Level 1 leaf page. This page must have zero PPN[0].
assign GigapageMisaligned = |(CurrentPPN[17:0]);
assign MegapageMisaligned = |(CurrentPPN[8:0]);
assign LeafPTE = Executable | Writable | Readable;
assign ValidPTE = Valid && ~(Writable && ~Readable);
assign AccessAlert = ~Accessed || (MemWriteM && ~Dirty);
assign BadGigapage = GigapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
// *** Should translate this flop block into our flop module notation
always_ff @(posedge clk, negedge reset)
if (reset) begin
TranslationPAdr <= '0;
PageTableEntryF <= '0;
MMUTranslationComplete <= '0;
DTLBWriteM <= '0;
ITLBWriteF <= '0;
InstrPageFaultM <= '0;
LoadPageFaultM <= '0;
StorePageFaultM <= '0;
end else begin
// default values
TranslationPAdr <= '0;
PageTableEntryF <= '0;
MMUTranslationComplete <= '0;
DTLBWriteM <= '0;
ITLBWriteF <= '0;
InstrPageFaultM <= '0;
LoadPageFaultM <= '0;
StorePageFaultM <= '0;
case (NextWalkerState)
LEVEL2: begin
TranslationPAdr <= {BasePageTablePPN, VPN2, 3'b00};
end
LEVEL1: begin
TranslationPAdr <= {CurrentPPN, VPN1, 3'b00};
end
LEVEL0: begin
TranslationPAdr <= {CurrentPPN, VPN0, 3'b00};
end
LEAF: begin
PageTableEntryF <= MMUReadPTE;
PageTableEntryM <= MMUReadPTE;
MMUTranslationComplete <= '1;
DTLBWriteM <= DTLBMissM;
ITLBWriteF <= ~DTLBMissM; // Prefer data over instructions
end
FAULT: begin
InstrPageFaultM <= ~DTLBMissM;
LoadPageFaultM <= DTLBMissM && ~MemWriteM;
StorePageFaultM <= DTLBMissM && MemWriteM;
end
endcase
end
// Interpret inputs from ahblite
assign CurrentPPN = MMUReadPTE[53:10];
// Assign outputs to ahblite
// *** Currently truncate address to 32 bits. This must be changed if
// we support larger physical address spaces
assign MMUPAdr = TranslationPAdr[31:0];
end end
endgenerate endgenerate
// rv32 case
*/
endmodule endmodule

View File

@ -39,6 +39,7 @@ module privileged (
input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongM, input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongM,
input logic [3:0] InstrClassM, input logic [3:0] InstrClassM,
input logic PrivilegedM, input logic PrivilegedM,
input logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM,
input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD, input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD,
input logic LoadMisalignedFaultM, LoadAccessFaultM, input logic LoadMisalignedFaultM, LoadAccessFaultM,
input logic StoreMisalignedFaultM, StoreAccessFaultM, input logic StoreMisalignedFaultM, StoreAccessFaultM,
@ -48,7 +49,7 @@ module privileged (
output logic [1:0] PrivilegeModeW, output logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] SATP_REGW, output logic [`XLEN-1:0] SATP_REGW,
output logic [2:0] FRM_REGW, output logic [2:0] FRM_REGW,
input logic FlushD, FlushE, FlushM, StallD, StallW input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM
); );
logic [1:0] NextPrivilegeModeM; logic [1:0] NextPrivilegeModeM;
@ -65,7 +66,6 @@ module privileged (
logic IllegalInstrFaultM; logic IllegalInstrFaultM;
logic BreakpointFaultM, EcallFaultM; logic BreakpointFaultM, EcallFaultM;
logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM;
logic MTrapM, STrapM, UTrapM; logic MTrapM, STrapM, UTrapM;
logic [1:0] STATUS_MPP; logic [1:0] STATUS_MPP;
@ -119,9 +119,11 @@ module privileged (
assign BreakpointFaultM = ebreakM; // could have other causes too assign BreakpointFaultM = ebreakM; // could have other causes too
assign EcallFaultM = ecallM; assign EcallFaultM = ecallM;
assign InstrPageFaultM = 0; // *** Page faults now driven by page table walker. Might need to make the
assign LoadPageFaultM = 0; // below signals ORs of a walker fault and a tlb fault if both of those come in
assign StorePageFaultM = 0; // assign InstrPageFaultM = 0;
// assign LoadPageFaultM = 0;
// assign StorePageFaultM = 0;
// pipeline fault signals // pipeline fault signals
flopenrc #(1) faultregD(clk, reset, FlushD, ~StallD, InstrAccessFaultF, InstrAccessFaultD); flopenrc #(1) faultregD(clk, reset, FlushD, ~StallD, InstrAccessFaultF, InstrAccessFaultD);

View File

@ -76,6 +76,7 @@ module wallypipelinedhart (
logic InstrMisalignedFaultM; logic InstrMisalignedFaultM;
logic DataMisalignedM; logic DataMisalignedM;
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD; logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM;
logic LoadMisalignedFaultM, LoadAccessFaultM; logic LoadMisalignedFaultM, LoadAccessFaultM;
logic StoreMisalignedFaultM, StoreAccessFaultM; logic StoreMisalignedFaultM, StoreAccessFaultM;
logic [`XLEN-1:0] InstrMisalignedAdrM; logic [`XLEN-1:0] InstrMisalignedAdrM;
@ -98,7 +99,7 @@ module wallypipelinedhart (
logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM; logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
logic [`XLEN-1:0] MMUPAdr, MMUReadPTE; logic [`XLEN-1:0] MMUPAdr, MMUReadPTE;
logic MMUTranslate, MMUReady; logic MMUTranslate, MMUTranslationComplete, MMUReady;
// bus interface to dmem // bus interface to dmem
logic MemReadM, MemWriteM; logic MemReadM, MemWriteM;