mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
commit
9cfbc4aec0
@ -123,6 +123,9 @@ module lsu
|
|||||||
logic HPTWStall;
|
logic HPTWStall;
|
||||||
logic [`XLEN-1:0] HPTWPAdrE;
|
logic [`XLEN-1:0] HPTWPAdrE;
|
||||||
logic [`XLEN-1:0] HPTWPAdrM;
|
logic [`XLEN-1:0] HPTWPAdrM;
|
||||||
|
logic [`XLEN-1:0] TranslationVAdr;
|
||||||
|
logic [`PA_BITS-1:0] TranslationPAdr;
|
||||||
|
logic UseTranslationVAdr;
|
||||||
logic HPTWRead;
|
logic HPTWRead;
|
||||||
logic [1:0] MemRWMtoDCache;
|
logic [1:0] MemRWMtoDCache;
|
||||||
logic [2:0] Funct3MtoDCache;
|
logic [2:0] Funct3MtoDCache;
|
||||||
@ -162,15 +165,22 @@ module lsu
|
|||||||
.DTLBWriteM(DTLBWriteM),
|
.DTLBWriteM(DTLBWriteM),
|
||||||
.HPTWReadPTE(HPTWReadPTE),
|
.HPTWReadPTE(HPTWReadPTE),
|
||||||
.HPTWStall(HPTWStall),
|
.HPTWStall(HPTWStall),
|
||||||
.HPTWPAdrE(HPTWPAdrE),
|
.TranslationVAdr,
|
||||||
.HPTWPAdrM(HPTWPAdrM),
|
.TranslationPAdr,
|
||||||
|
.UseTranslationVAdr,
|
||||||
.HPTWRead(HPTWRead),
|
.HPTWRead(HPTWRead),
|
||||||
.SelPTW(SelPTW),
|
.SelPTW(SelPTW),
|
||||||
.WalkerInstrPageFaultF(WalkerInstrPageFaultF),
|
.WalkerInstrPageFaultF(WalkerInstrPageFaultF),
|
||||||
.WalkerLoadPageFaultM(WalkerLoadPageFaultM),
|
.WalkerLoadPageFaultM(WalkerLoadPageFaultM),
|
||||||
.WalkerStorePageFaultM(WalkerStorePageFaultM));
|
.WalkerStorePageFaultM(WalkerStorePageFaultM));
|
||||||
|
|
||||||
// assign PageTableEntryF = PTE;
|
logic [`XLEN-1:0] TranslationPAdrXLEN;
|
||||||
|
generate // *** needs fixing about truncation dh 7/17/21
|
||||||
|
if (`XLEN == 32) assign TranslationPAdrXLEN = TranslationPAdr[31:0];
|
||||||
|
else assign TranslationPAdrXLEN = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]};
|
||||||
|
endgenerate
|
||||||
|
mux2 #(`XLEN) HPTWPAdrMux(TranslationPAdrXLEN, TranslationVAdr, UseTranslationVAdr, HPTWPAdrE); // *** misleading to call it PAdr, bad because some bits have been truncated
|
||||||
|
flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM);
|
||||||
|
|
||||||
assign WalkerPageFaultM = WalkerStorePageFaultM | WalkerLoadPageFaultM;
|
assign WalkerPageFaultM = WalkerStorePageFaultM | WalkerLoadPageFaultM;
|
||||||
|
|
||||||
|
@ -31,46 +31,29 @@
|
|||||||
|
|
||||||
module pagetablewalker
|
module pagetablewalker
|
||||||
(
|
(
|
||||||
// Control signals
|
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic [`XLEN-1:0] SATP_REGW,
|
input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table
|
||||||
|
input logic [`XLEN-1:0] PCF, MemAdrM, // addresses to translate
|
||||||
// Signals from TLBs (addresses to translate)
|
input logic ITLBMissF, DTLBMissM, // TLB Miss
|
||||||
input logic [`XLEN-1:0] PCF, MemAdrM,
|
input logic [1:0] MemRWM, // 10 = read, 01 = write
|
||||||
input logic ITLBMissF, DTLBMissM,
|
input logic [`XLEN-1:0] HPTWReadPTE, // page table entry from LSU
|
||||||
input logic [1:0] MemRWM,
|
input logic HPTWStall, // stall from LSU
|
||||||
|
output logic [`XLEN-1:0] PTE, // page table entry to TLBs
|
||||||
// Outputs to the TLBs (PTEs to write)
|
output logic [1:0] PageType, // page type to TLBs
|
||||||
output logic [`XLEN-1:0] PTE, //PageTableEntryM,
|
output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
|
||||||
output logic [1:0] PageType,
|
output logic SelPTW, // LSU Arbiter should select signals from the PTW rather than from the IEU
|
||||||
output logic ITLBWriteF, DTLBWriteM,
|
output logic [`XLEN-1:0] TranslationVAdr,
|
||||||
output logic SelPTW,
|
output logic [`PA_BITS-1:0] TranslationPAdr,
|
||||||
|
output logic UseTranslationVAdr,
|
||||||
|
output logic HPTWRead, // HPTW requesting to read memory
|
||||||
// *** modify to send to LSU // *** KMG: These are inputs/results from the ahblite whose addresses should have already been checked, so I don't think they need to be sent through the LSU
|
output logic WalkerInstrPageFaultF, WalkerLoadPageFaultM,WalkerStorePageFaultM // faults
|
||||||
input logic [`XLEN-1:0] HPTWReadPTE,
|
);
|
||||||
input logic HPTWStall,
|
|
||||||
|
|
||||||
// *** modify to send to LSU
|
|
||||||
output logic [`XLEN-1:0] HPTWPAdrE, // this probalby should be `PA_BITS wide
|
|
||||||
output logic [`XLEN-1:0] HPTWPAdrM, // this probalby should be `PA_BITS wide
|
|
||||||
output logic HPTWRead,
|
|
||||||
|
|
||||||
|
|
||||||
// Faults
|
|
||||||
output logic WalkerInstrPageFaultF,
|
|
||||||
output logic WalkerLoadPageFaultM,
|
|
||||||
output logic WalkerStorePageFaultM
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if (`MEM_VIRTMEM) begin
|
if (`MEM_VIRTMEM) begin
|
||||||
// Internal signals
|
// Internal signals
|
||||||
logic DTLBWalk; // register TLBs translation miss requests
|
logic DTLBWalk; // register TLBs translation miss requests
|
||||||
logic [`PPN_BITS-1:0] BasePageTablePPN;
|
logic [`PPN_BITS-1:0] BasePageTablePPN;
|
||||||
logic [`XLEN-1:0] TranslationVAdr;
|
|
||||||
logic [`PA_BITS-1:0] TranslationPAdr;
|
|
||||||
logic [`PPN_BITS-1:0] CurrentPPN;
|
logic [`PPN_BITS-1:0] CurrentPPN;
|
||||||
logic MemWrite;
|
logic MemWrite;
|
||||||
logic Executable, Writable, Readable, Valid;
|
logic Executable, Writable, Readable, Valid;
|
||||||
@ -96,13 +79,12 @@ module pagetablewalker
|
|||||||
|
|
||||||
// Determine which address to translate
|
// Determine which address to translate
|
||||||
assign TranslationVAdr = DTLBWalk ? MemAdrM : PCF;
|
assign TranslationVAdr = DTLBWalk ? MemAdrM : PCF;
|
||||||
|
|
||||||
flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM);
|
|
||||||
flopenrc #(1) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, DTLBMissM, DTLBWalk);
|
|
||||||
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
|
|
||||||
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, PTE); // Capture page table entry from data cache
|
|
||||||
assign CurrentPPN = PTE[`PPN_BITS+9:10];
|
assign CurrentPPN = PTE[`PPN_BITS+9:10];
|
||||||
|
|
||||||
|
// State flops
|
||||||
|
flopenrc #(1) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, DTLBMissM, DTLBWalk); // track whether walk is for DTLB or ITLB
|
||||||
|
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, PTE); // Capture page table entry from data cache
|
||||||
|
|
||||||
// Assign PTE descriptors common across all XLEN values
|
// Assign PTE descriptors common across all XLEN values
|
||||||
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
|
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
|
||||||
assign {Executable, Writable, Readable, Valid} = PTE[3:0];
|
assign {Executable, Writable, Readable, Valid} = PTE[3:0];
|
||||||
@ -119,6 +101,7 @@ module pagetablewalker
|
|||||||
assign SelPTW = (WalkerState != IDLE) & (WalkerState != FAULT);
|
assign SelPTW = (WalkerState != IDLE) & (WalkerState != FAULT);
|
||||||
assign DTLBWriteM = (WalkerState == LEAF) & DTLBWalk;
|
assign DTLBWriteM = (WalkerState == LEAF) & DTLBWalk;
|
||||||
assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBWalk;
|
assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBWalk;
|
||||||
|
assign UseTranslationVAdr = (NextWalkerState == LEAF) || (WalkerState == LEAF);
|
||||||
|
|
||||||
// Raise faults. DTLBMiss
|
// Raise faults. DTLBMiss
|
||||||
assign WalkerInstrPageFaultF = (WalkerState == FAULT) & ~DTLBWalk;
|
assign WalkerInstrPageFaultF = (WalkerState == FAULT) & ~DTLBWalk;
|
||||||
@ -136,49 +119,31 @@ module pagetablewalker
|
|||||||
default: NextPageType = PageType;
|
default: NextPageType = PageType;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
// TranslationPAdr mux
|
// TranslationPAdr muxing
|
||||||
if (`XLEN==32) begin
|
if (`XLEN==32) begin // RV32
|
||||||
logic [9:0] VPN1, VPN0;
|
logic [9:0] VPN;
|
||||||
assign VPN1 = TranslationVAdr[31:22];
|
logic [`PPN_BITS-1:0] PPN;
|
||||||
assign VPN0 = TranslationVAdr[21:12];
|
assign VPN = ((WalkerState == LEVEL1_SET_ADR) | (WalkerState == LEVEL1_READ)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state
|
||||||
|
assign PPN = ((WalkerState == LEVEL1_SET_ADR) | (WalkerState == LEVEL1_READ)) ? BasePageTablePPN : CurrentPPN;
|
||||||
|
assign TranslationPAdr = {PPN, VPN, 2'b00};
|
||||||
|
end else begin // RV64
|
||||||
|
logic [8:0] VPN;
|
||||||
|
logic [`PPN_BITS-1:0] PPN;
|
||||||
always_comb
|
always_comb
|
||||||
case (WalkerState)
|
case (WalkerState) // select VPN field based on HPTW state
|
||||||
LEVEL1_SET_ADR: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
|
LEVEL3_SET_ADR: VPN = TranslationVAdr[47:39];
|
||||||
LEVEL1_READ: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
|
LEVEL3_READ: VPN = TranslationVAdr[47:39];
|
||||||
LEVEL1: if (NextWalkerState == LEAF) TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; // ***check this and similar in LEVEL0 and LEAF
|
LEVEL3: VPN = TranslationVAdr[38:30];
|
||||||
else TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
LEVEL2_SET_ADR: VPN = TranslationVAdr[38:30];
|
||||||
LEVEL0_SET_ADR: TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
LEVEL2_READ: VPN = TranslationVAdr[38:30];
|
||||||
LEVEL0_READ: TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
LEVEL2: VPN = TranslationVAdr[29:21];
|
||||||
LEVEL0: TranslationPAdr = {2'b00, TranslationVAdr[31:0]};
|
LEVEL1_SET_ADR: VPN = TranslationVAdr[29:21];
|
||||||
LEAF: TranslationPAdr = {2'b00, TranslationVAdr[31:0]};
|
LEVEL1_READ: VPN = TranslationVAdr[29:21];
|
||||||
default: TranslationPAdr = 0; // cause seg fault if this is improperly used
|
default: VPN = TranslationVAdr[20:12];
|
||||||
endcase
|
|
||||||
end else begin
|
|
||||||
logic [8:0] VPN3, VPN2, VPN1, VPN0;
|
|
||||||
assign VPN3 = TranslationVAdr[47:39];
|
|
||||||
assign VPN2 = TranslationVAdr[38:30];
|
|
||||||
assign VPN1 = TranslationVAdr[29:21];
|
|
||||||
assign VPN0 = TranslationVAdr[20:12];
|
|
||||||
always_comb
|
|
||||||
case (WalkerState)
|
|
||||||
LEVEL3_SET_ADR: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
|
|
||||||
LEVEL3_READ: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000};
|
|
||||||
LEVEL3: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
|
|
||||||
else TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
|
|
||||||
LEVEL2_SET_ADR: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
|
|
||||||
LEVEL2_READ: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000};
|
|
||||||
LEVEL2: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
|
|
||||||
else TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
|
|
||||||
LEVEL1_SET_ADR: TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
|
|
||||||
LEVEL1_READ: TranslationPAdr = {CurrentPPN, VPN1, 3'b000};
|
|
||||||
LEVEL1: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
|
|
||||||
else TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
|
||||||
LEVEL0_SET_ADR: TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
|
||||||
LEVEL0_READ: TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
|
||||||
LEVEL0: TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
|
|
||||||
LEAF: TranslationPAdr = TranslationVAdr[`PA_BITS-1:0];
|
|
||||||
default: TranslationPAdr = 0; // cause seg fault if this is improperly used
|
|
||||||
endcase
|
endcase
|
||||||
|
assign PPN = ((WalkerState == LEVEL3_SET_ADR) | (WalkerState == LEVEL3_READ) |
|
||||||
|
(SvMode != `SV48 & ((WalkerState == LEVEL2_SET_ADR) | (WalkerState == LEVEL2_READ)))) ? BasePageTablePPN : CurrentPPN;
|
||||||
|
assign TranslationPAdr = {PPN, VPN, 3'b000};
|
||||||
end
|
end
|
||||||
|
|
||||||
if (`XLEN == 32) begin
|
if (`XLEN == 32) begin
|
||||||
@ -186,17 +151,18 @@ module pagetablewalker
|
|||||||
assign TerapageMisaligned = 0; // not applicable
|
assign TerapageMisaligned = 0; // not applicable
|
||||||
assign GigapageMisaligned = 0; // not applicable
|
assign GigapageMisaligned = 0; // not applicable
|
||||||
assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
|
assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
|
||||||
assign HPTWPAdrE = TranslationPAdr[31:0]; // ***not right?
|
|
||||||
end else begin
|
end else begin
|
||||||
assign InitialWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADR : LEVEL2_SET_ADR;
|
assign InitialWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADR : LEVEL2_SET_ADR;
|
||||||
assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0
|
assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0
|
||||||
assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0
|
assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0
|
||||||
assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0
|
assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0
|
||||||
assign HPTWPAdrE = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]};
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// Page Table Walker FSM
|
// Page Table Walker FSM
|
||||||
// ***Is there a w ay to reduce the number of cycles needed to do the walk?
|
// If the setup time on the D$ RAM is short, it should be possible to merge the LEVELx_READ and LEVELx states
|
||||||
|
// to decrease the latency of the HPTW. However, if the D$ is a cycle limiter, it's better to leave the
|
||||||
|
// HPTW as shown below to keep the D$ setup time out of the critical path.
|
||||||
|
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
|
||||||
always_comb
|
always_comb
|
||||||
case (WalkerState)
|
case (WalkerState)
|
||||||
IDLE: if (StartWalk) NextWalkerState = InitialWalkerState;
|
IDLE: if (StartWalk) NextWalkerState = InitialWalkerState;
|
||||||
@ -231,14 +197,10 @@ module pagetablewalker
|
|||||||
NextWalkerState = IDLE; // should never be reached
|
NextWalkerState = IDLE; // should never be reached
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end else begin
|
end else begin // No Virtual memory supported; tie HPTW outputs to 0
|
||||||
assign HPTWPAdrE = 0;
|
assign HPTWRead = 0; assign SelPTW = 0;
|
||||||
assign HPTWRead = 0;
|
assign WalkerInstrPageFaultF = 0; assign WalkerLoadPageFaultM = 0; assign WalkerStorePageFaultM = 0;
|
||||||
assign WalkerInstrPageFaultF = 0;
|
assign TranslationVAdr = 0; assign TranslationPAdr = 0; assign UseTranslationVAdr = 0;
|
||||||
assign WalkerLoadPageFaultM = 0;
|
|
||||||
assign WalkerStorePageFaultM = 0;
|
|
||||||
assign SelPTW = 0;
|
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user