Major rewrite of ptw to remove combo loop.

This commit is contained in:
Ross Thompson 2021-06-30 16:25:03 -05:00
parent b2d8ba6742
commit 9ec624702d
5 changed files with 272 additions and 125 deletions

View File

@ -240,7 +240,7 @@ add wave -noupdate -group AHB /testbench/dut/hart/ebu/HADDRD
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED
add wave -noupdate -group AHB /testbench/dut/hart/ebu/StallW add wave -noupdate -group AHB /testbench/dut/hart/ebu/StallW
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/CurrState add wave -noupdate -expand -group lsu -color Gold /testbench/dut/hart/lsu/CurrState
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/MemRWM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/MemRWM
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/DataStall add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/DataStall
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/MemAdrM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/MemAdrM
@ -293,27 +293,36 @@ add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/MTIME
add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/MTIMECMP add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/MTIMECMP
add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/TimerIntM add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/TimerIntM
add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/SwIntM add wave -noupdate -group CLINT /testbench/dut/uncore/genblk1/clint/SwIntM
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/PRegEn
add wave -noupdate -expand -group ptwalker -color Gold /testbench/dut/hart/pagetablewalker/WalkerState
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUReady
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/HPTWStall
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUTranslate add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUTranslate
add wave -noupdate -expand -group ptwalker -color Gold /testbench/dut/hart/pagetablewalker/WalkerState
add wave -noupdate -expand -group ptwalker -color Salmon /testbench/dut/hart/pagetablewalker/HPTWStall
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/HPTWRead add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/HPTWRead
add wave -noupdate -expand -group ptwalker -divider data
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUPAdr add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUPAdr
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUReadPTE add wave -noupdate -expand -group ptwalker -expand -group pte /testbench/dut/hart/pagetablewalker/MMUReadPTE
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/CurrentPTE add wave -noupdate -expand -group ptwalker -expand -group pte /testbench/dut/hart/pagetablewalker/PRegEn
add wave -noupdate -expand -group ptwalker -expand -group pte /testbench/dut/hart/pagetablewalker/CurrentPTE
add wave -noupdate -expand -group ptwalker -divider data
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/TranslationPAdr add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/TranslationPAdr
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/ValidPTE add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/ValidPTE
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/LeafPTE add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/LeafPTE
add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUStall add wave -noupdate -expand -group ptwalker /testbench/dut/hart/pagetablewalker/MMUStall
add wave -noupdate -expand -group ptwalker -expand -group {fsm outputs} /testbench/dut/hart/pagetablewalker/TranslationPAdr
add wave -noupdate -expand -group ptwalker -expand -group {fsm outputs} /testbench/dut/hart/pagetablewalker/PageTableEntry
add wave -noupdate -expand -group ptwalker -expand -group {fsm outputs} /testbench/dut/hart/pagetablewalker/PageType
add wave -noupdate -expand -group ptwalker -expand -group {fsm outputs} /testbench/dut/hart/pagetablewalker/ITLBWriteF
add wave -noupdate -expand -group ptwalker -expand -group {fsm outputs} /testbench/dut/hart/pagetablewalker/DTLBWriteM
add wave -noupdate -expand -group ptwalker -expand -group {fsm outputs} /testbench/dut/hart/pagetablewalker/WalkerInstrPageFaultF
add wave -noupdate -expand -group ptwalker -expand -group {fsm outputs} /testbench/dut/hart/pagetablewalker/WalkerLoadPageFaultM
add wave -noupdate -expand -group ptwalker -expand -group {fsm outputs} /testbench/dut/hart/pagetablewalker/WalkerStorePageFaultM
add wave -noupdate -expand -group ptwalker -expand -group {fsm outputs} /testbench/dut/hart/pagetablewalker/MMUStall
add wave -noupdate -expand -group {LSU ARB} -color Gold /testbench/dut/hart/arbiter/CurrState add wave -noupdate -expand -group {LSU ARB} -color Gold /testbench/dut/hart/arbiter/CurrState
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/HPTWTranslate
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/HPTWPAdr
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/HPTWReadPTE
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/HPTWReady
add wave -noupdate -expand -group {LSU ARB} -expand -group toLSU /testbench/dut/hart/arbiter/MemAdrMtoLSU
add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/SelPTW add wave -noupdate -expand -group {LSU ARB} /testbench/dut/hart/arbiter/SelPTW
add wave -noupdate -expand -group {LSU ARB} -expand -group hptw /testbench/dut/hart/arbiter/HPTWTranslate
add wave -noupdate -expand -group {LSU ARB} -expand -group hptw /testbench/dut/hart/arbiter/HPTWRead
add wave -noupdate -expand -group {LSU ARB} -expand -group hptw /testbench/dut/hart/arbiter/HPTWPAdr
add wave -noupdate -expand -group {LSU ARB} -expand -group hptw /testbench/dut/hart/arbiter/HPTWReadPTE
add wave -noupdate -expand -group {LSU ARB} -expand -group hptw /testbench/dut/hart/arbiter/HPTWReady
add wave -noupdate -expand -group {LSU ARB} -expand -group toLSU /testbench/dut/hart/arbiter/MemAdrMtoLSU
add wave -noupdate /testbench/dut/hart/lsu/DataStall add wave -noupdate /testbench/dut/hart/lsu/DataStall
add wave -noupdate -expand -group csr /testbench/dut/hart/priv/csr/MIP_REGW add wave -noupdate -expand -group csr /testbench/dut/hart/priv/csr/MIP_REGW
add wave -noupdate /testbench/dut/uncore/genblk2/plic/ExtIntM add wave -noupdate /testbench/dut/uncore/genblk2/plic/ExtIntM
@ -340,9 +349,10 @@ add wave -noupdate -group uart -expand -group outputs /testbench/dut/uncore/genb
add wave -noupdate -group uart -expand -group outputs /testbench/dut/uncore/genblk4/uart/TXRDYb add wave -noupdate -group uart -expand -group outputs /testbench/dut/uncore/genblk4/uart/TXRDYb
add wave -noupdate -group uart -expand -group outputs /testbench/dut/uncore/genblk4/uart/RXRDYb add wave -noupdate -group uart -expand -group outputs /testbench/dut/uncore/genblk4/uart/RXRDYb
add wave -noupdate -expand -group dtlb /testbench/dut/hart/lsu/dmmu/TLBMiss add wave -noupdate -expand -group dtlb /testbench/dut/hart/lsu/dmmu/TLBMiss
add wave -noupdate -expand -group itlb /testbench/dut/hart/ifu/ITLBMissF
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 5} {11172515 ns} 0} {{Cursor 8} {9673965 ns} 0} WaveRestoreCursors {{Cursor 5} {11172515 ns} 0} {{Cursor 8} {2967 ns} 0}
quietly wave cursor active 1 quietly wave cursor active 2
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 189 configure wave -valuecolwidth 189
configure wave -justifyvalue left configure wave -justifyvalue left
@ -357,4 +367,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update update
WaveRestoreZoom {11172446 ns} {11172732 ns} WaveRestoreZoom {2729 ns} {3045 ns}

View File

@ -103,14 +103,17 @@ module lsu (
logic SquashSCM; logic SquashSCM;
logic DTLBPageFaultM; logic DTLBPageFaultM;
logic MemAccessM; logic MemAccessM;
logic [2:0] CurrState, NextState;
logic preCommittedM; logic preCommittedM;
localparam STATE_READY = 0; typedef enum {STATE_READY,
localparam STATE_FETCH = 1; STATE_FETCH,
localparam STATE_FETCH_AMO_1 = 2; STATE_FETCH_AMO_1,
localparam STATE_FETCH_AMO_2 = 3; STATE_FETCH_AMO_2,
localparam STATE_STALLED = 4; STATE_STALLED,
STATE_TLB_MISS} statetype;
statetype CurrState, NextState;
logic PMPInstrAccessFaultF, PMAInstrAccessFaultF; // *** these are just so that the mmu has somewhere to put these outputs since they aren't used in dmem logic PMPInstrAccessFaultF, PMAInstrAccessFaultF; // *** these are just so that the mmu has somewhere to put these outputs since they aren't used in dmem
// *** 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.
@ -208,15 +211,20 @@ module lsu (
// requests data from memory rather than issuing a single request. // requests data from memory rather than issuing a single request.
flopr #(3) stateReg(.clk(clk), flopenl #(.TYPE(statetype)) stateReg(.clk(clk),
.reset(reset), .load(reset),
.d(NextState), .en(1'b1),
.q(CurrState)); .d(NextState),
.val(STATE_READY),
.q(CurrState));
always_comb begin always_comb begin
case (CurrState) case (CurrState)
STATE_READY: STATE_READY:
if (AtomicMaskedM[1]) begin if (DTLBMissM) begin
NextState = STATE_READY;
DataStall = 1'b0;
end else if (AtomicMaskedM[1]) begin
NextState = STATE_FETCH_AMO_1; // *** should be some misalign check NextState = STATE_FETCH_AMO_1; // *** should be some misalign check
DataStall = 1'b1; DataStall = 1'b1;
end else if((MemReadM & AtomicM[0]) | (MemWriteM & AtomicM[0])) begin end else if((MemReadM & AtomicM[0]) | (MemWriteM & AtomicM[0])) begin
@ -248,15 +256,13 @@ module lsu (
end end
end end
STATE_FETCH: begin STATE_FETCH: begin
DataStall = 1'b1;
if (MemAckW & ~StallW) begin if (MemAckW & ~StallW) begin
NextState = STATE_READY; NextState = STATE_READY;
DataStall = 1'b0;
end else if (MemAckW & StallW) begin end else if (MemAckW & StallW) begin
NextState = STATE_STALLED; NextState = STATE_STALLED;
DataStall = 1'b1;
end else begin end else begin
NextState = STATE_FETCH; NextState = STATE_FETCH;
DataStall = 1'b1;
end end
end end
STATE_STALLED: begin STATE_STALLED: begin
@ -267,6 +273,13 @@ module lsu (
NextState = STATE_STALLED; NextState = STATE_STALLED;
end end
end end
STATE_TLB_MISS: begin
if (DTLBWriteM) begin
NextState = STATE_READY;
end else begin
NextState = STATE_TLB_MISS;
end
end
default: begin default: begin
DataStall = 1'b0; DataStall = 1'b0;
NextState = STATE_READY; NextState = STATE_READY;

View File

@ -81,26 +81,31 @@ module lsuArb
// to data memory the d cache is already busy. We can interlock by // to data memory the d cache is already busy. We can interlock by
// leveraging Stall as a d cache busy. We will need an FSM to handle this. // leveraging Stall as a d cache busy. We will need an FSM to handle this.
localparam StateReady = 0; typedef enum{StateReady,
localparam StatePTWPending = 1; StatePTWPending,
localparam StatePTWActive = 2; StatePTWActive} statetype;
logic [1:0] CurrState, NextState; statetype CurrState, NextState;
logic SelPTW; logic SelPTW;
logic HPTWStallD; logic HPTWStallD;
flopr #(2) StateReg( flopenl #(.TYPE(statetype)) StateReg(.clk(clk),
.clk(clk), .load(reset),
.reset(reset), .en(1'b1),
.d(NextState), .d(NextState),
.q(CurrState)); .val(StateReady),
.q(CurrState));
always_comb begin always_comb begin
case(CurrState) case(CurrState)
StateReady: StateReady:
/* -----\/----- EXCLUDED -----\/-----
if (HPTWTranslate & DataStall) NextState = StatePTWPending; if (HPTWTranslate & DataStall) NextState = StatePTWPending;
else if (HPTWTranslate & ~DataStall) NextState = StatePTWActive; else
-----/\----- EXCLUDED -----/\----- */
if (HPTWTranslate) NextState = StatePTWActive;
else NextState = StateReady; else NextState = StateReady;
StatePTWPending: StatePTWPending:
if (HPTWTranslate & ~DataStall) NextState = StatePTWActive; if (HPTWTranslate & ~DataStall) NextState = StatePTWActive;
@ -143,11 +148,15 @@ module lsuArb
// *** need to rename DcacheStall and Datastall. // *** need to rename DcacheStall and Datastall.
// not clear at all. I think it should be LSUStall from the LSU, // not clear at all. I think it should be LSUStall from the LSU,
// which is demuxed to HPTWStall and CPUDataStall? (not sure on this last one). // which is demuxed to HPTWStall and CPUDataStall? (not sure on this last one).
assign HPTWStall = SelPTW ? DataStall : 1'b1;
//assign HPTWStallD = SelPTW ? DataStall : 1'b1;
/* -----\/----- EXCLUDED -----\/-----
assign HPTWStallD = SelPTW ? DataStall : 1'b1; assign HPTWStallD = SelPTW ? DataStall : 1'b1;
flopr #(1) HPTWStallReg (.clk(clk), flopr #(1) HPTWStallReg (.clk(clk),
.reset(reset), .reset(reset),
.d(HPTWStallD), .d(HPTWStallD),
.q(HPTWStall)); .q(HPTWStall));
-----/\----- EXCLUDED -----/\----- */
assign DCacheStall = SelPTW ? 1'b0 : DataStall; // *** this is probably going to change. assign DCacheStall = SelPTW ? 1'b0 : DataStall; // *** this is probably going to change.

View File

@ -126,6 +126,7 @@ module pagetablewalker (
assign MMUTranslate = DTLBMissMQ | ITLBMissFQ; assign MMUTranslate = DTLBMissMQ | ITLBMissFQ;
//assign MMUTranslate = DTLBMissM | ITLBMissF;
// unswizzle PTE bits // unswizzle PTE bits
assign {Dirty, Accessed, Global, User, assign {Dirty, Accessed, Global, User,
@ -142,20 +143,19 @@ module pagetablewalker (
assign PageTypeF = PageType; assign PageTypeF = PageType;
assign PageTypeM = PageType; assign PageTypeM = PageType;
localparam LEVEL0_WDV = 4'h0; typedef enum {LEVEL0_WDV,
localparam LEVEL0 = 4'h8; LEVEL0,
localparam LEVEL1_WDV = 4'h1; LEVEL1_WDV,
localparam LEVEL1 = 4'h9; LEVEL1,
localparam LEVEL2_WDV = 4'h2; LEVEL2_WDV,
localparam LEVEL2 = 4'hA; LEVEL2,
localparam LEVEL3_WDV = 4'h3; LEVEL3_WDV,
localparam LEVEL3 = 4'hB; LEVEL3,
// space left for more levels LEAF,
localparam LEAF = 4'h5; IDLE,
localparam IDLE = 4'h6; FAULT} statetype;
localparam FAULT = 4'h7;
logic [3:0] WalkerState, NextWalkerState; statetype WalkerState, NextWalkerState;
logic PRegEn; logic PRegEn;
@ -163,7 +163,7 @@ module pagetablewalker (
if (`XLEN == 32) begin if (`XLEN == 32) begin
logic [9:0] VPN1, VPN0; logic [9:0] VPN1, VPN0;
flopenl #(3) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
assign PRegEn = (WalkerState == LEVEL1_WDV || WalkerState == LEVEL0_WDV) && ~HPTWStall; assign PRegEn = (WalkerState == LEVEL1_WDV || WalkerState == LEVEL0_WDV) && ~HPTWStall;
@ -202,13 +202,13 @@ module pagetablewalker (
assign VPN1 = TranslationVAdrQ[31:22]; assign VPN1 = TranslationVAdrQ[31:22];
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
// default values // default values
TranslationPAdr = '0; //TranslationPAdr = '0;
PageTableEntry = '0; PageTableEntry = '0;
PageType ='0; PageType ='0;
DTLBWriteM = '0; DTLBWriteM = '0;
@ -216,38 +216,38 @@ module pagetablewalker (
WalkerInstrPageFaultF = '0; WalkerInstrPageFaultF = '0;
WalkerLoadPageFaultM = '0; WalkerLoadPageFaultM = '0;
WalkerStorePageFaultM = '0; WalkerStorePageFaultM = '0;
MMUStall = '1; //MMUStall = '1;
case (NextWalkerState) case (NextWalkerState)
IDLE: begin IDLE: begin
MMUStall = '0; //MMUStall = '0;
end end
LEVEL1: begin LEVEL1: begin
TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; //TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
end end
LEVEL1_WDV: begin LEVEL1_WDV: begin
TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; //TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
end end
LEVEL0: begin LEVEL0: begin
TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; //TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
end end
LEVEL0_WDV: begin LEVEL0_WDV: begin
TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; //TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
end end
LEAF: begin LEAF: begin
// Keep physical address alive to prevent HADDR dropping to 0 // Keep physical address alive to prevent HADDR dropping to 0
TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; //TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
PageTableEntry = CurrentPTE; PageTableEntry = CurrentPTE;
PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00; PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00;
DTLBWriteM = DTLBMissMQ; DTLBWriteM = DTLBMissMQ;
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
end end
FAULT: begin FAULT: begin
TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; //TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
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
@ -278,68 +278,179 @@ module pagetablewalker (
logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage; logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage;
flopenl #(4) 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 || assign PRegEn = (WalkerState == LEVEL1_WDV || WalkerState == LEVEL0_WDV ||
WalkerState == LEVEL2_WDV || WalkerState == LEVEL3_WDV) && ~HPTWStall; WalkerState == LEVEL2_WDV || WalkerState == LEVEL3_WDV) && ~HPTWStall;
-----/\----- 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
PRegEn = 1'b0;
TranslationPAdr = '0;
HPTWRead = 1'b0;
MMUStall = 1'b1;
WalkerInstrPageFaultF = 1'b0;
WalkerLoadPageFaultM = 1'b0;
WalkerStorePageFaultM = 1'b0;
case (WalkerState) case (WalkerState)
IDLE: if (MMUTranslate && SvMode == `SV48) NextWalkerState = LEVEL3_WDV; IDLE: begin
else if (MMUTranslate && SvMode == `SV39) NextWalkerState = LEVEL2_WDV; if (MMUTranslate && SvMode == `SV48) begin
else NextWalkerState = IDLE; NextWalkerState = LEVEL3_WDV;
TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
HPTWRead = 1'b1;
end else if (MMUTranslate && SvMode == `SV39) begin
NextWalkerState = LEVEL2_WDV;
TranslationPAdr = {BasePageTablePPN, VPN2, 3'b000};
HPTWRead = 1'b1;
end else begin
NextWalkerState = IDLE;
TranslationPAdr = '0;
MMUStall = 1'b0;
end
end
LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV; LEVEL3_WDV: begin
else NextWalkerState = LEVEL3; TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
LEVEL3: //HPTWRead = 1'b1;
if (HPTWStall) begin
NextWalkerState = LEVEL3_WDV;
end else begin
NextWalkerState = LEVEL3;
PRegEn = 1'b1;
end
end
LEVEL3: 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 && ~BadTerapage) begin
NextWalkerState = LEAF;
end
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
else if (ValidPTE && ~LeafPTE) begin
NextWalkerState = LEVEL2_WDV;
TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
HPTWRead = 1'b1;
end else begin
NextWalkerState = FAULT;
WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
WalkerStorePageFaultM = DTLBMissMQ && MemStore;
end
end
LEVEL2_WDV: begin
TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
//HPTWRead = 1'b1;
if (HPTWStall) begin
NextWalkerState = LEVEL2_WDV;
end else begin
NextWalkerState = LEVEL2;
PRegEn = 1'b1;
end
end
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 && ~BadTerapage) NextWalkerState = LEAF; if (ValidPTE && LeafPTE && ~BadGigapage) begin
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. NextWalkerState = LEAF;
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_WDV; end
else NextWalkerState = FAULT; // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
else if (ValidPTE && ~LeafPTE) begin
NextWalkerState = LEVEL1_WDV;
TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
HPTWRead = 1'b1;
end else begin
NextWalkerState = FAULT;
WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
WalkerStorePageFaultM = DTLBMissMQ && MemStore;
end
LEVEL2_WDV: if (HPTWStall) NextWalkerState = LEVEL2_WDV; end
else NextWalkerState = LEVEL2;
LEVEL2:
// *** <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 && ~BadGigapage) NextWalkerState = LEAF;
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line.
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_WDV;
else NextWalkerState = FAULT;
LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; LEVEL1_WDV: begin
else NextWalkerState = LEVEL1; TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
LEVEL1: //HPTWRead = 1'b1;
// *** <FUTURE WORK> According to the architecture, we should if (HPTWStall) begin
// fault upon finding a superpage that is misaligned or has 0 NextWalkerState = LEVEL1_WDV;
// access bit. The following commented line of code is end else begin
// supposed to perform that check. However, it is untested. NextWalkerState = LEVEL1;
if (ValidPTE && LeafPTE && ~BadMegapage) NextWalkerState = LEAF; PRegEn = 1'b1;
// else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. end
else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_WDV; end
else NextWalkerState = FAULT;
LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV; LEVEL1: begin
else NextWalkerState = LEVEL0; // *** <FUTURE WORK> According to the architecture, we should
LEVEL0: // fault upon finding a superpage that is misaligned or has 0
if (ValidPTE && LeafPTE && ~AccessAlert) NextWalkerState = LEAF; // access bit. The following commented line of code is
else NextWalkerState = FAULT; // supposed to perform that check. However, it is untested.
if (ValidPTE && LeafPTE && ~BadMegapage) begin
NextWalkerState = LEAF;
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, 3'b000};
HPTWRead = 1'b1;
end else begin
NextWalkerState = FAULT;
WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
WalkerStorePageFaultM = DTLBMissMQ && MemStore;
end
end
LEVEL0_WDV: begin
TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
//HPTWRead = 1'b1;
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;
end else begin
NextWalkerState = FAULT;
WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
WalkerStorePageFaultM = DTLBMissMQ && MemStore;
end
end
LEAF: NextWalkerState = IDLE; LEAF: begin
NextWalkerState = IDLE;
MMUStall = 1'b0;
end
FAULT: begin
NextWalkerState = IDLE;
MMUStall = 1'b0;
end
// Default case should never happen
default: begin
NextWalkerState = IDLE;
end
FAULT: NextWalkerState = IDLE;
// Default case should never happen, but is included for linter.
default: NextWalkerState = IDLE;
endcase endcase
end end
@ -363,53 +474,55 @@ module pagetablewalker (
always_comb begin always_comb begin
// default values // default values
TranslationPAdr = '0; //TranslationPAdr = '0;
PageTableEntry = '0; PageTableEntry = '0;
PageType = '0; PageType = '0;
DTLBWriteM = '0; DTLBWriteM = '0;
ITLBWriteF = '0; ITLBWriteF = '0;
/* -----\/----- EXCLUDED -----\/-----
WalkerInstrPageFaultF = '0; WalkerInstrPageFaultF = '0;
WalkerLoadPageFaultM = '0; WalkerLoadPageFaultM = '0;
WalkerStorePageFaultM = '0; WalkerStorePageFaultM = '0;
-----/\----- EXCLUDED -----/\----- */
// The MMU defaults to stalling the processor // The MMU defaults to stalling the processor
MMUStall = '1; //MMUStall = '1;
case (NextWalkerState) case (NextWalkerState)
IDLE: begin IDLE: begin
MMUStall = '0; //MMUStall = '0;
end end
LEVEL3: begin LEVEL3: begin
TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; //TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
// *** this is a huge breaking point. if we're going through level3 every time, even when sv48 is off, // *** this is a huge breaking point. if we're going through level3 every time, even when sv48 is off,
// what should translationPAdr be when level3 is just off? // what should translationPAdr be when level3 is just off?
end end
LEVEL3_WDV: begin LEVEL3_WDV: begin
TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; //TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
// *** this is a huge breaking point. if we're going through level3 every time, even when sv48 is off, // *** this is a huge breaking point. if we're going through level3 every time, even when sv48 is off,
// what should translationPAdr be when level3 is just off? // what should translationPAdr be when level3 is just off?
end end
LEVEL2: begin LEVEL2: begin
TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; //TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
end end
LEVEL2_WDV: begin LEVEL2_WDV: begin
TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; //TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
end end
LEVEL1: begin LEVEL1: begin
TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; //TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
end end
LEVEL1_WDV: begin LEVEL1_WDV: begin
TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; //TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
end end
LEVEL0: begin LEVEL0: begin
TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; //TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
end end
LEVEL0_WDV: begin LEVEL0_WDV: begin
TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; //TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
end end
LEAF: begin LEAF: begin
// Keep physical address alive to prevent HADDR dropping to 0 // Keep physical address alive to prevent HADDR dropping to 0
TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; //TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
PageTableEntry = CurrentPTE; PageTableEntry = CurrentPTE;
PageType = (WalkerState == LEVEL3) ? 2'b11 : PageType = (WalkerState == LEVEL3) ? 2'b11 :
((WalkerState == LEVEL2) ? 2'b10 : ((WalkerState == LEVEL2) ? 2'b10 :
@ -419,11 +532,13 @@ module pagetablewalker (
end end
FAULT: begin FAULT: begin
// Keep physical address alive to prevent HADDR dropping to 0 // Keep physical address alive to prevent HADDR dropping to 0
TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; //TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
/* -----\/----- EXCLUDED -----\/-----
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 -----/\----- EXCLUDED -----/\----- */
//MMUStall = '0; // Drop the stall early to enter trap handling code
end end
default: begin default: begin
// nothing // nothing

View File

@ -538,9 +538,9 @@ string tests32f[] = '{
else tests = {tests, tests64iNOc}; else tests = {tests, tests64iNOc};
if (`M_SUPPORTED) tests = {tests, tests64m}; if (`M_SUPPORTED) tests = {tests, tests64m};
if (`A_SUPPORTED) tests = {tests, tests64a}; if (`A_SUPPORTED) tests = {tests, tests64a};
if (`MEM_VIRTMEM) tests = {tests, tests64mmu};
if (`D_SUPPORTED) tests = {tests64d, tests}; if (`D_SUPPORTED) tests = {tests64d, tests};
if (`F_SUPPORTED) tests = {tests64f, tests}; if (`F_SUPPORTED) tests = {tests64f, tests};
if (`MEM_VIRTMEM) tests = {tests64mmu, tests};
end end
//tests = {tests64a, tests}; //tests = {tests64a, tests};
end else begin // RV32 end else begin // RV32