forked from Github_Repos/cvw
more cleaning up FSM
This commit is contained in:
parent
6d8a6eeba0
commit
bd270acdb6
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user