Merge branch 'main' of https://github.com/openhwgroup/cvw into main

This commit is contained in:
Sydeny 2023-04-26 03:00:25 -07:00
commit 069ca0ec29
32 changed files with 1425 additions and 169 deletions

View File

@ -1,12 +1,15 @@
# core-v-wally
Configurable RISC-V Processor
Wally is a 5-stage pipelined processor configurable to support all the standard RISC-V options, incluidng RV32/64, A, C, F, D, and M extensions, FENCE.I, and the various privileged modes and CSRs. It is written in SystemVerilog. It passes the RISC-V Arch Tests and boots Linux on an FPGA.
Wally is a 5-stage pipelined processor configurable to support all the standard RISC-V options, incluidng RV32/64, A, C, F, D, Q, M, and Zb* extensions, virtual memory, PMP, and the various privileged modes and CSRs. It provides optional caches, branch prediction, and standard RISC-V peripherals (CLINT, PLIC, UART, GPIO). Wally is written in SystemVerilog. It passes the RISC-V Arch Tests and boots Linux on an FPGA. Configurations range from a minimal RV32E core to a fully featured RV64GC application processor.
![Wally block diagram](wallyriscvTopAll.png)
Wally is described in an upcoming textbook, *RISC-V System-on-Chip Design*, by Harris, Stine, Thompson, and Harris. Users should follow the setup instructions below. A system administrator must install CAD tools using the directions further down.
# Verification
Wally is presently at Technology Readiness Level 4, passing the RISC-V compatibility test suite and custom tests, and booting Linux in simulation and on an FPGA. See the [Test Plan](docs/testplan.md) for details.
# New User Setup
New users may wish to do the following setup to access the server via a GUI and use a text editor.

View File

@ -1,6 +1,29 @@
# CORE-V Wally Test Plan
# CORE-V Wally Design Verification Test Plan
CORE-V Wally is functionally tested in the following ways. Each test is run in lock-step against ImperasDV to ensure all architectural state is correct after each instruction.
| Functions | Coverage Method | Status |
| ----------- | ----------- |----|
| Instructions | riscv-arch-test | Pass |
| Privileged Unit | wally-riscv-arch-test | Pass |
| Virtual Memory | wally-riscv-arch-test | Pass |
| PMP | wally-riscv-arch-test | Pass
| Peripherals | wally-riscv-arch-test | Pass |
| Floating-Point | TestFloat | Pass |
| General | Code Coverage | 91% |
| General | Boot Linux in Sim | Pass |
| General | Boot Linux on FPGA | Pass |
The following performance validation is also run:
| Function | Method | Status |
| --- | --- | --- |
| Overall Performance | embench | Pass|
| Overall Performance | coremark | Pass |
| Branch Predictor | *** | Pass |
| Cache Miss Rate | *** | Pass |
CORE-V Wally is tested in the following ways:
* Run [RISC-V Architecture Compatibility Tests](https://github.com/riscv-non-isa/riscv-arch-test) in lock-step against the ImperasDV reference model.
* Run custom tests to cover virtual memory, PMP, privileged unit, and peripherals in lock step against ImperasDV.

View File

@ -31,11 +31,14 @@
do GetLineNum.do
# LZA (i<64) statement confuses coverage tool
# This is ugly to exlcude the whole file - is there a better option? // coverage off isn't working
# DH 4/22/23: Exclude all LZAs
coverage exclude -srcfile lzc.sv
# FDIVSQRT has
coverage exclude -scope /core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state DONE->BUSY
# DH 4/22/23: FDIVSQRT can't go directly from done to busy again
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state DONE->BUSY
# DH 4/22/23: The busy->idle transition only occurs if a FlushE occurs while the divider is busy. The flush is caused by a trap or return,
# which won't happen while the divider is busy.
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state BUSY->IDLE
### Exclude D$ states and logic for the I$ instance
# This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too)
@ -52,7 +55,7 @@ set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache case"]
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $start-$end
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache WRITEBACKStatement"]
# exclude Atomic Operation logic
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache storeAMO"] -item e 1 -fecexprrow 6
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: cache AnyMiss"] -item e 1 -fecexprrow 6
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache storeAMO1"] -item e 1 -fecexprrow 2-4
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache AnyUpdateHit"] -item e 1 -fecexprrow 2
# cache write logic
@ -77,6 +80,19 @@ for {set i 0} {$i < $numcacheways} {incr i} {
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: icache SetValidEN"] -item e 1 -fecexprrow 4
}
## D$ Exclusions.
# InvalidateCache is I$ only:
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: dcache InvalidateCheck"] -item b 2
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: dcache InvalidateCheck"] -item s 1
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: dcache CacheEn"] -item e 1 -fecexprrow 12
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: cache AnyMiss"] -item e 1 -fecexprrow 4
set numcacheways 4
for {set i 0} {$i < $numcacheways} {incr i} {
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: dcache invalidateway"] -item be 1 -fecexprrow 4
}
# D$ writeback, flush, write_line, or flush_writeback states can't be cancelled by a flush
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -ftrans CurrState STATE_WRITEBACK->STATE_READY STATE_FLUSH->STATE_READY STATE_WRITE_LINE->STATE_READY STATE_FLUSH_WRITEBACK->STATE_READY
# Excluding peripherals as sources of instructions for the ifu
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/clintdec
@ -111,4 +127,8 @@ coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$lin
set line [GetLineNum ../src/mmu/pmachecker.sv "WriteAccessM \\| ExecuteAccessF"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 1-5
set line [GetLineNum ../src/mmu/pmachecker.sv "ReadAccessM \\| ExecuteAccessF"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 1-3
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 1-3
# Excluding reset and clear for impossible case in the wficountreg in privdec
set line [GetLineNum ../src/generic/flop/floprc.sv "reset \\| clear"]
coverage exclude -scope /dut/core/priv/priv/pmd/wfi/wficountreg -linerange $line-$line -item c 1 -feccondrow 2

View File

@ -28,6 +28,7 @@ regressionDir = os.path.dirname(os.path.abspath(__file__))
os.chdir(regressionDir)
coverage = '-coverage' in sys.argv
fp = '-fp' in sys.argv
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
# name: the name of this test configuration (used in printing human-readable
@ -140,6 +141,9 @@ if (coverage): # delete all but 64gc tests when running coverage
"arch64zi", "wally64a", "wally64periph", "wally64priv",
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
"imperas64f", "imperas64d", "imperas64c", "imperas64i"]
if (fp):
tests64gc.append("arch64f")
tests64gc.append("arch64d")
coverStr = '-coverage'
else:
coverStr = ''

17
src/cache/cachefsm.sv vendored
View File

@ -69,7 +69,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
);
logic resetDelay;
logic AMO, StoreAMO;
logic StoreAMO;
logic AnyUpdateHit, AnyHit;
logic AnyMiss;
logic FlushFlag;
@ -86,16 +86,15 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
statetype CurrState, NextState;
assign AMO = CacheAtomic[1] & (&CacheRW);
assign StoreAMO = AMO | CacheRW[0];
assign StoreAMO = CacheRW[0]; // AMO operations assert CacheRW[0]
assign AnyMiss = (StoreAMO | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: icache storeAMO
assign AnyMiss = (StoreAMO | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
assign AnyUpdateHit = (StoreAMO) & CacheHit; // exclusion-tag: icache storeAMO1
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit
assign FlushFlag = FlushAdrFlag & FlushWayFlag;
// outputs for the performance counters.
assign CacheAccess = (AMO | CacheRW[1] | CacheRW[0]) & CurrState == STATE_READY; // exclusion-tag: icache CacheW
assign CacheAccess = (|CacheRW) & CurrState == STATE_READY; // exclusion-tag: icache CacheW
assign CacheMiss = CacheAccess & ~CacheHit;
// special case on reset. When the fsm first exists reset the
@ -110,10 +109,10 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
always_comb begin
NextState = STATE_READY;
case (CurrState) // exclusion-tag: icache state-case
STATE_READY: if(InvalidateCache) NextState = STATE_READY;
STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
else if(AnyMiss) /* & LineDirty */ NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
else NextState = STATE_READY;
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
else NextState = STATE_FETCH;
@ -160,6 +159,8 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
assign SelFlush = (CurrState == STATE_READY & FlushCache) |
(CurrState == STATE_FLUSH) |
(CurrState == STATE_FLUSH_WRITEBACK);
// coverage off -item e 1 -fecexprrow 1
// (state is always FLUSH_WRITEBACK when FlushWayFlag & CacheBusAck)
assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) |
(CurrState == STATE_FLUSH & FlushWayFlag & ~LineDirty);
assign FlushWayCntEn = (CurrState == STATE_FLUSH & ~LineDirty) |
@ -181,6 +182,6 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
(CurrState == STATE_WRITE_LINE) |
resetDelay;
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD;
assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache;
assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
endmodule // cachefsm

View File

@ -155,7 +155,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
if (reset) ValidBits <= #1 '0;
if(CacheEn) begin
ValidWay <= #1 ValidBits[CacheSet];
if(InvalidateCache) ValidBits <= #1 '0;
if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway
else if (SetValidEN) ValidBits[CacheSet] <= #1 SetValidWay;
end
end

View File

@ -138,10 +138,10 @@ module fctrl (
endcase
7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)
ControlsD = `FCTRLW'b0_1_10_00_000_0_0_0; // fclass
else if (Funct3D == 3'b000 & Rs2D == 5'b00000)
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0; // fmv.x.w / fmv.x.d to int register
7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000)
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg
else if (Funct3D == 3'b000 & Rs2D == 5'b00000 & SupportedFmt)
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0; // fmv.x.w/d/h/q fp to int register
7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000 & SupportedFmt)
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0; // fmv.w/d/h/q.x int to fp reg
7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h)
7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01)

View File

@ -57,43 +57,43 @@ module fdivsqrt(
logic [`DIVb+3:0] WS, WC; // Partial remainder components
logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend)
logic [`DIVb-1:0] DPreproc, D; // Iterator Divisor
logic [`DIVb+3:0] D; // Iterator Divisor
logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values
logic [`DIVb+1:0] FirstC; // Step tracker
logic Firstun; // Quotient selection
logic WZeroE; // Early termination flag
logic [`DURLEN-1:0] CyclesE; // FSM cycles
logic SpecialCaseM; // Divide by zero, square root of negative, etc.
logic DivStartE; // Enable signal for flops during stall
// Integer div/rem signals
logic BZeroM; // Denominator is zero
logic IntDivM; // Integer operation
logic [`DIVBLEN:0] nE, nM, mM; // Shift amounts
logic [`DIVBLEN:0] nM, mM; // Shift amounts
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
logic ISpecialCaseE; // Integer div/remainder special cases
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
.Fmt(FmtE), .Sqrt(SqrtE), .XZeroE, .Funct3E,
.QeM, .X, .DPreproc,
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
.FmtE, .SqrtE, .XZeroE, .Funct3E, .QeM, .X, .D, .CyclesE,
// Int-specific
.ForwardedSrcAE, .ForwardedSrcBE, .IntDivE, .W64E, .ISpecialCaseE,
.nE, .BZeroM, .nM, .mM, .AM,
.BZeroM, .nM, .mM, .AM,
.IntDivM, .W64M, .NegQuotM, .ALTBM, .AsM);
fdivsqrtfsm fdivsqrtfsm( // FSM
.clk, .reset, .FmtE, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
fdivsqrtfsm fdivsqrtfsm( // FSM
.clk, .reset, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
.FDivStartE, .XsE, .SqrtE, .WZeroE, .FlushE, .StallM,
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM,
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM, .CyclesE,
// Int-specific
.IDivStartE, .ISpecialCaseE, .nE, .IntDivE);
.IDivStartE, .ISpecialCaseE, .IntDivE);
fdivsqrtiter fdivsqrtiter( // CSA Iterator
.clk, .IFDivStartE, .FDivBusyE, .SqrtE, .X, .DPreproc,
.D, .FirstU, .FirstUM, .FirstC, .Firstun, .FirstWS(WS), .FirstWC(WC));
fdivsqrtiter fdivsqrtiter( // CSA Iterator
.clk, .IFDivStartE, .FDivBusyE, .SqrtE, .X, .D,
.FirstU, .FirstUM, .FirstC, .Firstun, .FirstWS(WS), .FirstWC(WC));
fdivsqrtpostproc fdivsqrtpostproc( // Postprocessor
fdivsqrtpostproc fdivsqrtpostproc( // Postprocessor
.clk, .reset, .StallM, .WS, .WC, .D, .FirstU, .FirstUM, .FirstC,
.SqrtE, .Firstun, .SqrtM, .SpecialCaseM,
.QmM, .WZeroE, .DivStickyM,

View File

@ -0,0 +1,76 @@
///////////////////////////////////////////
// fdivsqrtcycles.sv
//
// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu, amaiuolo@hmc.edu
// Modified: 18 April 2022
//
// Purpose: Determine number of cycles for divsqrt
//
// Documentation: RISC-V System on Chip Design Chapter 13
//
// 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.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module fdivsqrtcycles(
input logic [`FMTBITS-1:0] FmtE,
input logic SqrtE,
input logic IntDivE,
input logic [`DIVBLEN:0] nE,
output logic [`DURLEN-1:0] CyclesE
);
logic [`DURLEN+1:0] Nf, fbits; // number of fractional bits
// DIVN = `NF+3
// NS = NF + 1
// N = NS or NS+2 for div/sqrt.
/* verilator lint_off WIDTH */
if (`FPSIZES == 1)
assign Nf = `NF;
else if (`FPSIZES == 2)
always_comb
case (FmtE)
1'b0: Nf = `NF1;
1'b1: Nf = `NF;
endcase
else if (`FPSIZES == 3)
always_comb
case (FmtE)
`FMT: Nf = `NF;
`FMT1: Nf = `NF1;
`FMT2: Nf = `NF2;
endcase
else if (`FPSIZES == 4)
always_comb
case(FmtE)
`S_FMT: Nf = `S_NF;
`D_FMT: Nf = `D_NF;
`H_FMT: Nf = `H_NF;
`Q_FMT: Nf = `Q_NF;
endcase
always_comb begin
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
else fbits = Nf + 2 + `LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
if (`IDIV_ON_FPU) CyclesE = IntDivE ? ((nE + 1)/`DIVCOPIES) : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
else CyclesE = (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
end
/* verilator lint_on WIDTH */
endmodule

View File

@ -29,32 +29,27 @@
`include "wally-config.vh"
module fdivsqrtfsm(
input logic clk,
input logic reset,
input logic [`FMTBITS-1:0] FmtE,
input logic XInfE, YInfE,
input logic XZeroE, YZeroE,
input logic XNaNE, YNaNE,
input logic FDivStartE, IDivStartE,
input logic XsE,
input logic SqrtE,
input logic StallM,
input logic FlushE,
input logic WZeroE,
input logic IntDivE,
input logic [`DIVBLEN:0] nE,
input logic ISpecialCaseE,
output logic IFDivStartE,
output logic FDivBusyE, FDivDoneE,
output logic SpecialCaseM
input logic clk, reset,
input logic XInfE, YInfE,
input logic XZeroE, YZeroE,
input logic XNaNE, YNaNE,
input logic FDivStartE, IDivStartE,
input logic XsE, WZeroE,
input logic SqrtE,
input logic StallM, FlushE,
input logic IntDivE,
input logic ISpecialCaseE,
input logic [`DURLEN-1:0] CyclesE,
output logic IFDivStartE,
output logic FDivBusyE, FDivDoneE,
output logic SpecialCaseM
);
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
statetype state;
logic [`DURLEN-1:0] step;
logic [`DURLEN-1:0] cycles;
logic SpecialCaseE, FSpecialCaseE;
logic [`DURLEN-1:0] step;
// FDivStartE and IDivStartE come from fctrl, reflecitng the start of floating-point and possibly integer division
assign IFDivStartE = (FDivStartE | (IDivStartE & `IDIV_ON_FPU)) & (state == IDLE) & ~StallM;
@ -67,53 +62,11 @@ module fdivsqrtfsm(
else assign SpecialCaseE = FSpecialCaseE;
flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
// DIVN = `NF+3
// NS = NF + 1
// N = NS or NS+2 for div/sqrt.
// *** CT 4/13/23 move cycles calculation back to preprocesor
/* verilator lint_off WIDTH */
logic [`DURLEN+1:0] Nf, fbits; // number of fractional bits
if (`FPSIZES == 1)
assign Nf = `NF;
else if (`FPSIZES == 2)
always_comb
case (FmtE)
1'b0: Nf = `NF1;
1'b1: Nf = `NF;
endcase
else if (`FPSIZES == 3)
always_comb
case (FmtE)
`FMT: Nf = `NF;
`FMT1: Nf = `NF1;
`FMT2: Nf = `NF2;
endcase
else if (`FPSIZES == 4)
always_comb
case(FmtE)
`S_FMT: Nf = `S_NF;
`D_FMT: Nf = `D_NF;
`H_FMT: Nf = `H_NF;
`Q_FMT: Nf = `Q_NF;
endcase
always_comb begin
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
else fbits = Nf + 2 + `LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
if (`IDIV_ON_FPU) cycles = IntDivE ? ((nE + 1)/`DIVCOPIES) : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
else cycles = (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
end
/* verilator lint_on WIDTH */
always_ff @(posedge clk) begin
if (reset | FlushE) begin
state <= #1 IDLE;
end else if (IFDivStartE) begin // IFDivStartE implies stat is IDLE
// end else if ((state == IDLE) & IFDivStartE) begin // IFDivStartE implies stat is IDLE
step <= cycles;
step <= CyclesE;
if (SpecialCaseE) state <= #1 DONE;
else state <= #1 BUSY;
end else if (state == BUSY) begin

View File

@ -33,9 +33,7 @@ module fdivsqrtiter(
input logic IFDivStartE,
input logic FDivBusyE,
input logic SqrtE,
input logic [`DIVb+3:0] X,
input logic [`DIVb-1:0] DPreproc,
output logic [`DIVb-1:0] D,
input logic [`DIVb+3:0] X, D,
output logic [`DIVb:0] FirstU, FirstUM,
output logic [`DIVb+1:0] FirstC,
output logic Firstun,
@ -95,16 +93,11 @@ module fdivsqrtiter(
mux2 #(`DIVb+2) cmux(C[`DIVCOPIES], initC, IFDivStartE, NextC);
flopen #(`DIVb+2) creg(clk, FDivBusyE, NextC, C[0]);
// Divisior register
flopen #(`DIVb) dreg(clk, IFDivStartE, DPreproc, D);
// Divisor Selections
// - choose the negitive version of what's being selected
// - D is a 0.b mantissa
assign DBar = {3'b111, 1'b0, ~D};
assign DBar = ~D; // for -D
if(`RADIX == 4) begin : d2
assign DBar2 = {2'b11, 1'b0, ~D, 1'b1};
assign D2 = {2'b0, 1'b1, D, 1'b0};
assign D2 = D << 1; // for 2D, only used in R4
assign DBar2 = ~D2; // for -2D, only used in R4
end
// k=DIVCOPIES of the recurrence logic

View File

@ -32,7 +32,7 @@ module fdivsqrtpostproc(
input logic clk, reset,
input logic StallM,
input logic [`DIVb+3:0] WS, WC,
input logic [`DIVb-1:0] D,
input logic [`DIVb+3:0] D,
input logic [`DIVb:0] FirstU, FirstUM,
input logic [`DIVb+1:0] FirstC,
input logic SqrtE,
@ -46,7 +46,7 @@ module fdivsqrtpostproc(
output logic [`XLEN-1:0] FIntDivResultM
);
logic [`DIVb+3:0] W, Sum, DM;
logic [`DIVb+3:0] W, Sum;
logic [`DIVb:0] PreQmM;
logic NegStickyM;
logic weq0E, WZeroM;
@ -67,7 +67,7 @@ module fdivsqrtpostproc(
assign FirstK = ({1'b1, FirstC} & ~({1'b1, FirstC} << 1));
assign FZeroSqrtE = {FirstUM[`DIVb], FirstUM, 2'b0} | {FirstK,1'b0}; // F for square root
assign FZeroDivE = {3'b001,D,1'b0}; // F for divide
assign FZeroDivE = D << 1; // F for divide
mux2 #(`DIVb+4) fzeromux(FZeroDivE, FZeroSqrtE, SqrtE, FZeroE);
csa #(`DIVb+4) fadd(WS, WC, FZeroE, 1'b0, WSF, WCF); // compute {WCF, WSF} = {WS + WC + FZero};
aplusbeq0 #(`DIVb+4) wcfpluswsfeq0(WCF, WSF, wfeq0E);
@ -102,11 +102,10 @@ module fdivsqrtpostproc(
logic signed [`DIVb+3:0] PreResultM, PreIntResultM;
assign W = $signed(Sum) >>> `LOGR;
assign DM = {4'b0001, D};
assign UnsignedQuotM = {3'b000, PreQmM};
// Integer remainder: sticky and sign correction muxes
mux2 #(`DIVb+4) normremdmux(W, W+DM, NegStickyM, NormRemDM);
mux2 #(`DIVb+4) normremdmux(W, W+D, NegStickyM, NormRemDM);
mux2 #(`DIVb+4) normremsmux(NormRemDM, -NormRemDM, AsM, NormRemM);
mux2 #(`DIVb+4) quotresmux(UnsignedQuotM, -UnsignedQuotM, NegQuotM, NormQuotM);

View File

@ -33,54 +33,59 @@ module fdivsqrtpreproc (
input logic IFDivStartE,
input logic [`NF:0] Xm, Ym,
input logic [`NE-1:0] Xe, Ye,
input logic [`FMTBITS-1:0] Fmt,
input logic Sqrt,
input logic [`FMTBITS-1:0] FmtE,
input logic SqrtE,
input logic XZeroE,
input logic [2:0] Funct3E,
output logic [`NE+1:0] QeM,
output logic [`DIVb+3:0] X,
output logic [`DIVb-1:0] DPreproc,
output logic [`DIVb+3:0] X, D,
// Int-specific
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
input logic IntDivE, W64E,
output logic ISpecialCaseE,
output logic [`DIVBLEN:0] nE, nM, mM,
output logic [`DURLEN-1:0] CyclesE,
output logic [`DIVBLEN:0] nM, mM,
output logic NegQuotM, ALTBM, IntDivM, W64M,
output logic AsM, BZeroM,
output logic [`XLEN-1:0] AM
);
logic [`DIVb-1:0] XPreproc;
logic [`DIVb-1:0] Xfract, Dfract;
logic [`DIVb:0] PreSqrtX;
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
logic [`DIVb-1:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs
logic [`DIVBLEN:0] mE, nE, ell; // Leading zeros of inputs
logic NumerZeroE; // Numerator is zero (X or A)
logic AZeroE, BZeroE; // A or B is Zero for integer division
logic signedDiv; // signed division
logic SignedDivE; // signed division
logic NegQuotE; // Integer quotient is negative
logic AsE, BsE; // Signs of integer inputs
logic [`XLEN-1:0] AE; // input A after W64 adjustment
logic ALTBE;
//////////////////////////////////////////////////////
// Integer Preprocessing
//////////////////////////////////////////////////////
if (`IDIV_ON_FPU) begin:intpreproc // Int Supported
logic [`XLEN-1:0] BE, PosA, PosB;
// Extract inputs, signs, zero, depending on W64 mode if applicable
assign signedDiv = ~Funct3E[0];
assign SignedDivE = ~Funct3E[0];
// Source handling
if (`XLEN==64) begin // 64-bit, supports W64
mux2 #(64) amux(ForwardedSrcAE, {{32{ForwardedSrcAE[31] & signedDiv}}, ForwardedSrcAE[31:0]}, W64E, AE);
mux2 #(64) bmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31] & signedDiv}}, ForwardedSrcBE[31:0]}, W64E, BE);
mux2 #(64) amux(ForwardedSrcAE, {{32{ForwardedSrcAE[31] & SignedDivE}}, ForwardedSrcAE[31:0]}, W64E, AE);
mux2 #(64) bmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31] & SignedDivE}}, ForwardedSrcBE[31:0]}, W64E, BE);
end else begin // 32 bits only
assign AE = ForwardedSrcAE;
assign BE = ForwardedSrcBE;
end
assign AZeroE = ~(|AE);
assign BZeroE = ~(|BE);
assign AsE = AE[`XLEN-1] & signedDiv;
assign BsE = BE[`XLEN-1] & signedDiv;
assign AsE = AE[`XLEN-1] & SignedDivE;
assign BsE = BE[`XLEN-1] & SignedDivE;
assign NegQuotE = AsE ^ BsE; // Integer Quotient is negative
// Force integer inputs to be postiive
@ -90,33 +95,35 @@ module fdivsqrtpreproc (
// Select integer or floating point inputs
mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFX);
mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFD);
mux2 #(1) numzmux(XZeroE, AZeroE, IntDivE, NumerZeroE);
end else begin // Int not supported
assign IFX = {Xm, {(`DIVb-`NF-1){1'b0}}};
assign IFD = {Ym, {(`DIVb-`NF-1){1'b0}}};
assign NumerZeroE = XZeroE;
end
//////////////////////////////////////////////////////
// Integer & FP leading zero and normalization shift
//////////////////////////////////////////////////////
// count leading zeros for Subnorm FP and to normalize integer inputs
lzc #(`DIVb) lzcX (IFX, ell);
lzc #(`DIVb) lzcY (IFD, mE);
// Normalization shift: shift off leading one
assign XPreproc = (IFX << ell) << 1;
assign DPreproc = (IFD << mE) << 1;
assign Xfract = (IFX << ell) << 1;
assign Dfract = (IFD << mE) << 1;
// append leading 1 (for nonzero inputs)
// shift square root to be in range [1/4, 1)
// Normalized numbers are shifted right by 1 if the exponent is odd
// Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX);
assign DivX = {3'b000, ~NumerZeroE, XPreproc};
// *** CT 4/13/23 Create D output here with leading 1 appended as well, use in the other modules
// *** CT: move to fdivsqrtintpreshift
//////////////////////////////////////////////////////
// Integer Right Shift to digit boundary
// Determine DivXShifted (X shifted to digit boundary)
// and nE (number of fractional digits)
//////////////////////////////////////////////////////
// ***CT: factor out fdivsqrtcycles
if (`IDIV_ON_FPU) begin:intrightshift // Int Supported
logic [`DIVBLEN:0] ZeroDiff, p;
logic ALTBE;
// calculate number of fractional bits p
assign ZeroDiff = mE - ell; // Difference in number of leading zeros
@ -126,31 +133,68 @@ module fdivsqrtpreproc (
// Integer special cases (terminate immediately)
assign ISpecialCaseE = BZeroE | ALTBE;
/* verilator lint_off WIDTH */
// calculate number of fractional digits nE and right shift amount RightShiftX to complete in discrete number of steps
if (`LOGRK > 0) begin // more than 1 bit per cycle
logic [`LOGRK-1:0] IntTrunc, RightShiftX;
logic [`DIVBLEN:0] TotalIntBits, IntSteps;
/* verilator lint_off WIDTH */
assign TotalIntBits = `LOGR + p; // Total number of result bits (r integer bits plus p fractional bits)
assign IntTrunc = TotalIntBits % `RK; // Truncation check for ceiling operator
assign IntSteps = (TotalIntBits >> `LOGRK) + |IntTrunc; // Number of steps for int div
assign nE = (IntSteps * `DIVCOPIES) - 1; // Fractional digits
assign RightShiftX = `RK - 1 - ((TotalIntBits - 1) % `RK); // Right shift amount
assign DivXShifted = DivX >> RightShiftX; // shift X by up to R*K-1 to complete in nE steps
/* verilator lint_on WIDTH */
end else begin // radix 2 1 copy doesn't require shifting
assign nE = p;
assign DivXShifted = DivX;
end
/* verilator lint_on WIDTH */
end else begin
assign ISpecialCaseE = 0;
end
// Selet integer or floating-point operands
mux2 #(1) numzmux(XZeroE, AZeroE, IntDivE, NumerZeroE);
// CT *** fdivsqrtfplead1
//////////////////////////////////////////////////////
// Floating-Point Preprocessing
// append leading 1 (for nonzero inputs)
// shift square root to be in range [1/4, 1)
// Normalized numbers are shifted right by 1 if the exponent is odd
// Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
//////////////////////////////////////////////////////
assign DivX = {3'b000, ~NumerZeroE, Xfract};
// Sqrt is initialized on step one as R(X-1), so depends on Radix
mux2 #(`DIVb+1) sqrtxmux({~XZeroE, Xfract}, {1'b0, ~XZeroE, Xfract[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX);
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
mux2 #(`DIVb+4) prexmux(DivX, SqrtX, SqrtE, PreShiftX);
//////////////////////////////////////////////////////
// Selet integer or floating-point operands
//////////////////////////////////////////////////////
if (`IDIV_ON_FPU) begin
mux2 #(`DIVb+4) xmux(PreShiftX, DivXShifted, IntDivE, X);
end else begin
assign X = PreShiftX;
end
// Divisior register
flopen #(`DIVb+4) dreg(clk, IFDivStartE, {4'b0001, Dfract}, D);
// Floating-point exponent
fdivsqrtexpcalc expcalc(.Fmt(FmtE), .Xe, .Ye, .Sqrt(SqrtE), .XZero(XZeroE), .ell, .m(mE), .Qe(QeE));
flopen #(`NE+2) expreg(clk, IFDivStartE, QeE, QeM);
// Number of FSM cycles (to FSM)
fdivsqrtcycles cyclecalc(.FmtE, .SqrtE, .IntDivE, .nE, .CyclesE);
if (`IDIV_ON_FPU) begin:intpipelineregs
// pipeline registers
flopen #(1) mdureg(clk, IFDivStartE, IntDivE, IntDivM);
flopen #(1) mdureg(clk, IFDivStartE, IntDivE, IntDivM);
flopen #(1) altbreg(clk, IFDivStartE, ALTBE, ALTBM);
flopen #(1) negquotreg(clk, IFDivStartE, NegQuotE, NegQuotM);
flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM);
@ -160,18 +204,7 @@ module fdivsqrtpreproc (
flopen #(`XLEN) srcareg(clk, IFDivStartE, AE, AM);
if (`XLEN==64)
flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M);
end else begin
assign NumerZeroE = XZeroE;
assign X = PreShiftX;
end
// Sqrt is initialized on step one as R(X-1), so depends on Radix
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
mux2 #(`DIVb+4) prexmux(DivX, SqrtX, Sqrt, PreShiftX);
// Floating-point exponent
fdivsqrtexpcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZero(XZeroE), .ell, .m(mE), .Qe(QeE));
flopen #(`NE+2) expreg(clk, IFDivStartE, QeE, QeM);
endmodule

View File

@ -30,8 +30,7 @@
/* verilator lint_off UNOPTFLAT */
module fdivsqrtstage2 (
input logic [`DIVb-1:0] D,
input logic [`DIVb+3:0] DBar,
input logic [`DIVb+3:0] D, DBar,
input logic [`DIVb:0] U, UM,
input logic [`DIVb+3:0] WS, WC,
input logic [`DIVb+1:0] C,
@ -66,7 +65,7 @@ module fdivsqrtstage2 (
always_comb
if (up) Dsel = DBar;
else if (uz) Dsel = '0;
else Dsel = {4'b0001, D}; // un
else Dsel = D; // un
// Partial Product Generation
// WSA, WCA = WS + WC - qD

View File

@ -29,8 +29,7 @@
`include "wally-config.vh"
module fdivsqrtstage4 (
input logic [`DIVb-1:0] D,
input logic [`DIVb+3:0] DBar, D2, DBar2,
input logic [`DIVb+3:0] D, DBar, D2, DBar2,
input logic [`DIVb:0] U,UM,
input logic [`DIVb+3:0] WS, WC,
input logic [`DIVb+1:0] C,
@ -75,7 +74,7 @@ module fdivsqrtstage4 (
4'b1000: Dsel = DBar2;
4'b0100: Dsel = DBar;
4'b0000: Dsel = '0;
4'b0010: Dsel = {3'b0, 1'b1, D};
4'b0010: Dsel = D;
4'b0001: Dsel = D2;
default: Dsel = 'x;
endcase

View File

@ -171,7 +171,8 @@ module csrm #(parameter
IllegalCSRMAccessM = !(`S_SUPPORTED) & (CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
if (CSRAdrM >= PMPADDR0 & CSRAdrM < PMPADDR0 + `PMP_ENTRIES) // reading a PMP entry
CSRMReadValM = {{(`XLEN-(`PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]};
else if (CSRAdrM >= PMPCFG0 & CSRAdrM < PMPCFG0 + `PMP_ENTRIES/4) begin
else if (CSRAdrM >= PMPCFG0 & CSRAdrM < PMPCFG0 + `PMP_ENTRIES/4 & (`XLEN==32 | CSRAdrM[0] == 0)) begin
// only odd-numbered PMPCFG entries exist in RV64
if (`XLEN==64) begin
entry = ({CSRAdrM[11:1], 1'b0} - PMPCFG0)*4; // disregard odd entries in RV64
CSRMReadValM = {PMPCFG_ARRAY_REGW[entry+7],PMPCFG_ARRAY_REGW[entry+6],PMPCFG_ARRAY_REGW[entry+5],PMPCFG_ARRAY_REGW[entry+4],

View File

@ -122,7 +122,10 @@ module csrsr (
logic [1:0] EndiannessPrivMode;
always_comb begin
if (SelHPTW) EndiannessPrivMode = `S_MODE;
//coverage off -item c 1 -feccondrow 1
// status.MPRV always gets reset upon leaving machine mode, so MPRV will never be high when out of machine mode
else if (PrivilegeModeW == `M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP;
//coverage on
else EndiannessPrivMode = PrivilegeModeW;
case (EndiannessPrivMode)

View File

@ -53,7 +53,17 @@ string tvpaths[] = '{
"lsu",
"vm64check",
"pmp",
"tlbKP"
"dcache1",
"dcache2",
"pmpcfg",
"pmpcfg1",
"pmpcfg2",
"tlbKP",
"tlbMP",
"tlbM3",
"tlbASID",
"tlbGLB",
"ifuCamlineWrite"
};
string coremark[] = '{

View File

@ -63,6 +63,9 @@ trap_handler:
bgez t0, exception # if msb is clear, it is an exception
interrupt: # must be a timer interrupt
li t0, -1 # set mtimecmp to biggest number so it doesnt interrupt again
li t1, 0x02004000 # MTIMECMP in CLINT
sd t0, 0(t1)
j trap_return # clean up and return
exception:

83
tests/coverage/dcache1.S Normal file
View File

@ -0,0 +1,83 @@
#include "WALLY-init-lib.h"
main:
// start way test #1
li t0, 0x80100000
.align 6
// i$ boundary, way test #1
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
sd zero, 0(t0)
sd zero, 0(t0)
.word 0x00000013
.word 0x00000013
// start way test #2
li t0, 0x80101000
.align 6
// i$ boundary, way test #2
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
sd zero, 0(t0)
sd zero, 0(t0)
.word 0x00000013
.word 0x00000013
// start way test #3
li t0, 0x80102000
.align 6
// i$ boundary, way test #3
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
sd zero, 0(t0)
sd zero, 0(t0)
.word 0x00000013
.word 0x00000013
// start way test #4
li t0, 0x80103000
.align 6
// i$ boundary, way test #4
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
sd zero, 0(t0)
sd zero, 0(t0)
.word 0x00000013
.word 0x00000013
j done

86
tests/coverage/dcache1.py Normal file
View File

@ -0,0 +1,86 @@
####################
# dcache1.py
#
# Written: avercruysse@hmc.edu 18 April 2023
#
# Purpose: Test Coverage for D$
# (For each way, trigger a CacheDataMem write enable while chip enable is low)
#
# 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.
################################################
import os
test_name = "dcache1.S"
dcache_num_ways = 4
dcache_way_size_in_bytes = 4096
# warning i$ line size is not currently parameterized.
# arbitrary start location of where I send stores to.
mem_start_addr = 0x80100000
# pointer to the start of unused memory (strictly increasing)
mem_addr = mem_start_addr
def wl(line="", comment=None, fname=test_name):
with open(fname, "a") as f:
instr = False if (":" in line or
".align" in line or
"# include" in line) else True
indent = 6 if instr else 0
comment = "// " + comment if comment is not None else ""
to_write = " " * indent + line + comment + "\n"
f.write(to_write)
def write_repro_instrs():
"""
Assumes that the store location has been fetched to d$, and is in t0.
"""
for i in range(16): # write a whole cache set.
if i == 12:
wl('sd zero, 0(t0)') # D$ write to set PCM = PCF + 8 for proper alignment (stallD will happen).
elif i == 13:
# the store in question happens here, at adresses 0x34, 0x74
wl('sd zero, 0(t0)') # it should hit this time
else:
# can't be a NOP or anything else that is encoded as compressed.
# this is because the branch predictor will use the wrong address
# so the IFU cache miss will come late.
wl('.word 0x00000013') # addi x0, x0, 0 (canonical NOP, uncompressed).
if __name__ == "__main__":
if os.path.exists(test_name):
os.remove(test_name)
# os.rename(test_name, test_name + ".old")
wl(comment="This file is generated by dcache1.py (run that script manually)")
wl('#include "WALLY-init-lib.h"')
wl('main:')
# excercise all 4 D$ ways. If they're not all full, it uses the first empty.
# So we are sure all 4 ways are exercised.
for i in range(dcache_num_ways):
wl(comment=f"start way test #{i+1}")
wl(f'li t0, {hex(mem_addr)}')
wl(f'.align 6') # start at i$ set boundary. 6 lsb bits are zero.
wl(comment=f"i$ boundary, way test #{i+1}")
write_repro_instrs()
mem_addr += dcache_way_size_in_bytes # so that we excercise a new D$ way.
wl("j done")

49
tests/coverage/dcache2.S Normal file
View File

@ -0,0 +1,49 @@
///////////////////////////////////////////
// dcache2.S
//
// Written: avercruysse@hmc.edu 18 April 2023
//
// Purpose: Test Coverage for D$
// (for all 4 cache ways, trigger a FlushStage while SetDirtyWay=1)
//
// 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.
////////////////////////////////////////////////////////////////////////////////////////////////
#include "WALLY-init-lib.h"
main:
// way 0
li t0, 0x80100770
sd zero, 0(t0)
sd zero, 1(t0)
// way 1
li t0, 0x80101770
sd zero, 0(t0)
sd zero, 1(t0)
// way 2
li t0, 0x80102770
sd zero, 0(t0)
sd zero, 1(t0)
// way 3
li t0, 0x80103770
sd zero, 0(t0)
sd zero, 1(t0)
j done

View File

@ -28,7 +28,7 @@
main:
#bseti t0, zero, 14 # turn on FPU
bseti t0, zero, 14 # turn on FPU
csrs mstatus, t0
#Pull denormalized FP number from memory and pass it to fclass.S for coverage
@ -105,6 +105,25 @@ main:
# fcvt.w.q a0, ft0
# fcvt.q.d ft3, ft0
// fdivsqrt: test busy->idle transition caused by a FlushE while divider is busy (when interrupt arrives)
// This code doesn't actually trigger a busy->idle transition because the pending timer interrupt doesn't occur until the division finishes.
li t0, 0x3F812345 # random value slightly bigger than 1
li t1, 0x3F823456
fmv.w.x ft0, t0 # move int to fp register
fmv.w.x ft1, t1
li t0, -1 # set mtimecmp to biggest number so it doesnt interrupt again
li t1, 0x02004000 # MTIMECMP in CLINT
sd t0, 0(t1)
csrsi mstatus, 0b1000 # enable interrupts with mstatus.MIE
li t1, 0x0200bff8 # read MTIME in CLINT
ld t0, 0(t1)
addi t0, t0, 11
li t1, 0x02004000 # MTIMECMP in CLINT
sd t0, 0(t1) # write mtime+10 to cause interrupt soon This is very touchy timing and is sensitive to cache line fetch latency
nop
fdiv.s ft2, ft1, ft0 # should get interrupted, triggering a flush
csrci mstatus, 0b1000 # disable interrupts with mstatus.MIE
# Completing branch coverage in fctrl.sv
.word 0x38007553 // Testing the all False case for 119 - funct7 under, op = 101 0011
.word 0x40000053 // Line 145 All False Test case - illegal instruction?
@ -145,4 +164,5 @@ TestData2:
.word 0x7f800000 #INF
.int 0xbf800000 #FP -1.0
.int 0x7fa00000 #SNaN
.int 0x3fffffff #OverFlow Test
.int 0x3fffffff #OverFlow Test
DivTestData:

View File

@ -0,0 +1,146 @@
///////////////////////////////////////////
// ifuCamlineWrite.S
//
// Written: Miles Cook <mdcook@g.hmc.edu> and Kevin Box <kbox@g.hmc.edu> 4/17
//
// Acknowledgements: The pagetable and outline for this test was written by Manuel Mendoza
// and Noah Limpert.
//
// Purpose: Test coverage for TLBCamlines in IFU
//
// 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.h"
# run-elf.bash find this in project description
main:
# Page table root address at 0x80010000
li t5, 0x9000000000080010
csrw satp, t5
# switch to supervisor mode
li a0, 1
ecall
li t0, 0x80015000 # base addr
li t2, 0 # i = 0
li t3, 33 # Max amount of Loops = 32
loop: bge t2, t3, finished # exit loop if i >= loops
li t4, 0x1000
li t1, 0x00008067 # load in jalr
sw t1, 0 (t0)
fence.I
jalr t0
add t0, t0, t4
addi t2, t2, 1
j loop
finished:
j done
.data
.align 16
# Page table situated at 0x80010000
pagetable:
.8byte 0x200044C1 // old page table was 200040 which just pointed to itself! wrong
.align 12
.8byte 0x0000000000000000
.8byte 0x00000000200048C1
.8byte 0x00000000200048C1
.align 12
.8byte 0x0000000020004CC1
//.8byte 0x00000200800CF// ADD IN THE MEGAPAGE should 3 nibbles of zeros be removed?
.align 12
#80000000
.8byte 0x200000CF
.8byte 0x200004CF
.8byte 0x200008CF
.8byte 0x20000CCF
.8byte 0x200010CF
.8byte 0x200014CF
.8byte 0x200018CF
.8byte 0x20001CCF
.8byte 0x200020CF
.8byte 0x200024CF
.8byte 0x200028CF
.8byte 0x20002CCF
.8byte 0x200030CF
.8byte 0x200034CF
.8byte 0x200038CF
.8byte 0x20003CCF
.8byte 0x200040CF
.8byte 0x200044CF
.8byte 0x200048CF
.8byte 0x20004CCF
.8byte 0x200050CF
.8byte 0x200054CF
.8byte 0x200058CF
.8byte 0x20005CCF
.8byte 0x200060CF
.8byte 0x200064CF
.8byte 0x200068CF
.8byte 0x20006CCF
.8byte 0x200070CF
.8byte 0x200074CF
.8byte 0x200078CF
.8byte 0x20007CCF
.8byte 0x200080CF
.8byte 0x200084CF
.8byte 0x200088CF
.8byte 0x20008CCF
.8byte 0x200090CF
.8byte 0x200094CF
.8byte 0x200098CF
.8byte 0x20009CCF
.8byte 0x200100CF
.8byte 0x200104CF
.8byte 0x200108CF
.8byte 0x20010CCF
.8byte 0x200110CF
.8byte 0x200114CF
.8byte 0x200118CF
.8byte 0x20011CCF
.8byte 0x200120CF
.8byte 0x200124CF
.8byte 0x200128CF
.8byte 0x20012CCF
.8byte 0x200130CF
.8byte 0x200134CF

106
tests/coverage/pmpcfg.S Normal file
View File

@ -0,0 +1,106 @@
// pmpcfg part 1
// Kevin Wan, kewan@hmc.edu, 4/18/2023
// Liam Chalk, lchalk@hmc.edu, 4/25/2023
// locks each pmpXcfg bit field in order, from X = 15 to X = 0, with the A[1:0] field set to TOR.
// See the next part in pmpcfg1.S
#include "WALLY-init-lib.h"
main:
li t0, 0x90000000
csrw pmpaddr0, t0
li t0, 0x00000017
csrw pmpcfg0, t0
li t0, 0x90000000
csrw pmpaddr2, t0
li t0, 0x00000017
csrw pmpcfg2, t0
li t0, 0x90000000
csrw pmpaddr0, t0
li t0, 0x00001700
csrw pmpcfg0, t0
li t0, 0x90000000
csrw pmpaddr0, t0
li t0, 0x00001700
csrw pmpcfg1, t0
li t0, 0x90000000
csrw pmpaddr0, t0
li t0, 0x00001700
csrw pmpcfg2, t0
li t0, 0x90000000
csrw pmpaddr0, t0
li t0, 0x00001700
csrw pmpcfg3, t0
li t0, 0x90000000
csrw pmpaddr1, t0
li t0, 0x00001700
csrw pmpcfg1, t0
li t0, 0x90000000
csrw pmpaddr2, t0
li t0, 0x00001700
csrw pmpcfg2, t0
li t0, 0x90000000
csrw pmpaddr3, t0
li t0, 0x00001700
csrw pmpcfg3, t0
li t0, 0x90000000
csrw pmpaddr0, t0
li t0, 0x00170000
csrw pmpcfg0, t0
li t0, 0x90000000
csrw pmpaddr2, t0
li t0, 0x00170000
csrw pmpcfg2, t0
li t0, 0x90000000
csrw pmpaddr0, t0
li t0, 0x17000000
csrw pmpcfg0, t0
li t0, 0x90000000
csrw pmpaddr2, t0
li t0, 0x17000000
csrw pmpcfg2, t0
li t0, 0x8800000000000000
csrw pmpcfg2, t0
li t0, 0x88000000000000
csrw pmpcfg2, t0
li t0, 0x880000000000
csrw pmpcfg2, t0
li t0, 0x8800000000
csrw pmpcfg2, t0
li t0, 0x88000000
csrw pmpcfg2, t0
li t0, 0x880000
csrw pmpcfg2, t0
li t0, 0x8800
csrw pmpcfg2, t0
li t0, 0x88
csrw pmpcfg2, t0
li t0, 0x8800000000000000
csrw pmpcfg0, t0
li t0, 0x88000000000000
csrw pmpcfg0, t0
li t0, 0x880000000000
csrw pmpcfg0, t0
li t0, 0x8800000000
csrw pmpcfg0, t0
li t0, 0x88000000
csrw pmpcfg0, t0
li t0, 0x880000
csrw pmpcfg0, t0
li t0, 0x8800
csrw pmpcfg0, t0
j done

48
tests/coverage/pmpcfg1.S Normal file
View File

@ -0,0 +1,48 @@
// another set of pmpcfg tests. A new file is made because pmpcfg register fields are
// locked forever after writing 1 to the lock bit for the first time.
// Kevin Wan, kewan@hmc.edu, 4/13/2023
// This set tests locking the pmpXcfg fields in descending order again, without setting the TOR bits.
// for the other part of the tests, see pmpcfg.S
#include "WALLY-init-lib.h"
main:
li t0, 0x800
csrw pmpcfg0, t0
li t0, 0x8000000
csrw pmpcfg0, t0
li t0, 0x8000000000000000
csrw pmpcfg2, t0
li t0, 0x80000000000000
csrw pmpcfg2, t0
li t0, 0x800000000000
csrw pmpcfg2, t0
li t0, 0x8000000000
csrw pmpcfg2, t0
li t0, 0x80000000
csrw pmpcfg2, t0
li t0, 0x800000
csrw pmpcfg2, t0
li t0, 0x8000
csrw pmpcfg2, t0
li t0, 0x80
csrw pmpcfg2, t0
li t0, 0x8000000000000000
csrw pmpcfg0, t0
li t0, 0x80000000000000
csrw pmpcfg0, t0
li t0, 0x800000000000
csrw pmpcfg0, t0
li t0, 0x8000000000
csrw pmpcfg0, t0
li t0, 0x80000000
csrw pmpcfg0, t0
li t0, 0x800000
csrw pmpcfg0, t0
li t0, 0x8000
csrw pmpcfg0, t0
j done

12
tests/coverage/pmpcfg2.S Normal file
View File

@ -0,0 +1,12 @@
// pmpcfg part 3
// Kevin Wan, kewan@hmc.edu, 4/18/2023
// locks each pmpXcfg bit field in order, from X = 15 to X = 0, with the A[1:0] field set to TOR.
// See the next part in pmpcfg1.S
#include "WALLY-init-lib.h"
main:
li t0, 0x80
csrw pmpcfg0, t0
j done

View File

@ -189,6 +189,7 @@ main:
li t1, -1
csrw mcounteren, t1
# Go to supervisor mode
li a0, 1
ecall

133
tests/coverage/tlbASID.S Normal file
View File

@ -0,0 +1,133 @@
///////////////////////////////////////////
// tlbASID.S
//
// Written: mmendozamanriquez@hmc.edu 4 April 2023
// nlimpert@hmc.edu
//
// Purpose: Test coverage for LSU
//
// 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.h"
# run-elf.bash find this in project description
main:
# Page table root address at 0x80010000
li t5, 0x9000000000080080 // try making asid = 0.
csrw satp, t5
# sfence.vma x0, x0
# switch to supervisor mode
li a0, 1
ecall
li t0, 0xC0000000
li t2, 0 # i = 0
li t5, 0 # j = 0 // now use as a counter for new asid loop
li t3, 32 # Max amount of Loops = 32
loop: bge t2, t3, nASID # exit loop if i >= loops
lw t1, 0(t0)
li t4, 0x1000
add t0, t0, t4
addi t2, t2, 1
j loop
nASID: bne t5, zero, finished
li a0, 3 // go
ecall
li t5, 0x9000100000080080 // try making asid = 1
csrw satp, t5
li a0, 1
ecall
li t2, 0
li t0, 0xC0000000
li t5, 1 // make this not zero.
j loop
finished:
j done
.data
.align 19
# level 3 Page table situated at 0x8008 0000, should point to 8008,1000
pagetable:
.8byte 0x200204C1
.align 12 // level 2 page table, contains direction to a gigapageg
.8byte 0x0
.8byte 0x0
.8byte 0x200000CF // gigapage that starts at 8000 0000 goes to C000 0000
.8byte 0x200208C1 // pointer to next page table entry at 8008 2000
.align 12 // level 1 page table, points to level 0 page table
.8byte 0x20020CC1
.align 12 // level 0 page table, points to address C000 0000 // FOR NOW ALL OF THESE GO TO 8 instead of C cause they start with 2
.8byte 0x200000CF // access xC000 0000
.8byte 0x200004CF // access xC000 1000
.8byte 0x200008CF // access xC000 2000
.8byte 0x20000CCF // access xC000 3000
.8byte 0x200010CF // access xC000 4000
.8byte 0x200014CF
.8byte 0x200018CF
.8byte 0x20001CCF
.8byte 0x200020CF // access xC000 8000
.8byte 0x200024CF
.8byte 0x200028CF
.8byte 0x20002CCF
.8byte 0x200030CF // access xC000 C000
.8byte 0x200034CF
.8byte 0x200038CF
.8byte 0x20003CCF
.8byte 0x200040CF // access xC001 0000
.8byte 0x200044CF
.8byte 0x200048CF
.8byte 0x20004CCF
.8byte 0x200050CF // access xC001 4000
.8byte 0x200054CF
.8byte 0x200058CF
.8byte 0x20005CCF
.8byte 0x200060CF // access xC001 8000
.8byte 0x200064CF
.8byte 0x200068CF
.8byte 0x20006CCF
.8byte 0x200070CF // access xC001 C000
.8byte 0x200074CF
.8byte 0x200078CF
.8byte 0x20007CCF
.8byte 0x200080CF // access xC002 0000
.8byte 0x200084CF
.8byte 0x200088CF
.8byte 0x20008CCF

134
tests/coverage/tlbGLB.S Normal file
View File

@ -0,0 +1,134 @@
///////////////////////////////////////////
// tlbGLB.S
//
// Written: mmendozamanriquez@hmc.edu 4 April 2023
// nlimpert@hmc.edu
//
// Purpose: coverage for the global check.
//
// 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.h"
# run-elf.bash find this in project description
main:
# Page table root address at 0x80010000
li t5, 0x9000000000080080 // try making asid = 0.
csrw satp, t5
# sfence.vma x0, x0
# switch to supervisor mode
li a0, 1
ecall
li t0, 0xC0000000
li t2, 0 # i = 0
li t5, 0 # j = 0 // now use as a counter for new asid loop
li t3, 32 # Max amount of Loops = 32
loop: bge t2, t3, nASID # exit loop if i >= loops
lw t1, 0(t0)
li t4, 0x1000
add t0, t0, t4
addi t2, t2, 1
j loop
nASID: bne t5, zero, finished
li a0, 3 // go
ecall
li t5, 0x9000100000080080 // try making asid = 1
csrw satp, t5
li a0, 1
ecall
li t2, 0
li t0, 0xC0000000
li t5, 1 // make this not zero.
j loop
finished:
j done
.data
.align 19
# level 3 Page table situated at 0x8008 0000, should point to 8008,1000
pagetable:
.8byte 0x200204C1
.align 12 // level 2 page table, contains direction to a gigapageg
.8byte 0x0
.8byte 0x0
.8byte 0x200000CF // gigapage that starts at 8000 0000 goes to C000 0000
.8byte 0x200208C1 // pointer to next page table entry at 8008 2000
.align 12 // level 1 page table, points to level 0 page table
.8byte 0x20020CE1
.align 12 // level 0 page table, points to address C000 0000 // FOR NOW ALL OF THESE GO TO 8 instead of C cause they start with 2
.8byte 0x200000CF // access xC000 0000
.8byte 0x200004CF // access xC000 1000
.8byte 0x200008CF // access xC000 2000
.8byte 0x20000CCF // access xC000 3000
.8byte 0x200010EF // access xC000 4000
.8byte 0x200014EF
.8byte 0x200018EF
.8byte 0x20001CEF
.8byte 0x200020EF // access xC000 8000
.8byte 0x200024EF
.8byte 0x200028EF
.8byte 0x20002CEF
.8byte 0x200030EF // access xC000 C000
.8byte 0x200034EF
.8byte 0x200038EF
.8byte 0x20003CEF
.8byte 0x200040EF // access xC001 0000
.8byte 0x200044EF
.8byte 0x200048EF
.8byte 0x20004CEF
.8byte 0x200050EF // access xC001 4000
.8byte 0x200054EF
.8byte 0x200058EF
.8byte 0x20005CEF
.8byte 0x200060EF // access xC001 8000
.8byte 0x200064EF
.8byte 0x200068EF
.8byte 0x20006CEF
.8byte 0x200070EF // access xC001 C000
.8byte 0x200074eF
.8byte 0x200078EF
.8byte 0x20007CEF
.8byte 0x200080EF // access xC002 0000
.8byte 0x200084EF
.8byte 0x200088EF
.8byte 0x20008CEF

155
tests/coverage/tlbM3.S Normal file
View File

@ -0,0 +1,155 @@
///////////////////////////////////////////
// tlbKP.S
//
// Written: mmendozamanriquez@hmc.edu 4 April 2023
// nlimpert@hmc.edu
//
// Purpose: Test coverage for LSU
//
// 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.h"
# run-elf.bash find this in project description
main:
# Page table root address at 0x80010000
li t5, 0x9000000000080010
csrw satp, t5
# sfence.vma x0, x0
# switch to supervisor mode
li a0, 1
ecall
li t0, 0x1000
li t2, 0 # i = 0
li t3, 64 # Max amount of Loops = 32
li t4, 0x1000
loop: bge t2, t3, interim # exit loop if i >= loops
lw t1, 0(t0)
# sfence.vma x0, x0
add t0, t0, t4
addi t2, t2, 1
j loop
interim:
li t0, 0xFFFFFFFF000
li t2, 0 # i = 0
loop2:bge t2, t3, finished # exit loop if i >= loops
lw t1, 0(t0)
add t0, t0, t4
addi t2, t2, 1
j loop2
finished:
j done
.data
.align 16
# Page table situated at 0x80010000
pagetable:
.8byte 0x200044C1 // old page table was 200040 which just pointed to itself! wrong
.align 12
.8byte 0x00000000200048C1
.8byte 0x00000000200048C1
.8byte 0x00000000200048C1
.align 12
.8byte 0x0000000020004CC1
//.8byte 0x00000200800CF// ADD IN THE MEGAPAGE should 3 nibbles of zeros be removed?
.align 12
#80000000
.8byte 0x200000CF
.8byte 0x200004CF
.8byte 0x200008CF
.8byte 0x20000CCF
.8byte 0x200010CF
.8byte 0x200014CF
.8byte 0x200018CF
.8byte 0x20001CCF
.8byte 0x200020CF
.8byte 0x200024CF
.8byte 0x200028CF
.8byte 0x20002CCF
.8byte 0x200030CF
.8byte 0x200034CF
.8byte 0x200038CF
.8byte 0x20003CCF
.8byte 0x200040CF
.8byte 0x200044CF
.8byte 0x200048CF
.8byte 0x20004CCF
.8byte 0x200050CF
.8byte 0x200054CF
.8byte 0x200058CF
.8byte 0x20005CCF
.8byte 0x200060CF
.8byte 0x200064CF
.8byte 0x200068CF
.8byte 0x20006CCF
.8byte 0x200070CF
.8byte 0x200074CF
.8byte 0x200078CF
.8byte 0x20007CCF
.8byte 0x200080CF
.8byte 0x200084CF
.8byte 0x200088CF
.8byte 0x20008CCF
.8byte 0x200090CF
.8byte 0x200094CF
.8byte 0x200098CF
.8byte 0x20009CCF
.8byte 0x2000A0CF
.8byte 0x2000A4CF
.8byte 0x2000A8CF
.8byte 0x2000ACCF
.8byte 0x2000B0CF
.8byte 0x2000B4CF
.8byte 0x2000B8CF
.8byte 0x2000BCCF
.8byte 0x2000C0CF
.8byte 0x2000C4CF
.8byte 0x2000C8CF
.8byte 0x2000CCCF
.8byte 0x2000D0CF
.8byte 0x2000D4CF

163
tests/coverage/tlbMP.S Normal file
View File

@ -0,0 +1,163 @@
///////////////////////////////////////////
// tlbMP.S
//
// Written: mmendozamanriquez@hmc.edu 4 April 2023
// nlimpert@hmc.edu
//
// Purpose: Test coverage for LSU
//
// 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.h"
# run-elf.bash find this in project description
main:
# Page table root address at 0x80010000
li t5, 0x9000000000080010
csrw satp, t5
# sfence.vma x0, x0
# switch to supervisor mode
li a0, 1
ecall
li t5, 0
li t0, 0x84000000 // go to first megapage
li t4, 0x1000 // put this outside the loop.
li t2, 0 # i = 0
li t3, 32 # Max amount of Loops = 16
loop: bge t2, t3, lKP # exit loop if i >= loops
lw t1, 0(t0)
add t0, t0, t4
addi t2, t2, 1
j loop
lKP: bne t5, zero, finished
li t0, 0x80000000
slli t4, t4, 9
addi t5, t5, 1
li t2, 0
j loop
finished:
j done
.data
.align 16
# Page table situated at 0x80010000
pagetable:
.8byte 0x200044C1
.align 12
.8byte 0x00000000200048C1
.8byte 0x00000000200048C1
.8byte 0x00000000200048C1
.align 12 // megapages starting at 8000 0000 going to 8480 0000 (32*2 MiB beyond that)
.8byte 0x200000CF // access 8000,0000
.8byte 0x200800CF // access 8020,0000
.8byte 0x201000CF // acesss 8040,0000
.8byte 0x201800CF // acesss 8060,0000
.8byte 0x202000CF // access 8080,0000
.8byte 0x202800CF // access 80A0,0000
.8byte 0x203000CF // access 80C0,0000
.8byte 0x203800CF // access 80E0,0000
.8byte 0x204000CF // access 8100,0000
.8byte 0x204800CF
.8byte 0x205000CF
.8byte 0x205800CF
.8byte 0x206000CF // access 8180,0000
.8byte 0x206800CF
.8byte 0x207000CF
.8byte 0x207800CF
.8byte 0x208000CF // access 8200,0000
.8byte 0x208800CF
.8byte 0x209000CF
.8byte 0x209800CF
.8byte 0x20A000CF // access 8280,0000
.8byte 0x20A800CF
.8byte 0x20B000CF
.8byte 0x20B800CF
.8byte 0x20C000CF // access 8300,0000
.8byte 0x20C800CF
.8byte 0x20D000CF
.8byte 0x20D800CF
.8byte 0x20E000CF // access 8380,0000
.8byte 0x20E800CF
.8byte 0x20F000CF
.8byte 0x20F800CF
.8byte 0x20004CC1
// Kilopage entry, for addresses from 8400, 0000 to 841F, FFFF
// point to ...
.align 12 // should start at 84000000
.8byte 0x210000CF
.8byte 0x210004CF
.8byte 0x210008CF
.8byte 0x21000CCF
.8byte 0x210010CF
.8byte 0x210014CF
.8byte 0x210018CF
.8byte 0x21001CCF
.8byte 0x210020CF
.8byte 0x210024CF
.8byte 0x210028CF
.8byte 0x21002CCF
.8byte 0x210030CF
.8byte 0x210034CF
.8byte 0x210038CF
.8byte 0x21003CCF
.8byte 0x210040CF
.8byte 0x210044CF
.8byte 0x210048CF
.8byte 0x21004CCF
.8byte 0x210050CF
.8byte 0x210054CF
.8byte 0x210058CF
.8byte 0x21005CCF
.8byte 0x210060CF
.8byte 0x210064CF
.8byte 0x210068CF
.8byte 0x21006CCF
.8byte 0x210070CF
.8byte 0x210074CF
.8byte 0x210078CF
.8byte 0x21007CCF