Still broken, midway through fixing understanding of how ptw and datacache interact in time especially wrt adrE, adrM, faults, and tlb interaction.

This commit is contained in:
Kip Macsai-Goren 2021-07-15 18:30:29 -04:00
parent 53072d55f3
commit ba5bb12e26
2 changed files with 86 additions and 17 deletions

View File

@ -163,6 +163,8 @@ module dcache
STATE_PTW_READ_MISS_WRITE_CACHE_BLOCK, STATE_PTW_READ_MISS_WRITE_CACHE_BLOCK,
STATE_PTW_READ_MISS_READ_WORD, STATE_PTW_READ_MISS_READ_WORD,
STATE_PTW_READ_MISS_READ_WORD_DELAY, STATE_PTW_READ_MISS_READ_WORD_DELAY,
STATE_PTW_ACCESS_AFTER_WALK,
STATE_PTW_UPDATE_TLB,
STATE_UNCACHED_WRITE, STATE_UNCACHED_WRITE,
STATE_UNCACHED_WRITE_DONE, STATE_UNCACHED_WRITE_DONE,
@ -590,8 +592,8 @@ module dcache
// now all output connect to PTW instead of CPU. // now all output connect to PTW instead of CPU.
CommittedM = 1'b1; CommittedM = 1'b1;
// return to ready if page table walk completed. // return to ready if page table walk completed.
if(DTLBWriteM) begin if (DTLBWriteM) begin
NextState = STATE_READY; NextState = STATE_PTW_ACCESS_AFTER_WALK;
// read hit valid cached // read hit valid cached
end else if(MemRWM[1] & CacheableM & ~ExceptionM & CacheHit) begin end else if(MemRWM[1] & CacheableM & ~ExceptionM & CacheHit) begin
@ -652,6 +654,59 @@ module dcache
CommittedM = 1'b1; CommittedM = 1'b1;
end end
STATE_PTW_ACCESS_AFTER_WALK: begin
SelAdrM = 1'b1;
// amo hit
if(|AtomicM & CacheableM & ~(ExceptionM | PendingInterruptM) & CacheHit & ~DTLBMissM) begin
NextState = STATE_AMO_UPDATE;
DCacheStall = 1'b1;
if(StallW) NextState = STATE_CPU_BUSY;
else NextState = STATE_AMO_UPDATE;
end
// read hit valid cached
else if(MemRWM[1] & CacheableM & ~(ExceptionM | PendingInterruptM) & CacheHit & ~DTLBMissM) begin
DCacheStall = 1'b0;
if(StallW) NextState = STATE_CPU_BUSY;
else NextState = STATE_READY;
end
// write hit valid cached
else if (MemRWM[0] & CacheableM & ~(ExceptionM | PendingInterruptM) & CacheHit & ~DTLBMissM) begin
DCacheStall = 1'b0;
SRAMWordWriteEnableM = 1'b1;
SetDirtyM = 1'b1;
if(StallW) NextState = STATE_CPU_BUSY;
else NextState = STATE_READY;
end
// read or write miss valid cached
else if((|MemRWM) & CacheableM & ~(ExceptionM | PendingInterruptM) & ~CacheHit & ~DTLBMissM) begin
NextState = STATE_MISS_FETCH_WDV;
CntReset = 1'b1;
DCacheStall = 1'b1;
end
// uncached write
else if(MemRWM[0] & ~CacheableM & ~ExceptionM & ~DTLBMissM) begin
NextState = STATE_UNCACHED_WRITE;
CntReset = 1'b1;
DCacheStall = 1'b1;
AHBWrite = 1'b1;
end
// uncached read
else if(MemRWM[1] & ~CacheableM & ~ExceptionM & ~DTLBMissM) begin
NextState = STATE_UNCACHED_READ;
CntReset = 1'b1;
DCacheStall = 1'b1;
AHBRead = 1'b1;
end
// fault
else if(AnyCPUReqM & (ExceptionM | PendingInterruptM) & ~DTLBMissM) begin
NextState = STATE_READY;
end
else NextState = STATE_READY;
end
STATE_CPU_BUSY : begin STATE_CPU_BUSY : begin
CommittedM = 1'b1; CommittedM = 1'b1;
if(StallW) NextState = STATE_CPU_BUSY; if(StallW) NextState = STATE_CPU_BUSY;

View File

@ -86,6 +86,7 @@ module pagetablewalker
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;
logic DTLBWriteM_d;
// PTE Control Bits // PTE Control Bits
logic Dirty, Accessed, Global, User, logic Dirty, Accessed, Global, User,
@ -122,6 +123,18 @@ module pagetablewalker
.d(HPTWPAdrE), .d(HPTWPAdrE),
.q(HPTWPAdrM)); .q(HPTWPAdrM));
flop #(2) PageTypeReg(.clk(clk),
.d(PageType),
.q(PageTypeM));
flop #(`XLEN) PageTableEntryReg(.clk(clk),
.d(PageTableEntry),
.q(PageTableEntryM));
flop #(1) DTLBWriteReg(.clk(clk),
.d(DTLBWriteM_d),
.q(DTLBWriteM));
flop #(1) HPTWReadMReg(.clk(clk), flop #(1) HPTWReadMReg(.clk(clk),
.d(HPTWReadE), .d(HPTWReadE),
.q(HPTWReadM)); .q(HPTWReadM));
@ -157,9 +170,9 @@ module pagetablewalker
assign StartWalk = WalkerState == IDLE && (DTLBMissM | ITLBMissF); assign StartWalk = WalkerState == IDLE && (DTLBMissM | ITLBMissF);
assign EndWalk = WalkerState == LEAF || assign EndWalk = WalkerState == LEAF ||
//(WalkerState == LEVEL0 && ValidPTE && LeafPTE && ~AccessAlert) || //(WalkerState == LEVEL0 && ValidPTE && LeafPTE && ~AccessAlert) ||
(WalkerState == LEVEL1 && ValidPTE && LeafPTE && ~AccessAlert) || //(WalkerState == LEVEL1 && ValidPTE && LeafPTE && ~AccessAlert) ||
(WalkerState == LEVEL2 && ValidPTE && LeafPTE && ~AccessAlert) || //(WalkerState == LEVEL2 && ValidPTE && LeafPTE && ~AccessAlert) ||
(WalkerState == LEVEL3 && ValidPTE && LeafPTE && ~AccessAlert) || //(WalkerState == LEVEL3 && ValidPTE && LeafPTE && ~AccessAlert) ||
(WalkerState == FAULT); (WalkerState == FAULT);
assign HPTWTranslate = (DTLBMissMQ | ITLBMissFQ); assign HPTWTranslate = (DTLBMissMQ | ITLBMissFQ);
@ -176,9 +189,9 @@ module pagetablewalker
// Assign specific outputs to general outputs // Assign specific outputs to general outputs
assign PageTableEntryF = PageTableEntry; assign PageTableEntryF = PageTableEntry;
assign PageTableEntryM = PageTableEntry; //assign PageTableEntryM = PageTableEntry;
assign PageTypeF = PageType; assign PageTypeF = PageType;
assign PageTypeM = PageType; //assign PageTypeM = PageType;
// generate // generate
@ -198,7 +211,7 @@ module pagetablewalker
HPTWReadE = 1'b0; HPTWReadE = 1'b0;
PageTableEntry = '0; PageTableEntry = '0;
PageType = '0; PageType = '0;
DTLBWriteM = '0; DTLBWriteM_d = '0;
ITLBWriteF = '0; ITLBWriteF = '0;
WalkerInstrPageFaultF = 1'b0; WalkerInstrPageFaultF = 1'b0;
@ -240,7 +253,7 @@ module pagetablewalker
NextWalkerState = LEAF; NextWalkerState = LEAF;
PageTableEntry = CurrentPTE; PageTableEntry = CurrentPTE;
PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux? PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux?
DTLBWriteM = DTLBMissMQ; DTLBWriteM_d = DTLBMissMQ;
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; TranslationPAdr = {2'b00, TranslationVAdr[31:0]};
end end
@ -270,7 +283,7 @@ module pagetablewalker
NextWalkerState = LEAF; NextWalkerState = LEAF;
PageTableEntry = CurrentPTE; PageTableEntry = CurrentPTE;
PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00; PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00;
DTLBWriteM = DTLBMissMQ; DTLBWriteM_d = DTLBMissMQ;
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; TranslationPAdr = {2'b00, TranslationVAdr[31:0]};
end else begin end else begin
@ -281,6 +294,7 @@ module pagetablewalker
LEAF: begin LEAF: begin
NextWalkerState = IDLE; NextWalkerState = IDLE;
end end
FAULT: begin FAULT: begin
NextWalkerState = IDLE; NextWalkerState = IDLE;
WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerInstrPageFaultF = ~DTLBMissMQ;
@ -342,7 +356,7 @@ module pagetablewalker
HPTWReadE = 1'b0; HPTWReadE = 1'b0;
PageTableEntry = '0; PageTableEntry = '0;
PageType = '0; PageType = '0;
DTLBWriteM = '0; DTLBWriteM_d = '0;
ITLBWriteF = '0; ITLBWriteF = '0;
WalkerInstrPageFaultF = 1'b0; WalkerInstrPageFaultF = 1'b0;
@ -395,7 +409,7 @@ module pagetablewalker
PageType = (WalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux? PageType = (WalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux?
((WalkerState == LEVEL2) ? 2'b10 : ((WalkerState == LEVEL2) ? 2'b10 :
((WalkerState == LEVEL1) ? 2'b01 : 2'b00)); ((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
DTLBWriteM = DTLBMissMQ; DTLBWriteM_d = DTLBMissMQ;
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
end end
@ -432,7 +446,7 @@ module pagetablewalker
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_d = DTLBMissMQ;
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
end end
@ -469,7 +483,7 @@ module pagetablewalker
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_d = DTLBMissMQ;
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
@ -502,7 +516,7 @@ module pagetablewalker
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_d = DTLBMissMQ;
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
end else begin end else begin