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