mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
HPTW: more cleanup
This commit is contained in:
parent
a0f6c9aec1
commit
880aa1c03a
@ -95,21 +95,11 @@ module pagetablewalker
|
|||||||
logic StartWalk;
|
logic StartWalk;
|
||||||
logic EndWalk;
|
logic EndWalk;
|
||||||
|
|
||||||
typedef enum {LEVEL0_SET_ADRE,
|
typedef enum {LEVEL0_SET_ADRE, LEVEL0_WDV, LEVEL0,
|
||||||
LEVEL0_WDV,
|
LEVEL1_SET_ADRE, LEVEL1_WDV, LEVEL1,
|
||||||
LEVEL0,
|
LEVEL2_SET_ADRE, LEVEL2_WDV, LEVEL2,
|
||||||
LEVEL1_SET_ADRE,
|
LEVEL3_SET_ADRE, LEVEL3_WDV, LEVEL3,
|
||||||
LEVEL1_WDV,
|
LEAF, IDLE, FAULT} statetype;
|
||||||
LEVEL1,
|
|
||||||
LEVEL2_SET_ADRE,
|
|
||||||
LEVEL2_WDV,
|
|
||||||
LEVEL2,
|
|
||||||
LEVEL3_SET_ADRE,
|
|
||||||
LEVEL3_WDV,
|
|
||||||
LEVEL3,
|
|
||||||
LEAF,
|
|
||||||
IDLE,
|
|
||||||
FAULT} statetype;
|
|
||||||
|
|
||||||
statetype WalkerState, NextWalkerState, PreviousWalkerState;
|
statetype WalkerState, NextWalkerState, PreviousWalkerState;
|
||||||
|
|
||||||
@ -117,13 +107,8 @@ module pagetablewalker
|
|||||||
logic SelDataTranslation;
|
logic SelDataTranslation;
|
||||||
logic AnyTLBMissM;
|
logic AnyTLBMissM;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
|
assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
|
||||||
|
|
||||||
assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0];
|
assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0];
|
||||||
|
|
||||||
assign MemStore = MemRWM[0];
|
assign MemStore = MemRWM[0];
|
||||||
|
|
||||||
// Prefer data address translations over instruction address translations
|
// Prefer data address translations over instruction address translations
|
||||||
@ -137,7 +122,6 @@ module pagetablewalker
|
|||||||
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache
|
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache
|
||||||
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
|
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
|
||||||
|
|
||||||
|
|
||||||
assign AnyTLBMissM = DTLBMissM | ITLBMissF;
|
assign AnyTLBMissM = DTLBMissM | ITLBMissF;
|
||||||
|
|
||||||
assign StartWalk = (WalkerState == IDLE) & AnyTLBMissM;
|
assign StartWalk = (WalkerState == IDLE) & AnyTLBMissM;
|
||||||
@ -161,6 +145,14 @@ module pagetablewalker
|
|||||||
assign DTLBWriteM = (WalkerState == LEAF) & DTLBMissMQ;
|
assign DTLBWriteM = (WalkerState == LEAF) & DTLBMissMQ;
|
||||||
assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBMissMQ;
|
assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBMissMQ;
|
||||||
|
|
||||||
|
assign WalkerInstrPageFaultF = (WalkerState == FAULT) & ~DTLBMissMQ; //*** why do these only get raised on TLB misses? Should they always fault even for ADpagefaults, invalid addresses,etc??
|
||||||
|
assign WalkerLoadPageFaultM = (WalkerState == FAULT) & DTLBMissMQ & ~MemStore;
|
||||||
|
assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBMissMQ & MemStore;
|
||||||
|
|
||||||
|
assign PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux?
|
||||||
|
((PreviousWalkerState == LEVEL2) ? 2'b10 :
|
||||||
|
((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
||||||
|
|
||||||
// *** is there a way to speed up HPTW?
|
// *** is there a way to speed up HPTW?
|
||||||
|
|
||||||
// TranslationPAdr mux
|
// TranslationPAdr mux
|
||||||
@ -218,11 +210,6 @@ module pagetablewalker
|
|||||||
always_comb begin
|
always_comb begin
|
||||||
PRegEn = 1'b0;
|
PRegEn = 1'b0;
|
||||||
HPTWRead = 1'b0;
|
HPTWRead = 1'b0;
|
||||||
PageType = '0;
|
|
||||||
|
|
||||||
WalkerInstrPageFaultF = 1'b0;
|
|
||||||
WalkerLoadPageFaultM = 1'b0;
|
|
||||||
WalkerStorePageFaultM = 1'b0;
|
|
||||||
|
|
||||||
case (WalkerState)
|
case (WalkerState)
|
||||||
IDLE: if (AnyTLBMissM & SvMode == `SV32) NextWalkerState = LEVEL1_SET_ADRE;
|
IDLE: if (AnyTLBMissM & SvMode == `SV32) NextWalkerState = LEVEL1_SET_ADRE;
|
||||||
@ -254,27 +241,13 @@ module pagetablewalker
|
|||||||
end
|
end
|
||||||
LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF;
|
LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF;
|
||||||
else NextWalkerState = FAULT;
|
else NextWalkerState = FAULT;
|
||||||
LEAF: begin
|
LEAF: NextWalkerState = IDLE;
|
||||||
NextWalkerState = IDLE;
|
FAULT: NextWalkerState = IDLE;
|
||||||
PageType = (PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux?
|
|
||||||
end
|
|
||||||
|
|
||||||
FAULT: begin
|
|
||||||
NextWalkerState = IDLE;
|
|
||||||
WalkerInstrPageFaultF = ~DTLBMissMQ;
|
|
||||||
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
|
|
||||||
WalkerStorePageFaultM = DTLBMissMQ && MemStore;
|
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Assign outputs to ahblite
|
// Assign outputs to ahblite
|
||||||
// *** Currently truncate address to 32 bits. This must be changed if
|
// *** Currently truncate address to 32 bits. This must be changed if
|
||||||
// we support larger physical address spaces
|
// we support larger physical address spaces
|
||||||
@ -294,11 +267,6 @@ module pagetablewalker
|
|||||||
always_comb begin
|
always_comb begin
|
||||||
PRegEn = 1'b0;
|
PRegEn = 1'b0;
|
||||||
HPTWRead = 1'b0;
|
HPTWRead = 1'b0;
|
||||||
PageType = '0;
|
|
||||||
|
|
||||||
WalkerInstrPageFaultF = 1'b0;
|
|
||||||
WalkerLoadPageFaultM = 1'b0;
|
|
||||||
WalkerStorePageFaultM = 1'b0;
|
|
||||||
|
|
||||||
case (WalkerState)
|
case (WalkerState)
|
||||||
IDLE: if (AnyTLBMissM) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE;
|
IDLE: if (AnyTLBMissM) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE;
|
||||||
@ -354,18 +322,8 @@ module pagetablewalker
|
|||||||
LEVEL0:
|
LEVEL0:
|
||||||
if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF;
|
if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF;
|
||||||
else NextWalkerState = FAULT;
|
else NextWalkerState = FAULT;
|
||||||
LEAF: begin
|
LEAF: NextWalkerState = IDLE;
|
||||||
PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux?
|
FAULT: NextWalkerState = IDLE;
|
||||||
((PreviousWalkerState == LEVEL2) ? 2'b10 :
|
|
||||||
((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00));
|
|
||||||
NextWalkerState = IDLE;
|
|
||||||
end
|
|
||||||
FAULT: begin // *** why do these only get raised on TLB misses? Should they always fault?
|
|
||||||
NextWalkerState = IDLE;
|
|
||||||
WalkerInstrPageFaultF = ~DTLBMissMQ;
|
|
||||||
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
|
|
||||||
WalkerStorePageFaultM = DTLBMissMQ && MemStore;
|
|
||||||
end
|
|
||||||
default: NextWalkerState = IDLE; // should never be reached
|
default: NextWalkerState = IDLE; // should never be reached
|
||||||
|
|
||||||
endcase
|
endcase
|
||||||
|
Loading…
Reference in New Issue
Block a user