mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge branch 'main' of https://github.com/openhwgroup/cvw
This commit is contained in:
		
						commit
						cbc44a68ab
					
				@ -246,6 +246,30 @@ coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerang
 | 
			
		||||
# never reaches this when ENVCFG_ADUE_1 because HPTW updates A bit first
 | 
			
		||||
coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerange [GetLineNum ../src/mmu/tlb/tlbcontrol.sv "assign PrePageFault"] -item e 1 -fecexprrow 18 
 | 
			
		||||
 | 
			
		||||
###############
 | 
			
		||||
# HPTW exclusions
 | 
			
		||||
###############
 | 
			
		||||
 | 
			
		||||
# RV64GC HPTW never starts at L1_ADR
 | 
			
		||||
set line [GetLineNum ../src/mmu/hptw.sv "InitialWalkerState == L1_ADR"] 
 | 
			
		||||
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item c 1 -feccondrow 2
 | 
			
		||||
 | 
			
		||||
# Never possible to get a page fault when neither reading nor writing
 | 
			
		||||
set line [GetLineNum ../src/mmu/hptw.sv "assign HPTWLoadPageFault"] 
 | 
			
		||||
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item e 1 -fecexprrow 7
 | 
			
		||||
 
 | 
			
		||||
# Never possible to get a store page fault from an ITLB walk
 | 
			
		||||
set line [GetLineNum ../src/mmu/hptw.sv "assign HPTWStoreAmoPageFault"] 
 | 
			
		||||
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item e 1 -fecexprrow 3
 | 
			
		||||
 
 | 
			
		||||
# Never possible to get Access = 0 on a nonleaf PTE with no OtherPageFault (because InvalidRead/Write will be 1 on the nonleaf)
 | 
			
		||||
set line [GetLineNum ../src/mmu/hptw.sv "assign HPTWUpdateDA"] 
 | 
			
		||||
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item e 1 -fecexprrow 3
 | 
			
		||||
 
 | 
			
		||||
###############
 | 
			
		||||
# Other exclusions
 | 
			
		||||
###############
 | 
			
		||||
 | 
			
		||||
# IMMU PMP does not support CBO instructions
 | 
			
		||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcbom"] 
 | 
			
		||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboz"] 
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@
 | 
			
		||||
--override cpu/mvendorid=0x602
 | 
			
		||||
--override cpu/marchid=0x24
 | 
			
		||||
--override refRoot/cpu/tvec_align=64
 | 
			
		||||
--override refRoot/cpu/envcfg_mask=1 
 | 
			
		||||
--override refRoot/cpu/envcfg_mask=1   # dh 1/26/24 this should be deleted when ImperasDV is updated to allow envcfg.FIOM to be written
 | 
			
		||||
 | 
			
		||||
# bit manipulation
 | 
			
		||||
--override cpu/add_Extensions=B 
 | 
			
		||||
 | 
			
		||||
@ -93,7 +93,6 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  logic [P.PA_BITS-1:0]     HPTWReadAdr;
 | 
			
		||||
  logic                     SelHPTWAdr;
 | 
			
		||||
  logic [P.XLEN+1:0]        HPTWAdrExt;
 | 
			
		||||
  logic                     ITLBMissOrUpdateDAF;
 | 
			
		||||
  logic                     DTLBMissOrUpdateDAM;
 | 
			
		||||
  logic                     LSUAccessFaultM;
 | 
			
		||||
  logic [P.PA_BITS-1:0]     HPTWAdr;
 | 
			
		||||
@ -113,12 +112,12 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  // map hptw access faults onto either the original LSU load/store fault or instruction access fault
 | 
			
		||||
  assign LSUAccessFaultM         = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM;
 | 
			
		||||
  assign HPTWFaultM              = LSUAccessFaultM | PBMTFaultM;
 | 
			
		||||
  assign HPTWLoadAccessFault     = LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
 | 
			
		||||
  assign HPTWLoadAccessFault     = LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];  
 | 
			
		||||
  assign HPTWStoreAmoAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[0];
 | 
			
		||||
  assign HPTWInstrAccessFault    = LSUAccessFaultM & ~DTLBWalk;
 | 
			
		||||
  assign HPTWLoadPageFault     = PBMTFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
 | 
			
		||||
  assign HPTWStoreAmoPageFault = PBMTFaultM & DTLBWalk & MemRWM[0];
 | 
			
		||||
  assign HPTWInstrPageFault    = PBMTFaultM & ~DTLBWalk;
 | 
			
		||||
  assign HPTWLoadPageFault       = PBMTFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
 | 
			
		||||
  assign HPTWStoreAmoPageFault   = PBMTFaultM & DTLBWalk & MemRWM[0];   
 | 
			
		||||
  assign HPTWInstrPageFault      = PBMTFaultM & ~DTLBWalk;
 | 
			
		||||
 | 
			
		||||
  flopr #(7) HPTWAccesFaultReg(clk, reset, {TakeHPTWFault, HPTWLoadAccessFault, HPTWStoreAmoAccessFault, HPTWInstrAccessFault, 
 | 
			
		||||
                                            HPTWLoadPageFault, HPTWStoreAmoPageFault, HPTWInstrPageFault},
 | 
			
		||||
@ -127,17 +126,18 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
 | 
			
		||||
  assign TakeHPTWFault = WalkerState != IDLE;
 | 
			
		||||
  
 | 
			
		||||
  assign LoadAccessFaultM      = TakeHPTWFault ? HPTWLoadAccessFaultDelay : LSULoadAccessFaultM;
 | 
			
		||||
  // Improve timing by taking HPTW faults off critical path because these are multicycle operations anyway
 | 
			
		||||
  assign LoadAccessFaultM      = TakeHPTWFault ? HPTWLoadAccessFaultDelay : LSULoadAccessFaultM;                     
 | 
			
		||||
  assign StoreAmoAccessFaultM  = TakeHPTWFault ? HPTWStoreAmoAccessFaultDelay : LSUStoreAmoAccessFaultM;
 | 
			
		||||
  assign HPTWInstrAccessFaultF = TakeHPTWFault ? HPTWInstrAccessFaultDelay : 1'b0;
 | 
			
		||||
  assign LoadPageFaultM      = TakeHPTWFault ? HPTWLoadPageFaultDelay : LSULoadPageFaultM;
 | 
			
		||||
  assign StoreAmoPageFaultM  = TakeHPTWFault ? HPTWStoreAmoPageFaultDelay : LSUStoreAmoPageFaultM;
 | 
			
		||||
  assign HPTWInstrPageFaultF = TakeHPTWFault ? HPTWInstrPageFaultDelay : 1'b0;
 | 
			
		||||
  assign LoadPageFaultM        = TakeHPTWFault ? HPTWLoadPageFaultDelay : LSULoadPageFaultM;
 | 
			
		||||
  assign StoreAmoPageFaultM    = TakeHPTWFault ? HPTWStoreAmoPageFaultDelay : LSUStoreAmoPageFaultM;
 | 
			
		||||
  assign HPTWInstrPageFaultF   = TakeHPTWFault ? HPTWInstrPageFaultDelay : 1'b0;
 | 
			
		||||
  
 | 
			
		||||
  // Extract bits from CSRs and inputs
 | 
			
		||||
  assign SvMode = SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS];
 | 
			
		||||
  assign BasePageTablePPN = SATP_REGW[P.PPN_BITS-1:0];
 | 
			
		||||
  assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissOrUpdateDAF);
 | 
			
		||||
  assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissF);
 | 
			
		||||
 | 
			
		||||
  // Determine which address to translate
 | 
			
		||||
  mux2 #(P.XLEN) vadrmux(PCSpillF, IEUAdrExtM[P.XLEN-1:0], DTLBWalk, TranslationVAdr);
 | 
			
		||||
@ -203,7 +203,7 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
    // memory access.  If there is the PTE needs to be updated seting Access
 | 
			
		||||
    // and possibly also Dirty.  Dirty is set if the operation is a store/amo.
 | 
			
		||||
    // However any other fault should not cause the update, and updates are in software when ENVCFG_ADUE = 0
 | 
			
		||||
    assign HPTWUpdateDA = ValidLeafPTE & (~Accessed | SetDirty) & ENVCFG_ADUE & ~OtherPageFault;  
 | 
			
		||||
    assign HPTWUpdateDA = ValidLeafPTE & (~Accessed | SetDirty) & ENVCFG_ADUE & ~OtherPageFault;   
 | 
			
		||||
 | 
			
		||||
    assign HPTWRW[0] = (WalkerState == UPDATE_PTE);           // HPTWRW[0] will always be 0 if ADUE = 0 because HPTWUpdateDA will be 0 so WalkerState never is UPDATE_PTE
 | 
			
		||||
    assign UpdatePTE = (WalkerState == LEAF) & HPTWUpdateDA;  // UpdatePTE will always be 0 if ADUE = 0 because HPTWUpdateDA will be 0
 | 
			
		||||
@ -283,7 +283,7 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState); 
 | 
			
		||||
  always_comb 
 | 
			
		||||
    case (WalkerState)
 | 
			
		||||
      IDLE:       if (TLBMiss & ~DCacheBusStallM)                     NextWalkerState = InitialWalkerState;
 | 
			
		||||
      IDLE:       if (TLBMiss)                                        NextWalkerState = InitialWalkerState;                      
 | 
			
		||||
                  else                                                NextWalkerState = IDLE;
 | 
			
		||||
      L3_ADR:                                                         NextWalkerState = L3_RD; // first access in SV48
 | 
			
		||||
      L3_RD:      if (DCacheBusStallM)                                NextWalkerState = L3_RD;
 | 
			
		||||
@ -294,7 +294,7 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
      L2_RD:      if (DCacheBusStallM)                                NextWalkerState = L2_RD;
 | 
			
		||||
                  else if(HPTWFaultM)                                 NextWalkerState = FAULT;
 | 
			
		||||
                  else                                                NextWalkerState = L1_ADR;
 | 
			
		||||
      L1_ADR:     if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
 | 
			
		||||
      L1_ADR:     if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32                 
 | 
			
		||||
                  else                                                NextWalkerState = LEAF;  
 | 
			
		||||
      L1_RD:      if (DCacheBusStallM)                                NextWalkerState = L1_RD;
 | 
			
		||||
                  else if(HPTWFaultM)                                 NextWalkerState = FAULT;
 | 
			
		||||
@ -320,9 +320,8 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  // The FSM directly transistions to IDLE to ready for the next operation when the delayed version will not be high.
 | 
			
		||||
 | 
			
		||||
  assign HPTWAccessFaultDelay = HPTWLoadAccessFaultDelay | HPTWStoreAmoAccessFaultDelay | HPTWInstrAccessFaultDelay;
 | 
			
		||||
  assign HPTWStall = (WalkerState != IDLE & WalkerState != FAULT) | (WalkerState == IDLE & TLBMiss);
 | 
			
		||||
  assign HPTWStall = (WalkerState != IDLE & WalkerState != FAULT) | (WalkerState == IDLE & TLBMiss); 
 | 
			
		||||
 | 
			
		||||
  assign ITLBMissOrUpdateDAF = ITLBMissF | (P.SVADU_SUPPORTED & InstrUpdateDAF);
 | 
			
		||||
  assign DTLBMissOrUpdateDAM = DTLBMissM | (P.SVADU_SUPPORTED & DataUpdateDAM);  
 | 
			
		||||
 | 
			
		||||
  // HTPW address/data/control muxing
 | 
			
		||||
 | 
			
		||||
@ -123,6 +123,27 @@ main:
 | 
			
		||||
    li t0, 0x80806000
 | 
			
		||||
    jalr ra, t0      # jump to page to exercise ITLB with PBMT !=0 when ENVCFG_PMTE=0
 | 
			
		||||
 | 
			
		||||
    # Load and AMO operation on page table entry that causes access fault
 | 
			
		||||
    li t0, 0x81000000 
 | 
			
		||||
    lw t1, 0(t0)
 | 
			
		||||
    sfence.vma
 | 
			
		||||
    amoadd.w t0, t0, 0(t0)
 | 
			
		||||
 | 
			
		||||
    # Access fault on top level PTE
 | 
			
		||||
    li t0, 0x1000000000
 | 
			
		||||
    lw t1, 0(t0)
 | 
			
		||||
 | 
			
		||||
    # Access fault on megapage
 | 
			
		||||
    li t0, 0x81400000
 | 
			
		||||
    lw t1, 0(t0)
 | 
			
		||||
 | 
			
		||||
    # AMO operation on page table entry that causes page fault due to malformed PBMT
 | 
			
		||||
    li t0, 0x81200000 
 | 
			
		||||
    jalr t0          # Attempt to fetch instruction from address causing faulty page walk
 | 
			
		||||
    lw t1, 0(t0)
 | 
			
		||||
    sfence.vma
 | 
			
		||||
    amoadd.w t0, t0, 0(t0)
 | 
			
		||||
 | 
			
		||||
    # change back to default trap handler after checking everything that might cause an instruction page fault
 | 
			
		||||
    jal changetodefaulthandler
 | 
			
		||||
 | 
			
		||||
@ -178,8 +199,6 @@ main:
 | 
			
		||||
    li a0, 1
 | 
			
		||||
    ecall
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    # wrap up
 | 
			
		||||
    li a0, 3 # switch back to machine mode because code at 0x80000000 may not have clean page table entry
 | 
			
		||||
    ecall
 | 
			
		||||
@ -237,32 +256,30 @@ ipf:
 | 
			
		||||
.align 16
 | 
			
		||||
# root Page table situated at 0x80010000
 | 
			
		||||
pagetable: 
 | 
			
		||||
    .8byte 0x200044C1  # 0x00000000-0x80_00000000: PTE at 0x80011000 C1 dirty, accessed, valid
 | 
			
		||||
    .8byte 0x200044C1  # 0x00000000-0x7F_FFFFFFFF: PTE at 0x80011000 C1 dirty, accessed, valid
 | 
			
		||||
    .8byte 0x00000000000010CF # misaligned terapage at 0x80_00000000
 | 
			
		||||
    .8byte 0x00000000000000CF # access fault terapage at 0x100_00000000
 | 
			
		||||
 | 
			
		||||
# next page table at 0x80011000
 | 
			
		||||
.align 12
 | 
			
		||||
    .8byte 0x00000000000010CF # misaligned gigapage at 0x00000000
 | 
			
		||||
    .8byte 0x00000000200058C1 # PTE for pages at 0x40000000
 | 
			
		||||
    .8byte 0x00000000200058C1 # PTE for pages at 0x40000000 pointing to 0x80150000
 | 
			
		||||
    .8byte 0x00000000200048C1 # gigapage at 0x80000000 pointing to 0x80120000
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
# Next page table at 0x80012000 for gigapage at 0x80000000
 | 
			
		||||
.align 12
 | 
			
		||||
    .8byte 0x0000000020004CC1  # for VA starting at 80000000 (pointer to NAPOT 64 KiB pages)
 | 
			
		||||
    .8byte 0x0000000020004CC1  # for VA starting at 80000000 (pointer to NAPOT 64 KiB pages Page table at 80013000)
 | 
			
		||||
    .8byte 0x0000000020014CCF  # for VA starting at 80200000 (misaligned megapage)
 | 
			
		||||
    .8byte 0x00000000200050C1  # for VA starting at 80400000 (bad PBMT pages)
 | 
			
		||||
    .8byte 0x00000000200050C1  # for VA starting at 80400000 (bad PBMT pages page table at 0x80014000)
 | 
			
		||||
    .8byte 0x4000000020004CC1  # for VA starting at 80600000 (bad entry: nonleaf PTE can't have PBMT != 0)
 | 
			
		||||
    .8byte 0x00000000200054C1  # for VA starting at 80800000 (testing rwx permissiosn with cbom/cboz)
 | 
			
		||||
    .8byte 0x0000000020004CC1  # for VA starting at 80A00000 (pointer to NAPOT 64 KiB pages like at 80000000)
 | 
			
		||||
    .8byte 0x00000000200054C1  # for VA starting at 80800000 (testing rwx permissiosn with cbom/cboz . page table at 0x80015000)
 | 
			
		||||
    .8byte 0x0000000020004CC1  # for VA starting at 80A00000 (pointer to NAPOT 64 KiB pages like at 80000000.  page table at 0x80013000)
 | 
			
		||||
    .8byte 0x0F00000020004CCF  # for VA starting at 80C00000 (bad reserved field in bits 60:54)
 | 
			
		||||
    .8byte 0x000000002000000F  # for VA starting at 80E00000 (not dirty or accessed)
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
    .8byte 0x000000002000000F  # for VA starting at 80E00000 (megapage not dirty or accessed)
 | 
			
		||||
    .8byte 0x0000000000004CC1  # for VA starting at 81000000 (nonleaf pointing to unimplemented memory causes access fault)
 | 
			
		||||
    .8byte 0x4000000020004CC1  # for VA starting at 81200000 (nonleaf with PBMT nonzero causes page fault)
 | 
			
		||||
    .8byte 0x00000000000000CF  # for VA starting at 81400000 (megapage with access fault)
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
@ -288,7 +305,7 @@ pagetable:
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
    .8byte 0x0000000020004CC1
 | 
			
		||||
 | 
			
		||||
# Leaf page table at 0x80013000 with NAPOT pages
 | 
			
		||||
# Leaf page table at 0x80013000 with 64 KiB NAPOT pages
 | 
			
		||||
.align 12
 | 
			
		||||
    #80000000
 | 
			
		||||
    .8byte 0xA0000000200020CF
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user