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
						8f5b5e0989
					
				@ -5,7 +5,8 @@ WALLYDIR:= $(ROOT)/tests/wally-riscv-arch-test
 | 
			
		||||
# IMPERASDIR	:= $(ROOT)/tests/imperas-riscv-tests
 | 
			
		||||
# ALLDIRS := $(ARCHDIR)/$(SUFFIX) $(WALLYDIR)/$(SUFFIX) $(IMPERASDIR)/$(SUFFIX)
 | 
			
		||||
IMPERASDIR	:= $(ROOT)/tests/imperas-riscv-tests
 | 
			
		||||
ALLDIRS := $(ARCHDIR)/$(SUFFIX) $(WALLYDIR)/$(SUFFIX) 
 | 
			
		||||
#ALLDIRS := $(ARCHDIR)/$(SUFFIX) $(WALLYDIR)/$(SUFFIX) 
 | 
			
		||||
ALLDIRS := $(ARCHDIR)/$(SUFFIX)
 | 
			
		||||
 | 
			
		||||
ELFFILES	?= $(shell find $(ALLDIRS) -type f -regex ".*\.elf")
 | 
			
		||||
OBJDUMPFILES	?= $(shell find $(ALLDIRS) -type f -regex ".*\.elf.objdump")
 | 
			
		||||
 | 
			
		||||
@ -98,7 +98,6 @@ module hptw (
 | 
			
		||||
  logic [2:0]                 HPTWSize; // 32 or 64 bit access
 | 
			
		||||
	(* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // map hptw access faults onto either the original LSU load/store fault or instruction access fault
 | 
			
		||||
  assign LoadAccessFaultM 		 = WalkerState == IDLE ? LSULoadAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[1] & ~MemRWM[0];
 | 
			
		||||
  assign StoreAmoAccessFaultM	 = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[0];
 | 
			
		||||
@ -189,13 +188,13 @@ module hptw (
 | 
			
		||||
	// FSM to track PageType based on the levels of the page table traversed
 | 
			
		||||
	flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
 | 
			
		||||
	always_comb 
 | 
			
		||||
	case (WalkerState)
 | 
			
		||||
		L3_RD:  NextPageType = 2'b11; // terapage
 | 
			
		||||
		L2_RD:  NextPageType = 2'b10; // gigapage
 | 
			
		||||
		L1_RD:  NextPageType = 2'b01; // megapage
 | 
			
		||||
		L0_RD:  NextPageType = 2'b00; // kilopage
 | 
			
		||||
		default: NextPageType = PageType;
 | 
			
		||||
	endcase
 | 
			
		||||
		case (WalkerState)
 | 
			
		||||
			L3_RD:  NextPageType = 2'b11; // terapage
 | 
			
		||||
			L2_RD:  NextPageType = 2'b10; // gigapage
 | 
			
		||||
			L1_RD:  NextPageType = 2'b01; // megapage
 | 
			
		||||
			L0_RD:  NextPageType = 2'b00; // kilopage
 | 
			
		||||
			default: NextPageType = PageType;
 | 
			
		||||
		endcase
 | 
			
		||||
 | 
			
		||||
	// HPTWAdr muxing
 | 
			
		||||
	if (`XLEN==32) begin // RV32
 | 
			
		||||
 | 
			
		||||
@ -107,16 +107,10 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) (
 | 
			
		||||
    .Cacheable, .Idempotent, .SelTIM,
 | 
			
		||||
    .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
 | 
			
		||||
 
 | 
			
		||||
  if (`PMP_ENTRIES > 0) // instantiate PMP
 | 
			
		||||
    pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW,
 | 
			
		||||
      .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
 | 
			
		||||
      .ExecuteAccessF, .WriteAccessM, .ReadAccessM,
 | 
			
		||||
      .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM);
 | 
			
		||||
  else begin
 | 
			
		||||
    assign PMPInstrAccessFaultF = 0;
 | 
			
		||||
    assign PMPLoadAccessFaultM = 0;
 | 
			
		||||
    assign PMPStoreAmoAccessFaultM = 0;
 | 
			
		||||
  end
 | 
			
		||||
  pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW,
 | 
			
		||||
    .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
 | 
			
		||||
    .ExecuteAccessF, .WriteAccessM, .ReadAccessM,
 | 
			
		||||
    .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM);
 | 
			
		||||
 | 
			
		||||
  // Access faults
 | 
			
		||||
  // If TLB miss and translating we want to not have faults from the PMA and PMP checkers.
 | 
			
		||||
 | 
			
		||||
@ -49,28 +49,34 @@ module pmpchecker (
 | 
			
		||||
  output logic                     PMPStoreAmoAccessFaultM
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  // Bit i is high when the address falls in PMP region i
 | 
			
		||||
  logic                    EnforcePMP;
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address.
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0] Active;     // PMP register i is non-null
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0]   PAgePMPAdr;  // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
 | 
			
		||||
  if (`PMP_ENTRIES > 0) begin
 | 
			
		||||
    // Bit i is high when the address falls in PMP region i
 | 
			
		||||
    logic                    EnforcePMP;
 | 
			
		||||
    logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges
 | 
			
		||||
    logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address.
 | 
			
		||||
    logic [`PMP_ENTRIES-1:0] Active;     // PMP register i is non-null
 | 
			
		||||
    logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set
 | 
			
		||||
    logic [`PMP_ENTRIES-1:0]   PAgePMPAdr;  // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
 | 
			
		||||
 | 
			
		||||
  pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0](
 | 
			
		||||
    .PhysicalAddress, 
 | 
			
		||||
    .PMPCfg(PMPCFG_ARRAY_REGW),
 | 
			
		||||
    .PMPAdr(PMPADDR_ARRAY_REGW),
 | 
			
		||||
    .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
 | 
			
		||||
    .PAgePMPAdrOut(PAgePMPAdr),
 | 
			
		||||
    .Match, .Active, .L, .X, .W, .R);
 | 
			
		||||
    pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0](
 | 
			
		||||
      .PhysicalAddress, 
 | 
			
		||||
      .PMPCfg(PMPCFG_ARRAY_REGW),
 | 
			
		||||
      .PMPAdr(PMPADDR_ARRAY_REGW),
 | 
			
		||||
      .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
 | 
			
		||||
      .PAgePMPAdrOut(PAgePMPAdr),
 | 
			
		||||
      .Match, .Active, .L, .X, .W, .R);
 | 
			
		||||
 | 
			
		||||
  priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
 | 
			
		||||
    priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
 | 
			
		||||
 | 
			
		||||
  // Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region
 | 
			
		||||
  assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active; 
 | 
			
		||||
    // Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region
 | 
			
		||||
    assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active; 
 | 
			
		||||
 | 
			
		||||
  assign PMPInstrAccessFaultF     = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;
 | 
			
		||||
  assign PMPStoreAmoAccessFaultM  = EnforcePMP & WriteAccessM   & ~|(W & FirstMatch) ;
 | 
			
		||||
  assign PMPLoadAccessFaultM      = EnforcePMP & ReadAccessM    & ~|(R & FirstMatch) ;
 | 
			
		||||
    assign PMPInstrAccessFaultF     = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;
 | 
			
		||||
    assign PMPStoreAmoAccessFaultM  = EnforcePMP & WriteAccessM   & ~|(W & FirstMatch) ;
 | 
			
		||||
    assign PMPLoadAccessFaultM      = EnforcePMP & ReadAccessM    & ~|(R & FirstMatch) ;
 | 
			
		||||
  end else begin
 | 
			
		||||
    assign PMPInstrAccessFaultF     = 0;
 | 
			
		||||
    assign PMPStoreAmoAccessFaultM  = 0;
 | 
			
		||||
    assign PMPLoadAccessFaultM      = 0;
 | 
			
		||||
  end
 | 
			
		||||
 endmodule
 | 
			
		||||
 | 
			
		||||
@ -63,12 +63,8 @@ module tlbcontrol #(parameter ITLB = 0) (
 | 
			
		||||
  // Determine whether TLB is being used
 | 
			
		||||
  assign TLBAccess = ReadAccess | WriteAccess;
 | 
			
		||||
 | 
			
		||||
  if (`XLEN==64) // Check whether upper bits of 64-bit virtual addressses are all equal
 | 
			
		||||
    vm64check vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequalPageFault);
 | 
			
		||||
  else begin
 | 
			
		||||
    assign SV39Mode = 0;
 | 
			
		||||
    assign UpperBitsUnequalPageFault = 0;
 | 
			
		||||
  end           
 | 
			
		||||
  // Check that upper bits are legal (all 0s or all 1s)
 | 
			
		||||
  vm64check vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequalPageFault);
 | 
			
		||||
 | 
			
		||||
  // unswizzle useful PTE bits
 | 
			
		||||
  assign {PTE_D, PTE_A} = PTEAccessBits[7:6];
 | 
			
		||||
 | 
			
		||||
@ -35,12 +35,16 @@ module vm64check (
 | 
			
		||||
  output logic                    UpperBitsUnequalPageFault
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic                           eq_63_47, eq_46_38;
 | 
			
		||||
  if (`XLEN == 64) begin
 | 
			
		||||
    assign SV39Mode = (SATP_MODE == `SV39);
 | 
			
		||||
 | 
			
		||||
  assign SV39Mode = (SATP_MODE == `SV39);
 | 
			
		||||
 | 
			
		||||
  // page fault if upper bits aren't all the same
 | 
			
		||||
  assign eq_46_38 = &(VAdr[46:38]) | ~|(VAdr[46:38]);
 | 
			
		||||
  assign eq_63_47 = &(VAdr[63:47]) | ~|(VAdr[63:47]); 
 | 
			
		||||
  assign UpperBitsUnequalPageFault = SV39Mode ? ~(eq_63_47 & eq_46_38) : ~eq_63_47;
 | 
			
		||||
    // page fault if upper bits aren't all the same
 | 
			
		||||
    logic                           eq_63_47, eq_46_38;
 | 
			
		||||
    assign eq_46_38 = &(VAdr[46:38]) | ~|(VAdr[46:38]);
 | 
			
		||||
    assign eq_63_47 = &(VAdr[63:47]) | ~|(VAdr[63:47]); 
 | 
			
		||||
    assign UpperBitsUnequalPageFault = SV39Mode ? ~(eq_63_47 & eq_46_38) : ~eq_63_47;
 | 
			
		||||
  end else begin
 | 
			
		||||
    assign SV39Mode = 0;
 | 
			
		||||
    assign UpperBitsUnequalPageFault = 0;
 | 
			
		||||
  end
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
@ -155,7 +155,7 @@ module testbench;
 | 
			
		||||
  `define MCOUNTEREN  `CSR_BASE.csrm.mcounteren.MCOUNTERENreg.q
 | 
			
		||||
  `define SCOUNTEREN  `CSR_BASE.csrs.csrs.SCOUNTERENreg.q
 | 
			
		||||
  `define MSCRATCH    `CSR_BASE.csrm.MSCRATCHreg.q
 | 
			
		||||
  `define SSCRATCH    `CSR_BASE.csrs.csrs.csrs.SSCRATCHreg.q
 | 
			
		||||
  `define SSCRATCH    `CSR_BASE.csrs.csrs.SSCRATCHreg.q
 | 
			
		||||
  `define MTVEC       `CSR_BASE.csrm.MTVECreg.q
 | 
			
		||||
  `define STVEC       `CSR_BASE.csrs.csrs.STVECreg.q
 | 
			
		||||
  `define SATP        `CSR_BASE.csrs.csrs.genblk1.SATPreg.q
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user