forked from Github_Repos/cvw
Fixed a bunch of the virtual memory changes. Now supports atomic update of PTE in memory concurrent with TLB.
This commit is contained in:
parent
565ca4e4a3
commit
4cfb601dc8
@ -346,15 +346,15 @@ add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dm
|
|||||||
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPInstrAccessFaultF
|
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPInstrAccessFaultF
|
||||||
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPLoadAccessFaultM
|
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPLoadAccessFaultM
|
||||||
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPStoreAmoAccessFaultM
|
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPStoreAmoAccessFaultM
|
||||||
add wave -noupdate -expand -group lsu -group ptwalker -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/WalkerState
|
add wave -noupdate -expand -group lsu -expand -group ptwalker -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/WalkerState
|
||||||
add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PCF
|
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PCF
|
||||||
add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/HPTWReadPTE
|
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/HPTWReadPTE
|
||||||
add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/HPTWAdr
|
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/HPTWAdr
|
||||||
add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PTE
|
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PTE
|
||||||
add wave -noupdate -expand -group lsu -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBMissF
|
add wave -noupdate -expand -group lsu -expand -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBMissF
|
||||||
add wave -noupdate -expand -group lsu -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBMissM
|
add wave -noupdate -expand -group lsu -expand -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBMissM
|
||||||
add wave -noupdate -expand -group lsu -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBWriteF
|
add wave -noupdate -expand -group lsu -expand -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBWriteF
|
||||||
add wave -noupdate -expand -group lsu -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBWriteM
|
add wave -noupdate -expand -group lsu -expand -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBWriteM
|
||||||
add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HCLK
|
add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HCLK
|
||||||
add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HSELPLIC
|
add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HSELPLIC
|
||||||
add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HADDR
|
add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HADDR
|
||||||
@ -470,8 +470,11 @@ add wave -noupdate -group {Performance Counters} -expand -group ICACHE -label {I
|
|||||||
add wave -noupdate -group {Performance Counters} -expand -group ICACHE -label {ICACHE MISS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[14]}
|
add wave -noupdate -group {Performance Counters} -expand -group ICACHE -label {ICACHE MISS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[14]}
|
||||||
add wave -noupdate -group {Performance Counters} -expand -group DCACHE -label {DCACHE ACCESS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[11]}
|
add wave -noupdate -group {Performance Counters} -expand -group DCACHE -label {DCACHE ACCESS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[11]}
|
||||||
add wave -noupdate -group {Performance Counters} -expand -group DCACHE -label {DCACHE MISS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[12]}
|
add wave -noupdate -group {Performance Counters} -expand -group DCACHE -label {DCACHE MISS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[12]}
|
||||||
|
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/NextPTE
|
||||||
|
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/HPTWWrite
|
||||||
|
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/UpdatePTE
|
||||||
TreeUpdate [SetDefaultTree]
|
TreeUpdate [SetDefaultTree]
|
||||||
WaveRestoreCursors {{Cursor 7} {283655 ns} 1} {{Cursor 5} {25122 ns} 0} {{Cursor 3} {235459 ns} 1} {{Cursor 4} {217231 ns} 1}
|
WaveRestoreCursors {{Cursor 7} {283655 ns} 1} {{Cursor 5} {86805 ns} 0} {{Cursor 3} {235459 ns} 1} {{Cursor 4} {217231 ns} 1}
|
||||||
quietly wave cursor active 2
|
quietly wave cursor active 2
|
||||||
configure wave -namecolwidth 250
|
configure wave -namecolwidth 250
|
||||||
configure wave -valuecolwidth 314
|
configure wave -valuecolwidth 314
|
||||||
@ -487,4 +490,4 @@ configure wave -griddelta 40
|
|||||||
configure wave -timeline 0
|
configure wave -timeline 0
|
||||||
configure wave -timelineunits ns
|
configure wave -timelineunits ns
|
||||||
update
|
update
|
||||||
WaveRestoreZoom {24516 ns} {25586 ns}
|
WaveRestoreZoom {86757 ns} {87017 ns}
|
||||||
|
@ -76,8 +76,8 @@ module lsuvirtmem(
|
|||||||
logic HPTWWrite;
|
logic HPTWWrite;
|
||||||
|
|
||||||
assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
|
assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
|
||||||
assign ITLBMissOrDAFaultF = ITLBWriteF | InstrDAPageFaultF;
|
assign ITLBMissOrDAFaultF = ITLBMissF | InstrDAPageFaultF;
|
||||||
assign DTLBMissOrDAFaultM = DTLBWriteM | DataDAPageFaultM;
|
assign DTLBMissOrDAFaultM = DTLBMissM | DataDAPageFaultM;
|
||||||
interlockfsm interlockfsm (
|
interlockfsm interlockfsm (
|
||||||
.clk, .reset, .AnyCPUReqM, .ITLBMissOrDAFaultF, .ITLBWriteF,
|
.clk, .reset, .AnyCPUReqM, .ITLBMissOrDAFaultF, .ITLBWriteF,
|
||||||
.DTLBMissOrDAFaultM, .DTLBWriteM, .TrapM, .DCacheStallM,
|
.DTLBMissOrDAFaultM, .DTLBWriteM, .TrapM, .DCacheStallM,
|
||||||
|
@ -72,6 +72,9 @@ module hptw
|
|||||||
logic UpdatePTE;
|
logic UpdatePTE;
|
||||||
logic SetDirty;
|
logic SetDirty;
|
||||||
logic DAPageFault;
|
logic DAPageFault;
|
||||||
|
logic SaveHPTWAdr, SelHPTWWriteAdr;
|
||||||
|
logic [`PA_BITS-1:0] HPTWWriteAdr, HPTWReadAdr;
|
||||||
|
|
||||||
|
|
||||||
(* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState;
|
(* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState;
|
||||||
|
|
||||||
@ -89,7 +92,13 @@ module hptw
|
|||||||
assign PRegEn = HPTWRead & ~DCacheStallM;
|
assign PRegEn = HPTWRead & ~DCacheStallM;
|
||||||
assign NextPTE = UpdatePTE ? {PTE[`XLEN-1:8], SetDirty , 1'b1, PTE[5:0]} : HPTWReadPTE;
|
assign NextPTE = UpdatePTE ? {PTE[`XLEN-1:8], SetDirty , 1'b1, PTE[5:0]} : HPTWReadPTE;
|
||||||
|
|
||||||
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn | HPTWWrite, NextPTE, PTE); // Capture page table entry from data cache
|
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn | UpdatePTE, NextPTE, PTE); // Capture page table entry from data cache
|
||||||
|
|
||||||
|
flopenr #(`PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);
|
||||||
|
assign SaveHPTWAdr = WalkerState == L0_ADR;
|
||||||
|
|
||||||
|
assign SelHPTWWriteAdr = UpdatePTE | HPTWWrite;
|
||||||
|
mux2 #(`PA_BITS) HPTWWriteAdrMux(HPTWReadAdr, HPTWWriteAdr, SelHPTWWriteAdr, HPTWAdr);
|
||||||
|
|
||||||
// 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
|
||||||
@ -105,11 +114,10 @@ module hptw
|
|||||||
// Enable and select signals based on states
|
// Enable and select signals based on states
|
||||||
assign StartWalk = (WalkerState == IDLE) & TLBMiss;
|
assign StartWalk = (WalkerState == IDLE) & TLBMiss;
|
||||||
assign HPTWRead = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
|
assign HPTWRead = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
|
||||||
assign DTLBWriteM = (WalkerState == LEAF) & DTLBWalk;
|
assign DTLBWriteM = (WalkerState == LEAF & ~DAPageFault) & DTLBWalk;
|
||||||
assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBWalk;
|
assign ITLBWriteF = (WalkerState == LEAF & ~DAPageFault) & ~DTLBWalk;
|
||||||
assign HPTWWrite = (WalkerState == UPDATE_PTE);
|
assign HPTWWrite = (WalkerState == UPDATE_PTE);
|
||||||
assign UpdatePTE = ((WalkerState == L2_ADR | WalkerState == L1_ADR | WalkerState == L0_ADR)
|
assign UpdatePTE = WalkerState == LEAF & DAPageFault;
|
||||||
& ValidLeafPTE & ~Misaligned & DAPageFault);
|
|
||||||
|
|
||||||
|
|
||||||
// FSM to track PageType based on the levels of the page table traversed
|
// FSM to track PageType based on the levels of the page table traversed
|
||||||
@ -129,7 +137,7 @@ module hptw
|
|||||||
logic [`PPN_BITS-1:0] PPN;
|
logic [`PPN_BITS-1:0] PPN;
|
||||||
assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state
|
assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state
|
||||||
assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN;
|
assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN;
|
||||||
assign HPTWAdr = {PPN, VPN, 2'b00};
|
assign HPTWReadAdr = {PPN, VPN, 2'b00};
|
||||||
assign HPTWSize = 3'b010;
|
assign HPTWSize = 3'b010;
|
||||||
end else begin // RV64
|
end else begin // RV64
|
||||||
logic [8:0] VPN;
|
logic [8:0] VPN;
|
||||||
@ -143,7 +151,7 @@ module hptw
|
|||||||
endcase
|
endcase
|
||||||
assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) |
|
assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) |
|
||||||
(SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN;
|
(SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN;
|
||||||
assign HPTWAdr = {PPN, VPN, 3'b000};
|
assign HPTWReadAdr = {PPN, VPN, 3'b000};
|
||||||
assign HPTWSize = 3'b011;
|
assign HPTWSize = 3'b011;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -177,26 +185,24 @@ module hptw
|
|||||||
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
|
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
|
||||||
else NextWalkerState = L2_ADR;
|
else NextWalkerState = L2_ADR;
|
||||||
L2_ADR: if (InitialWalkerState == L2_ADR) NextWalkerState = L2_RD; // first access in SV39
|
L2_ADR: if (InitialWalkerState == L2_ADR) NextWalkerState = L2_RD; // first access in SV39
|
||||||
else if (ValidLeafPTE & ~Misaligned & ~DAPageFault) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
|
else if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
|
||||||
else if (ValidLeafPTE & ~Misaligned & DAPageFault) NextWalkerState = UPDATE_PTE;
|
|
||||||
else if (ValidNonLeafPTE) NextWalkerState = L2_RD;
|
else if (ValidNonLeafPTE) NextWalkerState = L2_RD;
|
||||||
else NextWalkerState = LEAF;
|
else NextWalkerState = LEAF;
|
||||||
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
|
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
|
||||||
else NextWalkerState = L1_ADR;
|
else NextWalkerState = L1_ADR;
|
||||||
L1_ADR: if (InitialWalkerState == L1_ADR) NextWalkerState = L1_RD; // first access in SV32
|
L1_ADR: if (InitialWalkerState == L1_ADR) NextWalkerState = L1_RD; // first access in SV32
|
||||||
else if (ValidLeafPTE & ~Misaligned & ~DAPageFault) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
|
else if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
|
||||||
else if (ValidLeafPTE & ~Misaligned & DAPageFault) NextWalkerState = UPDATE_PTE;
|
|
||||||
else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
|
else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
|
||||||
else NextWalkerState = LEAF;
|
else NextWalkerState = LEAF;
|
||||||
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
|
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
|
||||||
else NextWalkerState = L0_ADR;
|
else NextWalkerState = L0_ADR;
|
||||||
L0_ADR: if (ValidLeafPTE & ~Misaligned & ~DAPageFault) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
|
L0_ADR: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
|
||||||
else if (ValidLeafPTE & ~Misaligned & DAPageFault) NextWalkerState = UPDATE_PTE;
|
|
||||||
else if (ValidNonLeafPTE) NextWalkerState = L0_RD;
|
else if (ValidNonLeafPTE) NextWalkerState = L0_RD;
|
||||||
else NextWalkerState = LEAF;
|
else NextWalkerState = LEAF;
|
||||||
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
|
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
|
||||||
else NextWalkerState = LEAF;
|
else NextWalkerState = LEAF;
|
||||||
LEAF: NextWalkerState = IDLE;
|
LEAF: if (DAPageFault) NextWalkerState = UPDATE_PTE;
|
||||||
|
else NextWalkerState = IDLE;
|
||||||
// *** TODO update PTE with dirty/access. write to TLB and update memory.
|
// *** TODO update PTE with dirty/access. write to TLB and update memory.
|
||||||
// probably want to write the PTE in UPDATE_PTE then go to leaf and update TLB.
|
// probably want to write the PTE in UPDATE_PTE then go to leaf and update TLB.
|
||||||
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE;
|
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE;
|
||||||
|
Loading…
Reference in New Issue
Block a user