more cleaning up FSM

This commit is contained in:
David Harris 2021-07-17 04:35:51 -04:00
parent 6d8a6eeba0
commit bd270acdb6

View File

@ -207,10 +207,6 @@ module pagetablewalker
end end
// generate // generate
if (`XLEN == 32) begin if (`XLEN == 32) begin
// *** make sure 32/34 bit addresses are being handled properly
//logic [9:0] VPN1, VPN0;
//assign VPN1 = TranslationVAdr[31:22];
//assign VPN0 = TranslationVAdr[21:12];
// A megapage is a Level 1 leaf page. This page must have zero PPN[0]. // A megapage is a Level 1 leaf page. This page must have zero PPN[0].
assign MegapageMisaligned = |(CurrentPPN[9:0]); assign MegapageMisaligned = |(CurrentPPN[9:0]);
@ -317,130 +313,57 @@ module pagetablewalker
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;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
LEVEL3_SET_ADRE: NextWalkerState = LEVEL3_WDV;
LEVEL3_SET_ADRE: begin
NextWalkerState = LEVEL3_WDV;
//TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
end
LEVEL3_WDV: begin LEVEL3_WDV: begin
//TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
HPTWRead = 1'b1; HPTWRead = 1'b1;
if (HPTWStall) begin if (HPTWStall) NextWalkerState = LEVEL3_WDV;
NextWalkerState = LEVEL3_WDV; else begin
end else begin NextWalkerState = LEVEL3;
NextWalkerState = LEVEL3; PRegEn = 1'b1;
PRegEn = 1'b1;
end end
end end
LEVEL3:
LEVEL3: begin if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) NextWalkerState = LEAF;
if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) begin else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_SET_ADRE;
NextWalkerState = LEAF; else NextWalkerState = FAULT;
//TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; LEVEL2_SET_ADRE: NextWalkerState = LEVEL2_WDV;
end
else if (ValidPTE && ~LeafPTE) begin
NextWalkerState = LEVEL2_SET_ADRE;
//TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
end else begin
NextWalkerState = FAULT;
end
end
LEVEL2_SET_ADRE: begin
NextWalkerState = LEVEL2_WDV;
//TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
end
LEVEL2_WDV: begin LEVEL2_WDV: begin
//TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
HPTWRead = 1'b1; HPTWRead = 1'b1;
if (HPTWStall) begin if (HPTWStall) NextWalkerState = LEVEL2_WDV;
NextWalkerState = LEVEL2_WDV; else begin
end else begin NextWalkerState = LEVEL2;
NextWalkerState = LEVEL2; PRegEn = 1'b1;
PRegEn = 1'b1;
end end
end end
LEVEL2:
LEVEL2: begin if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) NextWalkerState = LEAF;
// *** <FUTURE WORK> According to the architecture, we should else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_SET_ADRE;
// fault upon finding a superpage that is misaligned or has 0 else NextWalkerState = FAULT;
// access bit. The following commented line of code is LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV;
// supposed to perform that check. However, it is untested.
if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) begin
NextWalkerState = LEAF;
//TranslationPAdr = TranslationVAdr[`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 = LEVEL1_SET_ADRE;
//TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
end else begin
NextWalkerState = FAULT;
end
end
LEVEL1_SET_ADRE: begin
NextWalkerState = LEVEL1_WDV;
//TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
end
LEVEL1_WDV: begin LEVEL1_WDV: begin
//TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
HPTWRead = 1'b1; HPTWRead = 1'b1;
if (HPTWStall) begin if (HPTWStall) NextWalkerState = LEVEL1_WDV;
NextWalkerState = LEVEL1_WDV; else begin
end else begin NextWalkerState = LEVEL1;
NextWalkerState = LEVEL1; PRegEn = 1'b1;
PRegEn = 1'b1;
end end
end end
LEVEL1:
LEVEL1: begin if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) NextWalkerState = LEAF;
// *** <FUTURE WORK> According to the architecture, we should else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_SET_ADRE;
// fault upon finding a superpage that is misaligned or has 0 else NextWalkerState = FAULT;
// access bit. The following commented line of code is LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV;
// supposed to perform that check. However, it is untested.
if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) begin
NextWalkerState = LEAF;
//TranslationPAdr = TranslationVAdr[`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_SET_ADRE;
//TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
end else begin
NextWalkerState = FAULT;
end
end
LEVEL0_SET_ADRE: begin
NextWalkerState = LEVEL0_WDV;
//TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
end
LEVEL0_WDV: begin LEVEL0_WDV: begin
//TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
HPTWRead = 1'b1; HPTWRead = 1'b1;
if (HPTWStall) begin if (HPTWStall) NextWalkerState = LEVEL0_WDV;
NextWalkerState = LEVEL0_WDV; else begin
end else begin NextWalkerState = LEVEL0;
NextWalkerState = LEVEL0; PRegEn = 1'b1;
PRegEn = 1'b1;
end end
end end
LEVEL0:
LEVEL0: begin if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF;
if (ValidPTE && LeafPTE && ~ADPageFault) begin else NextWalkerState = FAULT;
NextWalkerState = LEAF;
//TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
end else begin
NextWalkerState = FAULT;
end
end
LEAF: begin LEAF: begin
PageTableEntry = CurrentPTE; PageTableEntry = CurrentPTE;
PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux? PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux?
@ -448,12 +371,9 @@ module pagetablewalker
((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00)); ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00));
DTLBWriteM = DTLBMissMQ; DTLBWriteM = DTLBMissMQ;
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
//TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
NextWalkerState = IDLE; NextWalkerState = IDLE;
end end
FAULT: begin // *** why do these only get raised on TLB misses? Should they always fault?
FAULT: begin
//SelPTW = 1'b0;
NextWalkerState = IDLE; NextWalkerState = IDLE;
WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerInstrPageFaultF = ~DTLBMissMQ;
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
@ -467,15 +387,8 @@ module pagetablewalker
endcase endcase
end end
// *** Major issue. We need the full virtual address here.
// When the TLB's are update it use use the orignal address
// *** Currently truncate address to 32 bits. This must be changed if
// we support larger physical address spaces
assign HPTWPAdrE = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]}; assign HPTWPAdrE = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]};
end end
//endgenerate
end else begin end else begin
assign HPTWPAdrE = 0; assign HPTWPAdrE = 0;
assign HPTWRead = 0; assign HPTWRead = 0;