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

This commit is contained in:
Sydeny 2023-04-17 13:51:16 -07:00
commit ee5deb10a7
57 changed files with 914 additions and 577 deletions

View file

@ -5,7 +5,7 @@
##
## Written: lserafini@hmc.edu
## Created: 27 March 2023
## Modified: 5 April 2023
## Modified: 12 April 2023
##
## Purpose: Simulate a L1 D$ or I$ for comparison with Wally
##

View file

@ -0,0 +1,29 @@
# CORE-V Wally Test Plan
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.
* ***pending: Run random tests generated by risc-dv
* Run CoreMark and Embench benchmarks.
* Run performance validation against reference models for the branch predictor and caches.
* Run the TestFloat suite against all precisions of all operations for the FPU unit.
* *** 83.5% coverage of statements, branches, expressions, and FSM states and transitions
* Boot Buildroot Linux in lock-step against ImperasDV.
* Boot Buildroot Linux on an FPGA and run programs.
# Running Tests
#
# Detailed Test Plans
The test plans for specific units are lined below:
* Privileged Unit
* Memory Management Unit
* Peripherals
* Branch Predictor Performance Validation
* Cache Performance Validation
Wally is described in an upcoming textbook, *RISC-V System-on-Chip Design*, by Harris, Stine, Thompson, and Harris.

18
sim/GetLineNum.do Normal file
View file

@ -0,0 +1,18 @@
# Alec Vercruysse
# 2023-04-12
# Note that the target string is regex, and needs to be double-escaped.
# e.g. to match a (, you need \\(.
proc GetLineNum {fname target} {
set f [open $fname]
set linectr 1
while {[gets $f line] != -1} {
if {[regexp $target $line]} {
close $f
return $linectr
}
incr linectr
}
close $f
return -code error \
"target string not found"
}

View file

@ -27,25 +27,56 @@
# This file should be a last resort. It's preferable to put
# // coverage off
# statements inline with the code whenever possible.
# a hack to describe coverage exclusions without hardcoding linenumbers:
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
coverage exclude -srcfile lzc.sv
# FDIVSQRT has
coverage exclude -scope /core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state DONE->BUSY
######################
# Toggle exclusions
# Not used because toggle coverage isn't measured
######################
### 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)
# Also exclude the write line to ready transition for the I$ since we can't get a flush during this operation.
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -fstate CurrState STATE_FLUSH STATE_FLUSH_WRITEBACK STATE_FLUSH_WRITEBACK STATE_WRITEBACK
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -ftrans CurrState STATE_WRITE_LINE->STATE_READY
# exclude unused transitions from case statement. Unfortunately the whole branch needs to be excluded I think. Expression coverage should still work.
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache state-case"] -item b 1
# exclude branch/condition coverage: LineDirty if statement
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FETCHStatement"] -item bc 1
# exclude the unreachable logic
set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache case"]
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: 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
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheW"] -item e 1 -fecexprrow 4
# output signal logic
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache StallStates"] -item e 1 -fecexprrow 8 12 14
set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache flushdirtycontrols"]
set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache flushdirtycontrols"]
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 CacheBusW"]
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrCauses"] -item e 1 -fecexprrow 4 10
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusRCauses"] -item e 1 -fecexprrow 1-2 12
# cache.sv AdrSelMux and CacheBusAdrMux, excluding unhit Flush branch
coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMux -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheBusAdrMux -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1 3
# CacheWay Dirty logic. -scope does not accept wildcards.
set numcacheways 4
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 SetDirtyWay"] -item e 1
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: icache SelectedWiteWordEn"] -item e 1 -fecexprrow 4 6
# below: flushD can't go high during an icache write b/c of pipeline stall
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
}
# 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
# Excluding peripherals as sources of instructions for the ifu
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/clintdec

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
###########################################
## CacheSimTest.py
## rv64gc_CacheSim.py
##
## Written: lserafini@hmc.edu
## Created: 11 April 2023

4
src/cache/cache.sv vendored
View file

@ -1,5 +1,5 @@
///////////////////////////////////////////
// cache
// cache.sv
//
// Written: Ross Thompson ross1728@gmail.com
// Created: 7 July 2021
@ -122,7 +122,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
// Select victim way for associative caches
if(NUMWAYS > 1) begin:vict
cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU(
.clk, .reset, .CacheEn, .FlushStage, .HitWay, .ValidWay, .VictimWay, .CacheSet, .LRUWriteEn,
.clk, .reset, .CacheEn, .HitWay, .ValidWay, .VictimWay, .CacheSet, .LRUWriteEn,
.SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache);
end else
assign VictimWay = 1'b1; // one hot.

49
src/cache/cacheLRU.sv vendored
View file

@ -1,5 +1,5 @@
///////////////////////////////////////////
// dcache (data cache)
// cacheLRU.sv
//
// Written: Ross Thompson ross1728@gmail.com
// Created: 20 July 2021
@ -33,7 +33,6 @@ module cacheLRU
#(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128) (
input logic clk,
input logic reset,
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
input logic [NUMWAYS-1:0] HitWay, // Which way is valid and matches PAdr's tag
input logic [NUMWAYS-1:0] ValidWay, // Which ways for a particular set are valid, ignores tag
@ -90,16 +89,26 @@ module cacheLRU
assign WayExpanded[StartIndex : EndIndex] = {{DuplicationFactor}{WayEncoded[row]}};
end
genvar r, a, s;
genvar node;
assign LRUUpdate[NUMWAYS-2] = '1;
for(s = NUMWAYS-2; s >= NUMWAYS/2; s--) begin : enables
localparam p = NUMWAYS - s - 1;
localparam g = log2(p);
localparam t0 = s - p;
localparam t1 = t0 - 1;
localparam r = LOGNUMWAYS - g;
assign LRUUpdate[t0] = LRUUpdate[s] & ~WayEncoded[r];
assign LRUUpdate[t1] = LRUUpdate[s] & WayEncoded[r];
for(node = NUMWAYS-2; node >= NUMWAYS/2; node--) begin : enables
localparam ctr = NUMWAYS - node - 1;
localparam ctr_depth = log2(ctr);
localparam lchild = node - ctr;
localparam rchild = lchild - 1;
localparam r = LOGNUMWAYS - ctr_depth;
// the child node will be updated if its parent was updated and
// the WayEncoded bit was the correct value.
// The if statement is only there for coverage since LRUUpdate[root] is always 1.
if (node == NUMWAYS-2) begin
assign LRUUpdate[lchild] = ~WayEncoded[r];
assign LRUUpdate[rchild] = WayEncoded[r];
end
else begin
assign LRUUpdate[lchild] = LRUUpdate[node] & ~WayEncoded[r];
assign LRUUpdate[rchild] = LRUUpdate[node] & WayEncoded[r];
end
end
// The root node of the LRU tree will always be selected in LRUUpdate. No mux needed.
@ -107,15 +116,15 @@ module cacheLRU
mux2 #(1) LRUMuxes[NUMWAYS-3:0](CurrLRU[NUMWAYS-3:0], ~WayExpanded[NUMWAYS-3:0], LRUUpdate[NUMWAYS-3:0], NextLRU[NUMWAYS-3:0]);
// Compute next victim way.
for(s = NUMWAYS-2; s >= NUMWAYS/2; s--) begin
localparam t0 = 2*s - NUMWAYS;
for(node = NUMWAYS-2; node >= NUMWAYS/2; node--) begin
localparam t0 = 2*node - NUMWAYS;
localparam t1 = t0 + 1;
assign Intermediate[s] = CurrLRU[s] ? Intermediate[t0] : Intermediate[t1];
assign Intermediate[node] = CurrLRU[node] ? Intermediate[t0] : Intermediate[t1];
end
for(s = NUMWAYS/2-1; s >= 0; s--) begin
localparam int0 = (NUMWAYS/2-1-s)*2;
for(node = NUMWAYS/2-1; node >= 0; node--) begin
localparam int0 = (NUMWAYS/2-1-node)*2;
localparam int1 = int0 + 1;
assign Intermediate[s] = CurrLRU[s] ? int1[LOGNUMWAYS-1:0] : int0[LOGNUMWAYS-1:0];
assign Intermediate[node] = CurrLRU[node] ? int1[LOGNUMWAYS-1:0] : int0[LOGNUMWAYS-1:0];
end
logic [NUMWAYS-1:0] FirstZero;
@ -134,11 +143,9 @@ module cacheLRU
always_ff @(posedge clk) begin
if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
if(CacheEn) begin
// if((InvalidateCache | FlushCache) & ~FlushStage) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
if (LRUWriteEn & ~FlushStage) begin
if(LRUWriteEn)
LRUMemory[PAdr] <= NextLRU;
end
if(LRUWriteEn & ~FlushStage & (PAdr == CacheSet))
if(LRUWriteEn & (PAdr == CacheSet))
CurrLRU <= #1 NextLRU;
else
CurrLRU <= #1 LRUMemory[CacheSet];

44
src/cache/cachefsm.sv vendored
View file

@ -1,11 +1,11 @@
///////////////////////////////////////////
// dcache (data cache) fsm
// cachefsm.sv
//
// Written: Ross Thompson ross1728@gmail.com
// Created: 25 August 2021
// Modified: 20 January 2023
//
// Purpose: Controller for the dcache fsm
// Purpose: Controller for the cache fsm
//
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.14 and Table 7.1)
//
@ -55,7 +55,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
input logic FlushAdrFlag, // On last set of a cache flush
input logic FlushWayFlag, // On the last way for any set of a cache flush
output logic SelAdr, // [0] SRAM reads from NextAdr, [1] SRAM reads from PAdr
output logic SetValid, // Set the dirty bit in the selected way and set
output logic SetValid, // Set the valid bit in the selected way and set
output logic ClearDirty, // Clear the dirty bit in the selected way and set
output logic SetDirty, // Set the dirty bit in the selected way and set
output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
@ -89,13 +89,13 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
assign AMO = CacheAtomic[1] & (&CacheRW);
assign StoreAMO = AMO | CacheRW[0];
assign AnyMiss = (StoreAMO | CacheRW[1]) & ~CacheHit & ~InvalidateCache;
assign AnyUpdateHit = (StoreAMO) & CacheHit;
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit);
assign AnyMiss = (StoreAMO | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: icache storeAMO
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;
assign CacheAccess = (AMO | CacheRW[1] | CacheRW[0]) & CurrState == STATE_READY; // exclusion-tag: icache CacheW
assign CacheMiss = CacheAccess & ~CacheHit;
// special case on reset. When the fsm first exists reset the
@ -109,17 +109,18 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
always_comb begin
NextState = STATE_READY;
case (CurrState)
case (CurrState) // exclusion-tag: icache state-case
STATE_READY: if(InvalidateCache) NextState = STATE_READY;
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH;
else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK;
else 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 NextState = STATE_READY;
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
else NextState = STATE_FETCH;
STATE_WRITE_LINE: NextState = STATE_READ_HOLD;
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
else NextState = STATE_READY;
// exclusion-tag-start: icache case
STATE_WRITEBACK: if(CacheBusAck) NextState = STATE_FETCH;
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.
@ -129,13 +130,14 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH;
else if(CacheBusAck) NextState = STATE_READ_HOLD;
else NextState = STATE_FLUSH_WRITEBACK;
// exclusion-tag-end: icache case
default: NextState = STATE_READY;
endcase
end
// com back to CPU
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & CurrState == STATE_READ_HOLD);
assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss)) |
assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss)) | // exclusion-tag: icache StallStates
(CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) | // this cycle writes the sram, must keep stalling so the next cycle can read the next hit/miss unless its a write.
@ -143,12 +145,14 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
(CurrState == STATE_FLUSH_WRITEBACK);
// write enables internal to cache
assign SetValid = CurrState == STATE_WRITE_LINE;
assign SetDirty = (CurrState == STATE_READY & AnyUpdateHit) |
(CurrState == STATE_WRITE_LINE & (StoreAMO));
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(StoreAMO)) |
(CurrState == STATE_FLUSH & LineDirty); // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
// coverage off -item e 1 -fecexprrow 8
assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) |
(CurrState == STATE_WRITE_LINE);
(CurrState == STATE_WRITE_LINE) & ~FlushStage;
// exclusion-tag-start: icache flushdirtycontrols
assign SetDirty = (CurrState == STATE_READY & AnyUpdateHit) | // exclusion-tag: icache SetDirty
(CurrState == STATE_WRITE_LINE & (StoreAMO));
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(StoreAMO)) | // exclusion-tag: icache ClearDirty
(CurrState == STATE_FLUSH & LineDirty); // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
// Flush and eviction controls
assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_READY & AnyMiss & LineDirty);
@ -162,20 +166,20 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
(CurrState == STATE_FLUSH_WRITEBACK & CacheBusAck);
assign FlushCntRst = (CurrState == STATE_FLUSH & FlushFlag & ~LineDirty) |
(CurrState == STATE_FLUSH_WRITEBACK & FlushFlag & CacheBusAck);
// exclusion-tag-end: icache flushdirtycontrols
// Bus interface controls
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) |
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses
(CurrState == STATE_FETCH & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & CacheBusAck);
assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) |
assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) | // exclusion-tag: icache CacheBusW
(CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck);
assign SelAdr = (CurrState == STATE_READY & (StoreAMO | AnyMiss)) | // changes if store delay hazard removed
assign SelAdr = (CurrState == STATE_READY & (StoreAMO | AnyMiss)) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
(CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) |
(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;

13
src/cache/cacheway.sv vendored
View file

@ -52,7 +52,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
output logic HitWay, // This way hits
output logic ValidWay, // This way is valid
output logic DirtyWay, // This way is dirty
output logic [TAGLEN-1:0] TagWay); // THis way's tag if valid
output logic [TAGLEN-1:0] TagWay); // This way's tag if valid
localparam WORDSPERLINE = LINELEN/`XLEN;
localparam BYTESPERLINE = LINELEN/8;
@ -97,18 +97,13 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
/////////////////////////////////////////////////////////////////////////////////////////////
assign SetValidWay = SetValid & SelData;
assign SetDirtyWay = SetDirty & SelData; // exclusion-tag: icache SetDirtyWay
assign ClearDirtyWay = ClearDirty & SelData;
if (!READ_ONLY_CACHE) begin
assign SetDirtyWay = SetDirty & SelData;
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage;
end
else begin
assign SelectedWriteWordEn = SetValidWay & ~FlushStage;
end
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn
assign SetValidEN = SetValidWay & ~FlushStage; // exclusion-tag: icache SetValidEN
// If writing the whole line set all write enables to 1, else only set the correct word.
assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR
assign SetValidEN = SetValidWay & ~FlushStage;
/////////////////////////////////////////////////////////////////////////////////////////////
// Tag Array

View file

@ -1,11 +1,11 @@
///////////////////////////////////////////
// subcachelineread
// subcachelineread.sv
//
// Written: Ross Thompson ross1728@gmail.com
// Created: 4 February 2022
// Modified: 20 January 2023
//
// Purpose: Muxes the cache line downto the word size. Also include possilbe save/restore registers/muxes.
// Purpose: Muxes the cache line down to the word size. Also include possible save/restore registers/muxes.
//
// Documentation: RISC-V System on Chip Design Chapter 7
@ -31,7 +31,6 @@
module subcachelineread #(parameter LINELEN, WORDLEN,
parameter MUXINTERVAL )( // The number of bits between mux. Set to 16 for I$ to support compressed. Set to `LLEN for D$
input logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1 : 0] PAdr, // Physical address
input logic [LINELEN-1:0] ReadDataLine,// Read data of the whole cacheline
output logic [WORDLEN-1:0] ReadDataWord // read data of selected word.

View file

@ -51,11 +51,11 @@ module ahbcacheinterface #(
// cache interface
input logic [`PA_BITS-1:0] CacheBusAdr, // Address of cache line
input logic [`LLEN-1:0] CacheReadDataWordM, // one word of cache line during a writeback
input logic [`LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$
input logic Cacheable, // Memory operation is cachable
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
output logic CacheBusAck, // Handshack to $ indicating bus transaction completed
output logic CacheBusAck, // Handshake to $ indicating bus transaction completed
output logic [LINELEN-1:0] FetchBuffer, // Register to hold beats of cache line as the arrive from bus
output logic [AHBWLOGBWPL-1:0] BeatCount, // Beat position within the cache line in the Address Phase
output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr

View file

@ -1,5 +1,5 @@
///////////////////////////////////////////
// controller input stage
// controllerinput.sv
//
// Written: Ross Thompson ross1728@gmail.com
// Created: August 31, 2022
@ -40,7 +40,7 @@ module controllerinput #(
input logic HRESETn,
input logic Save, // Two or more managers requesting (HTRANS != 00) at the same time. Save the non-granted manager inputs
input logic Restore, // Restore a saved manager inputs when it is finally granted
input logic Disable, // Supress HREADY to the non-granted manager
input logic Disable, // Suppress HREADY to the non-granted manager
output logic Request, // This manager is making a request
// controller input
input logic [1:0] HTRANSIn, // Manager input. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
@ -48,14 +48,14 @@ module controllerinput #(
input logic [2:0] HSIZEIn, // Manager input. AHB transaction width
input logic [2:0] HBURSTIn, // Manager input. AHB burst length
input logic [`PA_BITS-1:0] HADDRIn, // Manager input. AHB address
output logic HREADYOut, // Indicate to manager the peripherial is not busy and another manager does not have priority
output logic HREADYOut, // Indicate to manager the peripheral is not busy and another manager does not have priority
// controller output
output logic [1:0] HTRANSOut, // Aribrated manager transaction. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
output logic HWRITEOut, // Aribrated manager transaction. AHB 0: Read operation 1: Write operation
output logic [2:0] HSIZEOut, // Aribrated manager transaction. AHB transaction width
output logic [2:0] HBURSTOut, // Aribrated manager transaction. AHB burst length
output logic [`PA_BITS-1:0] HADDROut, // Aribrated manager transaction. AHB address
input logic HREADYIn // Peripherial ready
output logic [1:0] HTRANSOut, // Arbitrated manager transaction. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
output logic HWRITEOut, // Arbitrated manager transaction. AHB 0: Read operation 1: Write operation
output logic [2:0] HSIZEOut, // Arbitrated manager transaction. AHB transaction width
output logic [2:0] HBURSTOut, // Arbitrated manager transaction. AHB burst length
output logic [`PA_BITS-1:0] HADDROut, // Arbitrated manager transaction. AHB address
input logic HREADYIn // Peripheral ready
);
logic HWRITESave;

View file

@ -1,5 +1,5 @@
///////////////////////////////////////////
// ebufsmarb
// ebufsmarb.sv
//
// Written: Ross Thompson ross1728@gmail.com
// Created: 23 January 2023
@ -86,7 +86,7 @@ module ebufsmarb (
// Controller 1 (LSU)
// When both the IFU and LSU request at the same time, the FSM will go into the arbitrate state.
// Once the LSU request is done the fsm returns to IDLE. To prevent the LSU from regaining
// priority and re issuing the same memroy operation, the delayed IFUReqD squashes the LSU request.
// priority and re-issuing the same memory operation, the delayed IFUReqD squashes the LSU request.
// This is necessary because the pipeline is stalled for the entire duration of both transactions,
// and the LSU memory request will stil be active.
flopr #(1) ifureqreg(HCLK, ~HRESETn, IFUReq, IFUReqD);

View file

@ -1,5 +1,5 @@
///////////////////////////////////////////
// fdivsqrtpreproc.sv
// fdivsqrtexpcalc.sv
//
// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu
// Modified:13 January 2022

View file

@ -71,6 +71,7 @@ module fdivsqrtfsm(
// 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)
@ -110,7 +111,8 @@ module fdivsqrtfsm(
always_ff @(posedge clk) begin
if (reset | FlushE) begin
state <= #1 IDLE;
end else if ((state == IDLE) & IFDivStartE) begin
end else if (IFDivStartE) begin // IFDivStartE implies stat is IDLE
// end else if ((state == IDLE) & IFDivStartE) begin // IFDivStartE implies stat is IDLE
step <= cycles;
if (SpecialCaseE) state <= #1 DONE;
else state <= #1 BUSY;

View file

@ -101,17 +101,19 @@ module fdivsqrtpreproc (
lzc #(`DIVb) lzcX (IFX, ell);
lzc #(`DIVb) lzcY (IFD, mE);
// Normalization shift
assign XPreproc = IFX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // *** try to remove this +1
assign DPreproc = IFD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});
// Normalization shift: shift off leading one
assign XPreproc = (IFX << ell) << 1;
assign DPreproc = (IFD << mE) << 1;
// append leading 1 (for normal inputs)
// 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: factor out fdivsqrtcycles
if (`IDIV_ON_FPU) begin:intrightshift // Int Supported
logic [`DIVBLEN:0] ZeroDiff, p;
logic ALTBE;
@ -119,7 +121,7 @@ module fdivsqrtpreproc (
// calculate number of fractional bits p
assign ZeroDiff = mE - ell; // Difference in number of leading zeros
assign ALTBE = ZeroDiff[`DIVBLEN]; // A less than B (A has more leading zeros)
mux2 #(`DIVBLEN+1) pmux(ZeroDiff, {(`DIVBLEN+1){1'b0}}, ALTBE, p); // *** is there a more graceful way to write these constants
mux2 #(`DIVBLEN+1) pmux(ZeroDiff, '0, ALTBE, p);
// Integer special cases (terminate immediately)
assign ISpecialCaseE = BZeroE | ALTBE;

View file

@ -48,7 +48,7 @@ module fsgninj (
// format final result based on precision
// - uses NaN-blocking format
// - if there are any unsused bits the most significant bits are filled with 1s
// - if there are any unused bits the most significant bits are filled with 1s
if (`FPSIZES == 1)
assign SgnRes = {ResSgn, X[`FLEN-2:0]};

View file

@ -111,7 +111,7 @@ module round(
// determine what format the final result is in: int or fp
assign IntRes = CvtOp & ToInt;
assign IntRes = ToInt;
assign FpRes = ~IntRes;
// sticky bit calculation

View file

@ -40,7 +40,7 @@ module mux3 #(parameter WIDTH = 8) (
input logic [1:0] s,
output logic [WIDTH-1:0] y);
assign y = s[1] ? d2 : (s[0] ? d1 : d0);
assign y = s[1] ? d2 : (s[0] ? d1 : d0); // exclusion-tag: mux3
endmodule
module mux4 #(parameter WIDTH = 8) (

View file

@ -1,5 +1,5 @@
///////////////////////////////////////////
// oneHotDecoder.sv
// onehotdecoder.sv
//
// Written: ross1728@gmail.com July 09, 2021
// Modified:

View file

@ -300,7 +300,7 @@ module controller(
assign FlushDCacheD = 0;
end
// Decocde stage pipeline control register
// Decode stage pipeline control register
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
// Execute stage pipeline control register and logic

View file

@ -138,7 +138,8 @@ module datapath (
assign MulDivResultW = MDUResultW;
end
end else begin:fpmux
assign IFResultM = IEUResultM; assign IFCvtResultW = IFResultW;
assign IFResultM = IEUResultM;
assign IFCvtResultW = IFResultW;
assign MulDivResultW = MDUResultW;
end
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW);

View file

@ -187,7 +187,7 @@ module bpred (
// Correct branch/jump target.
mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
// If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
// If the fence/csrw was predicted as a taken branch then we select PCF, rather than PCE.
// Effectively this is PCM+4 or the non-existant PCLinkM
if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
else assign NextValidPCE = PCE;
@ -201,7 +201,7 @@ module bpred (
// 3. target ras (ras target wrong / class[2])
// 4. direction (br dir wrong / class[0])
// Unforuantely we can't use PCD to infer the correctness of the BTB or RAS because the class prediction
// Unfortunately we can't use PCD to infer the correctness of the BTB or RAS because the class prediction
// could be wrong or the fall through address selected for branch predict not taken.
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
// both without the above inaccuracies.

View file

@ -1,7 +1,7 @@
///////////////////////////////////////////
// btb.sv
//
// Written: Ross Thomposn ross1728@gmail.com
// Written: Ross Thompson ross1728@gmail.com
// Created: February 15, 2021
// Modified: 24 January 2023
//
@ -73,7 +73,7 @@ module btb #(parameter Depth = 10 ) (
// must output a valid PC and valid bit during reset. Because only PCF, not PCNextF is reset, PCNextF is invalid
// during reset. The BTB must produce a non X PC1NextF to allow the simulation to run.
// While thie mux could be included in IFU it is not necessary for the IROM/I$/bus.
// While the mux could be included in IFU it is not necessary for the IROM/I$/bus.
// For now it is optimal to leave it here.
assign ResetPC = `RESET_VECTOR;
assign PCNextFIndex = reset ? ResetPC[Depth+1:2] : {PCNextF[Depth+1] ^ PCNextF[1], PCNextF[Depth:2]};

View file

@ -44,7 +44,7 @@ module decompress (
logic [5:0] immSH;
logic [1:0] op;
// Extrac op and register source/destination fields
// Extract op and register source/destination fields
assign instr16 = InstrRawD[15:0]; // instruction is already aligned
assign op = instr16[1:0];
assign rds1 = instr16[11:7];

View file

@ -4,7 +4,7 @@
// Written: David_Harris@hmc.edu 9 January 2021
// Modified:
//
// Purpose: Instrunction Fetch Unit
// Purpose: Instruction Fetch Unit
// PC, branch prediction, instruction cache
//
// A component of the CORE-V-WALLY configurable RISC-V project.
@ -362,7 +362,7 @@ module ifu (
assign IllegalIEUFPUInstrD = IllegalIEUInstrD & IllegalFPUInstrD;
// Misaligned PC logic
// Instruction address misalignement only from br/jal(r) instructions.
// Instruction address misalignment only from br/jal(r) instructions.
// instruction address misalignment is generated by the target of control flow instructions, not
// the fetch itself.
// xret and Traps both cannot produce instruction misaligned.
@ -372,7 +372,7 @@ module ifu (
// Spec 3.1.14
// Traps: Cant happen. The bottom two bits of MTVEC are ignored so the trap always is to a multiple of 4. See 3.1.7 of the privileged spec.
assign BranchMisalignedFaultE = (IEUAdrE[1] & ~`C_SUPPORTED) & PCSrcE;
flopenr #(1) InstrMisalginedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM);
flopenr #(1) InstrMisalignedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM);
// Instruction and PC/PCLink pipeline registers
// Cannot use flopenrc for Instr(E/M) as it resets to NOP not 0.

View file

@ -93,7 +93,7 @@ module csrsr (
// harwired STATUS bits
assign STATUS_TSR = `S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_TW = (`S_SUPPORTED | `U_SUPPORTED) & STATUS_TW_INT; // override reigster with 0 if only machine mode supported
assign STATUS_TW = (`S_SUPPORTED | `U_SUPPORTED) & STATUS_TW_INT; // override register with 0 if only machine mode supported
assign STATUS_TVM = `S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_MXR = `S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported
/* assign STATUS_UBE = 0; // little-endian
@ -198,9 +198,12 @@ module csrsr (
STATUS_UBE <= #1 CSRWriteValM[6] & `U_SUPPORTED & `BIGENDIAN_SUPPORTED;
STATUS_MBE <= #1 nextMBE;
STATUS_SBE <= #1 nextSBE;
// coverage off
// MSTATUSH only exists in 32-bit configurations, will not be hit on rv64gc
end else if (WriteMSTATUSHM) begin
STATUS_MBE <= #1 CSRWriteValM[5] & `BIGENDIAN_SUPPORTED;
STATUS_SBE <= #1 CSRWriteValM[4] & `S_SUPPORTED & `BIGENDIAN_SUPPORTED;
// coverage on
end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
STATUS_MXR_INT <= #1 CSRWriteValM[19];
STATUS_SUM_INT <= #1 CSRWriteValM[18];

View file

@ -81,11 +81,14 @@ module trap (
///////////////////////////////////////////
assign BothInstrAccessFaultM = InstrAccessFaultM | HPTWInstrAccessFaultM;
// coverage off -item e 1 -fecexprrow 2
// excludes InstrMisalignedFaultM from coverage of this line, since misaligned instructions cannot occur in rv64gc.
assign ExceptionM = InstrMisalignedFaultM | BothInstrAccessFaultM | IllegalInstrFaultM |
LoadMisalignedFaultM | StoreAmoMisalignedFaultM |
InstrPageFaultM | LoadPageFaultM | StoreAmoPageFaultM |
BreakpointFaultM | EcallFaultM |
LoadAccessFaultM | StoreAmoAccessFaultM;
// coverage on
assign TrapM = ExceptionM | InterruptM;
assign RetM = mretM | sretM;

View file

@ -169,7 +169,7 @@ logic [3:0] dummy;
logic InitializingMemories;
integer ResetCount, ResetThreshold;
logic InReset;
logic Begin;
logic BeginSample;
// instantiate device to be tested
assign GPIOIN = 0;
@ -225,7 +225,8 @@ logic [3:0] dummy;
totalerrors = 0;
testadr = 0;
testadrNoBase = 0;
// riscof tests have a different signature, tests[0] == "1" refers to RiscvArchTests and tests[0] == "2" refers to WallyRiscvArchTests
// riscof tests have a different signature, tests[0] == "1" refers to RiscvArchTests
// and tests[0] == "2" refers to WallyRiscvArchTests
riscofTest = tests[0] == "1" | tests[0] == "2";
// fill memory with defined values to reduce Xs in simulation
// Quick note the memory will need to be initialized. The C library does not
@ -265,8 +266,9 @@ logic [3:0] dummy;
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
end
// declare memory labels that interest us, the updateProgramAddrLabelArray task will find the addr of each label and fill the array
// to expand, add more elements to this array and initialize them to zero (also initilaize them to zero at the start of the next test)
// declare memory labels that interest us, the updateProgramAddrLabelArray task will find
// the addr of each label and fill the array. To expand, add more elements to this array
// and initialize them to zero (also initilaize them to zero at the start of the next test)
if(!`FPGA) begin
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
$display("Read memfile %s", memfilename);
@ -311,8 +313,10 @@ logic [3:0] dummy;
#600; // give time for instructions in pipeline to finish
if (TEST == "embench") begin
// Writes contents of begin_signature to .sim.output file
// this contains instret and cycles for start and end of test run, used by embench python speed script to calculate embench speed score
// also begin_signature contains the results of the self checking mechanism, which will be read by the python script for error checking
// this contains instret and cycles for start and end of test run, used by embench
// python speed script to calculate embench speed score.
// also, begin_signature contains the results of the self checking mechanism,
// which will be read by the python script for error checking
$display("Embench Benchmark: %s is done.", tests[test]);
if (riscofTest) outputfile = {pathname, tests[test], "/ref/ref.sim.output"};
else outputfile = {pathname, tests[test], ".sim.output"};
@ -373,8 +377,7 @@ logic [3:0] dummy;
/* verilator lint_on INFINITELOOP */
if (errors == 0) begin
$display("%s succeeded. Brilliant!!!", tests[test]);
end
else begin
end else begin
$display("%s failed with %d errors. :(", tests[test], errors);
totalerrors = totalerrors+1;
end
@ -385,8 +388,7 @@ logic [3:0] dummy;
if (totalerrors == 0) $display("SUCCESS! All tests ran without failures.");
else $display("FAIL: %d test programs had errors", totalerrors);
$stop;
end
else begin
end else begin
InitializingMemories = 1;
// If there are still additional tests to run, read in information for the next test
//pathname = tvpaths[tests[0]];
@ -480,10 +482,9 @@ logic [3:0] dummy;
assign EndSample = DCacheFlushStart & ~DCacheFlushDone;
flop #(1) BeginReg(clk, StartSampleFirst, BeginDelayed);
assign Begin = StartSampleFirst & ~BeginDelayed;
assign BeginSample = StartSampleFirst & ~BeginDelayed;
end
always @(negedge clk) begin
if(StartSample) begin
for(HPMCindex = 0; HPMCindex < 32; HPMCindex += 1) begin
@ -560,10 +561,8 @@ end
string LogFile;
logic resetD, resetEdge;
logic Enable;
// assign Enable = ~dut.core.StallD & ~dut.core.FlushD & dut.core.ifu.bus.icache.CacheRWF[1] & ~reset;
logic InvalDelayed, InvalEdge;
// this version of Enable allows for accurate eviction logging.
// Likely needs further improvement.
assign Enable = dut.core.ifu.bus.icache.icache.cachefsm.LRUWriteEn &
dut.core.ifu.immu.immu.pmachecker.Cacheable &
~dut.core.ifu.bus.icache.icache.cachefsm.FlushStage &
@ -584,7 +583,7 @@ end
dut.core.ifu.bus.icache.icache.vict.cacheLRU.AllValid ? "E" : "M";
always @(posedge clk) begin
if(resetEdge) $fwrite(file, "TRAIN\n");
if(Begin) $fwrite(file, "BEGIN %s\n", memfilename);
if(BeginSample) $fwrite(file, "BEGIN %s\n", memfilename);
if(Enable) begin // only log i cache reads
$fwrite(file, "%h R %s\n", dut.core.ifu.PCPF, HitMissString);
end
@ -611,12 +610,7 @@ end
dut.core.lsu.bus.dcache.CacheRWM == 2'b10 ? "R" :
dut.core.lsu.bus.dcache.CacheRWM == 2'b01 ? "W" :
"NULL";
// assign Enabled = (dut.core.lsu.bus.dcache.dcache.cachefsm.CurrState == 0) &
// ~dut.core.lsu.bus.dcache.dcache.cachefsm.FlushStage &
// (AccessTypeString != "NULL");
// This version of enable allows for accurate eviction logging.
// Likely needs further improvement.
assign Enabled = dut.core.lsu.bus.dcache.dcache.cachefsm.LRUWriteEn &
~dut.core.lsu.bus.dcache.dcache.cachefsm.FlushStage &
dut.core.lsu.dmmu.dmmu.pmachecker.Cacheable &
@ -629,7 +623,7 @@ end
end
always @(posedge clk) begin
if(resetEdge) $fwrite(file, "TRAIN\n");
if(Begin) $fwrite(file, "BEGIN %s\n", memfilename);
if(BeginSample) $fwrite(file, "BEGIN %s\n", memfilename);
if(Enabled) begin
$fwrite(file, "%h %s %s\n", dut.core.lsu.PAdrM, AccessTypeString, HitMissString);
end
@ -664,7 +658,7 @@ end
end
end
// check for hange up.
// check for hang up.
logic [`XLEN-1:0] OldPCW;
integer WatchDogTimerCount;
localparam WatchDogTimerThreshold = 1000000;
@ -814,8 +808,7 @@ task automatic updateProgramAddrLabelArray;
integer returncode;
returncode = $fscanf(ProgramLabelMapFP, "%s\n", label);
returncode = $fscanf(ProgramAddrMapFP, "%s\n", adrstr);
if (ProgramAddrLabelArray.exists(label))
ProgramAddrLabelArray[label] = adrstr.atohex();
if (ProgramAddrLabelArray.exists(label)) ProgramAddrLabelArray[label] = adrstr.atohex();
end
end
$fclose(ProgramLabelMapFP);

View file

@ -52,7 +52,8 @@ string tvpaths[] = '{
"fpu",
"lsu",
"vm64check",
"pmp"
"pmp",
"tlbKP"
};
string coremark[] = '{

View file

@ -66,8 +66,7 @@ interrupt: # must be a timer interrupt
j trap_return # clean up and return
exception:
li t0, 2
csrr t1, mcause
csrr t0, mcause
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

View file

@ -31,6 +31,44 @@ main:
#bseti t0, zero, 14 # turn on FPU
csrs mstatus, t0
#Pull denormalized FP number from memory and pass it to fclass.S for coverage
la t0, TestData1
flw ft0, 0(t0)
fclass.s t1, ft0
#Result Sign Test Coverage
la t0, TestData2
flw ft0, 0(t0)
flw ft1, 4(t0)
fadd.s ft2, ft0, ft1 #Adds coverage for inf as arg for FADD
flw ft2, 4(t0)
fmsub.s ft3, ft0, ft1, ft2 #Adds coverage for fmaAs or Z Sign Bit
#Adds Coverage for Flag fmaAs, fmaPs, YSNaN, ZSNaN
fmadd.s ft3, ft0, ft1, ft2
flw ft0, 8(t0)
fmadd.s ft3, ft0, ft1, ft2
flw ft1, 12(t0)
fmadd.s ft3, ft0, ft1, ft2
flw ft2, 12(t0)
flw ft1, 4(t0)
fmadd.s ft3, ft0, ft1, ft2
#Add Coverage for round lsbRes
flw ft0, 16(t0)
flw ft1, 4(t0)
fmadd.s ft3, ft0, ft1, ft2
#Fix BadNaNBox test on unpackinput Z
la t0, TestData2
flw ft3, 0(t0)
flw ft4, 0(t0)
fadd.s ft5, ft3, ft4
# Test legal instructions not covered elsewhere
flq ft0, 0(a0)
flh ft0, 8(a0)
@ -98,3 +136,13 @@ main:
j done
.section .data
.align 3
TestData1:
.int 0x00100000 #Denormalized FP number
TestData2:
.int 0x3f800000 #FP 1.0
.word 0x7f800000 #INF
.int 0xbf800000 #FP -1.0
.int 0x7fa00000 #SNaN
.int 0x3fffffff #OverFlow Test

View file

@ -143,6 +143,65 @@ main:
csrw frm, t0
csrw fflags, t0
# CSRC MCOUNTEREN Register
# Go to machine mode
li a0, 3
ecall
# Activate HPM3
li t0, -1
csrw mcounteren, t0
csrw scounteren, t0
# Go to supervisor
li a0, 1
ecall
#try to write to HPMs
csrw 333, t0
#go to user mode
li a0, 0
ecall
csrr t0, hpmcounter22
# setting registers bits to 0
li a0, 3 # back to machine mode
ecall
li t0, 0
csrw mcounteren, t0
csrw scounteren, t0
# Write to satp when status.TVM is 1 from machine mode
bseti t0, zero, 20
csrs mstatus, t0
csrw satp, t0
# Test checking privilege for reading counters (using counter 22 as an example)
# Go to machine mode
li a0, 3
ecall
# Set SCOUNTEREN to all 0s, MCOUNTEREN to all 1s
li t0, 0
csrw scounteren, t0
li t1, -1
csrw mcounteren, t1
# Go to supervisor mode
li a0, 1
ecall
# try to read from HPM22
csrr t0, hpmcounter22
# go to user mode
li a0, 0
ecall
csrr t0, hpmcounter22
j done

143
tests/coverage/tlbKP.S Normal file
View file

@ -0,0 +1,143 @@
///////////////////////////////////////////
// lsu_test.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, 0x80015000
li t2, 0 # i = 0
li t3, 33 # Max amount of Loops = 32
loop: bge t2, t3, finished # exit loop if i >= loops
lw t1, 0(t0)
li t4, 0x1000
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