mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	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
							
								
									62f5f1e622
								
							
						
					
					
						commit
						2fc7dc3e57
					
				| @ -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