forked from Github_Repos/cvw
Fixed combo loop in between the page table walker and i/dtlb.
This commit is contained in:
parent
aeeaf6d919
commit
c02141697d
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
module pagetablewalker (
|
module pagetablewalker (
|
||||||
// Control signals
|
// Control signals
|
||||||
input logic HCLK, HRESETn,
|
input logic clk, reset,
|
||||||
input logic [`XLEN-1:0] SATP_REGW,
|
input logic [`XLEN-1:0] SATP_REGW,
|
||||||
|
|
||||||
// Signals from TLBs (addresses to translate)
|
// Signals from TLBs (addresses to translate)
|
||||||
@ -73,6 +73,10 @@ module pagetablewalker (
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Internal signals
|
// Internal signals
|
||||||
|
// register TLBs translation miss requests
|
||||||
|
logic [`XLEN-1:0] TranslationVAdrQ;
|
||||||
|
logic ITLBMissFQ, DTLBMissMQ;
|
||||||
|
|
||||||
logic [`PPN_BITS-1:0] BasePageTablePPN;
|
logic [`PPN_BITS-1:0] BasePageTablePPN;
|
||||||
logic [`XLEN-1:0] TranslationVAdr;
|
logic [`XLEN-1:0] TranslationVAdr;
|
||||||
logic [`XLEN-1:0] SavedPTE, CurrentPTE;
|
logic [`XLEN-1:0] SavedPTE, CurrentPTE;
|
||||||
@ -98,8 +102,28 @@ module pagetablewalker (
|
|||||||
assign MemStore = MemRWM[0];
|
assign MemStore = MemRWM[0];
|
||||||
|
|
||||||
// Prefer data address translations over instruction address translations
|
// Prefer data address translations over instruction address translations
|
||||||
assign TranslationVAdr = (DTLBMissM) ? MemAdrM : PCF;
|
assign TranslationVAdr = (DTLBMissM) ? MemAdrM : PCF; // *** need to register TranslationVAdr
|
||||||
assign MMUTranslate = DTLBMissM || ITLBMissF;
|
flopenr #(`XLEN)
|
||||||
|
TranslationVAdrReg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(1'b1), // *** use enable later to save power
|
||||||
|
.d(TranslationVAdr),
|
||||||
|
.q(TranslationVAdrQ));
|
||||||
|
|
||||||
|
flopr #(1)
|
||||||
|
DTLBMissMReg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.d(DTLBMissM),
|
||||||
|
.q(DTLBMissMQ));
|
||||||
|
|
||||||
|
flopr #(1)
|
||||||
|
ITLBMissMReg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.d(ITLBMissF),
|
||||||
|
.q(ITLBMissFQ));
|
||||||
|
|
||||||
|
|
||||||
|
assign MMUTranslate = DTLBMissMQ | ITLBMissFQ;
|
||||||
|
|
||||||
// unswizzle PTE bits
|
// unswizzle PTE bits
|
||||||
assign {Dirty, Accessed, Global, User,
|
assign {Dirty, Accessed, Global, User,
|
||||||
@ -108,7 +132,7 @@ module pagetablewalker (
|
|||||||
// Assign PTE descriptors common across all XLEN values
|
// Assign PTE descriptors common across all XLEN values
|
||||||
assign LeafPTE = Executable | Writable | Readable;
|
assign LeafPTE = Executable | Writable | Readable;
|
||||||
assign ValidPTE = Valid && ~(Writable && ~Readable);
|
assign ValidPTE = Valid && ~(Writable && ~Readable);
|
||||||
assign AccessAlert = ~Accessed || (MemStore && ~Dirty);
|
assign AccessAlert = ~Accessed | (MemStore & ~Dirty);
|
||||||
|
|
||||||
// Assign specific outputs to general outputs
|
// Assign specific outputs to general outputs
|
||||||
assign PageTableEntryF = PageTableEntry;
|
assign PageTableEntryF = PageTableEntry;
|
||||||
@ -129,7 +153,7 @@ localparam LEVEL0 = 3'h0;
|
|||||||
if (`XLEN == 32) begin
|
if (`XLEN == 32) begin
|
||||||
logic [9:0] VPN1, VPN0;
|
logic [9:0] VPN1, VPN0;
|
||||||
|
|
||||||
flopenl #(3) mmureg(HCLK, ~HRESETn, 1'b1, NextWalkerState, IDLE, WalkerState);
|
flopenl #(3) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
|
||||||
|
|
||||||
// State transition logic
|
// State transition logic
|
||||||
always_comb begin
|
always_comb begin
|
||||||
@ -162,8 +186,8 @@ localparam LEVEL0 = 3'h0;
|
|||||||
assign MegapageMisaligned = |(CurrentPPN[9:0]);
|
assign MegapageMisaligned = |(CurrentPPN[9:0]);
|
||||||
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
|
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
|
||||||
|
|
||||||
assign VPN1 = TranslationVAdr[31:22];
|
assign VPN1 = TranslationVAdrQ[31:22];
|
||||||
assign VPN0 = TranslationVAdr[21:12];
|
assign VPN0 = TranslationVAdrQ[21:12];
|
||||||
|
|
||||||
// Assign combinational outputs
|
// Assign combinational outputs
|
||||||
always_comb begin
|
always_comb begin
|
||||||
@ -193,14 +217,14 @@ localparam LEVEL0 = 3'h0;
|
|||||||
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 = DTLBMissM;
|
DTLBWriteM = DTLBMissMQ;
|
||||||
ITLBWriteF = ~DTLBMissM; // 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 = ~DTLBMissM;
|
WalkerInstrPageFaultF = ~DTLBMissMQ;
|
||||||
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
|
||||||
WalkerStorePageFaultM = DTLBMissM && 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
|
||||||
@ -210,7 +234,7 @@ localparam LEVEL0 = 3'h0;
|
|||||||
end
|
end
|
||||||
|
|
||||||
// Capture page table entry from ahblite
|
// Capture page table entry from ahblite
|
||||||
flopenr #(32) ptereg(HCLK, ~HRESETn, MMUReady, MMUReadPTE, SavedPTE);
|
flopenr #(32) ptereg(clk, reset, MMUReady, MMUReadPTE, SavedPTE);
|
||||||
mux2 #(32) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE);
|
mux2 #(32) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE);
|
||||||
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
|
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
|
||||||
|
|
||||||
@ -227,7 +251,7 @@ localparam LEVEL0 = 3'h0;
|
|||||||
|
|
||||||
logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage;
|
logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage;
|
||||||
|
|
||||||
flopenl #(3) mmureg(HCLK, ~HRESETn, 1'b1, NextWalkerState, IDLE, WalkerState);
|
flopenl #(3) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case (WalkerState)
|
case (WalkerState)
|
||||||
@ -294,10 +318,10 @@ localparam LEVEL0 = 3'h0;
|
|||||||
assign BadGigapage = GigapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
|
assign BadGigapage = GigapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
|
||||||
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
|
assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme
|
||||||
|
|
||||||
assign VPN3 = TranslationVAdr[47:39];
|
assign VPN3 = TranslationVAdrQ[47:39];
|
||||||
assign VPN2 = TranslationVAdr[38:30];
|
assign VPN2 = TranslationVAdrQ[38:30];
|
||||||
assign VPN1 = TranslationVAdr[29:21];
|
assign VPN1 = TranslationVAdrQ[29:21];
|
||||||
assign VPN0 = TranslationVAdr[20:12];
|
assign VPN0 = TranslationVAdrQ[20:12];
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
// default values
|
// default values
|
||||||
@ -338,15 +362,15 @@ localparam LEVEL0 = 3'h0;
|
|||||||
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 = DTLBMissM;
|
DTLBWriteM = DTLBMissMQ;
|
||||||
ITLBWriteF = ~DTLBMissM; // Prefer data over instructions
|
ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions
|
||||||
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};
|
||||||
WalkerInstrPageFaultF = ~DTLBMissM;
|
WalkerInstrPageFaultF = ~DTLBMissMQ;
|
||||||
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
|
||||||
WalkerStorePageFaultM = DTLBMissM && 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
|
||||||
@ -356,7 +380,7 @@ localparam LEVEL0 = 3'h0;
|
|||||||
end
|
end
|
||||||
|
|
||||||
// Capture page table entry from ahblite
|
// Capture page table entry from ahblite
|
||||||
flopenr #(`XLEN) ptereg(HCLK, ~HRESETn, MMUReady, MMUReadPTE, SavedPTE);
|
flopenr #(`XLEN) ptereg(clk, reset, MMUReady, MMUReadPTE, SavedPTE);
|
||||||
mux2 #(`XLEN) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE);
|
mux2 #(`XLEN) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE);
|
||||||
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
|
assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user