mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
commit
a605f4801e
9
.gitignore
vendored
9
.gitignore
vendored
@ -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
|
||||||
|
@ -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 = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
sim/coverage-exclusions-rv64gc.do
Normal file
34
sim/coverage-exclusions-rv64gc.do
Normal 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
|
@ -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)
|
||||||
|
@ -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
2
src/cache/cache.sv
vendored
@ -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
16
src/cache/cachefsm.sv
vendored
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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
|
@ -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)
|
@ -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
|
||||||
|
@ -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) ;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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
19
tests/coverage/Makefile
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
119
tests/coverage/WALLY-init-lib.S
Normal file
119
tests/coverage/WALLY-init-lib.S
Normal 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
47
tests/coverage/badinstr.S
Normal 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
|
||||||
|
|
||||||
|
*/
|
Loading…
Reference in New Issue
Block a user