Fixed tab space issue.

This commit is contained in:
Ross Thompson 2021-07-01 17:17:53 -05:00
parent 2dc349ea6f
commit 6916784354

View File

@ -30,90 +30,91 @@
`include "wally-config.vh" `include "wally-config.vh"
/* *** /* ***
TO-DO: TO-DO:
- Implement faults on accessed/dirty behavior - Implement faults on accessed/dirty behavior
*/ */
module pagetablewalker ( module pagetablewalker
// Control signals (
input logic clk, reset, // Control signals
input logic [`XLEN-1:0] SATP_REGW, input logic clk, reset,
input logic [`XLEN-1:0] SATP_REGW,
// Signals from TLBs (addresses to translate) // Signals from TLBs (addresses to translate)
input logic [`XLEN-1:0] PCF, MemAdrM, input logic [`XLEN-1:0] PCF, MemAdrM,
input logic ITLBMissF, DTLBMissM, input logic ITLBMissF, DTLBMissM,
input logic [1:0] MemRWM, input logic [1:0] MemRWM,
// Outputs to the TLBs (PTEs to write) // Outputs to the TLBs (PTEs to write)
output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM, output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM,
output logic [1:0] PageTypeF, PageTypeM, output logic [1:0] PageTypeF, PageTypeM,
output logic ITLBWriteF, DTLBWriteM, output logic ITLBWriteF, DTLBWriteM,
// *** modify to send to LSU // *** KMG: These are inputs/results from the ahblite whose addresses should have already been checked, so I don't think they need to be sent through the LSU // *** modify to send to LSU // *** KMG: These are inputs/results from the ahblite whose addresses should have already been checked, so I don't think they need to be sent through the LSU
input logic [`XLEN-1:0] MMUReadPTE, input logic [`XLEN-1:0] MMUReadPTE,
input logic MMUReady, input logic MMUReady,
input logic HPTWStall, input logic HPTWStall,
// *** modify to send to LSU // *** modify to send to LSU
output logic [`XLEN-1:0] MMUPAdr, output logic [`XLEN-1:0] MMUPAdr,
output logic MMUTranslate, // *** rename to HPTWReq output logic MMUTranslate, // *** rename to HPTWReq
output logic HPTWRead, output logic HPTWRead,
// Stall signal // Stall signal
output logic MMUStall, output logic MMUStall,
// Faults // Faults
output logic WalkerInstrPageFaultF, output logic WalkerInstrPageFaultF,
output logic WalkerLoadPageFaultM, output logic WalkerLoadPageFaultM,
output logic WalkerStorePageFaultM output logic WalkerStorePageFaultM
); );
// Internal signals // Internal signals
// register TLBs translation miss requests // register TLBs translation miss requests
logic [`XLEN-1:0] TranslationVAdrQ; logic [`XLEN-1:0] TranslationVAdrQ;
logic ITLBMissFQ, DTLBMissMQ; logic ITLBMissFQ, DTLBMissMQ;
logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`XLEN-1:0] TranslationVAdr; logic [`XLEN-1:0] TranslationVAdr;
logic [`XLEN-1:0] SavedPTE, CurrentPTE; logic [`XLEN-1:0] SavedPTE, CurrentPTE;
logic [`PA_BITS-1:0] TranslationPAdr; logic [`PA_BITS-1:0] TranslationPAdr;
logic [`PPN_BITS-1:0] CurrentPPN; logic [`PPN_BITS-1:0] CurrentPPN;
logic [`SVMODE_BITS-1:0] SvMode; logic [`SVMODE_BITS-1:0] SvMode;
logic MemStore; logic MemStore;
// PTE Control Bits // PTE Control Bits
logic Dirty, Accessed, Global, User, logic Dirty, Accessed, Global, User,
Executable, Writable, Readable, Valid; Executable, Writable, Readable, Valid;
// PTE descriptions // PTE descriptions
logic ValidPTE, AccessAlert, MegapageMisaligned, BadMegapage, LeafPTE; logic ValidPTE, AccessAlert, MegapageMisaligned, BadMegapage, LeafPTE;
// Outputs of walker // Outputs of walker
logic [`XLEN-1:0] PageTableEntry; logic [`XLEN-1:0] PageTableEntry;
logic [1:0] PageType; logic [1:0] PageType;
logic StartWalk; logic StartWalk;
logic EndWalk; logic EndWalk;
typedef enum {LEVEL0_WDV, typedef enum {LEVEL0_WDV,
LEVEL0, LEVEL0,
LEVEL1_WDV, LEVEL1_WDV,
LEVEL1, LEVEL1,
LEVEL2_WDV, LEVEL2_WDV,
LEVEL2, LEVEL2,
LEVEL3_WDV, LEVEL3_WDV,
LEVEL3, LEVEL3,
LEAF, LEAF,
IDLE, IDLE,
FAULT} statetype; FAULT} statetype;
statetype WalkerState, NextWalkerState; statetype WalkerState, NextWalkerState;
logic PRegEn; logic PRegEn;
assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
@ -145,7 +146,7 @@ module pagetablewalker (
.clear(EndWalk), .clear(EndWalk),
.d(ITLBMissF), .d(ITLBMissF),
.q(ITLBMissFQ)); .q(ITLBMissFQ));
assign StartWalk = WalkerState == IDLE && (DTLBMissM | ITLBMissF); assign StartWalk = WalkerState == IDLE && (DTLBMissM | ITLBMissF);
assign EndWalk = WalkerState == LEAF || assign EndWalk = WalkerState == LEAF ||
@ -186,23 +187,23 @@ module pagetablewalker (
always_comb begin always_comb begin
case (WalkerState) case (WalkerState)
IDLE: if (MMUTranslate) NextWalkerState = LEVEL1_WDV; IDLE: if (MMUTranslate) NextWalkerState = LEVEL1_WDV;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV;
else NextWalkerState = LEVEL1; else NextWalkerState = LEVEL1;
LEVEL1: LEVEL1:
// *** <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) NextWalkerState = LEAF;
// 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) NextWalkerState = LEVEL0_WDV; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_WDV;
else NextWalkerState = FAULT; else NextWalkerState = FAULT;
LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV; LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV;
else NextWalkerState = LEVEL0; else NextWalkerState = LEVEL0;
LEVEL0: if (ValidPTE & LeafPTE & ~AccessAlert) LEVEL0: if (ValidPTE & LeafPTE & ~AccessAlert)
NextWalkerState = LEAF; NextWalkerState = LEAF;
else NextWalkerState = FAULT; else NextWalkerState = FAULT;
LEAF: NextWalkerState = IDLE; LEAF: NextWalkerState = IDLE;
FAULT: NextWalkerState = IDLE; FAULT: NextWalkerState = IDLE;
// Default case should never happen, but is included for linter. // Default case should never happen, but is included for linter.
@ -218,7 +219,7 @@ module pagetablewalker (
assign VPN0 = TranslationVAdrQ[21:12]; assign VPN0 = TranslationVAdrQ[21:12];
//assign HPTWRead = (WalkerState == IDLE && MMUTranslate) || //assign HPTWRead = (WalkerState == IDLE && MMUTranslate) ||
// WalkerState == LEVEL2 || WalkerState == LEVEL1; // WalkerState == LEVEL2 || WalkerState == LEVEL1;
// Assign combinational outputs // Assign combinational outputs
always_comb begin always_comb begin
@ -262,7 +263,7 @@ module pagetablewalker (
WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
WalkerStorePageFaultM = DTLBMissMQ && MemStore; WalkerStorePageFaultM = DTLBMissMQ && MemStore;
// MMUStall = '0; // Drop the stall early to enter trap handling code // MMUStall = '0; // Drop the stall early to enter trap handling code
end end
default: begin default: begin
// nothing // nothing
@ -291,17 +292,17 @@ module pagetablewalker (
logic [8:0] VPN3, VPN2, VPN1, VPN0; logic [8:0] VPN3, VPN2, VPN1, VPN0;
logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage; logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage;
flopenl #(.TYPE(statetype)) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
/* -----\/----- EXCLUDED -----\/----- /* -----\/----- EXCLUDED -----\/-----
assign PRegEn = (WalkerState == LEVEL1_WDV || WalkerState == LEVEL0_WDV || assign PRegEn = (WalkerState == LEVEL1_WDV || WalkerState == LEVEL0_WDV ||
WalkerState == LEVEL2_WDV || WalkerState == LEVEL3_WDV) && ~HPTWStall; WalkerState == LEVEL2_WDV || WalkerState == LEVEL3_WDV) && ~HPTWStall;
-----/\----- EXCLUDED -----/\----- */ -----/\----- EXCLUDED -----/\----- */
//assign HPTWRead = (WalkerState == IDLE && MMUTranslate) || WalkerState == LEVEL3 || //assign HPTWRead = (WalkerState == IDLE && MMUTranslate) || WalkerState == LEVEL3 ||
// WalkerState == LEVEL2 || WalkerState == LEVEL1; // WalkerState == LEVEL2 || WalkerState == LEVEL1;
always_comb begin always_comb begin
@ -352,152 +353,152 @@ module pagetablewalker (
// 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 && ~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 :
((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;
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
NextWalkerState = LEVEL2_WDV; NextWalkerState = LEVEL2_WDV;
TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
HPTWRead = 1'b1; HPTWRead = 1'b1;
end else begin end else begin
NextWalkerState = FAULT; NextWalkerState = FAULT;
WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
WalkerStorePageFaultM = DTLBMissMQ && MemStore; WalkerStorePageFaultM = DTLBMissMQ && MemStore;
end end
end end
LEVEL2_WDV: begin LEVEL2_WDV: begin
TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
//HPTWRead = 1'b1; //HPTWRead = 1'b1;
if (HPTWStall) begin if (HPTWStall) begin
NextWalkerState = LEVEL2_WDV; NextWalkerState = LEVEL2_WDV;
end else begin end else begin
NextWalkerState = LEVEL2; NextWalkerState = LEVEL2;
PRegEn = 1'b1; PRegEn = 1'b1;
end end
end end
LEVEL2: begin LEVEL2: 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 && ~BadGigapage) begin if (ValidPTE && LeafPTE && ~BadGigapage) begin
NextWalkerState = LEAF; NextWalkerState = LEAF;
PageTableEntry = CurrentPTE; PageTableEntry = CurrentPTE;
PageType = (WalkerState == LEVEL3) ? 2'b11 : PageType = (WalkerState == LEVEL3) ? 2'b11 :
((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;
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
NextWalkerState = LEVEL1_WDV; NextWalkerState = LEVEL1_WDV;
TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
HPTWRead = 1'b1; HPTWRead = 1'b1;
end else begin end else begin
NextWalkerState = FAULT; NextWalkerState = FAULT;
WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
WalkerStorePageFaultM = DTLBMissMQ && MemStore; WalkerStorePageFaultM = DTLBMissMQ && MemStore;
end end
end end
LEVEL1_WDV: begin LEVEL1_WDV: begin
TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
//HPTWRead = 1'b1; //HPTWRead = 1'b1;
if (HPTWStall) begin if (HPTWStall) begin
NextWalkerState = LEVEL1_WDV; NextWalkerState = LEVEL1_WDV;
end else begin end else begin
NextWalkerState = LEVEL1; NextWalkerState = LEVEL1;
PRegEn = 1'b1; PRegEn = 1'b1;
end end
end end
LEVEL1: begin 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) begin if (ValidPTE && LeafPTE && ~BadMegapage) begin
NextWalkerState = LEAF; NextWalkerState = LEAF;
PageTableEntry = CurrentPTE; PageTableEntry = CurrentPTE;
PageType = (WalkerState == LEVEL3) ? 2'b11 : PageType = (WalkerState == LEVEL3) ? 2'b11 :
((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;
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
NextWalkerState = LEVEL0_WDV; NextWalkerState = LEVEL0_WDV;
TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
HPTWRead = 1'b1; HPTWRead = 1'b1;
end else begin end else begin
NextWalkerState = FAULT; NextWalkerState = FAULT;
WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
WalkerStorePageFaultM = DTLBMissMQ && MemStore; WalkerStorePageFaultM = DTLBMissMQ && MemStore;
end end
end end
LEVEL0_WDV: begin LEVEL0_WDV: begin
TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
//HPTWRead = 1'b1; //HPTWRead = 1'b1;
if (HPTWStall) begin if (HPTWStall) begin
NextWalkerState = LEVEL0_WDV; NextWalkerState = LEVEL0_WDV;
end else begin end else begin
NextWalkerState = LEVEL0; NextWalkerState = LEVEL0;
PRegEn = 1'b1; PRegEn = 1'b1;
end end
end end
LEVEL0: begin LEVEL0: begin
if (ValidPTE && LeafPTE && ~AccessAlert) begin if (ValidPTE && LeafPTE && ~AccessAlert) begin
NextWalkerState = LEAF; NextWalkerState = LEAF;
PageTableEntry = CurrentPTE; PageTableEntry = CurrentPTE;
PageType = (WalkerState == LEVEL3) ? 2'b11 : PageType = (WalkerState == LEVEL3) ? 2'b11 :
((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;
end else begin end else begin
NextWalkerState = FAULT; NextWalkerState = FAULT;
WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
WalkerStorePageFaultM = DTLBMissMQ && MemStore; WalkerStorePageFaultM = DTLBMissMQ && MemStore;
end end
end end
LEAF: begin LEAF: begin
NextWalkerState = IDLE; NextWalkerState = IDLE;
MMUStall = 1'b0; MMUStall = 1'b0;
end end
FAULT: begin FAULT: begin
NextWalkerState = IDLE; NextWalkerState = IDLE;
MMUStall = 1'b0; MMUStall = 1'b0;
end end
// Default case should never happen // Default case should never happen
default: begin default: begin
NextWalkerState = IDLE; NextWalkerState = IDLE;
end end
endcase endcase
end end