mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge branch 'main' of github.com:ross144/cvw
This commit is contained in:
		
						commit
						9f4c32d49c
					
				@ -30,7 +30,7 @@ OBJDUMPS := $(foreach name, $(OBJDUMPS), $(DIS)/$(name).objdump)
 | 
			
		||||
 | 
			
		||||
.PHONY: all generate disassemble install clean cleanDTB cleanDriver test
 | 
			
		||||
 | 
			
		||||
all: download Image disassemble install
 | 
			
		||||
all: clean download Image disassemble install
 | 
			
		||||
 | 
			
		||||
Image:
 | 
			
		||||
	bash -c "unset LD_LIBRARY_PATH; make -C $(BUILDROOT) --jobs;"
 | 
			
		||||
@ -120,4 +120,4 @@ cleanDTB:
 | 
			
		||||
	rm -f $(IMAGES)/*.dtb
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -rf $(DIS)
 | 
			
		||||
	rm -rf $(BUILDROOT)
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,7 @@
 | 
			
		||||
--override cpu/misa_Extensions_mask=0x0
 | 
			
		||||
--override cpu/Sstc=T
 | 
			
		||||
 | 
			
		||||
# Enable SVADU hardware update of A/D bits when menvcfg.HADE=1
 | 
			
		||||
# Enable SVADU hardware update of A/D bits when menvcfg.ADUE=1
 | 
			
		||||
--override cpu/Svadu=T
 | 
			
		||||
--override cpu/updatePTEA=F
 | 
			
		||||
--override cpu/updatePTED=F
 | 
			
		||||
 | 
			
		||||
@ -110,14 +110,16 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
 | 
			
		||||
    // ***************************************************************************
 | 
			
		||||
    integer i;
 | 
			
		||||
    
 | 
			
		||||
    initial begin // initialize memory for simulation only
 | 
			
		||||
      integer j;
 | 
			
		||||
      for (j=0; j < DEPTH; j++) 
 | 
			
		||||
        mem[j] = '0;
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    // Read
 | 
			
		||||
    logic [$clog2(DEPTH)-1:0] ra1d;
 | 
			
		||||
    flopen #($clog2(DEPTH)) adrreg(clk, ce1, ra1, ra1d);
 | 
			
		||||
    assign rd1 = mem[ra1d];
 | 
			
		||||
 | 
			
		||||
    /*      // Read
 | 
			
		||||
     always_ff @(posedge clk) 
 | 
			
		||||
     if(ce1) rd1 <= #1 mem[ra1]; */
 | 
			
		||||
    
 | 
			
		||||
    // Write divided into part for bytes and part for extra msbs
 | 
			
		||||
    // coverage off     
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,6 @@ module btb import cvw::*;  #(parameter cvw_t P,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic [Depth-1:0]        PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex;
 | 
			
		||||
  logic [P.XLEN-1:0]        ResetPC;
 | 
			
		||||
  logic                    MatchD, MatchE, MatchM, MatchW, MatchX;
 | 
			
		||||
  logic [P.XLEN+3:0]        ForwardBTBPrediction, ForwardBTBPredictionF;
 | 
			
		||||
  logic [P.XLEN+3:0]        TableBTBPredF;
 | 
			
		||||
@ -70,12 +69,7 @@ module btb import cvw::*;  #(parameter cvw_t P,
 | 
			
		||||
  assign PCMIndex = {PCM[Depth+1] ^ PCM[1], PCM[Depth:2]};
 | 
			
		||||
  assign PCWIndex = {PCW[Depth+1] ^ PCW[1], PCW[Depth:2]};
 | 
			
		||||
 | 
			
		||||
  // must output a valid PC and valid bit during reset.  Because only PCF, not PCNextF is reset, PCNextF is invalid
 | 
			
		||||
  // during reset.  The BTB must produce a non X PC1NextF to allow the simulation to run.
 | 
			
		||||
  // While the mux could be included in IFU it is not necessary for the IROM/I$/bus.
 | 
			
		||||
  // For now it is optimal to leave it here.
 | 
			
		||||
  assign ResetPC = P.RESET_VECTOR[P.XLEN-1:0];
 | 
			
		||||
  assign PCNextFIndex = reset ? ResetPC[Depth+1:2] : {PCNextF[Depth+1] ^ PCNextF[1], PCNextF[Depth:2]}; 
 | 
			
		||||
  assign PCNextFIndex = {PCNextF[Depth+1] ^ PCNextF[1], PCNextF[Depth:2]}; 
 | 
			
		||||
 | 
			
		||||
  assign MatchD = PCFIndex == PCDIndex;
 | 
			
		||||
  assign MatchE = PCFIndex == PCEIndex;
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ module ifu import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  input  logic                 STATUS_MPRV,                              // Status CSR: modify machine privilege
 | 
			
		||||
  input  logic [1:0]           STATUS_MPP,                               // Status CSR: previous machine privilege level
 | 
			
		||||
  input  logic                 ENVCFG_PBMTE,                             // Page-based memory types enabled
 | 
			
		||||
  input  logic                 ENVCFG_HADE,                              // HPTW A/D Update enable
 | 
			
		||||
  input  logic                 ENVCFG_ADUE,                              // HPTW A/D Update enable
 | 
			
		||||
  input  logic                 sfencevmaM,                               // Virtual memory address fence, invalidate TLB entries
 | 
			
		||||
  output logic                 ITLBMissF,                                // ITLB miss causes HPTW (hardware pagetable walker) walk
 | 
			
		||||
  output logic                 InstrUpdateDAF,                           // ITLB hit needs to update dirty or access bits
 | 
			
		||||
@ -168,7 +168,7 @@ module ifu import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
    assign TLBFlush = sfencevmaM & ~StallMQ;
 | 
			
		||||
 | 
			
		||||
    mmu #(.P(P), .TLB_ENTRIES(P.ITLB_ENTRIES), .IMMU(1))
 | 
			
		||||
    immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_HADE,
 | 
			
		||||
    immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
 | 
			
		||||
         .PrivilegeModeW, .DisableTranslation(1'b0),
 | 
			
		||||
         .VAdr(PCFExt),
 | 
			
		||||
         .Size(2'b10),
 | 
			
		||||
@ -300,23 +300,17 @@ module ifu import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
    mux2 #(P.XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF));
 | 
			
		||||
  else assign PC2NextF = PC1NextF;
 | 
			
		||||
 | 
			
		||||
  assign  PCNextF = {UnalignedPCNextF[P.XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
 | 
			
		||||
  flopenl #(P.XLEN) pcreg(clk, reset, ~StallF, PCNextF, P.RESET_VECTOR[P.XLEN-1:0], PCF);
 | 
			
		||||
  mux2 #(P.XLEN) pcresetmux({UnalignedPCNextF[P.XLEN-1:1], 1'b0}, P.RESET_VECTOR[P.XLEN-1:0], reset, PCNextF);
 | 
			
		||||
  flopen #(P.XLEN) pcreg(clk, ~StallF | reset, PCNextF, PCF);
 | 
			
		||||
 | 
			
		||||
  // pcadder
 | 
			
		||||
  // add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
 | 
			
		||||
  // *** consider using PCPlus2or4F = PCF + CompressedF ? 2 : 4;
 | 
			
		||||
  assign PCPlus4F = PCF[P.XLEN-1:2] + 1; // add 4 to PC
 | 
			
		||||
  // choose PC+2 or PC+4 based on CompressedF, which arrives later. 
 | 
			
		||||
  // Speeds up critical path as compared to selecting adder input based on CompressedF
 | 
			
		||||
  // *** consider gating PCPlus4F to provide the reset.
 | 
			
		||||
 | 
			
		||||
  // *** There is actually a bug in the regression test.  We fetched an address which returns data with
 | 
			
		||||
  // an X.  This version of the code does not die because if CompressedF is an X it just defaults to the last
 | 
			
		||||
  // option.  The above code would work, but propagates the x.
 | 
			
		||||
  always_comb
 | 
			
		||||
    if(reset) PCPlus2or4F = '0;
 | 
			
		||||
    else if (CompressedF) // add 2
 | 
			
		||||
    if (CompressedF) // add 2
 | 
			
		||||
      if (PCF[1]) PCPlus2or4F = {PCPlus4F, 2'b00}; 
 | 
			
		||||
      else        PCPlus2or4F = {PCF[P.XLEN-1:2], 2'b10};
 | 
			
		||||
    else          PCPlus2or4F = {PCPlus4F, PCF[1:0]}; // add 4
 | 
			
		||||
 | 
			
		||||
@ -82,7 +82,7 @@ module lsu import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  input  logic                    STATUS_MXR, STATUS_SUM, STATUS_MPRV,  // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege
 | 
			
		||||
  input  logic [1:0]              STATUS_MPP,                           // Machine previous privilege mode
 | 
			
		||||
  input  logic                    ENVCFG_PBMTE,                         // Page-based memory types enabled
 | 
			
		||||
  input  logic                    ENVCFG_HADE,                          // HPTW A/D Update enable
 | 
			
		||||
  input  logic                    ENVCFG_ADUE,                          // HPTW A/D Update enable
 | 
			
		||||
  input  logic [P.XLEN-1:0]       PCSpillF,                             // Fetch PC 
 | 
			
		||||
  input  logic                    ITLBMissF,                            // ITLB miss causes HPTW (hardware pagetable walker) walk
 | 
			
		||||
  input  logic                    InstrUpdateDAF,                       // ITLB hit needs to update dirty or access bits
 | 
			
		||||
@ -194,7 +194,7 @@ module lsu import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
    hptw #(P) hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF,
 | 
			
		||||
      .DTLBMissM, .DTLBWriteM, .InstrUpdateDAF, .DataUpdateDAM,
 | 
			
		||||
      .FlushW, .DCacheStallM, .SATP_REGW, .PCSpillF,
 | 
			
		||||
      .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_HADE, .PrivilegeModeW,
 | 
			
		||||
      .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_ADUE, .PrivilegeModeW,
 | 
			
		||||
      .ReadDataM(ReadDataM[P.XLEN-1:0]), // ReadDataM is LLEN, but HPTW only needs XLEN
 | 
			
		||||
      .WriteDataM(WriteDataZM), .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M,
 | 
			
		||||
      .IEUAdrExtM, .PTE, .IHWriteDataM, .PageType, .PreLSURWM, .LSUAtomicM,
 | 
			
		||||
@ -232,7 +232,7 @@ module lsu import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
    assign DisableTranslation = SelHPTW | FlushDCacheM;
 | 
			
		||||
    assign WriteAccessM = PreLSURWM[0];
 | 
			
		||||
    mmu #(.P(P), .TLB_ENTRIES(P.DTLB_ENTRIES), .IMMU(0))
 | 
			
		||||
    dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_HADE,
 | 
			
		||||
    dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
 | 
			
		||||
      .PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]),
 | 
			
		||||
      .PTE, .PageTypeWriteVal(PageType), .TLBWrite(DTLBWriteM), .TLBFlush(sfencevmaM),
 | 
			
		||||
      .PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .SelTIM(SelDTIM), 
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  // system status
 | 
			
		||||
  input  logic              STATUS_MXR, STATUS_SUM, STATUS_MPRV,
 | 
			
		||||
  input  logic [1:0]        STATUS_MPP,
 | 
			
		||||
  input  logic              ENVCFG_HADE,            // HPTW A/D Update enable
 | 
			
		||||
  input  logic              ENVCFG_ADUE,            // HPTW A/D Update enable
 | 
			
		||||
  input  logic [1:0]        PrivilegeModeW,
 | 
			
		||||
  input  logic [P.XLEN-1:0] ReadDataM,              // page table entry from LSU 
 | 
			
		||||
  input  logic [P.XLEN-1:0] WriteDataM,
 | 
			
		||||
@ -154,7 +154,7 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
    logic [P.XLEN-1:0]    AccessedPTE;
 | 
			
		||||
 | 
			
		||||
    assign AccessedPTE = {PTE[P.XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit
 | 
			
		||||
    mux2 #(P.XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); // NextPTE = ReadDataM when HADE = 0 because UpdatePTE = 0
 | 
			
		||||
    mux2 #(P.XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); // NextPTE = ReadDataM when ADUE = 0 because UpdatePTE = 0
 | 
			
		||||
    flopenr #(P.PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);
 | 
			
		||||
    
 | 
			
		||||
    assign SaveHPTWAdr = WalkerState == L0_ADR;
 | 
			
		||||
@ -183,11 +183,11 @@ module hptw import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
    // hptw needs to know if there is a Dirty or Access fault occuring on this
 | 
			
		||||
    // 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_HADE = 0
 | 
			
		||||
    assign HPTWUpdateDA = ValidLeafPTE & (~Accessed | SetDirty) & ENVCFG_HADE & ~OtherPageFault;  
 | 
			
		||||
    // 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 HPTWRW[0] = (WalkerState == UPDATE_PTE);           // HPTWRW[0] will always be 0 if HADE = 0 because HPTWUpdateDA will be 0 so WalkerState never is UPDATE_PTE
 | 
			
		||||
    assign UpdatePTE = (WalkerState == LEAF) & HPTWUpdateDA;  // UpdatePTE will always be 0 if HADE = 0 because HPTWUpdateDA will be 0
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
  end else begin // block: hptwwrites
 | 
			
		||||
    assign NextPTE = ReadDataM;
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ module mmu import cvw::*;  #(parameter cvw_t P,
 | 
			
		||||
  input  logic                 STATUS_MPRV,        // Status CSR: modify machine privilege
 | 
			
		||||
  input  logic [1:0]           STATUS_MPP,         // Status CSR: previous machine privilege level
 | 
			
		||||
  input  logic                 ENVCFG_PBMTE,       // Page-based memory types enabled
 | 
			
		||||
  input  logic                 ENVCFG_HADE,        // HPTW A/D Update enable
 | 
			
		||||
  input  logic                 ENVCFG_ADUE,        // HPTW A/D Update enable
 | 
			
		||||
  input  logic [1:0]           PrivilegeModeW,     // Current privilege level of the processeor
 | 
			
		||||
  input  logic                 DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses
 | 
			
		||||
  input  logic [P.XLEN+1:0]    VAdr,               // virtual/physical address from IEU or physical address from HPTW
 | 
			
		||||
@ -84,7 +84,7 @@ module mmu import cvw::*;  #(parameter cvw_t P,
 | 
			
		||||
          .clk, .reset,
 | 
			
		||||
          .SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]),
 | 
			
		||||
          .SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]),
 | 
			
		||||
          .VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_HADE,
 | 
			
		||||
          .VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
 | 
			
		||||
          .PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOp,
 | 
			
		||||
          .DisableTranslation, .PTE, .PageTypeWriteVal,
 | 
			
		||||
          .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit, 
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,7 @@ module tlb import cvw::*;  #(parameter cvw_t P,
 | 
			
		||||
  input  logic                     STATUS_MXR, STATUS_SUM, STATUS_MPRV,
 | 
			
		||||
  input  logic [1:0]               STATUS_MPP,
 | 
			
		||||
  input  logic                     ENVCFG_PBMTE,     // Page-based memory types enabled
 | 
			
		||||
  input  logic                     ENVCFG_HADE,      // HPTW A/D Update enable
 | 
			
		||||
  input  logic                     ENVCFG_ADUE,      // HPTW A/D Update enable
 | 
			
		||||
  input  logic [1:0]               PrivilegeModeW,   // Current privilege level of the processeor
 | 
			
		||||
  input  logic                     ReadAccess, 
 | 
			
		||||
  input  logic                     WriteAccess,
 | 
			
		||||
@ -106,7 +106,7 @@ module tlb import cvw::*;  #(parameter cvw_t P,
 | 
			
		||||
 | 
			
		||||
  assign VPN = VAdr[P.VPN_BITS+11:12];
 | 
			
		||||
 | 
			
		||||
  tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_HADE,
 | 
			
		||||
  tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
 | 
			
		||||
    .PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOp, .DisableTranslation, .TLBFlush,
 | 
			
		||||
    .PTEAccessBits, .CAMHit, .Misaligned, 
 | 
			
		||||
    .TLBMiss, .TLBHit, .TLBPageFault, 
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@ module tlbcontrol import cvw::*;  #(parameter cvw_t P, ITLB = 0) (
 | 
			
		||||
  input  logic                     STATUS_MXR, STATUS_SUM, STATUS_MPRV,
 | 
			
		||||
  input  logic [1:0]               STATUS_MPP,
 | 
			
		||||
  input  logic                     ENVCFG_PBMTE,       // Page-based memory types enabled
 | 
			
		||||
  input  logic                     ENVCFG_HADE,        // HPTW A/D Update enable
 | 
			
		||||
  input  logic                     ENVCFG_ADUE,        // HPTW A/D Update enable
 | 
			
		||||
  input  logic [1:0]               PrivilegeModeW,     // Current privilege level of the processeor
 | 
			
		||||
  input  logic                     ReadAccess, WriteAccess,
 | 
			
		||||
  input  logic [3:0]               CMOp,
 | 
			
		||||
@ -119,10 +119,10 @@ module tlbcontrol import cvw::*;  #(parameter cvw_t P, ITLB = 0) (
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  // Determine wheter to update DA bits.  With SVADU, it is done in hardware
 | 
			
		||||
  assign UpdateDA = P.SVADU_SUPPORTED & PreUpdateDA & Translate & TLBHit & ~TLBPageFault & ENVCFG_HADE;
 | 
			
		||||
  assign UpdateDA = P.SVADU_SUPPORTED & PreUpdateDA & Translate & TLBHit & ~TLBPageFault & ENVCFG_ADUE;
 | 
			
		||||
 | 
			
		||||
  // Determine whether page fault occurs
 | 
			
		||||
  assign PrePageFault = UpperBitsUnequal | Misaligned | ~PTE_V | ImproperPrivilege | (P.XLEN == 64 & (BadPBMT | BadNAPOT | BadReserved)) | (PreUpdateDA & (~P.SVADU_SUPPORTED | ~ENVCFG_HADE));
 | 
			
		||||
  assign PrePageFault = UpperBitsUnequal | Misaligned | ~PTE_V | ImproperPrivilege | (P.XLEN == 64 & (BadPBMT | BadNAPOT | BadReserved)) | (PreUpdateDA & (~P.SVADU_SUPPORTED | ~ENVCFG_ADUE));
 | 
			
		||||
  assign TLBPageFault = Translate & TLBHit & (PrePageFault | InvalidAccess);
 | 
			
		||||
 | 
			
		||||
  assign TLBHit = CAMHit & TLBAccess;
 | 
			
		||||
 | 
			
		||||
@ -85,7 +85,7 @@ module csr import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  output logic [2:0]               FRM_REGW, 
 | 
			
		||||
  output logic [3:0]               ENVCFG_CBE,
 | 
			
		||||
  output logic                     ENVCFG_PBMTE,              // Page-based memory type enable
 | 
			
		||||
  output logic                     ENVCFG_HADE,               // HPTW A/D Update enable
 | 
			
		||||
  output logic                     ENVCFG_ADUE,               // HPTW A/D Update enable
 | 
			
		||||
  //
 | 
			
		||||
  output logic [P.XLEN-1:0]        CSRReadValW,               // value read from CSR
 | 
			
		||||
  output logic [P.XLEN-1:0]        UnalignedPCNextF,          // Next PC, accounting for traps and returns
 | 
			
		||||
@ -292,7 +292,7 @@ module csr import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
   // Broadcast appropriate environment configuration based on privilege mode
 | 
			
		||||
  assign ENVCFG_STCE =  MENVCFG_REGW[63]; // supervisor timer counter enable
 | 
			
		||||
  assign ENVCFG_PBMTE = MENVCFG_REGW[62]; // page-based memory types enable
 | 
			
		||||
  assign ENVCFG_HADE  = MENVCFG_REGW[61]; // Hardware A/D Update enable
 | 
			
		||||
  assign ENVCFG_ADUE  = MENVCFG_REGW[61]; // Hardware A/D Update enable
 | 
			
		||||
  assign ENVCFG_CBE =   (PrivilegeModeW == P.M_MODE) ? 4'b1111 : 
 | 
			
		||||
                        (PrivilegeModeW == P.S_MODE | !P.S_SUPPORTED) ? MENVCFG_REGW[7:4] : 
 | 
			
		||||
                                                                       (MENVCFG_REGW[7:4] & SENVCFG_REGW[7:4]);
 | 
			
		||||
 | 
			
		||||
@ -84,7 +84,7 @@ module privileged import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  output logic [2:0]        FRM_REGW,                                       // FPU rounding mode
 | 
			
		||||
  output logic [3:0]        ENVCFG_CBE,                                     // Cache block operation enables
 | 
			
		||||
  output logic              ENVCFG_PBMTE,                                   // Page-based memory type enable
 | 
			
		||||
  output logic              ENVCFG_HADE,                                    // HPTW A/D Update enable
 | 
			
		||||
  output logic              ENVCFG_ADUE,                                    // HPTW A/D Update enable
 | 
			
		||||
  // PC logic output in privileged unit                                    
 | 
			
		||||
  output logic [P.XLEN-1:0] UnalignedPCNextF,                               // Next PC from trap/return PC logic
 | 
			
		||||
  // control outputs                                                       
 | 
			
		||||
@ -141,7 +141,7 @@ module privileged import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
    .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS,
 | 
			
		||||
    .MEDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
 | 
			
		||||
    .SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
 | 
			
		||||
    .SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_HADE,
 | 
			
		||||
    .SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE,
 | 
			
		||||
    .CSRReadValW,.UnalignedPCNextF, .IllegalCSRAccessM, .BigEndianM);
 | 
			
		||||
 | 
			
		||||
  // pipeline early-arriving trap sources
 | 
			
		||||
 | 
			
		||||
@ -92,8 +92,7 @@ module trap import cvw::*;  #(parameter cvw_t P) (
 | 
			
		||||
  assign RetM  = mretM | sretM;
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // Cause priority defined in table 3.7 of 20190608 privileged spec
 | 
			
		||||
  // Exceptions are of lower priority than all interrupts (3.1.9)
 | 
			
		||||
  // Cause priority defined in privileged spec
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  always_comb
 | 
			
		||||
 | 
			
		||||
@ -79,7 +79,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
  logic                          LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
 | 
			
		||||
  logic                          SquashSCW;
 | 
			
		||||
  logic                          MDUActiveE;                      // Mul/Div instruction being executed
 | 
			
		||||
  logic                          ENVCFG_HADE;                     // HPTW A/D Update enable
 | 
			
		||||
  logic                          ENVCFG_ADUE;                     // HPTW A/D Update enable
 | 
			
		||||
  logic                          ENVCFG_PBMTE;                    // Page-based memory type enable
 | 
			
		||||
  logic [3:0]                    ENVCFG_CBE;                      // Cache Block operation enables
 | 
			
		||||
  logic [3:0]                    CMOpM;                           // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
 | 
			
		||||
@ -186,7 +186,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
    .IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM,
 | 
			
		||||
    // mmu management
 | 
			
		||||
    .PrivilegeModeW, .PTE, .PageType, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV,
 | 
			
		||||
    .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_HADE, .ITLBWriteF, .sfencevmaM, .ITLBMissF,
 | 
			
		||||
    .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, .ITLBWriteF, .sfencevmaM, .ITLBMissF,
 | 
			
		||||
    // pmp/pma (inside mmu) signals. 
 | 
			
		||||
    .PMPCFG_ARRAY_REGW,  .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF); 
 | 
			
		||||
    
 | 
			
		||||
@ -236,7 +236,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
    .STATUS_MPRV,                 // from csr            
 | 
			
		||||
    .STATUS_MPP,                  // from csr     
 | 
			
		||||
    .ENVCFG_PBMTE,                // from csr
 | 
			
		||||
    .ENVCFG_HADE,                 // from csr
 | 
			
		||||
    .ENVCFG_ADUE,                 // from csr
 | 
			
		||||
    .sfencevmaM,                  // connects to privilege
 | 
			
		||||
    .DCacheStallM,                // connects to privilege
 | 
			
		||||
    .LoadPageFaultM,              // connects to privilege
 | 
			
		||||
@ -298,7 +298,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
      .PrivilegeModeW, .SATP_REGW,
 | 
			
		||||
      .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, 
 | 
			
		||||
      .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, 
 | 
			
		||||
      .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_HADE, .wfiM, .IntPendingM, .BigEndianM);
 | 
			
		||||
      .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .wfiM, .IntPendingM, .BigEndianM);
 | 
			
		||||
  end else begin
 | 
			
		||||
    assign CSRReadValW      = 0;
 | 
			
		||||
    assign UnalignedPCNextF = PC2NextF;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
module loggers import cvw::*; #(parameter cvw_t P,
 | 
			
		||||
                                parameter TEST,
 | 
			
		||||
                                parameter string TEST,
 | 
			
		||||
                                parameter PrintHPMCounters,
 | 
			
		||||
                                parameter I_CACHE_ADDR_LOGGER,
 | 
			
		||||
                                parameter D_CACHE_ADDR_LOGGER,
 | 
			
		||||
 | 
			
		||||
@ -86,6 +86,24 @@ module testbench;
 | 
			
		||||
  logic Validate;
 | 
			
		||||
  logic SelectTest;
 | 
			
		||||
 | 
			
		||||
  // Nasty hack to get around Verilog simulators being picky about conditionally instantiated signals
 | 
			
		||||
  initial begin
 | 
			
		||||
    if (P.DTIM_SUPPORTED) begin
 | 
			
		||||
//      `define P_DTIM_SUPPORTED=1;
 | 
			
		||||
    end
 | 
			
		||||
    if (P.IROM_SUPPORTED) begin
 | 
			
		||||
      `define P_IROM_SUPPORTED=1;
 | 
			
		||||
    end
 | 
			
		||||
    if (P.BUS_SUPPORTED) begin
 | 
			
		||||
      `define P_BUS_SUPPORTED=1;
 | 
			
		||||
    end
 | 
			
		||||
    if (P.SDC_SUPPORTED) begin
 | 
			
		||||
      `define P_SDC_SUPPORTED=1;
 | 
			
		||||
    end
 | 
			
		||||
    if (P.UNCORE_RAM_SUPPORTED) begin
 | 
			
		||||
      `define P_UNCORE_RAM_SUPPORTED=1;
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  // pick tests based on modes supported
 | 
			
		||||
  initial begin
 | 
			
		||||
@ -271,7 +289,7 @@ module testbench;
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    if(TestBenchReset) test = 1;
 | 
			
		||||
    if (TEST == "coremark")
 | 
			
		||||
      if (dut.core.EcallFaultM) begin
 | 
			
		||||
      if (dut.core.priv.priv.EcallFaultM) begin
 | 
			
		||||
        $display("Benchmark: coremark is done.");
 | 
			
		||||
        $stop;
 | 
			
		||||
      end
 | 
			
		||||
@ -326,7 +344,7 @@ module testbench;
 | 
			
		||||
      if (P.UNCORE_RAM_SUPPORTED)
 | 
			
		||||
        for (adrindex=0; adrindex<(P.UNCORE_RAM_RANGE>>1+(P.XLEN/32)); adrindex = adrindex+1) 
 | 
			
		||||
          dut.uncore.uncore.ram.ram.memory.RAM[adrindex] = '0;
 | 
			
		||||
    if(reset) begin  // branch predictor must always be reset
 | 
			
		||||
/*    if(reset) begin  // branch predictor must always be reset
 | 
			
		||||
      if (P.BPRED_SUPPORTED) begin
 | 
			
		||||
        // local history only
 | 
			
		||||
        if (P.BPRED_TYPE == `BP_LOCAL_AHEAD | P.BPRED_TYPE == `BP_LOCAL_REPAIR)
 | 
			
		||||
@ -337,7 +355,7 @@ module testbench;
 | 
			
		||||
        for(adrindex = 0; adrindex < 2**P.BPRED_SIZE; adrindex++)
 | 
			
		||||
          dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex] = 0;
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    end */
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@ -345,18 +363,22 @@ module testbench;
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  always @(posedge clk) begin
 | 
			
		||||
    if (LoadMem) begin
 | 
			
		||||
      if (P.SDC_SUPPORTED) begin
 | 
			
		||||
      `ifdef P_SDC_SUPPORTED 
 | 
			
		||||
        string romfilename, sdcfilename;
 | 
			
		||||
        romfilename = {"../tests/custom/fpga-test-sdc/bin/fpga-test-sdc.memfile"};
 | 
			
		||||
        sdcfilename = {"../testbench/sdc/ramdisk2.hex"};   
 | 
			
		||||
        //$readmemh(romfilename, dut.uncore.uncore.bootrom.bootrom.memory.ROM);
 | 
			
		||||
        //$readmemh(sdcfilename, sdcard.sdcard.FLASHmem);
 | 
			
		||||
        // shorten sdc timers for simulation
 | 
			
		||||
        //dut.uncore.uncore.sdc.SDC.LimitTimers = 1;
 | 
			
		||||
      end 
 | 
			
		||||
      else if (P.IROM_SUPPORTED)     $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM);
 | 
			
		||||
      else if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
 | 
			
		||||
      if (P.DTIM_SUPPORTED)     $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM);
 | 
			
		||||
        //dut.uncore.uncore.sdc.SDC.LimitTimers = 1; 
 | 
			
		||||
      `elsif P_IROM_SUPPORTED   
 | 
			
		||||
        $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM);
 | 
			
		||||
      `else if P_BUS_SUPPORTED 
 | 
			
		||||
        $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
 | 
			
		||||
      `endif
 | 
			
		||||
      `ifdef P_DTIM_SUPPORTED
 | 
			
		||||
        $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM);
 | 
			
		||||
      `endif
 | 
			
		||||
      $display("Read memfile %s", memfilename);
 | 
			
		||||
    end
 | 
			
		||||
  end  
 | 
			
		||||
 | 
			
		||||
@ -42,8 +42,8 @@ beef0110
 | 
			
		||||
deadbeef # Test 11.3.1.3.7(a) successful read when D = 0
 | 
			
		||||
00000009 # call from going to m mode from s mode
 | 
			
		||||
0000000b # ecall from going to S mode from m mode
 | 
			
		||||
beef0770 # Test 11.3.1.3.6: check successful read/write when A=0 and MENVCFG.HADE=1
 | 
			
		||||
beef0aa0 # Test 11.3.1.3.7: check successful read/write when D=0 and MENVCFG.HADE=1
 | 
			
		||||
beef0770 # Test 11.3.1.3.6: check successful read/write when A=0 and MENVCFG.ADUE=1
 | 
			
		||||
beef0aa0 # Test 11.3.1.3.7: check successful read/write when D=0 and MENVCFG.ADUE=1
 | 
			
		||||
beef0077 # Test 11.3.1.4.1: successful read back of saved value with new memory mapping
 | 
			
		||||
00000009 # Test 11.3.1.5.1: ecall from going to m mode from s mode
 | 
			
		||||
00000000 # previous value of mprv before being set
 | 
			
		||||
 | 
			
		||||
@ -157,7 +157,7 @@ test_cases:
 | 
			
		||||
.4byte 0xBFFDE0, 0xbad, executable_test             # instr page fault when X=0 
 | 
			
		||||
 | 
			
		||||
# In the following two tests, SVADU is supported, so the hardware handles the A/D bits
 | 
			
		||||
# Initially test with HADE = 0, so needing to set A/D bits triggers page fault
 | 
			
		||||
# Initially test with ADUE = 0, so needing to set A/D bits triggers page fault
 | 
			
		||||
 | 
			
		||||
# test 11.3.1.3.6(a) Accessed flag == 0
 | 
			
		||||
.4byte 0x3020, 0xBEEF0770, write32_test     # store page fault when A=0
 | 
			
		||||
@ -167,9 +167,9 @@ test_cases:
 | 
			
		||||
.4byte 0x4658, 0xBEEF0AA0, write32_test # store page fault when D=0
 | 
			
		||||
.4byte 0x4658, 0xDEADBEEF, read32_test  # read success when D=0; default DEADBEEF value wasn't changed
 | 
			
		||||
 | 
			
		||||
# Now set HADE bit
 | 
			
		||||
# Now set ADUE bit
 | 
			
		||||
.4byte 0x0, 0x0, goto_m_mode # change to M mode, 0x9 written to output
 | 
			
		||||
.4byte 0x0, 0x20000000, write_menvcfgh  # set menvcfg.HADE = 1
 | 
			
		||||
.4byte 0x0, 0x20000000, write_menvcfgh  # set menvcfg.ADUE = 1
 | 
			
		||||
.4byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
 | 
			
		||||
 | 
			
		||||
# Since SVADU is 1, there are no faults when A/D=0
 | 
			
		||||
 | 
			
		||||
@ -196,7 +196,7 @@ test_cases:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# In the following two tests, SVADU is supported, so the hardware handles the A/D bits
 | 
			
		||||
# Initially test with HADE = 0, so needing to set A/D bits triggers page fault
 | 
			
		||||
# Initially test with ADUE = 0, so needing to set A/D bits triggers page fault
 | 
			
		||||
 | 
			
		||||
# test 11.3.1.3.6(a) Accessed flag == 0
 | 
			
		||||
.8byte 0x36D0, 0x0990DEADBEEF0770, write64_test# store page fault when A=0
 | 
			
		||||
@ -206,9 +206,9 @@ test_cases:
 | 
			
		||||
.8byte 0x4658, 0x0440DEADBEEF0AA0, write64_test# store page fault when D=0
 | 
			
		||||
.8byte 0x4AA0, 0xDEADBEEFDEADBEEF, read64_test# read success when D=0
 | 
			
		||||
 | 
			
		||||
# Now set HADE bit
 | 
			
		||||
# Now set ADUE bit
 | 
			
		||||
.8byte 0x0, 0x0, goto_m_mode # change to M mode, 0x9 written to output
 | 
			
		||||
.8byte 0x0, 0x2000000000000000, write_menvcfg  # set menvcfg.HADE = 1
 | 
			
		||||
.8byte 0x0, 0x2000000000000000, write_menvcfg  # set menvcfg.ADUE = 1
 | 
			
		||||
.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
 | 
			
		||||
 | 
			
		||||
# Since SVADU is 1, there are no faults when A/D=0
 | 
			
		||||
 | 
			
		||||
@ -189,7 +189,7 @@ test_cases:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# In the following two tests, SVADU is supported, so the hardware handles the A/D bits
 | 
			
		||||
# Initially test with HADE = 0, so needing to set A/D bits triggers page fault
 | 
			
		||||
# Initially test with ADUE = 0, so needing to set A/D bits triggers page fault
 | 
			
		||||
 | 
			
		||||
# test 11.3.1.3.6(a) Accessed flag == 0
 | 
			
		||||
.8byte 0x802036D0, 0x0990DEADBEEF0770, write64_test # store page fault when A=0
 | 
			
		||||
@ -199,9 +199,9 @@ test_cases:
 | 
			
		||||
.8byte 0x80204658, 0x0440DEADBEEF0AA0, write64_test # store page fault when D=0
 | 
			
		||||
.8byte 0x80204658, 0xDEADBEEFDEADBEEF, read64_test  # read success when D=0
 | 
			
		||||
 | 
			
		||||
# Now set HADE bit
 | 
			
		||||
# Now set ADUE bit
 | 
			
		||||
.8byte 0x0, 0x0, goto_m_mode # change to M mode, 0x9 written to output
 | 
			
		||||
.8byte 0x0, 0x2000000000000000, write_menvcfg  # set menvcfg.HADE = 1
 | 
			
		||||
.8byte 0x0, 0x2000000000000000, write_menvcfg  # set menvcfg.ADUE = 1
 | 
			
		||||
.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
 | 
			
		||||
 | 
			
		||||
# Since SVADU is 1, there are no faults when A/D=0
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user