diff --git a/.gitignore b/.gitignore index acaab4b01..e8ff572fa 100644 --- a/.gitignore +++ b/.gitignore @@ -103,4 +103,11 @@ external sim/results tests/wally-riscv-arch-test/riscv-test-suite/rv*i_m/I/src/*.S tests/wally-riscv-arch-test/riscv-test-suite/rv*i_m/I/Makefrag - +sim/branch_BP_GSHARE10.log +sim/branch_BP_GSHARE16.log +sim/cov/ +sim/covhtmlreport/ +sim/imperas.log +sim/results-error/ +sim/test1.rep +sim/vsim.log diff --git a/examples/link/link.ld b/examples/link/link.ld index d84c332a1..1e20a7a13 100644 --- a/examples/link/link.ld +++ b/examples/link/link.ld @@ -12,6 +12,8 @@ SECTIONS .data.string : { *(.data.string)} . = ALIGN(0x1000); .bss : { *(.bss) } + . = ALIGN(0x1000); + .text : { *(.text.main) } _end = .; } diff --git a/sim/coverage-exclusions-rv64gc.do b/sim/coverage-exclusions-rv64gc.do new file mode 100644 index 000000000..8f79b7d5d --- /dev/null +++ b/sim/coverage-exclusions-rv64gc.do @@ -0,0 +1,34 @@ +#/////////////////////////////////////////// +#// coverage-exclusions-rv64gc.do +#// +#// Written: David_Harris@hmc.edu 19 March 2023 +#// +#// Purpose: Set of exclusions from coverage for rv64gc configuration +#// For example, signals hardwired to 0 should not be checked for toggle coverage +#// +#// A component of the CORE-V-WALLY configurable RISC-V project. +#// +#// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +#// +#// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +#// +#// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +#// except in compliance with the License, or, at your option, the Apache License version 2.0. You +#// may obtain a copy of the License at +#// +#// https://solderpad.org/licenses/SHL-2.1/ +#// +#// Unless required by applicable law or agreed to in writing, any work distributed under the +#// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +#// either express or implied. See the License for the specific language governing permissions +#// and limitations under the License. +#//////////////////////////////////////////////////////////////////////////////////////////////// + +# Exclude DivBusyE from all design units because rv64gc uses the fdivsqrt unit for integer division +coverage exclude -togglenode DivBusyE -du * +# Exclude QuotM and RemM from MDU because rv64gc uses the fdivsqrt rather tha div unit for integer division +coverage exclude -togglenode /dut/core/mdu/mdu/QuotM +coverage exclude -togglenode /dut/core/mdu/mdu/RemM + +# StallFCause is hardwired to 0 +coverage exclude -togglenode /dut/core/hzu/StallFCause diff --git a/sim/regression-wally b/sim/regression-wally index 560f7795b..11c75c090 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -126,6 +126,7 @@ for test in ahbTests: grepstr="All tests ran without failures") configs.append(tc) +#tests64gc = ["arch64i", "arch64c", "arch64m"] tests64gc = ["arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zi", "wally64a", "wally64periph", "wally64priv"] if (coverage): # delete all but 64gc tests when running coverage configs = [] @@ -217,8 +218,10 @@ def main(): if coverage: print('Generating coverage report') os.system('vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log') - os.system('vcover report -details cov/cov.ucdb > cov/rv64gc_coverage.rpt') - os.system('vcover report -html cov/cov.ucdb') + os.system('vcover report -details cov/cov.ucdb > cov/rv64gc_coverage_details.rpt') + os.system('vcover report -below 100 cov/cov.ucdb > cov/rv64gc_coverage.rpt') + os.system('vcover report -recursive cov/cov.ucdb > cov/rv64gc_recursive.rpt') + os.system('vcover report -details -threshH 100 -html cov/cov.ucdb') # Count the number of failures if num_fail: print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail) diff --git a/sim/wally-batch.do b/sim/wally-batch.do index 830538999..7815e94fc 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -124,7 +124,8 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals if {$coverage} { - vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf +# vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf + vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbecf vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage } else { vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt @@ -138,8 +139,8 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { } if {$coverage} { - do coverage-exclusions.do - coverage save -instance /testbench/dut cov/${1}_${2}.ucdb + do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration + coverage save -instance /testbench/dut/core cov/${1}_${2}.ucdb } # These aren't doing anything helpful diff --git a/src/cache/cache.sv b/src/cache/cache.sv index de3b8d711..5d4fca7d5 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -197,7 +197,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE // Cache FSM ///////////////////////////////////////////////////////////////////////////////////////////// - cachefsm cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck, + cachefsm #(READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck, .FlushStage, .CacheRW, .CacheAtomic, .Stall, .CacheHit, .LineDirty, .CacheStall, .CacheCommitted, .CacheMiss, .CacheAccess, .SelAdr, diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index d7af193b1..1edb0b65a 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -29,7 +29,7 @@ `include "wally-config.vh" -module cachefsm ( +module cachefsm #(parameter READ_ONLY_CACHE = 0) ( input logic clk, input logic reset, // hazard and privilege unit @@ -112,8 +112,8 @@ module cachefsm ( NextState = STATE_READY; case (CurrState) STATE_READY: if(InvalidateCache) NextState = STATE_READY; - else if(FlushCache) NextState = STATE_FLUSH; - else if(AnyMiss & ~LineDirty) NextState = STATE_FETCH; + else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; + else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK; else NextState = STATE_READY; STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE; @@ -125,11 +125,11 @@ module cachefsm ( else NextState = STATE_WRITEBACK; // eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack. STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK; - else if (FlushFlag) NextState = STATE_READ_HOLD; - else NextState = STATE_FLUSH; - STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH; - else if(CacheBusAck) NextState = STATE_READ_HOLD; - else NextState = STATE_FLUSH_WRITEBACK; + else if (FlushFlag) NextState = STATE_READ_HOLD; + else NextState = STATE_FLUSH; + STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH; + else if(CacheBusAck) NextState = STATE_READ_HOLD; + else NextState = STATE_FLUSH_WRITEBACK; default: NextState = STATE_READY; endcase end diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 876fdaa1a..9acaeb2ff 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -66,7 +66,6 @@ module controller( output logic RegWriteM, // Instruction writes a register (needed for Hazard unit) output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$ output logic InstrValidD, InstrValidE, InstrValidM, // Instruction is valid - output logic FenceM, // Fence instruction output logic FWriteIntM, // FPU controller writes integer register file // Writeback stage control signals input logic StallW, FlushW, // Stall, flush Writeback stage @@ -116,6 +115,7 @@ module controller( logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions logic JFunctD; // detect jalr instruction + logic FenceM; // Fence.I or sfence.VMA instruction in memory stage // Extract fields assign OpD = InstrD[6:0]; @@ -280,7 +280,6 @@ module controller( // Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA assign CSRWriteFenceM = CSRWriteM | FenceM; - // assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FenceD | FenceE | FenceM; // the synchronous DTIM cannot read immediately after write // a cache cannot read or write immediately after a write diff --git a/src/ieu/ieu.sv b/src/ieu/ieu.sv index 854233741..de99aebb4 100644 --- a/src/ieu/ieu.sv +++ b/src/ieu/ieu.sv @@ -71,8 +71,7 @@ module ieu ( output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit output logic MDUStallD, CSRRdStallD, StoreStallD, output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction - output logic CSRWriteFenceM, // CSR write or fence instruction needs to flush subsequent instructions - output logic FenceM + output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions ); logic [2:0] ImmSrcD; // Select type of immediate extension @@ -99,8 +98,8 @@ module ieu ( .PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE, .Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, - .RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, - .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .FenceM, .StoreStallD); + .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, + .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); datapath dp( .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, diff --git a/src/lsu/subwordread.sv b/src/lsu/subwordread.sv index 784db694d..7301f89aa 100644 --- a/src/lsu/subwordread.sv +++ b/src/lsu/subwordread.sv @@ -87,7 +87,8 @@ module subwordread 3'b001: ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh 3'b010: ReadDataM = {{`LLEN-32{WordM[31]|FpLoadStoreM}}, WordM[31:0]}; // lw/flw 3'b011: ReadDataM = {{`LLEN-64{DblWordM[63]|FpLoadStoreM}}, DblWordM[63:0]}; // ld/fld - 3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq + 3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu +// 3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128 3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu 3'b110: ReadDataM = {{`LLEN-32{1'b0}}, WordM[31:0]}; // lwu default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen diff --git a/src/mdu/intdivrestoring.sv b/src/mdu/div.sv similarity index 98% rename from src/mdu/intdivrestoring.sv rename to src/mdu/div.sv index 0d95233ca..05c3a5580 100644 --- a/src/mdu/intdivrestoring.sv +++ b/src/mdu/div.sv @@ -28,7 +28,7 @@ `include "wally-config.vh" -module intdivrestoring( +module div( input logic clk, input logic reset, input logic StallM, @@ -107,7 +107,7 @@ module intdivrestoring( // one copy of divstep for each bit produced per cycle genvar i; for (i=0; i<`IDIV_BITSPERCYCLE; i = i+1) - intdivrestoringstep divstep(W[i], XQ[i], DAbsB, W[i+1], XQ[i+1]); + divstep divstep(W[i], XQ[i], DAbsB, W[i+1], XQ[i+1]); ////////////////////////////// // Memory Stage: output sign correction and special cases diff --git a/src/mdu/intdivrestoringstep.sv b/src/mdu/divstep.sv similarity index 95% rename from src/mdu/intdivrestoringstep.sv rename to src/mdu/divstep.sv index cc27a7d5b..cb06efda2 100644 --- a/src/mdu/intdivrestoringstep.sv +++ b/src/mdu/divstep.sv @@ -4,7 +4,7 @@ // Written: David_Harris@hmc.edu 2 October 2021 // Modified: // -// Purpose: Restoring integer division step. k steps are used in intdivrestoring +// Purpose: Radix-2 restoring integer division step. k steps are used in div // // Documentation: RISC-V System on Chip Design Chapter 12 (Figure 12.19) // @@ -30,7 +30,7 @@ /* verilator lint_off UNOPTFLAT */ -module intdivrestoringstep( +module divstep( input logic [`XLEN-1:0] W, // Residual in input logic [`XLEN-1:0] XQ, // bits of dividend X and quotient Q in input logic [`XLEN-1:0] DAbsB, // complement of absolute value of divisor D (for subtraction) diff --git a/src/mdu/mdu.sv b/src/mdu/mdu.sv index 21d4dd4bc..7fc5c329f 100644 --- a/src/mdu/mdu.sv +++ b/src/mdu/mdu.sv @@ -57,8 +57,8 @@ module mdu( assign RemM = 0; assign DivBusyE = 0; end else begin:div - intdivrestoring div(.clk, .reset, .StallM, .FlushE, .DivSignedE(~Funct3E[0]), .W64E, .IntDivE, - .ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM); + div div(.clk, .reset, .StallM, .FlushE, .DivSignedE(~Funct3E[0]), .W64E, .IntDivE, + .ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM); end // Result multiplexer diff --git a/src/mmu/pmpchecker.sv b/src/mmu/pmpchecker.sv index 9c9c745bb..828747e24 100644 --- a/src/mmu/pmpchecker.sv +++ b/src/mmu/pmpchecker.sv @@ -50,14 +50,14 @@ module pmpchecker ( ); // 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 EnforcePMP; // should PMP be checked in this privilege level + 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] + logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] - if (`PMP_ENTRIES > 0) + if (`PMP_ENTRIES > 0) // prevent complaints about array of no elements when PMP_ENTRIES = 0 pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0]( .PhysicalAddress, .PMPCfg(PMPCFG_ARRAY_REGW), @@ -68,8 +68,10 @@ module pmpchecker ( 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 + // Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active; +// assign EnforcePMP = (PrivilegeModeW != `M_MODE) | |(L & FirstMatch); // *** switch to this logic when PMP is initialized for non-machine mode +// *** remove unused Active lines from pmpadrdecs assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ; diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 0764e6c69..06762e6db 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -72,7 +72,7 @@ module csr #(parameter input logic ICacheMiss, input logic ICacheAccess, input logic sfencevmaM, - input logic FenceM, + input logic InvalidateICacheM, input logic DivBusyE, // integer divide busy input logic FDivBusyE, // floating point divide busy // outputs from CSRs @@ -210,7 +210,7 @@ module csr #(parameter csri csri(.clk, .reset, .InstrValidNotFlushedM, .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, .MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt, - .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); + .MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); csrsr csrsr(.clk, .reset, .StallW, .WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM, @@ -268,7 +268,7 @@ module csr #(parameter .InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM, .CSRMWriteM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM, - .InterruptM, .ExceptionM, .FenceM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, + .InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .CSRAdrM, .PrivilegeModeW, .CSRWriteValM, .MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW, .MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM); diff --git a/src/privileged/csrc.sv b/src/privileged/csrc.sv index b4f89f188..56b7dbbc9 100644 --- a/src/privileged/csrc.sv +++ b/src/privileged/csrc.sv @@ -60,7 +60,7 @@ module csrc #(parameter input logic sfencevmaM, input logic InterruptM, input logic ExceptionM, - input logic FenceM, + input logic InvalidateICacheM, input logic DivBusyE, // integer divide busy input logic FDivBusyE, // floating point divide busy input logic [11:0] CSRAdrM, @@ -111,7 +111,7 @@ module csrc #(parameter assign CounterEvent[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[18] = ICacheStallF; // i cache miss cycles assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes - assign CounterEvent[20] = FenceM & InstrValidNotFlushedM; // fence.i + assign CounterEvent[20] = InvalidateICacheM & InstrValidNotFlushedM; // fence.i assign CounterEvent[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low diff --git a/src/privileged/csri.sv b/src/privileged/csri.sv index bdbb0f591..27ed7a016 100644 --- a/src/privileged/csri.sv +++ b/src/privileged/csri.sv @@ -40,6 +40,7 @@ module csri #(parameter input logic [`XLEN-1:0] CSRWriteValM, input logic [11:0] CSRAdrM, input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt, + input logic [11:0] MIDELEG_REGW, output logic [11:0] MIP_REGW, MIE_REGW, output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0 ); @@ -66,7 +67,7 @@ module csri #(parameter assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9) assign STIP = MIP_REGW_writeable[5]; end - assign SIP_WRITE_MASK = 12'h002; // SSIP is writeable in SIP (privileged 20210108-draft 4.1.3) + assign SIP_WRITE_MASK = 12'h002 & MIDELEG_REGW; // SSIP is writeable in SIP (privileged 20210108-draft 4.1.3) assign MIE_WRITE_MASK = 12'hAAA; end else begin:mask assign MIP_WRITE_MASK = 12'h000; @@ -80,7 +81,7 @@ module csri #(parameter always @(posedge clk) if (reset) MIE_REGW <= 12'b0; else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields - else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (MIE_REGW & 12'h888); // only S fields + else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222 & MIDELEG_REGW) | (MIE_REGW & 12'h888); // only S fields assign MIP_REGW = {MExtInt, 1'b0, SExtInt|MIP_REGW_writeable[9], 1'b0, diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index e47a44426..1795f72c8 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -123,7 +123,7 @@ module csrs #(parameter SSTATUS: CSRSReadValM = SSTATUS_REGW; STVEC: CSRSReadValM = STVEC_REGW; SIP: CSRSReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW & 12'h222 & MIDELEG_REGW}; // only read supervisor fields - SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW & 12'h222}; // only read supervisor fields + SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW & 12'h222 & MIDELEG_REGW}; // only read supervisor fields SSCRATCH: CSRSReadValM = SSCRATCH_REGW; SEPC: CSRSReadValM = SEPC_REGW; SCAUSE: CSRSReadValM = SCAUSE_REGW; diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 251dbb3d6..293fc4b31 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -88,7 +88,7 @@ module privileged ( // control outputs output logic RetM, TrapM, // return instruction, or trap output logic sfencevmaM, // sfence.vma instruction - input logic FenceM, // fence instruction + input logic InvalidateICacheM, // fence instruction output logic BigEndianM, // Use big endian in current privilege mode // Fault outputs output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire @@ -131,7 +131,7 @@ module privileged ( .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM, - .sfencevmaM, .ExceptionM, .FenceM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, + .sfencevmaM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM, diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index a226c7839..601668627 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -161,7 +161,6 @@ module wallypipelinedcore ( logic FCvtIntE; logic CommittedF; logic BranchD, BranchE, JumpD, JumpE; - logic FenceM; logic DCacheStallM, ICacheStallF; // instruction fetch unit: PC, branch prediction, instruction cache @@ -201,7 +200,7 @@ module wallypipelinedcore ( .WriteDataM, // Write data to LSU .Funct3M, // size and signedness to LSU .SrcAM, // to privilege and fpu - .RdE, .RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM, + .RdE, .RdM, .FIntResM, .FlushDCacheM, .BranchD, .BranchE, .JumpD, .JumpE, // Writeback stage .CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]), @@ -209,7 +208,7 @@ module wallypipelinedcore ( // hazards .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD, .PCSrcE, - .CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .FenceM, .StoreStallD); + .CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); lsu lsu( .clk, .reset, .StallM, .FlushM, .StallW, .FlushW, @@ -288,7 +287,7 @@ module wallypipelinedcore ( .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PC2NextF, .InstrM, .CSRReadValW, .UnalignedPCNextF, - .RetM, .TrapM, .sfencevmaM, .FenceM, .DCacheStallM, .ICacheStallF, + .RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF, .InstrValidM, .CommittedM, .CommittedF, .FRegWriteM, .LoadStallD, .StoreStallD, .BPDirPredWrongM, .BTAWrongM, .BPWrongM, diff --git a/testbench/tests.vh b/testbench/tests.vh index 2ec4e43fc..b07984834 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -1758,15 +1758,15 @@ string imperas32f[] = '{ "rv64i_m/privilege/src/WALLY-mtvec-01.S", "rv64i_m/privilege/src/WALLY-pma-01.S", "rv64i_m/privilege/src/WALLY-pmp-01.S", - "rv64i_m/privilege/src/WALLY-sie-01.S", +// "rv64i_m/privilege/src/WALLY-sie-01.S", "rv64i_m/privilege/src/WALLY-status-mie-01.S", - "rv64i_m/privilege/src/WALLY-status-sie-01.S", +// "rv64i_m/privilege/src/WALLY-status-sie-01.S", "rv64i_m/privilege/src/WALLY-status-tw-01.S", "rv64i_m/privilege/src/WALLY-status-tvm-01.S", "rv64i_m/privilege/src/WALLY-status-fp-enabled-01.S", - "rv64i_m/privilege/src/WALLY-stvec-01.S", - "rv64i_m/privilege/src/WALLY-trap-01.S", - "rv64i_m/privilege/src/WALLY-trap-s-01.S", +// "rv64i_m/privilege/src/WALLY-stvec-01.S", +// "rv64i_m/privilege/src/WALLY-trap-01.S", +// "rv64i_m/privilege/src/WALLY-trap-s-01.S", "rv64i_m/privilege/src/WALLY-trap-sret-01.S", "rv64i_m/privilege/src/WALLY-trap-u-01.S", "rv64i_m/privilege/src/WALLY-wfi-01.S", @@ -1846,15 +1846,15 @@ string imperas32f[] = '{ "rv32i_m/privilege/src/WALLY-mtvec-01.S", "rv32i_m/privilege/src/WALLY-pma-01.S", "rv32i_m/privilege/src/WALLY-pmp-01.S", - "rv32i_m/privilege/src/WALLY-sie-01.S", +// "rv32i_m/privilege/src/WALLY-sie-01.S", "rv32i_m/privilege/src/WALLY-status-mie-01.S", - "rv32i_m/privilege/src/WALLY-status-sie-01.S", +// "rv32i_m/privilege/src/WALLY-status-sie-01.S", "rv32i_m/privilege/src/WALLY-status-tw-01.S", "rv32i_m/privilege/src/WALLY-status-tvm-01.S", "rv32i_m/privilege/src/WALLY-status-fp-enabled-01.S", - "rv32i_m/privilege/src/WALLY-stvec-01.S", - "rv32i_m/privilege/src/WALLY-trap-01.S", - "rv32i_m/privilege/src/WALLY-trap-s-01.S", +// "rv32i_m/privilege/src/WALLY-stvec-01.S", +// "rv32i_m/privilege/src/WALLY-trap-01.S", +// "rv32i_m/privilege/src/WALLY-trap-s-01.S", "rv32i_m/privilege/src/WALLY-trap-sret-01.S", "rv32i_m/privilege/src/WALLY-trap-u-01.S", "rv32i_m/privilege/src/WALLY-wfi-01.S", diff --git a/tests/coverage/Makefile b/tests/coverage/Makefile new file mode 100644 index 000000000..7773e7c14 --- /dev/null +++ b/tests/coverage/Makefile @@ -0,0 +1,19 @@ +TARGET = badinstr + +$(TARGET).objdump: $(TARGET) + riscv64-unknown-elf-objdump -D $(TARGET) > $(TARGET).objdump + +$(TARGET): $(TARGET).S WALLY-init-lib.S Makefile + riscv64-unknown-elf-gcc -g -o $(TARGET) -march=rv64gc -mabi=lp64 -mcmodel=medany \ + -nostartfiles -T../../examples/link/link.ld $(TARGET).S + +sim: + spike +signature=$(TARGET).signature.output +signature-granularity=8 $(TARGET) + diff --ignore-case $(TARGET).signature.output $(TARGET).reference_output || exit + echo "Signature matches! Success!" + +clean: + rm -f $(TARGET) $(TARGET).objdump $(TARGET).signature.output + + + diff --git a/tests/coverage/WALLY-init-lib.S b/tests/coverage/WALLY-init-lib.S new file mode 100644 index 000000000..2d30aba24 --- /dev/null +++ b/tests/coverage/WALLY-init-lib.S @@ -0,0 +1,119 @@ +/////////////////////////////////////////// +// WALLY-init-lib.S +// +// Written: David_Harris@hmc.edu 21 March 2023 +// +// Purpose: Initialize stack, handle interrupts, terminate test case +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +// load code to initalize stack, handle interrupts, terminate + +.section .text.init +.global rvtest_entry_point + +rvtest_entry_point: + la sp, topofstack # Initialize stack pointer (not used) + + # Set up interrupts + la t0, trap_handler + csrw mtvec, t0 # Initialize MTVEC to trap_handler + csrw mideleg, zero # Don't delegate interrupts + csrw medeleg, zero # Don't delegate exceptions + csrw mie, t0 # Enable machine timer interrupt + la t0, topoftrapstack + csrw mscratch, t0 # MSCRATCH holds trap stack pointer + csrsi mstatus, 0x8 # Turn on mstatus.MIE global interrupt enable + j main # Call main function in user test program + +done: + li a0, 4 # argument to finish program + ecall # system call to finish program + j self_loop # wait forever (not taken) + +.align 4 # trap handlers must be aligned to multiple of 4 +trap_handler: + # Load trap handler stack pointer tp + csrrw tp, mscratch, tp # swap MSCRATCH and tp + sd t0, 0(tp) # Save t0 and t1 on the stack + sd t1, -8(tp) + csrr t0, mcause # Check the cause + csrr t1, mtval # And the trap value + bgez t0, exception # if msb is clear, it is an exception + +interrupt: # must be a timer interrupt + j trap_return # clean up and return + +exception: + csrr t1, mepc # add 4 to MEPC to determine return Address + addi t1, t1, 4 + csrw mepc, t1 + li t1, 8 # is it an ecall trap? + andi t0, t0, 0xFC # if CAUSE = 8, 9, or 11 + bne t0, t1, trap_return # ignore other exceptions + +ecall: + li t0, 4 + beq a0, t0, write_tohost # call 4: terminate program + bltu a0, t0, changeprivilege # calls 0-3: change privilege level + j trap_return # ignore other ecalls + +changeprivilege: + li t0, 0x00001800 # mask off mstatus.MPP in bits 11-12 + csrc mstatus, t0 + andi a0, a0, 0x003 # only keep bottom two bits of argument + slli a0, a0, 11 # move into mstatus.MPP position + csrs mstatus, a0 # set mstatus.MPP with desired privilege + +trap_return: # return from trap handler + ld t1, -8(tp) # restore t1 and t0 + ld t0, 0(tp) + csrrw tp, mscratch, tp # restore tp + mret # return from trap + +write_tohost: + la t1, tohost + li t0, 1 # 1 for success, 3 for failure + sd t0, 0(t1) # send success code + +self_loop: + j self_loop # wait + +.section .tohost +tohost: # write to HTIF + .dword 0 +fromhost: + .dword 0 + +.EQU XLEN,64 +begin_signature: + .fill 6*(XLEN/32),4,0xdeadbeef # +end_signature: + +# Initialize stack with room for 512 bytes +.bss + .space 512 +topofstack: +# And another stack for the trap handler +.bss + .space 512 +topoftrapstack: + +.align 4 +.section .text.main diff --git a/tests/coverage/badinstr.S b/tests/coverage/badinstr.S new file mode 100644 index 000000000..9ec6844d1 --- /dev/null +++ b/tests/coverage/badinstr.S @@ -0,0 +1,47 @@ +/////////////////////////////////////////// +// badinstr.S +// +// Written: David_Harris@hmc.edu 21 March 2023 +// +// Purpose: Test illegal instruction opcodes +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +// load code to initalize stack, handle interrupts, terminate +#include "WALLY-init-lib.S" + +main: + .word 0x00000033 // legal instruction + .word 0x80000033 // illegal instruction + .word 0x00000000 // illegal instruction + + j done +/* +main: + # Change to user mode + li a0, 0 # a0 = 0: argument to enter user mode + ecall # System call to enter user mode + + # Wait for timer interrupts + li t0, 0x1000 # loop counter start value +loop: + addi t0, t0, -1 # decrement counter + bne t0, zero, loop # and repeat until zero + +*/ \ No newline at end of file