Merge pull request #146 from davidharrishmc/dev

Many fixes
This commit is contained in:
Ross Thompson 2023-03-21 11:33:47 -05:00 committed by GitHub
commit a605f4801e
24 changed files with 290 additions and 57 deletions

9
.gitignore vendored
View File

@ -103,4 +103,11 @@ external
sim/results 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/src/*.S
tests/wally-riscv-arch-test/riscv-test-suite/rv*i_m/I/Makefrag 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

View File

@ -12,6 +12,8 @@ SECTIONS
.data.string : { *(.data.string)} .data.string : { *(.data.string)}
. = ALIGN(0x1000); . = ALIGN(0x1000);
.bss : { *(.bss) } .bss : { *(.bss) }
. = ALIGN(0x1000);
.text : { *(.text.main) }
_end = .; _end = .;
} }

View File

@ -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

View File

@ -126,6 +126,7 @@ for test in ahbTests:
grepstr="All tests ran without failures") grepstr="All tests ran without failures")
configs.append(tc) configs.append(tc)
#tests64gc = ["arch64i", "arch64c", "arch64m"]
tests64gc = ["arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zi", "wally64a", "wally64periph", "wally64priv"] tests64gc = ["arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zi", "wally64a", "wally64periph", "wally64priv"]
if (coverage): # delete all but 64gc tests when running coverage if (coverage): # delete all but 64gc tests when running coverage
configs = [] configs = []
@ -217,8 +218,10 @@ def main():
if coverage: if coverage:
print('Generating coverage report') 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 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 -details cov/cov.ucdb > cov/rv64gc_coverage_details.rpt')
os.system('vcover report -html cov/cov.ucdb') 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 # Count the number of failures
if num_fail: if num_fail:
print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail) print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail)

View File

@ -124,7 +124,8 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
# start and run simulation # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals
if {$coverage} { 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 vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage
} else { } else {
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt 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} { if {$coverage} {
do coverage-exclusions.do do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration
coverage save -instance /testbench/dut cov/${1}_${2}.ucdb coverage save -instance /testbench/dut/core cov/${1}_${2}.ucdb
} }
# These aren't doing anything helpful # These aren't doing anything helpful

2
src/cache/cache.sv vendored
View File

@ -197,7 +197,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
// Cache FSM // Cache FSM
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
cachefsm cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck, cachefsm #(READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck,
.FlushStage, .CacheRW, .CacheAtomic, .Stall, .FlushStage, .CacheRW, .CacheAtomic, .Stall,
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted, .CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr, .CacheMiss, .CacheAccess, .SelAdr,

16
src/cache/cachefsm.sv vendored
View File

@ -29,7 +29,7 @@
`include "wally-config.vh" `include "wally-config.vh"
module cachefsm ( module cachefsm #(parameter READ_ONLY_CACHE = 0) (
input logic clk, input logic clk,
input logic reset, input logic reset,
// hazard and privilege unit // hazard and privilege unit
@ -112,8 +112,8 @@ module cachefsm (
NextState = STATE_READY; NextState = STATE_READY;
case (CurrState) case (CurrState)
STATE_READY: if(InvalidateCache) NextState = STATE_READY; STATE_READY: if(InvalidateCache) NextState = STATE_READY;
else if(FlushCache) NextState = STATE_FLUSH; else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
else if(AnyMiss & ~LineDirty) NextState = STATE_FETCH; else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH;
else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK; else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK;
else NextState = STATE_READY; else NextState = STATE_READY;
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE; STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
@ -125,11 +125,11 @@ module cachefsm (
else NextState = STATE_WRITEBACK; 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. // 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; STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK;
else if (FlushFlag) NextState = STATE_READ_HOLD; else if (FlushFlag) NextState = STATE_READ_HOLD;
else NextState = STATE_FLUSH; else NextState = STATE_FLUSH;
STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH; STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH;
else if(CacheBusAck) NextState = STATE_READ_HOLD; else if(CacheBusAck) NextState = STATE_READ_HOLD;
else NextState = STATE_FLUSH_WRITEBACK; else NextState = STATE_FLUSH_WRITEBACK;
default: NextState = STATE_READY; default: NextState = STATE_READY;
endcase endcase
end end

View File

@ -66,7 +66,6 @@ module controller(
output logic RegWriteM, // Instruction writes a register (needed for Hazard unit) output logic RegWriteM, // Instruction writes a register (needed for Hazard unit)
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$ output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidD, InstrValidE, InstrValidM, // Instruction is valid output logic InstrValidD, InstrValidE, InstrValidM, // Instruction is valid
output logic FenceM, // Fence instruction
output logic FWriteIntM, // FPU controller writes integer register file output logic FWriteIntM, // FPU controller writes integer register file
// Writeback stage control signals // Writeback stage control signals
input logic StallW, FlushW, // Stall, flush Writeback stage 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 IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions
logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions
logic JFunctD; // detect jalr instruction logic JFunctD; // detect jalr instruction
logic FenceM; // Fence.I or sfence.VMA instruction in memory stage
// Extract fields // Extract fields
assign OpD = InstrD[6:0]; 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 // Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA
assign CSRWriteFenceM = CSRWriteM | FenceM; assign CSRWriteFenceM = CSRWriteM | FenceM;
// assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FenceD | FenceE | FenceM;
// the synchronous DTIM cannot read immediately after write // the synchronous DTIM cannot read immediately after write
// a cache cannot read or write immediately after a write // a cache cannot read or write immediately after a write

View File

@ -71,8 +71,7 @@ module ieu (
output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit
output logic MDUStallD, CSRRdStallD, StoreStallD, output logic MDUStallD, CSRRdStallD, StoreStallD,
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction 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 CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
output logic FenceM
); );
logic [2:0] ImmSrcD; // Select type of immediate extension logic [2:0] ImmSrcD; // Select type of immediate extension
@ -99,8 +98,8 @@ module ieu (
.PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE, .PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE,
.Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM, .Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM,
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .FenceM, .StoreStallD); .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD);
datapath dp( datapath dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,

View File

@ -87,7 +87,8 @@ module subwordread
3'b001: ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh 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'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'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'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
3'b110: ReadDataM = {{`LLEN-32{1'b0}}, WordM[31:0]}; // lwu 3'b110: ReadDataM = {{`LLEN-32{1'b0}}, WordM[31:0]}; // lwu
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen

View File

@ -28,7 +28,7 @@
`include "wally-config.vh" `include "wally-config.vh"
module intdivrestoring( module div(
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallM, input logic StallM,
@ -107,7 +107,7 @@ module intdivrestoring(
// one copy of divstep for each bit produced per cycle // one copy of divstep for each bit produced per cycle
genvar i; genvar i;
for (i=0; i<`IDIV_BITSPERCYCLE; i = i+1) 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 // Memory Stage: output sign correction and special cases

View File

@ -4,7 +4,7 @@
// Written: David_Harris@hmc.edu 2 October 2021 // Written: David_Harris@hmc.edu 2 October 2021
// Modified: // 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) // Documentation: RISC-V System on Chip Design Chapter 12 (Figure 12.19)
// //
@ -30,7 +30,7 @@
/* verilator lint_off UNOPTFLAT */ /* verilator lint_off UNOPTFLAT */
module intdivrestoringstep( module divstep(
input logic [`XLEN-1:0] W, // Residual in 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] XQ, // bits of dividend X and quotient Q in
input logic [`XLEN-1:0] DAbsB, // complement of absolute value of divisor D (for subtraction) input logic [`XLEN-1:0] DAbsB, // complement of absolute value of divisor D (for subtraction)

View File

@ -57,8 +57,8 @@ module mdu(
assign RemM = 0; assign RemM = 0;
assign DivBusyE = 0; assign DivBusyE = 0;
end else begin:div end else begin:div
intdivrestoring div(.clk, .reset, .StallM, .FlushE, .DivSignedE(~Funct3E[0]), .W64E, .IntDivE, div div(.clk, .reset, .StallM, .FlushE, .DivSignedE(~Funct3E[0]), .W64E, .IntDivE,
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM); .ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
end end
// Result multiplexer // Result multiplexer

View File

@ -50,14 +50,14 @@ module pmpchecker (
); );
// Bit i is high when the address falls in PMP region i // Bit i is high when the address falls in PMP region i
logic EnforcePMP; 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] 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] 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] 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] 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]( pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0](
.PhysicalAddress, .PhysicalAddress,
.PMPCfg(PMPCFG_ARRAY_REGW), .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. 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) : |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 PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;
assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ; assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ;

View File

@ -72,7 +72,7 @@ module csr #(parameter
input logic ICacheMiss, input logic ICacheMiss,
input logic ICacheAccess, input logic ICacheAccess,
input logic sfencevmaM, input logic sfencevmaM,
input logic FenceM, input logic InvalidateICacheM,
input logic DivBusyE, // integer divide busy input logic DivBusyE, // integer divide busy
input logic FDivBusyE, // floating point divide busy input logic FDivBusyE, // floating point divide busy
// outputs from CSRs // outputs from CSRs
@ -210,7 +210,7 @@ module csr #(parameter
csri csri(.clk, .reset, .InstrValidNotFlushedM, csri csri(.clk, .reset, .InstrValidNotFlushedM,
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
.MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt, .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, csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM, .WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM,
@ -268,7 +268,7 @@ module csr #(parameter
.InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM, .CSRMWriteM, .InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM, .CSRMWriteM,
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM,
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM,
.InterruptM, .ExceptionM, .FenceM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
.CSRAdrM, .PrivilegeModeW, .CSRWriteValM, .CSRAdrM, .PrivilegeModeW, .CSRWriteValM,
.MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW,
.MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM); .MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM);

View File

@ -60,7 +60,7 @@ module csrc #(parameter
input logic sfencevmaM, input logic sfencevmaM,
input logic InterruptM, input logic InterruptM,
input logic ExceptionM, input logic ExceptionM,
input logic FenceM, input logic InvalidateICacheM,
input logic DivBusyE, // integer divide busy input logic DivBusyE, // integer divide busy
input logic FDivBusyE, // floating point divide busy input logic FDivBusyE, // floating point divide busy
input logic [11:0] CSRAdrM, 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[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss
assign CounterEvent[18] = ICacheStallF; // i cache miss cycles assign CounterEvent[18] = ICacheStallF; // i cache miss cycles
assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes 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[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma
assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low
assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low

View File

@ -40,6 +40,7 @@ module csri #(parameter
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt, 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, MIE_REGW,
output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0 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 MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9)
assign STIP = MIP_REGW_writeable[5]; assign STIP = MIP_REGW_writeable[5];
end 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; assign MIE_WRITE_MASK = 12'hAAA;
end else begin:mask end else begin:mask
assign MIP_WRITE_MASK = 12'h000; assign MIP_WRITE_MASK = 12'h000;
@ -80,7 +81,7 @@ module csri #(parameter
always @(posedge clk) always @(posedge clk)
if (reset) MIE_REGW <= 12'b0; 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 (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, assign MIP_REGW = {MExtInt, 1'b0, SExtInt|MIP_REGW_writeable[9], 1'b0,

View File

@ -123,7 +123,7 @@ module csrs #(parameter
SSTATUS: CSRSReadValM = SSTATUS_REGW; SSTATUS: CSRSReadValM = SSTATUS_REGW;
STVEC: CSRSReadValM = STVEC_REGW; STVEC: CSRSReadValM = STVEC_REGW;
SIP: CSRSReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW & 12'h222 & MIDELEG_REGW}; // only read supervisor fields 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; SSCRATCH: CSRSReadValM = SSCRATCH_REGW;
SEPC: CSRSReadValM = SEPC_REGW; SEPC: CSRSReadValM = SEPC_REGW;
SCAUSE: CSRSReadValM = SCAUSE_REGW; SCAUSE: CSRSReadValM = SCAUSE_REGW;

View File

@ -88,7 +88,7 @@ module privileged (
// control outputs // control outputs
output logic RetM, TrapM, // return instruction, or trap output logic RetM, TrapM, // return instruction, or trap
output logic sfencevmaM, // sfence.vma instruction 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 output logic BigEndianM, // Use big endian in current privilege mode
// Fault outputs // Fault outputs
output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire
@ -131,7 +131,7 @@ module privileged (
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTimerInt, .MExtInt, .SExtInt, .MSwInt,
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD,
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM,
.sfencevmaM, .ExceptionM, .FenceM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .sfencevmaM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
.IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
.NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW, .NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW,
.STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM,

View File

@ -161,7 +161,6 @@ module wallypipelinedcore (
logic FCvtIntE; logic FCvtIntE;
logic CommittedF; logic CommittedF;
logic BranchD, BranchE, JumpD, JumpE; logic BranchD, BranchE, JumpD, JumpE;
logic FenceM;
logic DCacheStallM, ICacheStallF; logic DCacheStallM, ICacheStallF;
// instruction fetch unit: PC, branch prediction, instruction cache // instruction fetch unit: PC, branch prediction, instruction cache
@ -201,7 +200,7 @@ module wallypipelinedcore (
.WriteDataM, // Write data to LSU .WriteDataM, // Write data to LSU
.Funct3M, // size and signedness to LSU .Funct3M, // size and signedness to LSU
.SrcAM, // to privilege and fpu .SrcAM, // to privilege and fpu
.RdE, .RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM, .RdE, .RdM, .FIntResM, .FlushDCacheM,
.BranchD, .BranchE, .JumpD, .JumpE, .BranchD, .BranchE, .JumpD, .JumpE,
// Writeback stage // Writeback stage
.CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]), .CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]),
@ -209,7 +208,7 @@ module wallypipelinedcore (
// hazards // hazards
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD, .PCSrcE, .FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD, .PCSrcE,
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .FenceM, .StoreStallD); .CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD);
lsu lsu( lsu lsu(
.clk, .reset, .StallM, .FlushM, .StallW, .FlushW, .clk, .reset, .StallM, .FlushM, .StallW, .FlushW,
@ -288,7 +287,7 @@ module wallypipelinedcore (
.FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW,
.CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PC2NextF, .CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PC2NextF,
.InstrM, .CSRReadValW, .UnalignedPCNextF, .InstrM, .CSRReadValW, .UnalignedPCNextF,
.RetM, .TrapM, .sfencevmaM, .FenceM, .DCacheStallM, .ICacheStallF, .RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF,
.InstrValidM, .CommittedM, .CommittedF, .InstrValidM, .CommittedM, .CommittedF,
.FRegWriteM, .LoadStallD, .StoreStallD, .FRegWriteM, .LoadStallD, .StoreStallD,
.BPDirPredWrongM, .BTAWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .BPWrongM,

View File

@ -1758,15 +1758,15 @@ string imperas32f[] = '{
"rv64i_m/privilege/src/WALLY-mtvec-01.S", "rv64i_m/privilege/src/WALLY-mtvec-01.S",
"rv64i_m/privilege/src/WALLY-pma-01.S", "rv64i_m/privilege/src/WALLY-pma-01.S",
"rv64i_m/privilege/src/WALLY-pmp-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-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-tw-01.S",
"rv64i_m/privilege/src/WALLY-status-tvm-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-status-fp-enabled-01.S",
"rv64i_m/privilege/src/WALLY-stvec-01.S", // "rv64i_m/privilege/src/WALLY-stvec-01.S",
"rv64i_m/privilege/src/WALLY-trap-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-s-01.S",
"rv64i_m/privilege/src/WALLY-trap-sret-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-trap-u-01.S",
"rv64i_m/privilege/src/WALLY-wfi-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-mtvec-01.S",
"rv32i_m/privilege/src/WALLY-pma-01.S", "rv32i_m/privilege/src/WALLY-pma-01.S",
"rv32i_m/privilege/src/WALLY-pmp-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-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-tw-01.S",
"rv32i_m/privilege/src/WALLY-status-tvm-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-status-fp-enabled-01.S",
"rv32i_m/privilege/src/WALLY-stvec-01.S", // "rv32i_m/privilege/src/WALLY-stvec-01.S",
"rv32i_m/privilege/src/WALLY-trap-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-s-01.S",
"rv32i_m/privilege/src/WALLY-trap-sret-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-trap-u-01.S",
"rv32i_m/privilege/src/WALLY-wfi-01.S", "rv32i_m/privilege/src/WALLY-wfi-01.S",

19
tests/coverage/Makefile Normal file
View File

@ -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

View File

@ -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

47
tests/coverage/badinstr.S Normal file
View File

@ -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
*/