fix merge conflict

This commit is contained in:
Marina Bellido Rodriguez 2025-06-24 10:55:13 -07:00
commit df0d2e0bca
90 changed files with 2283 additions and 920 deletions

View file

@ -17,8 +17,9 @@ on:
- main
paths:
- 'bin/wally-tool-chain-install.sh'
- 'bin/wally-distro-check.sh'
- 'bin/wally-environment-check.sh'
- 'bin/wally-package-install.sh'
- 'bin/installation/*'
- '.github/workflows/install.yml'
schedule:
- cron: "0 7 * * 3" # Run at 12:00 AM Pacific Time on Wednesdays
@ -102,6 +103,7 @@ jobs:
apt-get install -y git
elif [ ${{ matrix.imageFamily }} == "redhat" ]; then
dnf install -y git
# Red Hat images come with curl-minimal, which breaks the installation script. This replaces it with regular curl.
dnf install curl -y --allowerasing || true
elif [ ${{ matrix.imageFamily }} == "suse" ]; then
zypper install -y git
@ -111,7 +113,7 @@ jobs:
- name: Clone Necessary Submodules
run: |
git config --global --add safe.directory '*'
git submodule update --init addins/riscv-arch-test addins/verilog-ethernet
git submodule update --init addins/riscv-arch-test addins/cvw-arch-verif addins/verilog-ethernet
# Free up space on the host machine, either from the container or the host
- name: Free Up Storage
run: |
@ -122,6 +124,17 @@ jobs:
nsenter -t 1 -m -u -n -i bash -c "$(cat .github/scripts/cli-space-cleanup.sh)"
fi
df -h
# Set $RISCV so log files can be found and uploaded
- name: Set RISCV Environment Variable
run: |
if [ ! -z ${{ matrix.riscv_path }} ]; then
export RISCV=${{ matrix.riscv_path }}
elif [ ! -z ${{ matrix.user }} ]; then
export RISCV=$HOME/riscv
else
export RISCV=/opt/riscv
fi
echo "RISCV=${RISCV}" >> $GITHUB_ENV
# Run main tool chain installation script, either as a user or system wide
- name: Install
run: |
@ -133,15 +146,10 @@ jobs:
sudo ./bin/wally-package-install.sh
./bin/wally-tool-chain-install.sh --clean ${{ matrix.riscv_path }}
fi
# Set environment variables for the rest of the job
- name: Set Environment Variables
if: always()
run: |
if [ ! -z ${{ matrix.riscv_path }} ]; then
sed -i 's,exit 1,export RISCV=${{ matrix.riscv_path }},g' setup.sh
fi
source setup.sh
echo "RISCV=$RISCV" >> "$GITHUB_ENV"
# Update setup.sh if using a custom $RISCV path
- name: Update setup.sh
if: ${{ matrix.riscv_path != null }}
run: sed -i 's,~/riscv,${{ matrix.riscv_path }},g' setup.sh
# Upload installation logs for debugging
- name: Upload Installation Logs
uses: actions/upload-artifact@v4
@ -160,7 +168,7 @@ jobs:
- name: make tests
run: |
source setup.sh
make riscof zsbl --jobs $(nproc --ignore 1)
make riscof zsbl deriv coverage --jobs $(nproc --ignore 1)
# Run standard regression, skipping distros that are known to be broken with Verilator
- name: Regression
if: ${{ matrix.regressionFail != true }}

1
.gitignore vendored
View file

@ -79,6 +79,7 @@ synthDC/wallyplots/
synthDC/runArchive
synthDC/hdl
synthDC/Summary.csv
synthDC/spyglass/lint-spyglass-reports
# Benchmarks
benchmarks/embench/wally*.json

View file

@ -118,16 +118,16 @@ If a user-level installation is desired, the script can instead be run by any us
$ sudo $WALLY/bin/wally-package-install.sh
```
In either case, the installation directory can be overridden by passing the desired directory as the last argument to the installation script. For example,
In either case, the installation directory can be overridden by passing the desired directory as an argument to the installation script. For example,
```bash
$ sudo $WALLY/bin/wally-tool-chain-install.sh /home/riscv
```
See `wally-tool-chain-install.sh` for a detailed description of each component, or to issue the commands one at a time to install on the command line.
See `wally-tool-chain-install.sh` and the scripts in the `$WALLY/bin/installation` directory for a detailed description of each component, or to issue the commands one at a time to install on the command line.
> [!NOTE]
> The complete installation process requires ~55 GB of free space. If the `--clean` flag is passed to the installation script then the final consumed space is only ~26 GB, but upgrading the tools will reinstall everything from scratch.
> The complete installation process requires ~55 GB of free space. If the `--clean` flag is passed to the installation script then the final consumed space is only ~26 GB. The `--clean` flag removes source files and build directories.
### Configuration
`$WALLY/setup.sh` sources `$RISCV/site-setup.sh`. If the toolchain was installed in either of the default locations (`/opt/riscv` or `~/riscv`), `$RISCV` will automatically be set to the correct path when `setup.sh` is run. If a custom installation directory was used, then `$WALLY/setup.sh` must be modified to set the correct path.

@ -1 +1 @@
Subproject commit 1afacf04ee975c6bcbc65d36e8648e96f18ea0d4
Subproject commit 7141afd7feb81a04db8c3110df0ef7d526e4efdb

@ -1 +1 @@
Subproject commit 44832a9d3bea991b099c6beb4c962e5b7c1ad3a3
Subproject commit 77907f0c5eb7b3da44a13597b26fb878d79ba7f5

View file

@ -1,13 +1,13 @@
Architecture,CM / MHz,CPI,MTIME,MINSTRET,Load Stalls,Store Stalls,D$ Accesses,D$ Misses,I$ Accesses,I$ Misses,Branches,Branch Mispredicts,BTB Misses,Jump/JR,RAS Wrong,Returns,BP Class Pred Wrong
rv32i_zicsr,1.20,1.16,8269385,7124630,261886,22307,716317,73,7827908,1040,2009578,443447,5476,122015,3468,113645,20699
rv32im_zicsr,3.26,1.12,3061233,2716910,264489,22198,690506,73,2975498,827,543885,45067,5483,30033,69,15237,20898
rv32imc_zicsr,3.24,1.13,3085767,2716550,264404,23853,690507,75,3011253,285,543761,44223,5615,29675,171,15237,20295
rv32im_zicsr_zba_zbb_zbs,3.38,1.12,2954414,2624181,266850,22258,689232,75,2878922,494,544408,42375,4295,29685,18,15249,14980
rv32gc,3.24,1.13,3085783,2716550,264134,23852,690500,74,3010201,286,543485,44182,5563,29668,162,15230,20108
rv32gc_zba_zbb_zbs,3.32,1.14,3003843,2624181,272635,22141,689226,74,2929468,280,543245,44490,6087,29680,23,15242,22189
rv64i_zicsr,1.02,1.13,9731538,8559698,273929,22198,720375,85,9242621,588,2340171,459594,4842,128954,178,109383,15941
rv64im_zicsr,2.86,1.10,3493939,3156218,271101,22149,691714,83,3406099,340,547671,42901,4651,34669,14,15099,15726
rv64imc_zicsr,2.82,1.12,3545301,3156218,271029,25304,691715,86,3457798,263,547535,43990,4970,34671,5,15099,15889
rv64im_zicsr_zba_zbb_zbs,3.08,1.11,3241375,2901479,273442,24665,689242,85,3150626,424,547796,41798,4635,34680,43,15111,16143
rv64gc,2.82,1.12,3545281,3156218,270740,25304,691708,86,3456812,264,547229,43969,4970,34664,5,15092,15889
rv64gc_zba_zbb_zbs,3.03,1.13,3297540,2901479,273107,26696,689236,83,3200848,250,547359,46238,6197,34675,73,15104,21328
rv32i_zicsr,1.20,1.16,8269377,7124630,262876,22307,716340,75,7831331,1038,2010591,443551,5476,122038,3467,113668,20699
rv32im_zicsr,3.26,1.12,3061215,2716910,265481,22198,690529,75,2978839,829,544899,45098,5483,30056,69,15260,20901
rv32imc_zicsr,3.24,1.13,3085748,2716550,265386,23854,690530,75,3014578,285,544767,44249,5615,29698,171,15260,20295
rv32im_zicsr_zba_zbb_zbs,3.38,1.12,2954396,2624181,267836,22258,689255,75,2882239,495,545416,42412,4295,29708,18,15272,14980
rv32gc,3.24,1.13,3085785,2716550,265126,23851,690523,74,3013537,286,544500,44191,5563,29691,162,15253,20108
rv32gc_zba_zbb_zbs,3.32,1.14,3003858,2624181,273728,22141,689249,75,2932896,280,544260,44486,6087,29703,23,15265,22189
rv64i_zicsr,1.02,1.13,9731538,8559698,274922,22198,720398,86,9245947,588,2341187,459621,4842,128977,178,109406,15941
rv64im_zicsr,2.86,1.10,3493929,3156218,272083,22149,691737,85,3409423,340,548686,42924,4651,34692,14,15122,15724
rv64imc_zicsr,2.82,1.12,3545291,3156218,272037,25303,691738,85,3461141,261,548556,43997,4970,34694,5,15122,15889
rv64im_zicsr_zba_zbb_zbs,3.08,1.11,3241385,2901479,274441,24666,689265,84,3153960,424,548818,41807,4635,34703,43,15134,16146
rv64gc,2.82,1.12,3545279,3156218,271734,25303,691731,86,3460160,263,548246,43992,4970,34687,5,15115,15887
rv64gc_zba_zbb_zbs,3.03,1.13,3297532,2901479,274101,26696,689259,84,3204202,249,548376,46265,6197,34698,73,15127,21328

1 Architecture CM / MHz CPI MTIME MINSTRET Load Stalls Store Stalls D$ Accesses D$ Misses I$ Accesses I$ Misses Branches Branch Mispredicts BTB Misses Jump/JR RAS Wrong Returns BP Class Pred Wrong
2 rv32i_zicsr 1.20 1.16 8269385 8269377 7124630 261886 262876 22307 716317 716340 73 75 7827908 7831331 1040 1038 2009578 2010591 443447 443551 5476 122015 122038 3468 3467 113645 113668 20699
3 rv32im_zicsr 3.26 1.12 3061233 3061215 2716910 264489 265481 22198 690506 690529 73 75 2975498 2978839 827 829 543885 544899 45067 45098 5483 30033 30056 69 15237 15260 20898 20901
4 rv32imc_zicsr 3.24 1.13 3085767 3085748 2716550 264404 265386 23853 23854 690507 690530 75 3011253 3014578 285 543761 544767 44223 44249 5615 29675 29698 171 15237 15260 20295
5 rv32im_zicsr_zba_zbb_zbs 3.38 1.12 2954414 2954396 2624181 266850 267836 22258 689232 689255 75 2878922 2882239 494 495 544408 545416 42375 42412 4295 29685 29708 18 15249 15272 14980
6 rv32gc 3.24 1.13 3085783 3085785 2716550 264134 265126 23852 23851 690500 690523 74 3010201 3013537 286 543485 544500 44182 44191 5563 29668 29691 162 15230 15253 20108
7 rv32gc_zba_zbb_zbs 3.32 1.14 3003843 3003858 2624181 272635 273728 22141 689226 689249 74 75 2929468 2932896 280 543245 544260 44490 44486 6087 29680 29703 23 15242 15265 22189
8 rv64i_zicsr 1.02 1.13 9731538 8559698 273929 274922 22198 720375 720398 85 86 9242621 9245947 588 2340171 2341187 459594 459621 4842 128954 128977 178 109383 109406 15941
9 rv64im_zicsr 2.86 1.10 3493939 3493929 3156218 271101 272083 22149 691714 691737 83 85 3406099 3409423 340 547671 548686 42901 42924 4651 34669 34692 14 15099 15122 15726 15724
10 rv64imc_zicsr 2.82 1.12 3545301 3545291 3156218 271029 272037 25304 25303 691715 691738 86 85 3457798 3461141 263 261 547535 548556 43990 43997 4970 34671 34694 5 15099 15122 15889
11 rv64im_zicsr_zba_zbb_zbs 3.08 1.11 3241375 3241385 2901479 273442 274441 24665 24666 689242 689265 85 84 3150626 3153960 424 547796 548818 41798 41807 4635 34680 34703 43 15111 15134 16143 16146
12 rv64gc 2.82 1.12 3545281 3545279 3156218 270740 271734 25304 25303 691708 691731 86 3456812 3460160 264 263 547229 548246 43969 43992 4970 34664 34687 5 15092 15115 15889 15887
13 rv64gc_zba_zbb_zbs 3.03 1.13 3297540 3297532 2901479 273107 274101 26696 689236 689259 83 84 3200848 3204202 250 249 547359 548376 46238 46265 6197 34675 34698 73 15104 15127 21328

View file

@ -1,29 +1,29 @@
{ "speed results" :
{ "detailed speed results" :
{ "aha-mont64" : 0.81,
{ "aha-mont64" : 0.82,
"crc32" : 1.00,
"cubic" : 0.42,
"edn" : 0.88,
"edn" : 0.94,
"huffbench" : 1.38,
"matmult-int" : 1.11,
"md5sum" : 2.00,
"minver" : 0.63,
"nbody" : 0.67,
"nettle-aes" : 0.82,
"nettle-sha256" : 0.96,
"md5sum" : 1.98,
"minver" : 0.62,
"nbody" : 0.66,
"nettle-aes" : 0.81,
"nettle-sha256" : 0.97,
"nsichneu" : 1.14,
"picojpeg" : 0.79,
"primecount" : 1.30,
"qrduino" : 1.22,
"qrduino" : 1.23,
"sglib-combined" : 1.17,
"slre" : 1.25,
"slre" : 1.26,
"st" : 0.84,
"statemate" : 2.15,
"statemate" : 2.16,
"tarfind" : 2.42,
"ud" : 0.88,
"ud" : 0.89,
"wikisort" : 1.71
},
"speed geometric mean" : 1.07,
"speed geometric standard deviation" : 1.51
"speed geometric standard deviation" : 1.50
}
}

View file

@ -1,27 +1,27 @@
{ "speed results" :
{ "detailed speed results" :
{ "aha-mont64" : 0.84,
{ "aha-mont64" : 0.85,
"crc32" : 1.05,
"cubic" : 0.42,
"edn" : 1.06,
"huffbench" : 1.58,
"matmult-int" : 1.11,
"md5sum" : 1.92,
"minver" : 0.65,
"minver" : 0.66,
"nbody" : 0.67,
"nettle-aes" : 0.93,
"nettle-sha256" : 0.99,
"nsichneu" : 0.70,
"picojpeg" : 0.99,
"nsichneu" : 0.75,
"picojpeg" : 1.00,
"primecount" : 1.41,
"qrduino" : 1.32,
"qrduino" : 1.35,
"sglib-combined" : 1.41,
"slre" : 1.54,
"slre" : 1.52,
"st" : 0.86,
"statemate" : 3.13,
"tarfind" : 3.31,
"statemate" : 3.16,
"tarfind" : 3.21,
"ud" : 0.94,
"wikisort" : 1.74
"wikisort" : 1.76
},
"speed geometric mean" : 1.15,
"speed geometric standard deviation" : 1.61

View file

@ -1,4 +1,4 @@
#!/usr/bin/env -S perl -w
#!/usr/bin/env perl
###########################################
## derivgen.pl

View file

@ -1,40 +0,0 @@
#!/bin/bash
###########################################
## Written: james.stine@okstate.edu
## Created: 4 Jan 2022
## Modified:
##
## Purpose: Script to run elf2hex for memfile for
## Imperas and riscv-arch-test benchmarks
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## 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.
################################################################################################
for file in work/rv64i_m/*/*.elf ; do
memfile=${file%.elf}.elf.memfile
echo riscv64-unknown-elf-elf2hex --bit-width 64 --input "$file"
riscv64-unknown-elf-elf2hex --bit-width 64 --input "$file" --output "$memfile"
done
for file in work/rv32i_m/*/*.elf ; do
memfile=${file%.elf}.elf.memfile
echo riscv64-unknown-elf-elf2hex --bit-width 32 --input "$file"
riscv64-unknown-elf-elf2hex --bit-width 32 --input "$file" --output "$memfile"
done

View file

@ -1,197 +0,0 @@
#!/usr/bin/env -S perl -w
###########################################
## exe2memfile.pl
##
## Written: David_Harris@hmc.edu
## Created: 26 November 2020
## Modified:
##
## Purpose: Converts an executable file to a series of 32-bit hex instructions
## to read into a Verilog simulation with $readmemh
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## 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.
################################################################################################
#
#
use File::stat;
use IO::Handle;
if ($#ARGV == -1) {
die("Usage: $0 executable_file");
}
# array to hold contents of memory file
my $maxmemfilesize = 1000000;
my @memfilebytes = (0)*$maxmemfilesize*4;
my $maxaddress = 0;
STDOUT->autoflush(1);
my $numfiles = $#ARGV+1;
if ($numfiles > 1) {
print ("Processing $numfiles memfiles: ");
}
my $frac = $#ARGV/10;
for(my $i=0; $i<=$#ARGV; $i++) {
if ($i > 0 && ($i < 10 || $i % $frac == 0)) { print ("$i ") };
my $fname = $ARGV[$i];
# print "fname = $fname";
my $ofile = $fname.".objdump";
my $memfile = $fname.".memfile";
my $needsprocessing = 0;
if (!-e $memfile) { $needsprocessing = 1; } # create memfile if it doesn't exist
else {
my $osb = stat($ofile) || die("Can't stat $ofile");
my $msb = stat($memfile) || die("Can't stat $memfile");
my $otime = $osb->mtime;
my $mtime = $msb->mtime;
if ($otime > $mtime) { $needsprocessing = 1; } # is memfile out of date?
}
if ($needsprocessing == 1) {
open(FILE, $ofile) || die("Can't read $ofile");
my $mode = 0; # parse for code
my $address;
# initialize to all zeros;
for (my $i=0; $i < $maxmemfilesize*4; $i++) {
$memfilebytes[$i] = "00";
}
while(<FILE>) {
if ($mode == 0) { # Parse code
# print("Examining $_\n");
if (/^\s*(\S\S\S\S\S\S\S\S):\s+(\S+)\s+/) {
$address = &fixadr($1);
my $instr = $2;
my $len = length($instr);
for (my $i=0; $i<$len/2; $i++) {
$memfilebytes[$address+$i] = substr($instr, $len-2-2*$i, 2);
}
# print ("address $address $instr\n");
}
if (/Disassembly of section .data:/) { $mode = 1;}
} elsif ($mode == 1) { # Parse data segment
# if (/^\s*(\S\S\S\S\S\S\S\S):\s+(.*)/) { # changed to \t 30 Oct 2021 dmh to fix parsing issue in d_fmadd_b17
if (/^\s*(\S\S\S\S\S\S\S\S):\s+(.*)/) {
$address = &fixadr($1);
# print "address $address maxaddress $maxaddress\n";
if ($address > $maxaddress) { $maxaddress = $address; }
#print "test $address $1 $2\n";
my $lineorig = $2;
my $line = $2;
# strip off leading 0x
$line =~ s/^0x//;
# merge chunks with spaces
$line =~ s/(\S)\s(\S)/$1$2/g;
my $linemerge = $line;
# strip off comments
$line =~ /^(\S*)/;
$payload = $1;
# if ($address >= 17520 && $address <= 17552) { # was 12304
# print "Address: $address\n orig: $lineorig \n merge: $linemerge \n line: $line \n payload: $payload\n";
# }
&emitData($address, $payload);
}
if (/Disassembly of section .riscv.attributes:/) { $mode = 2; }
}
}
close(FILE);
# print("maxaddress: $maxaddress\n");
$maxaddress += 32; # pad some zeros at the end
# print("maxaddress: $maxaddress\n");
# print to memory file
if ($fname =~ /rv32/) {
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
for (my $i=0; $i<= $maxaddress; $i = $i + 4) {
for ($j=3; $j>=0; $j--) {
if (defined($memfilebytes[$i+$j])) {
print MEMFILE "$memfilebytes[$i+$j]";
} else {
print MEMFILE "00";
}
}
print MEMFILE "\n";
}
close(MEMFILE);
} else {
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
for (my $i=0; $i<= $maxaddress; $i = $i + 8) {
for ($j=7; $j>=0; $j--) {
my $loc = $i+$j;
# if ($loc >= 17520 && $loc <= 17552) {
# print "loc: $loc val $memfilebytes[$loc]\n";
# }
if (defined($memfilebytes[$loc])) {
print MEMFILE "$memfilebytes[$loc]";
} else {
print MEMFILE "00";
}
}
print MEMFILE "\n";
}
close(MEMFILE);
}
}
}
print("\n");
sub emitData {
# print the data portion of the ELF into a memory file, including 0s for empty stuff
# deal with endianness
my $address = shift;
my $payload = shift;
# if ($address > 17520 && $address < 17552) { # was 12304
# print("Emitting data. address = $address payload = $payload\n");
# }
my $len = length($payload);
if ($len <= 8) {
# print word or halfword
for(my $i=0; $i<$len/2; $i++) {
my $adr = $address+$i;
my $b = substr($payload, $len-2-2*$i, 2);
$memfilebytes[$adr] = $b;
# if ($address >= 17520 && $address <= 17552) {
# print(" Wrote $b to $adr\n");
# }
# print(" $adr $b\n");
}
} elsif ($len == 12) {
# weird case of three halfwords on line
&emitData($address, substr($payload, 0, 4));
&emitData($address+2, substr($payload, 4, 4));
&emitData($address+4, substr($payload, 8, 4));
} else {
&emitData($address, substr($payload, 0, 8));
&emitData($address+4, substr($payload, 8, $len-8));
}
}
sub fixadr {
# strip off leading 8 from address and convert to decimal
my $adr = shift;
if ($adr =~ s/^8/0/) { return hex($adr); }
else { die("address $adr lacks leading 8\n"); }
}

View file

@ -0,0 +1,72 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: Activate gcc and python virtual environment
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# Activate python virtual environment
# Activate riscv-python Virtual Environment
if [ -e "$RISCV"/riscv-python/bin/activate ]; then
source "$RISCV"/riscv-python/bin/activate
else
echo -e "${FAIL_COLOR}Python virtual environment not found. Run wally-toolchain-install.sh or python-setup.sh to automatically create it.${ENDC}"
return 1
fi
# Enable newer version of gcc for older distros (required for QEMU/Verilator)
if [ "$FAMILY" == rhel ]; then
if [ -e /opt/rh/gcc-toolset-13/enable ]; then
source /opt/rh/gcc-toolset-13/enable
else
echo -e "${FAIL_COLOR}GCC toolset 13 not found. Please install it with wally-package-install.sh.${ENDC}"
return 1
fi
elif [ "$FAMILY" == suse ]; then
if [ ! -e "$RISCV"/gcc-13/bin/gcc ]; then
mkdir -p "$RISCV"/gcc-13/bin
for f in gcc cpp g++ gcc-ar gcc-nm gcc-ranlib gcov gcov-dump gcov-tool lto-dump; do
ln -vsf /usr/bin/$f-13 "$RISCV"/gcc-13/bin/$f
done
fi
export PATH="$RISCV"/gcc-13/bin:$PATH
elif (( UBUNTU_VERSION == 20 )); then
if [ ! -e "$RISCV"/gcc-10/bin/gcc ]; then
mkdir -p "$RISCV"/gcc-10/bin
for f in gcc cpp g++ gcc-ar gcc-nm gcc-ranlib gcov gcov-dump gcov-tool lto-dump; do
ln -vsf /usr/bin/$f-10 "$RISCV"/gcc-10/bin/$f
done
fi
export PATH="$RISCV"/gcc-10/bin:$PATH
fi

View file

@ -0,0 +1,56 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: Buildroot and Linux testvector installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# Buildroot and Linux testvectors
# Buildroot is used to boot a minimal version of Linux on Wally.
# Testvectors are generated using QEMU.
section_header "Installing Buildroot and Creating Linux testvectors"
STATUS="buildroot"
export LD_LIBRARY_PATH=$RISCV/lib:$RISCV/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}:$RISCV/riscv64-unknown-elf/lib:$RISCV/lib/x86_64-linux-gnu
cd "$WALLY"/linux
if [ ! -e "$RISCV"/buildroot ]; then
FORCE_UNSAFE_CONFIGURE=1 make 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ] # FORCE_UNSAFE_CONFIGURE is needed to allow buildroot to compile when run as root
echo -e "${SUCCESS_COLOR}Buildroot successfully installed and Linux testvectors created!${ENDC}"
elif [ ! -e "$RISCV"/linux-testvectors ]; then
echo -e "${OK_COLOR}Buildroot already exists, but Linux testvectors are missing. Generating them now.${ENDC}"
make dumptvs 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
echo -e "${SUCCESS_COLOR}Linux testvectors successfully generated!${ENDC}"
else
echo -e "${OK_COLOR}Buildroot and Linux testvectors already exist.${ENDC}"
echo -e "${WARNING_COLOR}Buildroot is not updated automatically. If you want to install a newer version, delete the existing $RISCV/buildroot directory and rerun this script.${ENDC}"
fi

View file

@ -0,0 +1,73 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: elf2hex installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
ELF2HEX_VERSION=f28a3103c06131ed3895052b1341daf4ca0b1c9c # Last commit as of May 30, 2025
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# elf2hex (https://github.com/sifive/elf2hex)
# The elf2hex utility to converts executable files into hexadecimal files for Verilog simulation.
# Note: The exe2hex utility that comes with Spike doesnt work for our purposes because it doesnt
# handle programs that start at 0x80000000. The SiFive version above is touchy to install.
# For example, if Python version 2.x is in your path, it wont install correctly.
# Also, be sure riscv64-unknown-elf-objcopy shows up in your path in $RISCV/bin
# at the time of compilation, or elf2hex wont work properly.
section_header "Installing/Updating elf2hex"
STATUS="elf2hex"
cd "$RISCV"
if check_tool_version $ELF2HEX_VERSION; then
# Verify riscv64-unknown-elf-objcopy is available
if ! command -v riscv64-unknown-elf-objcopy >/dev/null 2>&1; then
echo -e "${FAIL_COLOR}ERROR: riscv64-unknown-elf-objcopy not found in \$PATH.${ENDC}"
echo -e "${FAIL_COLOR}Run wally-tool-chain-install.sh or riscv-gnu-toolchain-install.sh before installing elf2hex.${ENDC}"
exit 1
fi
git_checkout "elf2hex" "https://github.com/sifive/elf2hex.git" "$ELF2HEX_VERSION"
cd "$RISCV"/elf2hex
autoreconf -i
./configure --target=riscv64-unknown-elf --prefix="$RISCV"
make 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
make install 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" = true ]; then
cd "$RISCV"
rm -rf elf2hex
fi
echo "$ELF2HEX_VERSION" > "$RISCV"/versions/$STATUS.version # Record installed version
echo -e "${SUCCESS_COLOR}elf2hex successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}elf2hex already up to date.${ENDC}"
fi

View file

@ -0,0 +1,58 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: glib installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# Newer version of glib required for QEMU.
# Anything newer than this won't build on red hat 8
STATUS="glib"
if [ ! -e "$RISCV"/include/glib-2.0 ]; then
section_header "Installing glib"
pip --require-virtualenv install -U meson # Meson is needed to build glib
cd "$RISCV"
wget -nv --retry-connrefused $retry_on_host_error https://download.gnome.org/sources/glib/2.70/glib-2.70.5.tar.xz
tar -xJf glib-2.70.5.tar.xz
rm -f glib-2.70.5.tar.xz
cd glib-2.70.5
meson setup _build --prefix="$RISCV"
meson compile -C _build -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
meson install -C _build 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
cd "$RISCV"
rm -rf glib-2.70.5
echo -e "${SUCCESS_COLOR}glib successfully installed!${ENDC}"
else
echo -e "${OK_COLOR}glib already installed.${ENDC}"
fi

View file

@ -0,0 +1,63 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: WALLY python virtual environment setup script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
# NOTE: These three tools need to be kept in sync. Update all versions simultaneously.
export RISCOF_VERSION=be84132874963e001c14d846a140a3edd9c9d48f # Last commit as May 31, 2025
export RISCV_CONFIG_VERSION=54171f205be802f9f8e0b1cf4156a6cc826fb467 # Last commit as of May 31, 2025
export RISCV_ISAC_VERSION=450de2eabfe4fcdfdf54135b5ab2dbb1d94805f8 # Last commit as of May 31, 2025 (commit hash of riscv-arch-test repo)
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# Create python virtual environment so the python command targets desired version of python
# and installed packages are isolated from the rest of the system.
section_header "Setting up Python Environment"
STATUS="python_virtual_environment"
cd "$RISCV"
if [ ! -e "$RISCV"/riscv-python/bin/activate ]; then
"$PYTHON_VERSION" -m venv riscv-python --prompt cvw
echo -e "${OK_COLOR}Python virtual environment created!\nInstalling pip packages.${ENDC}"
else
echo -e "${OK_COLOR}Python virtual environment already exists.\nUpdating pip packages.${ENDC}"
fi
source "$RISCV"/riscv-python/bin/activate # activate python virtual environment
# Install python packages, including RISCOF (https://github.com/riscv-software-src/riscof.git)
# RISCOF is a RISC-V compliance test framework that is used to run the RISC-V Arch Tests.
STATUS="python packages"
pip --require-virtualenv install --upgrade pip && pip --require-virtualenv install --upgrade -r "$WALLY"/bin/requirements.txt
echo -e "${SUCCESS_COLOR}Python environment successfully configured!${ENDC}"

View file

@ -0,0 +1,60 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: QEMU installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
QEMU_VERSION=v10.0.2 # Last release as of May 30, 2025
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# QEMU (https://www.qemu.org/docs/master/system/target-riscv.html)
# QEMU is an open source machine emulator and virtualizer capable of emulating RISC-V
section_header "Installing/Updating QEMU"
STATUS="qemu"
cd "$RISCV"
if check_tool_version $QEMU_VERSION; then
git_checkout "qemu" "https://github.com/qemu/qemu" "$QEMU_VERSION"
cd "$RISCV"/qemu
./configure --target-list=riscv64-softmmu --prefix="$RISCV"
make -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
make install 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" = true ]; then
cd "$RISCV"
rm -rf qemu
fi
echo "$QEMU_VERSION" > "$RISCV"/versions/$STATUS.version # Record installed version
echo -e "${SUCCESS_COLOR}QEMU successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}QEMU already up to date.${ENDC}"
fi

View file

@ -0,0 +1,63 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: QEMU installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
RISCV_GNU_TOOLCHAIN_VERSION=23863c2ca74e6c050f0c97e7af61f5f1776aadd1 # Last commit with GCC 14.2.0
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# RISC-V GNU Toolchain (https://github.com/riscv-collab/riscv-gnu-toolchain)
# The RISC-V GNU Toolchain includes the GNU Compiler Collection (gcc), GNU Binutils, Newlib,
# and the GNU Debugger Project (gdb). It is a collection of tools used to compile RISC-V programs.
# To install GCC from source can take hours to compile.
# This configuration enables multilib to target many flavors of RISC-V.
# This book is tested with GCC 13.2.0 and 14.2.0.
section_header "Installing/Updating RISC-V GNU Toolchain"
STATUS="riscv-gnu-toolchain"
cd "$RISCV"
if check_tool_version $RISCV_GNU_TOOLCHAIN_VERSION; then
git_checkout "riscv-gnu-toolchain" "https://github.com/riscv/riscv-gnu-toolchain" "$RISCV_GNU_TOOLCHAIN_VERSION"
cd "$RISCV"/riscv-gnu-toolchain
./configure --prefix="${RISCV}" --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
make -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" = true ]; then
cd "$RISCV"
rm -rf riscv-gnu-toolchain
fi
echo "$RISCV_GNU_TOOLCHAIN_VERSION" > "$RISCV"/versions/$STATUS.version # Record installed version
echo -e "${SUCCESS_COLOR}RISC-V GNU Toolchain successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}RISC-V GNU Toolchain already up to date.${ENDC}"
fi

102
bin/installation/sail-install.sh Executable file
View file

@ -0,0 +1,102 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: QEMU installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
SAIL_COMPILER_VERSION=0.19 # Last release as of May 30, 2025
CMAKE_VERSION=3.31.5 # Only used for distros with a system CMake that is too old (< 3.20)
RISCV_SAIL_MODEL_VERSION=3dc7e1c6dd957ba9a0520331270eb4c52dcd33a8 # Last commit as of June 6, 2025
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# Sail Compiler (https://github.com/rems-project/sail)
# Sail is a formal specification language designed for describing the semantics of an ISA.
# It is used to generate the RISC-V Sail Model, which is the golden reference model for RISC-V.
# The Sail Compiler is written in OCaml, which is an object-oriented extension of ML, which in turn
# is a functional programming language suited to formal verification.
section_header "Installing/Updating Sail Compiler"
STATUS="sail_compiler"
if check_tool_version $SAIL_COMPILER_VERSION; then
cd "$RISCV"
wget -nv --retry-connrefused $retry_on_host_error --output-document=sail.tar.gz "https://github.com/rems-project/sail/releases/download/$SAIL_COMPILER_VERSION-linux-binary/sail.tar.gz"
tar xz --directory="$RISCV" --strip-components=1 -f sail.tar.gz
rm -f sail.tar.gz
echo "$SAIL_COMPILER_VERSION" > "$RISCV"/versions/$STATUS.version # Record installed version
echo -e "${SUCCESS_COLOR}Sail Compiler successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}Sail Compiler already installed.${ENDC}"
fi
# Newer version of CMake needed to build sail-riscv model (at least 3.20)
if (( UBUNTU_VERSION == 20 || DEBIAN_VERSION == 11 )); then
STATUS="cmake"
if [ ! -e "$RISCV"/bin/cmake ] || [ "$("$RISCV"/bin/cmake --version | head -n1 | sed 's/cmake version //')" != "$CMAKE_VERSION" ]; then
section_header "Installing CMake"
cd "$RISCV"
wget -nv --retry-connrefused $retry_on_host_error --output-document=cmake.tar.gz "https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-linux-x86_64.tar.gz"
tar xz --directory="$RISCV" --strip-components=1 -f cmake.tar.gz
rm -f cmake.tar.gz
echo -e "${SUCCESS_COLOR}CMake successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}CMake already installed.${ENDC}"
fi
fi
# Newer version of gmp needed for sail-riscv model on RHEL 8
# sail-riscv will download and build gmp if told to do so, so no need to install it manually.
if (( RHEL_VERSION == 8 )); then
DOWNLOAD_GMP=TRUE
else
DOWNLOAD_GMP=FALSE
fi
# RISC-V Sail Model (https://github.com/riscv/sail-riscv)
# The RISC-V Sail Model is the golden reference model for RISC-V. It is written in Sail (described above)
section_header "Installing/Updating RISC-V Sail Model"
STATUS="riscv-sail-model"
if check_tool_version $RISCV_SAIL_MODEL_VERSION; then
git_checkout "sail-riscv" "https://github.com/riscv/sail-riscv.git" "$RISCV_SAIL_MODEL_VERSION"
cd "$RISCV"/sail-riscv
cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX="$RISCV" -DDOWNLOAD_GMP="$DOWNLOAD_GMP" -GNinja 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
cmake --build build 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
cmake --install build 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" = true ]; then
cd "$RISCV"
rm -rf sail-riscv
fi
echo "$RISCV_SAIL_MODEL_VERSION" > "$RISCV"/versions/$STATUS.version # Record installed version
echo -e "${SUCCESS_COLOR}RISC-V Sail Model successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}RISC-V Sail Model already up to date.${ENDC}"
fi

View file

@ -0,0 +1,53 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: QEMU installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
SKYWATER_LIB_VERSION=ac90ef0c622a9377a16b5218d9da3ac4169eeaaf # Last commit as of May 30, 2025
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# OSU Skywater 130 cell library (https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12)
# The OSU Skywater 130 cell library is a standard cell library that is used to synthesize Wally.
section_header "Installing/Updating OSU Skywater 130 cell library"
STATUS="osu_skywater_130_cell_library"
mkdir -p "$RISCV"/cad/lib
cd "$RISCV"/cad/lib
if check_tool_version $SKYWATER_LIB_VERSION; then
git_checkout "sky130_osu_sc_t12" "https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12" "$SKYWATER_LIB_VERSION"
echo "$SKYWATER_LIB_VERSION" > "$RISCV"/versions/$STATUS.version
echo -e "${SUCCESS_COLOR}OSU Skywater library successfully installed!${ENDC}"
else
echo -e "${SUCCESS_COLOR}OSU Skywater library already up to date.${ENDC}"
fi

View file

@ -0,0 +1,62 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: Spike installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
SPIKE_VERSION=4c870d063dbbaeb4dc7007fe5c2a1bf8b00a767e # Last commit as of May 30, 2025
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# Spike (https://github.com/riscv-software-src/riscv-isa-sim)
# Spike is a reference model for RISC-V. It is a functional simulator that can be used to run RISC-V programs.
section_header "Installing/Updating SPIKE"
STATUS="spike"
cd "$RISCV"
if check_tool_version $SPIKE_VERSION; then
git_checkout "riscv-isa-sim" "https://github.com/riscv-software-src/riscv-isa-sim" "$SPIKE_VERSION"
cd "$RISCV"/riscv-isa-sim
mkdir -p build
cd build
../configure --prefix="$RISCV"
make -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
make install 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" = true ]; then
cd "$RISCV"
rm -rf riscv-isa-sim
fi
echo "$SPIKE_VERSION" > "$RISCV"/versions/$STATUS.version # Record installed version
echo -e "${SUCCESS_COLOR}Spike successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}Spike already up to date.${ENDC}"
fi

View file

@ -0,0 +1,79 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: Verilator installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
VERILATOR_VERSION=v5.036 # Last release as of May 30, 2025
set -e # break on error
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname $(dirname "$dir"))"
export WALLY
source "${dir}"/../wally-environment-check.sh
fi
# Mold needed for Verilator, not available in all package managers.
if (( UBUNTU_VERSION == 20 || DEBIAN_VERSION == 11 )) || [ "$FAMILY" == suse ]; then
STATUS="mold"
if [ ! -e "$RISCV"/bin/mold ]; then
section_header "Installing mold"
cd "$RISCV"
wget -nv --retry-connrefused $retry_on_host_error --output-document=mold.tar.gz https://github.com/rui314/mold/releases/download/v2.34.1/mold-2.34.1-x86_64-linux.tar.gz
tar xz --directory="$RISCV" --strip-components=1 -f mold.tar.gz
rm -f mold.tar.gz
echo -e "${SUCCESS_COLOR}Mold successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}Mold already installed.${ENDC}"
fi
fi
# Verilator (https://github.com/verilator/verilator)
# Verilator is a fast open-source Verilog simulator that compiles synthesizable Verilog code into C++ code.
# It is used for linting and simulation of Wally.
# Verilator needs to be built from source to get the latest version (Wally needs 5.021 or later).
section_header "Installing/Updating Verilator"
STATUS="verilator"
cd "$RISCV"
if check_tool_version $VERILATOR_VERSION; then
git_checkout "verilator" "https://github.com/verilator/verilator" "$VERILATOR_VERSION"
unset VERILATOR_ROOT
cd "$RISCV"/verilator
autoconf
./configure --prefix="$RISCV"
make -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
make install 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" = true ]; then
cd "$RISCV"
rm -rf verilator
fi
echo "$VERILATOR_VERSION" > "$RISCV"/versions/$STATUS.version # Record installed version
echo -e "${SUCCESS_COLOR}Verilator successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}Verilator already up to date.${ENDC}"
fi

View file

@ -0,0 +1,111 @@
#!/bin/bash
###########################################
## Installation helper functions.
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: May 30 2025
## Modified:
##
## Purpose: Common functions for toolchain installation scripts
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-24 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.
################################################################################################
set -e # break on error
## Helper functions
# Error handler
error() {
echo -e "${FAIL_COLOR}Error: $STATUS installation failed"
echo -e "Error on line ${BASH_LINENO[0]} with command $BASH_COMMAND${ENDC}"
if [ -e "$RISCV/logs/$STATUS.log" ]; then
echo -e "Please check the log in $RISCV/logs/$STATUS.log for more information."
fi
exit 1
}
# Check if the specificed version of a tool is installed
# $1: required version
# Tool inferred from $STATUS variable
check_tool_version() {
local required_version="$1"
local version_file="$RISCV/versions/$STATUS.version"
if [ -f "$version_file" ] && [ "$(cat "$version_file")" = "$required_version" ]
then
return 1 # Tool is up-to-date
else
return 0 # Tool needs installation or update
fi
}
# Checkout specified version of a git repository
# $1: repo name
# $2: repo url to clone from
# $3: version to checkout (commit hash or tag)
git_checkout() {
local repo=$1
local url=$2
local version=$3
# Clone repo if it doesn't exist
if [[ ! -e $repo ]]; then
for ((i=1; i<=5; i++)); do
git clone "$url" "$repo" && break
echo -e "${WARNING_COLOR}Failed to clone $repo. Retrying.${ENDC}"
rm -rf "$repo"
sleep $i
done
if [[ ! -e $repo ]]; then
echo -e "${ERROR_COLOR}Failed to clone $repo after 5 attempts. Exiting.${ENDC}"
exit 1
fi
fi
# Update the repository
cd "$repo"
git fetch --all
# Checkout the specified version
git reset --hard "$version"
git clean -fdx && git submodule update
}
# Log output to a file and only print lines with keywords
logger() {
local log_file="$RISCV/logs/$STATUS.log"
local keyword_pattern="(\bwarning|\berror|\bfail|\bsuccess|\bstamp|\bdoesn't work)"
local exclude_pattern="(_warning|warning_|_error|error_|-warning|warning-|-error|error-|Werror|error\.o|warning flags)"
cat < /dev/stdin | tee -a "$log_file" | \
(grep -iE --color=never "$keyword_pattern" || true) | \
(grep -viE --color=never "$exclude_pattern" || true)
}
# Print section header
section_header() {
if tput cols > /dev/null 2>&1; then
printf "${SECTION_COLOR}%$(tput cols)s\n" | tr ' ' '#'
printf "%$(tput cols)s\n" | tr ' ' '#'
printf "%s\n" "$1"
printf "%$(tput cols)s\n" | tr ' ' '#'
printf "%$(tput cols)s${ENDC}\n" | tr ' ' '#'
else
printf "${SECTION_COLOR}%s\n${ENDC}" "$1"
fi
}

View file

@ -1,4 +1,4 @@
#!/usr/bin/env -S perl -w
#!/usr/bin/env perl
###########################################
## libppa.pl

87
bin/lint-spyglass.sh Executable file
View file

@ -0,0 +1,87 @@
#!/bin/bash
###############################################################################
# Script Name: lint_spyglass.sh
# Author: james.stine@okstate.edu 11 June 2025
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
# Description:
# Automates Synopsys SpyGlass linting for Wally RISC-V configurations.
# Supports command-line options for custom goals and configs.
###############################################################################
# Check WALLY environment
if [ -z "$WALLY" ]; then
echo "Error: WALLY environment variable is not set."
echo "Please source your setup before running this script."
exit 1
fi
# === Defaults ===
GOAL="lint/lint_rtl"
DEFAULT_CONFIGS=(rv32e rv64gc rv32gc rv32imc rv32i rv64i)
CONFIGS=()
BATCH_FLAG="-batch"
# === Parse command-line options ===
while [[ $# -gt 0 ]]; do
case "$1" in
-g|--goal)
GOAL="$2"
shift 2
;;
-c|--configs)
IFS=',' read -r -a CONFIGS <<< "$2"
shift 2
;;
--gui)
BATCH_FLAG=""
shift
;;
-h|--help)
echo "Usage: $0 [-g lint_goal] [-c config1,config2,...] [--gui]"
echo " -g, --goal Linting goal (e.g., lint/lint_rtl or lint/lint_rtl_enhanced)"
echo " -c, --configs Comma-separated list of configs to run (e.g., rv32e,rv64gc)"
echo " --gui Run SpyGlass with Verdi GUI"
echo "Defaults: goal=$GOAL, configs=${DEFAULT_CONFIGS[*]}"
exit 0
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Use default configs if none provided
if [ ${#CONFIGS[@]} -eq 0 ]; then
CONFIGS=("${DEFAULT_CONFIGS[@]}")
fi
# For GUI mode, warn if multiple configs are specified
if [ -z "$BATCH_FLAG" ] && [ ${#CONFIGS[@]} -gt 1 ]; then
echo "Warning: Multiple configurations selected. GUI will open for each configuration sequentially."
fi
# Spyglass work directories/files
SPYGLASS_DIR="$WALLY/synthDC/spyglass"
SPYGLASS_PRJ="$SPYGLASS_DIR/cvw.prj"
# Iterate configs
errors=0
for config in "${CONFIGS[@]}"; do
# Clean output directory
rm -rf "$SPYGLASS_DIR/lint-spyglass-reports/$config"
# Run SpyGlass
echo "Running spyglass for: $config with goal: $GOAL"
WALLY_CONFIG=$config spyglass -project "$SPYGLASS_PRJ" -goal "$GOAL" $BATCH_FLAG
if [ $? -ne 0 ]; then
echo "Error running spyglass for configuration: $config"
errors=$((errors + 1))
else
echo "Completed: $config"
fi
done
exit $errors

View file

@ -317,7 +317,6 @@ class bcolors:
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def addTests(testList, sim, coverStr, configs):
sim_logdir = f"{regressionDir}/{sim}/logs/"
for test in testList:
@ -489,12 +488,11 @@ def selectTests(args, sims, coverStr):
addTests(tests_buildrootbootlockstep, lockstepsim, coverStr, configs) # lockstep with Questa and ImperasDV runs overnight
# only run RV64GC tests on in code coverage mode
if args.ccov:
addTestsByDir(f"{archVerifDir}/tests/rv64/", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{archVerifDir}/tests/priv/rv64/", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1) # doesn't help coverage much dh 4/12/25
addTestsByDir(WALLY+"/tests/coverage/", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
# Extra tests from riscv-arch-test that should be run as part of the functional coverage suite
addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/pmp", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m/privilege", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{archVerifDir}/tests/rv64/", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(WALLY+"/tests/coverage/", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
# run tests in lockstep in functional coverage mode
if args.fcov or args.nightly:
addTestsByDir(f"{archVerifDir}/tests/rv32/", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
@ -516,7 +514,7 @@ def selectTests(args, sims, coverStr):
if args.breker:
addTestsByDir(WALLY+"/tests/breker/work", "breker", "questa", coverStr, configs, brekerMode=1)
# standard tests
if not(args.testfloat or args.ccov or args.fcov or args.fcov_act or args.branch or args.breker):
if not(args.testfloat or args.ccov or args.fcov or args.fcov_act or args.cache or args.branch or args.benchmark or args.breker):
for sim in sims:
if not (args.buildroot and sim == lockstepsim): # skip short buildroot sim if running long one
addTests(tests_buildrootshort, sim, coverStr, configs)

View file

@ -4,9 +4,9 @@ Markdown>=3.6
matplotlib>=3.9.0
pre-commit>=4.0.0
PyYAML>=5.2
riscof @ git+https://github.com/riscv/riscof.git
riscv-config @ git+https://github.com/riscv-software-src/riscv-config
riscv-isac @ git+https://github.com/riscv-non-isa/riscv-arch-test/#subdirectory=riscv-isac
riscof @ git+https://github.com/riscv/riscof.git@${RISCOF_VERSION} # version set in python-setup.sh
riscv-config @ git+https://github.com/riscv-software-src/riscv-config.git@${RISCV_CONFIG_VERSION} # version set in python-setup.sh
riscv-isac @ git+https://github.com/riscv-non-isa/riscv-arch-test.git@${RISCV_ISAC_VERSION}#subdirectory=riscv-isac # version set in python-setup.sh
scikit-learn>=1.5.0
scipy>=1.13.0
setuptools

View file

@ -1,4 +1,4 @@
#!/usr/bin/env -S perl -w
#!/usr/bin/env perl
###########################################
## testlist.pl

View file

@ -1,4 +1,4 @@
#!/usr/bin/env -S perl -w
#!/usr/bin/env perl
###########################################
## vclean.pl

View file

@ -1,10 +1,10 @@
#!/bin/bash
###########################################
## Get Linux distro information
## Get Linux distro information and check environment
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: 30 June 2024
## Modified:
## Modified: May 30 2025
##
## Purpose: Check for compatible Linux distribution and set variables accordingly
##
@ -29,31 +29,31 @@
set -e # break on error
# Colors
### Colors ###
BOLD='\033[1m'
UNDERLINE='\033[4m'
SECTION_COLOR='\033[95m'$BOLD
OK_COLOR='\033[94m'
SUCCESS_COLOR='\033[92m'
WARNING_COLOR='\033[93m'
FAIL_COLOR='\033[91m'
ENDC='\033[0m' # Reset to default color
# Print section header
section_header() {
if tput cols > /dev/null 2>&1; then
printf "${SECTION_COLOR}%$(tput cols)s\n" | tr ' ' '#'
printf "%$(tput cols)s\n" | tr ' ' '#'
printf "%s\n" "$1"
printf "%$(tput cols)s\n" | tr ' ' '#'
printf "%$(tput cols)s${ENDC}\n" | tr ' ' '#'
else
printf "${SECTION_COLOR}%s\n${ENDC}" "$1"
fi
}
if [ -z "$WALLY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WALLY="$(dirname "$dir")"
export WALLY
fi
### Common functions and error handling ###
source "$WALLY"/bin/installation/wally-installation-helper-functions.sh
trap error ERR # run error handler on error
STATUS="setup" # keep track of what part of the installation is running for error messages
section_header "Checking System Requirements and Configuring Installation"
# Get distribution information
### Get distribution information ###
if [ -f /etc/os-release ]; then
source /etc/os-release
else
@ -131,6 +131,85 @@ else
exit 1
fi
printf "${OK_COLOR}${UNDERLINE}%s\n${ENDC}" "Detected information"
# wget retry on host error flag not available with older wget on RHEL 8
if (( RHEL_VERSION != 8 )); then
retry_on_host_error="--retry-on-host-error"
fi
### Configure installation ###
# Check flags
clean=false
no_buildroot=false
packages_only=false
while [[ "$#" -gt 0 ]]; do
case $1 in
-c|--clean) clean=true ;;
--no-buildroot) no_buildroot=true ;;
--packages-only) packages_only=true;;
-h|--help)
echo -e "Usage: $0 [\$RISCV] [options]"
echo -e "${BOLD}Options:${ENDC}"
echo -e " -c, --clean Remove build directories after installation"
echo -e " --no-buildroot Skip installing Buildroot and Linux testvectors"
echo -e " \$RISCV Directory to install RISC-V tools (default: /opt/riscv as root, $HOME/riscv otherwise)"
exit 0 ;;
*) RISCV="$1" ;;
esac
shift
done
# Check if root
ROOT=$( [ "${EUID:=$(id -u)}" == 0 ] && echo true || echo false);
### Print system information ###
echo -e "${OK_COLOR}${UNDERLINE}Detected information${ENDC}"
echo "Distribution: $PRETTY_NAME"
echo "Version: $VERSION"
echo "Running as root: $ROOT"
if [ $packages_only != true ]; then
# Set installation directory based on execution privileges
# If the script is run as root, the default installation path is /opt/riscv
# If the script is run as a user, the default installation path is ~/riscv
# The installation path can be overridden with a positional argument passed to the script.
if [ "$ROOT" == true ]; then
export RISCV="${RISCV:-/opt/riscv}"
else
export RISCV="${RISCV:-$HOME/riscv}"
fi
# Set environment variables
export PATH=$RISCV/bin:$PATH:/usr/bin
export PKG_CONFIG_PATH=$RISCV/lib64/pkgconfig:$RISCV/lib/pkgconfig:$RISCV/share/pkgconfig:$RISCV/lib/x86_64-linux-gnu/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
# Check for incompatible PATH environment variable before proceeding with installation
if [[ ":$PATH:" == *::* || ":$PATH:" == *:.:* ]]; then
echo -e "${FAIL_COLOR}Error: You seem to have the current working directory in your \$PATH environment variable."
echo -e "This won't work. Please update your \$PATH and try again.${ENDC}"
exit 1
fi
# Increasing NUM_THREADS will speed up parallel compilation of the tools
NUM_THREADS=$(nproc --ignore 1) # One less than the total number of threads
# Check available memory
total_mem=$(grep MemTotal < /proc/meminfo | awk '{print $2}')
total_mem_gb=$((total_mem / 1024 / 1024))
# Reduce number of threads for systems with less than 8 GB of memory
if ((total_mem < 8400000 )) ; then
NUM_THREADS=1
echo -e "${WARNING_COLOR}Detected less than or equal to 8 GB of memory. Using a single thread for compiling tools. This may take a while.${ENDC}"
fi
# Create installation directory
mkdir -p "$RISCV"/logs
mkdir -p "$RISCV"/versions
# Print more system information
echo "Installation path: $RISCV"
echo "Number of cores: $(nproc)"
echo "Total memory: $total_mem_gb GB"
echo "Using $NUM_THREADS thread(s) for compilation"
fi

View file

@ -4,7 +4,7 @@
##
## Written: Jordan Carlin, jcarlin@hmc.edu
## Created: 30 June 2024
## Modified:
## Modified: May 30 2025
##
## Purpose: Package manager installation for open source tool chain installation script
##
@ -29,26 +29,24 @@
set -e # break on error
# Colors
BOLD='\033[1m'
SECTION_COLOR='\033[95m'$BOLD
SUCCESS_COLOR='\033[92m'
FAIL_COLOR='\033[91m'
ENDC='\033[0m' # Reset to default color
STATUS="system_packages"
# If run standalone, determine distro information. Otherwise, use info from main install script
# If run standalone, check environment. Otherwise, use info from main install script
if [ -z "$FAMILY" ]; then
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${dir}"/wally-distro-check.sh
WALLY="$(dirname "$dir")"
export WALLY
source "${dir}"/wally-environment-check.sh "--packages-only"
fi
# Packages are grouped by which tool requires them. If multiple tools need a package, it is included in the first tool only
# Packages are grouped by which tool requires them. If multiple tools need a package, it is included in each tool's list.
# Packages that are constant across distros
GENERAL_PACKAGES+=(rsync git make cmake curl wget tar unzip bzip2 dialog mutt)
GNU_PACKAGES+=(autoconf automake gawk bison flex texinfo gperf libtool patchutils bc gcc)
VERILATOR_PACKAGES+=(help2man perl clang ccache numactl)
BUILDROOT_PACKAGES+=(cpio)
GENERAL_PACKAGES+=(rsync git curl wget tar unzip gzip bzip2 gcc make dialog mutt) # TODO: check what needs dialog
GNU_PACKAGES+=(autoconf automake gawk bison flex texinfo gperf libtool patchutils bc)
SAIL_PACKAGES+=(cmake)
VERILATOR_PACKAGES+=(autoconf flex bison help2man perl ccache numactl)
BUILDROOT_PACKAGES+=(patchutils perl cpio bc)
# Distro specific packages and package manager
case "$FAMILY" in
@ -57,17 +55,18 @@ case "$FAMILY" in
PACKAGE_MANAGER="dnf -y"
UPDATE_COMMAND="$PACKAGE_MANAGER update"
GENERAL_PACKAGES+=(which "$PYTHON_VERSION" "$PYTHON_VERSION"-pip pkgconf-pkg-config gcc-c++ ssmtp)
GNU_PACKAGES+=(libmpc-devel mpfr-devel gmp-devel zlib-devel expat-devel libslirp-devel ninja-build)
QEMU_PACKAGES+=(glib2-devel libfdt-devel pixman-devel)
SPIKE_PACKAGES+=(dtc boost-regex boost-system)
VERILATOR_PACKAGES+=(gperftools mold)
GNU_PACKAGES+=(libmpc-devel mpfr-devel gmp-devel zlib-devel expat-devel glib2-devel libslirp-devel)
QEMU_PACKAGES+=(glib2-devel libfdt-devel pixman-devel zlib-devel ninja-build)
SPIKE_PACKAGES+=(dtc) # compiling Spike with boost fails on RHEL
SAIL_PACKAGES+=(ninja-build gmp-devel)
VERILATOR_PACKAGES+=(zlib-devel gperftools-devel mold)
BUILDROOT_PACKAGES+=(ncurses ncurses-base ncurses-libs ncurses-devel gcc-gfortran) # gcc-gfortran is only needed for compiling spec benchmarks on buildroot linux
# Extra packages not available in rhel8, nice for Verilator
if (( RHEL_VERSION >= 9 )); then
VERILATOR_PACKAGES+=(perl-doc)
fi
# A newer version of gcc is required for qemu
OTHER_PACKAGES+=(gcc-toolset-13)
GENERAL_PACKAGES+=(gcc-toolset-13)
;;
ubuntu | debian)
if (( UBUNTU_VERSION >= 24 )); then
@ -76,7 +75,7 @@ case "$FAMILY" in
PYTHON_VERSION=python3.11
elif (( UBUNTU_VERSION >= 20 )); then
PYTHON_VERSION=python3.9
OTHER_PACKAGES+=(gcc-10 g++-10 cpp-10) # Newer version of gcc needed for Verilator
GENERAL_PACKAGES+=(gcc-10 g++-10 cpp-10) # Newer version of gcc needed for Verilator
elif (( DEBIAN_VERSION >= 12 )); then
PYTHON_VERSION=python3.11
elif (( DEBIAN_VERSION >= 11 )); then
@ -88,11 +87,12 @@ case "$FAMILY" in
fi
PACKAGE_MANAGER="DEBIAN_FRONTEND=noninteractive apt-get -y"
UPDATE_COMMAND="$PACKAGE_MANAGER update && $PACKAGE_MANAGER upgrade --with-new-pkgs"
GENERAL_PACKAGES+=("$PYTHON_VERSION" python3-pip "$PYTHON_VERSION"-venv pkg-config g++ ssmtp)
GNU_PACKAGES+=(autotools-dev libmpc-dev libmpfr-dev libgmp-dev build-essential ninja-build zlib1g-dev libexpat1-dev libglib2.0-dev libslirp-dev)
QEMU_PACKAGES+=(libfdt-dev libpixman-1-dev)
GENERAL_PACKAGES+=("$PYTHON_VERSION" python3-pip "$PYTHON_VERSION"-venv pkg-config build-essential g++ ssmtp)
GNU_PACKAGES+=(autotools-dev libmpc-dev libmpfr-dev libgmp-dev zlib1g-dev libexpat1-dev libglib2.0-dev libslirp-dev)
QEMU_PACKAGES+=(libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build)
SPIKE_PACKAGES+=(device-tree-compiler libboost-regex-dev libboost-system-dev)
VERILATOR_PACKAGES+=(libunwind-dev libgoogle-perftools-dev perl-doc libfl2 libfl-dev zlib1g)
SAIL_PACKAGES+=(ninja-build libgmp-dev)
VERILATOR_PACKAGES+=(libfl2 libfl-dev zlib1g-dev libunwind-dev libgoogle-perftools-dev perl-doc)
BUILDROOT_PACKAGES+=(ncurses-base ncurses-bin libncurses-dev gfortran) # gfortran is only needed for compiling spec benchmarks on buildroot linux
VIVADO_PACKAGES+=(libncurses*) # Vivado hangs on the third stage of installation without this
;;
@ -102,12 +102,13 @@ case "$FAMILY" in
PACKAGE_MANAGER="zypper -n"
UPDATE_COMMAND="$PACKAGE_MANAGER update"
GENERAL_PACKAGES+=("$PYTHON_VERSION_PACKAGE" "$PYTHON_VERSION_PACKAGE"-pip pkg-config)
GNU_PACKAGES+=(mpc-devel mpfr-devel gmp-devel zlib-devel libexpat-devel libslirp-devel ninja)
QEMU_PACKAGES+=(glib2-devel libpixman-1-0-devel) # maybe also need qemu itself?
GNU_PACKAGES+=(mpc-devel mpfr-devel gmp-devel zlib-devel libexpat-devel glib2-devel libslirp-devel)
QEMU_PACKAGES+=(glib2-devel libfdt-devel libpixman-1-0-devel zlib-devel ninja)
SPIKE_PACKAGES+=(dtc libboost_regex1_75_0-devel libboost_system1_75_0-devel)
VERILATOR_PACKAGES+=(gperftools perl-doc)
SAIL_PACKAGES+=(ninja gmp-devel)
VERILATOR_PACKAGES+=(libfl2 libfl-devel zlib-devel gperftools-devel perl-doc)
BUILDROOT_PACKAGES+=(ncurses-utils ncurses-devel ncurses5-devel gcc-fortran) # gcc-fortran is only needed for compiling spec benchmarks on buildroot linux
OTHER_PACKAGES+=(gcc13 gcc13-c++ cpp13) # Newer version of gcc needed for many tools. Default is gcc7
GENERAL_PACKAGES+=(gcc13 gcc13-c++ cpp13) # Newer version of gcc needed for many tools. Default is gcc7
;;
esac
@ -116,18 +117,18 @@ esac
if [ "${1}" == "--check" ]; then
section_header "Checking Dependencies from Package Manager"
if [[ "$FAMILY" == rhel || "$FAMILY" == suse ]]; then
for pack in "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}"; do
for pack in "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${SAIL_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}"; do
rpm -q "$pack" > /dev/null || (echo -e "${FAIL_COLOR}Missing packages detected (${WARNING_COLOR}$pack${FAIL_COLOR}). Run as root to auto-install or run wally-package-install.sh first.${ENDC}" && exit 1)
done
elif [[ "$FAMILY" == ubuntu || "$FAMILY" == debian ]]; then
for pack in "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}"; do
for pack in "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${SAIL_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}"; do
dpkg -l "$pack" | grep "ii" > /dev/null || (echo -e "${FAIL_COLOR}Missing packages detected (${WARNING_COLOR}$pack${FAIL_COLOR}). Run as root to auto-install or run wally-package-install.sh first." && exit 1)
done
fi
echo -e "${OK_COLOR}All required packages detected.${ENDC}"
else
# Check if root, otherwise exit with error message
[ "${EUID:=$(id -u)}" -ne 0 ] && echo -e "\n${FAIL_COLOR}Must be run as root${ENDC}" && exit 1
[ "$ROOT" == false ] && echo -e "\n${FAIL_COLOR}Must be run as root${ENDC}" && exit 1
section_header "Installing/Updating Dependencies from Package Manager"
# Enable extra repos necessary for rhel
@ -150,7 +151,7 @@ else
# Update and Upgrade tools
eval "$UPDATE_COMMAND"
# Install packages listed above using appropriate package manager
eval $PACKAGE_MANAGER install "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${OTHER_PACKAGES[@]}" "${VIVADO_PACKAGES[@]}"
eval $PACKAGE_MANAGER install "${GENERAL_PACKAGES[@]}" "${GNU_PACKAGES[@]}" "${QEMU_PACKAGES[@]}" "${SPIKE_PACKAGES[@]}" "${SAIL_PACKAGES[@]}" "${VERILATOR_PACKAGES[@]}" "${BUILDROOT_PACKAGES[@]}" "${VIVADO_PACKAGES[@]}"
# Post install steps
# Vivado looks for ncurses5 libraries, but Ubuntu 24.04 only has ncurses6

View file

@ -3,11 +3,8 @@
## Tool chain install script.
##
## Written: Rose Thompson rose@rosethompson.net
## Created: 18 January 2023
## Modified: 22 January 2023
## Modified: 23 March 2023
## Modified: 30 June 2024, Jordan Carlin jcarlin@hmc.edu
## Modified: 1 September 2024
## Modified: 30 May 2025
##
## Purpose: Open source tool chain installation script
##
@ -30,99 +27,9 @@
## and limitations under the License.
################################################################################################
# Increasing NUM_THREADS will speed up parallel compilation of the tools
NUM_THREADS=$(nproc --ignore 1) # One less than the total number of threads
# Colors
BOLD='\033[1m'
UNDERLINE='\033[4m'
SECTION_COLOR='\033[95m'$BOLD
OK_COLOR='\033[94m'
SUCCESS_COLOR='\033[92m'
WARNING_COLOR='\033[93m'
FAIL_COLOR='\033[91m'
ENDC='\033[0m' # Reset to default color
## Helper functions
# Error handler
error() {
echo -e "${FAIL_COLOR}Error: $STATUS installation failed"
echo -e "Error on line ${BASH_LINENO[0]} with command $BASH_COMMAND${ENDC}"
if [ -e "$RISCV/logs/$STATUS.log" ]; then
echo -e "Please check the log in $RISCV/logs/$STATUS.log for more information."
fi
exit 1
}
# Check if a git repository exists, is up to date, and has been installed
# clones the repository if it doesn't exist
# $1: repo name
# $2: repo url to clone from
# $3: file to check if already installed
# $4: upstream branch, optional, default is master
git_check() {
local repo=$1
local url=$2
local check=$3
local branch="${4:-master}"
# Clone repo if it doesn't exist
if [[ ! -e $repo ]]; then
for ((i=1; i<=5; i++)); do
git clone "$url" && break
echo -e "${WARNING_COLOR}Failed to clone $repo. Retrying.${ENDC}"
rm -rf "$repo"
sleep $i
done
if [[ ! -e $repo ]]; then
echo -e "${ERROR_COLOR}Failed to clone $repo after 5 attempts. Exiting.${ENDC}"
exit 1
fi
fi
# Get the current HEAD commit hash and the remote branch commit hash
cd "$repo"
git fetch
local local_head=$(git rev-parse HEAD)
local remote_head=$(git rev-parse origin/"$branch")
# Check if the git repository is not up to date or the specified file does not exist
if [[ "$local_head" != "$remote_head" ]]; then
echo "$repo is not up to date. Updating now."
true
elif [[ ! -e $check ]]; then
true
else
false
fi
}
# Log output to a file and only print lines with keywords
logger() {
local log_file="$RISCV/logs/$STATUS.log"
local keyword_pattern="(\bwarning|\berror|\bfail|\bsuccess|\bstamp|\bdoesn't work)"
local exclude_pattern="(_warning|warning_|_error|error_|-warning|warning-|-error|error-|Werror|error\.o|warning flags)"
cat < /dev/stdin | tee -a "$log_file" | \
(grep -iE --color=never "$keyword_pattern" || true) | \
(grep -viE --color=never "$exclude_pattern" || true)
}
# NOTE: All scripts are sourced instead of executed so that environment variables and functions are shared properly.
set -e # break on error
trap error ERR # run error handler on error
STATUS="setup" # keep track of what part of the installation is running for error messages
# Check for clean flag
if [ "$1" == "--clean" ] || [ "$2" == "--clean" ]; then
clean=true
shift
fi
# Check for no-buildroot flag
if [ "$1" == "--no-buildroot" ] || [ "$2" == "--no-buildroot" ]; then
no_buidroot=true
shift
fi
# Determine script directory to locate related scripts
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@ -130,382 +37,86 @@ WALLY=$(dirname "$dir")
export WALLY
# Get Linux distro and version
source "${dir}"/wally-distro-check.sh
# Check if root
ROOT=$( [ "${EUID:=$(id -u)}" == 0 ] && echo true || echo false);
# Set installation directory based on execution privileges
# If the script is run as root, the default installation path is /opt/riscv
# If the script is run as a user, the default installation path is ~/riscv
# The installation path can be overridden with an argument passed to the script.
if [ "$ROOT" == true ]; then
export RISCV="${1:-/opt/riscv}"
else
export RISCV="${1:-$HOME/riscv}"
fi
# Set environment variables
export PATH=$PATH:$RISCV/bin:/usr/bin
export PKG_CONFIG_PATH=$RISCV/lib64/pkgconfig:$RISCV/lib/pkgconfig:$RISCV/share/pkgconfig:$RISCV/lib/x86_64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH
# wget retry on host error flag not available with older wget on RHEL 8
if (( RHEL_VERSION != 8 )); then
retry_on_host_error="--retry-on-host-error"
fi
# Check for incompatible PATH environment variable before proceeding with installation
if [[ ":$PATH:" == *::* || ":$PATH:" == *:.:* ]]; then
echo -e "${FAIL_COLOR}Error: You seem to have the current working directory in your \$PATH environment variable."
echo -e "This won't work. Please update your \$PATH and try again.${ENDC}"
exit 1
fi
# Check available memory
total_mem=$(grep MemTotal < /proc/meminfo | awk '{print $2}')
total_mem_gb=$((total_mem / 1024 / 1024))
# Print system information
echo "Running as root: $ROOT"
echo "Installation path: $RISCV"
echo "Number of cores: $(nproc)"
echo "Total memory: $total_mem_gb GB"
# Reduce number of threads for systems with less than 8 GB of memory
if ((total_mem < 8400000 )) ; then
NUM_THREADS=1
echo -e "${WARNING_COLOR}Detected less than or equal to 8 GB of memory. Using a single thread for compiling tools. This may take a while.${ENDC}"
fi
# Print number of threads
echo "Using $NUM_THREADS thread(s) for compilation"
# Create installation directory
mkdir -p "$RISCV"/logs
source "${dir}"/wally-environment-check.sh
# Install/update system packages if root. Otherwise, check that packages are already installed.
STATUS="system_packages"
if [ "$ROOT" == true ]; then
source "${dir}"/wally-package-install.sh
else
source "${dir}"/wally-package-install.sh --check
fi
# Older version of git defaults to protocol version incompatible with riscv-gnu-toolchain
if (( UBUNTU_VERSION == 20 )); then
git config --global protocol.version 2
fi
# Enable newer version of gcc for older distros (required for QEMU/Verilator)
if [ "$FAMILY" == rhel ]; then
source /opt/rh/gcc-toolset-13/enable
elif [ "$FAMILY" == suse ]; then
mkdir -p "$RISCV"/gcc-13/bin
for f in gcc cpp g++ gcc-ar gcc-nm gcc-ranlib gcov gcov-dump gcov-tool lto-dump; do
ln -vsf /usr/bin/$f-13 "$RISCV"/gcc-13/bin/$f
done
export PATH="$RISCV"/gcc-13/bin:$PATH
elif (( UBUNTU_VERSION == 20 )); then
mkdir -p "$RISCV"/gcc-10/bin
for f in gcc cpp g++ gcc-ar gcc-nm gcc-ranlib gcov gcov-dump gcov-tool lto-dump; do
ln -vsf /usr/bin/$f-10 "$RISCV"/gcc-10/bin/$f
done
export PATH="$RISCV"/gcc-10/bin:$PATH
fi
# Create python virtual environment so the python command targets desired version of python
# and installed packages are isolated from the rest of the system.
section_header "Setting up Python Environment"
STATUS="python_virtual_environment"
cd "$RISCV"
if [ ! -e "$RISCV"/riscv-python/bin/activate ]; then
"$PYTHON_VERSION" -m venv riscv-python --prompt cvw
echo -e "${OK_COLOR}Python virtual environment created!\nInstalling pip packages.${ENDC}"
else
echo -e "${OK_COLOR}Python virtual environment already exists.\nUpdating pip packages.${ENDC}"
fi
source "$RISCV"/riscv-python/bin/activate # activate python virtual environment
# Install python packages, including RISCOF (https://github.com/riscv-software-src/riscof.git)
# and installed packages are isolated from the rest of the system. Also installs python packages,
# including RISCOF (https://github.com/riscv-software-src/riscof.git)
# RISCOF is a RISC-V compliance test framework that is used to run the RISC-V Arch Tests.
STATUS="python packages"
pip install --upgrade pip && pip install --upgrade -r "$dir"/requirements.txt
source "$WALLY"/bin/installation/python-setup.sh
source "$RISCV"/riscv-python/bin/activate # reload python virtual environment
echo -e "${SUCCESS_COLOR}Python environment successfully configured!${ENDC}"
# Extra dependencies needed for older distros that don't have new enough versions available from package manager
# Activate tools (python virtual environment and possibly newer version of gcc)
source "${WALLY}"/bin/installation/activate-tools.sh
# Newer version of glib required for QEMU.
# Anything newer than this won't build on red hat 8
# Used for all installed tools becuase mixing glib versions can cause issues.
if (( RHEL_VERSION == 8 )) || (( UBUNTU_VERSION == 20 )); then
# Newer version of glib required for QEMU.
# Anything newer than this won't build on red hat 8
STATUS="glib"
if [ ! -e "$RISCV"/include/glib-2.0 ]; then
section_header "Installing glib"
pip install -U meson # Meson is needed to build glib
cd "$RISCV"
wget -nv --retry-connrefused $retry_on_host_error https://download.gnome.org/sources/glib/2.70/glib-2.70.5.tar.xz
tar -xJf glib-2.70.5.tar.xz
rm -f glib-2.70.5.tar.xz
cd glib-2.70.5
meson setup _build --prefix="$RISCV"
meson compile -C _build -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
meson install -C _build 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
cd "$RISCV"
rm -rf glib-2.70.5
echo -e "${SUCCESS_COLOR}glib successfully installed!${ENDC}"
fi
source "$WALLY"/bin/installation/glib-installation.sh
fi
# Newer version of gmp needed for sail-riscv model
if (( RHEL_VERSION == 8 )); then
STATUS="gmp"
if [ ! -e "$RISCV"/include/gmp.h ]; then
section_header "Installing gmp"
cd "$RISCV"
wget -nv --retry-connrefused $retry_on_host_error https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz
tar -xJf gmp-6.3.0.tar.xz
rm -f gmp-6.3.0.tar.xz
cd gmp-6.3.0
./configure --prefix="$RISCV"
make -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
make install 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
cd "$RISCV"
rm -rf gmp-6.3.0
echo -e "${SUCCESS_COLOR}gmp successfully installed!${ENDC}"
fi
fi
# Mold needed for Verilator
if (( UBUNTU_VERSION == 20 || DEBIAN_VERSION == 11 )) || [ "$FAMILY" == suse ]; then
STATUS="mold"
if [ ! -e "$RISCV"/bin/mold ]; then
section_header "Installing mold"
cd "$RISCV"
wget -nv --retry-connrefused $retry_on_host_error --output-document=mold.tar.gz https://github.com/rui314/mold/releases/download/v2.34.1/mold-2.34.1-x86_64-linux.tar.gz
tar xz --directory="$RISCV" --strip-components=1 -f mold.tar.gz
rm -f mold.tar.gz
echo -e "${SUCCESS_COLOR}Mold successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}Mold already installed.${ENDC}"
fi
fi
# Newer version of CMake needed to build sail-riscv model (at least 3.20)
if (( UBUNTU_VERSION == 20 || DEBIAN_VERSION == 11 )); then
STATUS="cmake"
if [ ! -e "$RISCV"/bin/cmake ]; then
section_header "Installing cmake"
cd "$RISCV"
wget -nv --retry-connrefused $retry_on_host_error --output-document=cmake.tar.gz https://github.com/Kitware/CMake/releases/download/v3.31.5/cmake-3.31.5-linux-x86_64.tar.gz
tar xz --directory="$RISCV" --strip-components=1 -f cmake.tar.gz
rm -f cmake.tar.gz
echo -e "${SUCCESS_COLOR}CMake successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}CMake already installed.${ENDC}"
fi
fi
# RISC-V GNU Toolchain (https://github.com/riscv-collab/riscv-gnu-toolchain)
# The RISC-V GNU Toolchain includes the GNU Compiler Collection (gcc), GNU Binutils, Newlib,
# and the GNU Debugger Project (gdb). It is a collection of tools used to compile RISC-V programs.
# To install GCC from source can take hours to compile.
# This configuration enables multilib to target many flavors of RISC-V.
# This book is tested with GCC 13.2.0 and 14.2.0.
section_header "Installing/Updating RISC-V GNU Toolchain"
STATUS="riscv-gnu-toolchain"
cd "$RISCV"
if git_check "riscv-gnu-toolchain" "https://github.com/riscv/riscv-gnu-toolchain" "$RISCV/riscv-gnu-toolchain/stamps/build-gcc-newlib-stage2"; then
cd "$RISCV"/riscv-gnu-toolchain
git reset --hard && git clean -f && git checkout master && git pull && git submodule update
./configure --prefix="${RISCV}" --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
make -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" ]; then
cd "$RISCV"
rm -rf riscv-gnu-toolchain
fi
echo -e "${SUCCESS_COLOR}RISC-V GNU Toolchain successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}RISC-V GNU Toolchain already up to date.${ENDC}"
fi
source "$WALLY"/bin/installation/riscv-gnu-toolchain-install.sh
# elf2hex (https://github.com/sifive/elf2hex)
# The elf2hex utility to converts executable files into hexadecimal files for Verilog simulation.
# Note: The exe2hex utility that comes with Spike doesnt work for our purposes because it doesnt
# handle programs that start at 0x80000000. The SiFive version above is touchy to install.
# For example, if Python version 2.x is in your path, it wont install correctly.
# Also, be sure riscv64-unknown-elf-objcopy shows up in your path in $RISCV/riscv-gnu-toolchain/bin
# at the time of compilation, or elf2hex wont work properly.
section_header "Installing/Updating elf2hex"
STATUS="elf2hex"
cd "$RISCV"
export PATH=$RISCV/bin:$PATH
if git_check "elf2hex" "https://github.com/sifive/elf2hex.git" "$RISCV/bin/riscv64-unknown-elf-elf2bin"; then
cd "$RISCV"/elf2hex
git reset --hard && git clean -f && git checkout master && git pull
autoreconf -i
./configure --target=riscv64-unknown-elf --prefix="$RISCV"
make 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
make install 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" ]; then
cd "$RISCV"
rm -rf elf2hex
fi
echo -e "${SUCCESS_COLOR}elf2hex successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}elf2hex already up to date.${ENDC}"
fi
# handle programs that start at 0x80000000.
source "$WALLY"/bin/installation/elf2hex-install.sh
# QEMU (https://www.qemu.org/docs/master/system/target-riscv.html)
# QEMU is an open source machine emulator and virtualizer capable of emulating RISC-V
section_header "Installing/Updating QEMU"
STATUS="qemu"
cd "$RISCV"
if git_check "qemu" "https://github.com/qemu/qemu" "$RISCV/include/qemu-plugin.h"; then
cd "$RISCV"/qemu
git reset --hard && git clean -f && git checkout master && git pull
./configure --target-list=riscv64-softmmu --prefix="$RISCV"
make -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
make install 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" ]; then
cd "$RISCV"
rm -rf qemu
fi
echo -e "${SUCCESS_COLOR}QEMU successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}QEMU already up to date.${ENDC}"
fi
source "$WALLY"/bin/installation/qemu-install.sh
# Spike (https://github.com/riscv-software-src/riscv-isa-sim)
# Spike is a reference model for RISC-V. It is a functional simulator that can be used to run RISC-V programs.
section_header "Installing/Updating SPIKE"
STATUS="spike"
cd "$RISCV"
if git_check "riscv-isa-sim" "https://github.com/riscv-software-src/riscv-isa-sim" "$RISCV/lib/pkgconfig/riscv-riscv.pc"; then
cd "$RISCV"/riscv-isa-sim
git reset --hard && git clean -f && git checkout master && git pull
mkdir -p build
cd build
../configure --prefix="$RISCV"
make -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
make install 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" ]; then
cd "$RISCV"
rm -rf riscv-isa-sim
fi
echo -e "${SUCCESS_COLOR}Spike successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}Spike already up to date.${ENDC}"
fi
source "$WALLY"/bin/installation/spike-install.sh
# RISC-V Sail Model (https://github.com/riscv/sail-riscv)
# The RISC-V Sail Model is the golden reference model for RISC-V. It is written in Sail.
# Sail is a formal specification language designed for describing the semantics of an ISA.
# It is used to generate the RISC-V Sail Model, which is the golden reference model for RISC-V.
# The Sail Compiler is written in OCaml, which is an object-oriented extension of ML, which in turn
# is a functional programming language suited to formal verification.
source "$WALLY"/bin/installation/sail-install.sh
# Verilator (https://github.com/verilator/verilator)
# Verilator is a fast open-source Verilog simulator that compiles synthesizable Verilog code into C++ code.
# It is used for linting and simulation of Wally.
# Verilator needs to be built from source to get the latest version (Wally needs 5.021 or later).
section_header "Installing/Updating Verilator"
STATUS="verilator"
if [ "$UBUNTU_VERSION" == 20 ] || [ "$DEBIAN_VERSION" == 11 ]; then
# On Ubuntu 20 and Debian 11, the last version of Verilator that build successfully is 5.036.
export VERILATOR_VERSION="5.036"
else
export VERILATOR_VERSION="master"
fi
cd "$RISCV"
if git_check "verilator" "https://github.com/verilator/verilator" "$RISCV/share/pkgconfig/verilator.pc"; then
unset VERILATOR_ROOT
cd "$RISCV"/verilator
git reset --hard && git clean -f && git checkout "$VERILATOR_VERSION" && (git pull || true)
autoconf
./configure --prefix="$RISCV"
make -j "${NUM_THREADS}" 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
make install 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" ]; then
cd "$RISCV"
rm -rf verilator
fi
echo -e "${SUCCESS_COLOR}Verilator successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}Verilator already up to date.${ENDC}"
fi
# Sail Compiler (https://github.com/rems-project/sail)
# Sail is a formal specification language designed for describing the semantics of an ISA.
# It is used to generate the RISC-V Sail Model, which is the golden reference model for RISC-V.
# The Sail Compiler is written in OCaml, which is an object-oriented extension of ML, which in turn
# is a functional programming language suited to formal verification.
section_header "Installing/Updating Sail Compiler"
STATUS="sail_compiler"
cd "$RISCV"
wget -nv --retry-connrefused $retry_on_host_error --output-document=sail.tar.gz https://github.com/rems-project/sail/releases/latest/download/sail.tar.gz
tar xz --directory="$RISCV" --strip-components=1 -f sail.tar.gz
rm -f sail.tar.gz
echo -e "${SUCCESS_COLOR}Sail Compiler successfully installed/updated!${ENDC}"
# RISC-V Sail Model (https://github.com/riscv/sail-riscv)
# The RISC-V Sail Model is the golden reference model for RISC-V. It is written in Sail (described above)
section_header "Installing/Updating RISC-V Sail Model"
STATUS="riscv-sail-model"
if git_check "sail-riscv" "https://github.com/riscv/sail-riscv.git" "$RISCV/bin/riscv_sim_rv32d"; then
cd "$RISCV"/sail-riscv
git reset --hard && git clean -f && git checkout master && git pull
cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX="$RISCV" -GNinja 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
cmake --build build 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
cmake --install build 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
if [ "$clean" ]; then
cd "$RISCV"
rm -rf sail-riscv
fi
echo -e "${SUCCESS_COLOR}RISC-V Sail Model successfully installed/updated!${ENDC}"
else
echo -e "${SUCCESS_COLOR}RISC-V Sail Model already up to date.${ENDC}"
fi
source "$WALLY"/bin/installation/verilator-install.sh
# OSU Skywater 130 cell library (https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12)
# The OSU Skywater 130 cell library is a standard cell library that is used to synthesize Wally.
section_header "Installing/Updating OSU Skywater 130 cell library"
STATUS="osu_skywater_130_cell_library"
mkdir -p "$RISCV"/cad/lib
cd "$RISCV"/cad/lib
if git_check "sky130_osu_sc_t12" "https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12" "$RISCV/cad/lib/sky130_osu_sc_t12" "main"; then
cd "$RISCV"/sky130_osu_sc_t12
git reset --hard && git clean -f && git checkout main && git pull
echo -e "${SUCCESS_COLOR}OSU Skywater library successfully installed!${ENDC}"
else
echo -e "${SUCCESS_COLOR}OSU Skywater library already up to date.${ENDC}"
fi
source "$WALLY"/bin/installation/skywater-lib-install.sh
# Buildroot and Linux testvectors
# Buildroot is used to boot a minimal version of Linux on Wally.
# Testvectors are generated using QEMU.
if [ ! "$no_buidroot" ]; then
section_header "Installing Buildroot and Creating Linux testvectors"
STATUS="buildroot"
if [ -z "$LD_LIBRARY_PATH" ]; then
export LD_LIBRARY_PATH=$RISCV/lib:$RISCV/lib64:$RISCV/riscv64-unknown-elf/lib:$RISCV/lib/x86_64-linux-gnu/
else
export LD_LIBRARY_PATH=$RISCV/lib:$RISCV/lib64:$LD_LIBRARY_PATH:$RISCV/riscv64-unknown-elf/lib:$RISCV/lib/x86_64-linux-gnu/
fi
cd "$dir"/../linux
if [ ! -e "$RISCV"/buildroot ]; then
FORCE_UNSAFE_CONFIGURE=1 make 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ] # FORCE_UNSAFE_CONFIGURE is needed to allow buildroot to compile when run as root
echo -e "${SUCCESS_COLOR}Buildroot successfully installed and Linux testvectors created!${ENDC}"
elif [ ! -e "$RISCV"/linux-testvectors ]; then
echo -e "${OK_COLOR}Buildroot already exists, but Linux testvectors are missing. Generating them now.${ENDC}"
make dumptvs 2>&1 | logger; [ "${PIPESTATUS[0]}" == 0 ]
echo -e "${SUCCESS_COLOR}Linux testvectors successfully generated!${ENDC}"
else
echo -e "${OK_COLOR}Buildroot and Linux testvectors already exist.${ENDC}"
fi
else
if [ "$no_buildroot" = true ]; then
echo -e "${OK_COLOR}Skipping Buildroot and Linux testvectors.${ENDC}"
else
source "$WALLY"/bin/installation/buildroot-install.sh
fi
@ -519,7 +130,7 @@ if [ ! -e "${RISCV}"/site-setup.sh ]; then
wget -nv --retry-connrefused $retry_on_host_error https://raw.githubusercontent.com/openhwgroup/cvw/main/site-setup.sh
wget -nv --retry-connrefused $retry_on_host_error https://raw.githubusercontent.com/openhwgroup/cvw/main/site-setup.csh
echo -e "${SUCCESS_COLOR}Site setup script successfully downloaded!${ENDC}"
echo -e "${WARNING_COLOR}Make sure to edit the environment variables in $RISCV/site-setup.sh (or .csh) to point to your installation of EDA tools and licensce files.${ENDC}"
echo -e "${WARNING_COLOR}Make sure to edit the environment variables in $RISCV/site-setup.sh (or .csh) to point to your installation of EDA tools and license files.${ENDC}"
else
echo -e "${OK_COLOR}Site setup script already exists. Not checking for updates to avoid overwritng modifications."
echo -e "You may need to manually update it if there were changes upstream.${ENDC}"

View file

@ -137,6 +137,7 @@ localparam logic IDIV_ON_FPU = 0;
// Legal number of PMP entries are 0, 16, or 64
localparam PMP_ENTRIES = 32'd0;
localparam PMP_G = 32'b0; // grain of 4 bytes is supported for uncached RV32
// Address space
localparam logic [63:0] RESET_VECTOR = 64'h80000000;

View file

@ -137,6 +137,9 @@ localparam logic IDIV_ON_FPU = 0;
// Legal number of PMP entries are 0, 16, or 64
localparam PMP_ENTRIES = 32'd16;
// grain size should be a full cache line to avoid problems with accesses within a cache line
// that span grain boundaries but are handled without a spill
localparam PMP_G = 32'd0; // 64 bytes for 512-bit cache line
// Address space
localparam logic [63:0] RESET_VECTOR = 64'h80000000;

View file

@ -32,6 +32,7 @@
// Note: Zmmul is a subset of M, so usually only one or the other would be used.
`define ZMMUL_COVERAGE
`define ZICOND_COVERAGE
`define ZIFENCEI_COVERAGE
`define ZCA_COVERAGE
`define ZCB_COVERAGE
`define ZCF_COVERAGE
@ -59,10 +60,12 @@
`define ENDIANU_COVERAGE
`define ENDIANS_COVERAGE
`define ENDIANM_COVERAGE
`define ENDIANZALRSC_COVERAGE
`define ENDIANZAAMO_COVERAGE
`define EXCEPTIONSM_COVERAGE
`define EXCEPTIONSS_COVERAGE
`define EXCEPTIONSU_COVERAGE
// `define EXCEPTIONSV_COVERAGE
//`define EXCEPTIONSV_COVERAGE
`define EXCEPTIONSF_COVERAGE
`define EXCEPTIONSZC_COVERAGE
`define EXCEPTIONSZAAMO_COVERAGE

View file

@ -45,7 +45,9 @@
# PMP Configuration
--override cpu/PMP_registers=16
--override cpu/PMP_undefined=T
--override cpu/PMP_grain=0 # 64-byte grains to match cache line width
--override cpu/PMP_decompose=T # unaligned accesses are decomposed into separate aligned accesses
--override cpu/PMP_undefined=T # access to unimplemented PMP registers cause illegal instruction exception
# PMA Settings
# 'r': read access allowed

View file

@ -137,6 +137,7 @@ localparam logic IDIV_ON_FPU = 0;
// Legal number of PMP entries are 0, 16, or 64
localparam PMP_ENTRIES = 32'd0;
localparam PMP_G = 32'b0; // grain of 4 bytes is supported for uncached RV32
// Address space
localparam logic [63:0] RESET_VECTOR = 64'h80000000;

View file

@ -137,6 +137,7 @@ localparam logic IDIV_ON_FPU = 0;
// Legal number of PMP entries are 0, 16, or 64
localparam PMP_ENTRIES = 32'd0;
localparam PMP_G = 32'b0; // grain of 4 bytes is supported for uncached RV32
// Address space
localparam logic [63:0] RESET_VECTOR = 64'h80000000;

View file

@ -138,6 +138,10 @@ localparam logic IDIV_ON_FPU = 1;
// Legal number of PMP entries are 0, 16, or 64
localparam PMP_ENTRIES = 32'd16;
// grain size should be a full cache line to avoid problems with accesses within a cache line
// that span grain boundaries but are handled without a spill
localparam PMP_G = 32'd0; //e.g. 4 for 64-byte grains (512-bit cache lines)
// Address space
localparam logic [63:0] RESET_VECTOR = 64'h0000000080000000;

View file

@ -17,10 +17,10 @@
`define M_COVERAGE
`define F_COVERAGE
`define D_COVERAGE
//`define VX8_COVERAGE
//`define VX16_COVERAGE
//`define VX32_COVERAGE
//`define VX64_COVERAGE
// `define VX8_COVERAGE
// `define VX16_COVERAGE
// `define VX32_COVERAGE
// `define VX64_COVERAGE
`define ZBA_COVERAGE
`define ZBB_COVERAGE
`define ZBC_COVERAGE
@ -32,6 +32,7 @@
// Note: Zmmul is a subset of M, so usually only one or the other would be used.
`define ZMMUL_COVERAGE
`define ZICOND_COVERAGE
`define ZIFENCEI_COVERAGE
`define ZCA_COVERAGE
`define ZCB_COVERAGE
`define ZCD_COVERAGE
@ -56,10 +57,12 @@
`define ENDIANU_COVERAGE
`define ENDIANS_COVERAGE
`define ENDIANM_COVERAGE
`define ENDIANZALRSC_COVERAGE
`define ENDIANZAAMO_COVERAGE
`define EXCEPTIONSM_COVERAGE
`define EXCEPTIONSS_COVERAGE
`define EXCEPTIONSU_COVERAGE
// `define EXCEPTIONSV_COVERAGE
//`define EXCEPTIONSV_COVERAGE
`define EXCEPTIONSF_COVERAGE
`define EXCEPTIONSZC_COVERAGE
`define EXCEPTIONSVM_COVERAGE

View file

@ -48,7 +48,9 @@
# PMP Configuration
--override cpu/PMP_registers=16
--override cpu/PMP_undefined=T
--override cpu/PMP_grain=0 # 64-byte grains to match cache line width
--override cpu/PMP_decompose=T # unaligned accesses are decomposed into separate aligned accesses
--override cpu/PMP_undefined=T # access to unimplemented PMP registers cause illegal instruction exception
# PMA Settings
# 'r': read access allowed

View file

@ -137,6 +137,7 @@ localparam logic IDIV_ON_FPU = 0;
// Legal number of PMP entries are 0, 16, or 64
localparam PMP_ENTRIES = 32'd0;
localparam PMP_G = 32'b0; // grain of 8 bytes is supported for uncached RV64
// Address space
localparam logic [63:0] RESET_VECTOR = 64'h0000000080000000;

View file

@ -48,6 +48,7 @@ localparam cvw_t P = '{
IDIV_BITSPERCYCLE : IDIV_BITSPERCYCLE,
IDIV_ON_FPU : IDIV_ON_FPU,
PMP_ENTRIES : PMP_ENTRIES,
PMP_G : PMP_G,
RESET_VECTOR : RESET_VECTOR,
WFI_TIMEOUT_BIT : WFI_TIMEOUT_BIT,
DTIM_SUPPORTED : DTIM_SUPPORTED,

View file

@ -7,13 +7,15 @@ CORE-V Wally is functionally tested in the following ways. Each test is run in
| Verilator Lint | 5.3 | All configs | rv64gc | lint-wally | PASS | regression-wally --nightly |
| Instructions | 3.7 | All configs | rv64gc | riscv-arch-test | PASS | regression-wally --nightly |
| Privileged | 3.7 | All configs | rv64gc | wally-riscv-arch-test | PASS | regression-wally --nightly |
| Floating-point | 5.11.7, 16.5.3 | rv{32/64}gc + derived | rv64gc | TestFloat | FAIL | regression-wally --nightly |
| CoreMark | 21.1 | Many configs | rv64gc | CoreMark | | regression-wally --nightly |
| Embench | 21.2 | rv32* | n/a | Embench | | regression-wally --nightly |
| Cache PV | 21.3.1 | rv{32/64}gc | rv64gc | TBD | TBD | TBD |
| Cache PV | 21.3.2 | rv{32/64}gc | rv64gc | TBD | TBD | TBD |
| Linux Boot | 22.3.2 | rv64gc | rv64gc | TBD | TBD | TBD |
| FPGA Linux Boot | 23.2 | | rv64gc | TBD | TBD | TBD |
| Code Coverage | 5.11.10 | | rv64gc | TBD | TBD | TBD |
| Functional Coverage | 5.11.11 | | rv64gc | TBD | TBD | TBD |
| Floating-point | 5.11.7, 16.5.3 | rv{32/64}gc + derived | rv64gc | TestFloat | PASS | regression-wally --nightly |
| CoreMark | 21.1 | Many configs | rv64gc | CoreMark | PASS | regression-wally --nightly |
| Embench | 21.2 | rv32* | n/a | Embench | PASS | regression-wally --nightly |
| Cache PV | 21.3.1 | rv{32/64}gc | rv64gc | CacheSim | TBD | TBD |
| Branch PV | 21.3.2 | rv{32/64}gc | rv64gc | BP simulator | TBD | TBD |
| Linux Boot | 22.3.2 | rv64gc | rv64gc | buildroot | PASS | regression-wally --nightly |
| FPGA Linux Boot | 23.2 | | rv64gc | Lab test | PASS | TBD |
| Code Coverage | 5.11.10 | | rv64gc | multiple tests | TBD | regression-wally --nightly |
| Functional Coverage | 5.11.11 | | rv64gc | cvw-arch-verif | TBD | regression-wally --nightly |
Functional Verification plans are in
https://drive.google.com/drive/folders/11hTR2Yl48kOMODxhwrSsC-eXYtM_rJJE?usp=sharing

11
errata.md Normal file
View file

@ -0,0 +1,11 @@
# Textbook Errata
This document contains errata for [RISC-V System-on-Chip Design](https://www.amazon.com/RISC-V-Microprocessor-System-Chip-Design/dp/0323994989) published by Elsevier.
Please contribute by making a pull request to modify this document on GitHub. Sort the errata by page number. Keep the correction as succinct as possible.
Sample Errata
| Page | Location | Error | Correction | Contributor |
| ---- | -------- | ----- | ----------- | ----------- |
| 42 | Fig 1.42 | foobar | FooBar | Ben Bitdiddle, Claremont, CA |

View file

@ -0,0 +1,77 @@
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
# set up PMP so all of memory is accessible and we don't trap when entering supervisor mode
# Define region 0 to cover all addresses as RWX
nop
csrw pmpcfg0, 0xF # configure PMP0 to TOR RWX
li t0, 0xFFFFFFFF
csrw pmpaddr0, t0 # configure PMP0 top of range to 0xFFFFFFFF to allow all 32-bit addresses
# switch to supervisor mode
# Set mstatus.MPP to 01, set MPEC to a trampoline address where supervisor should begin, do mret
la t0, supervisorstart
csrw mepc, t0 # set address for supervisor code to starting
li t0, 1
slli t1, t0, 11 # 1 in bit 11
csrs mstatus, t1
slli t1, t0, 12 # 1 in bit 12
csrc mstatus, t1 # change mstatus.MPP to 01 (for supervisor mode)
mret # enter supervisor mode at supervisorstart
nop
supervisorstart:
la t0, pagetable # get address of root page table
srli t0, t0, 12 # extract PPN of root page table
li t1, 1
slli t1, t1, 31 # 1 in bit 31
or t0, t0, t1 # satp value to enable SV32 with root page table
csrw satp, t0 # enable virtual memory
# now we are execuiting on virtual page 0x80000, which is also physical page 0x80000
li t0, 0x90000300
li t1, 42
sw t1, 0(t0)
la t0, testcode # address of a routine to run
lui t1, 0x10000
add t0, t0, t1 # address of testcode on virtual page 0x90000
jr t0 # jump to the testcode on Virtual page 0x90000,
# which still points to same code on physical page 0x80000
nop # shouldn't be executed
testcode:
li t0, 42 # do something
write_tohost:
la s1, tohost # terminate with write tohost
li t0, 1 # 1 for success, 3 for failure
sw t0, 0(s1) # send success code
sw zero, 4(s1) # not obvious why Sail isn't terminating unless this write is done
self_loop:
j self_loop
tohost:
.word 0
.data
.align 16
# root (L1) Page table situated at 0x80010000
pagetable:
.space 2048 # skip over addresses below 0x80000000
.4byte 0x20004401 # VPN1 = 512 (VA = 0x80000000) points to L0 page table at 80011000
.space 252 # skip over addresses below 0x90000000
.4byte 0x20004401 # VPN 576 (VA = 0x90000000) points to L0 page table at 0x80011000
.align 12
# L0 page table situated at 0x80011000
.4byte 0x200000CF # VPN 0 points to physical kilopage at 0x80000000 with Dirty, Access, XWR, Valid

View file

@ -0,0 +1,17 @@
TARGET = 11p6
$(TARGET).elf.objdump: $(TARGET).elf
riscv64-unknown-elf-objdump -D $(TARGET).elf > $(TARGET).elf.objdump
$(TARGET).elf: $(TARGET).S Makefile
riscv64-unknown-elf-gcc -g -o $(TARGET) -march=rv32i_zicsr -mabi=ilp32 -mcmodel=medany \
-nostartfiles -T../../link/link.ld $(TARGET).S -o $(TARGET).elf
# simulate in ImperasDV lockstep
sim: $(TARGET).elf.objdump
wsim rv32gc $(TARGET).elf --lockstepverbose
clean:
rm -f $(TARGET).elf*

View file

@ -0,0 +1,9 @@
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
li t0, 32 # 1 in bit 5
csrs mstatush, t0 # set bit 5 (mstatush.MBE)
self_loop:
j self_loop

View file

@ -0,0 +1,17 @@
TARGET = 8p3
$(TARGET).elf.objdump: $(TARGET).elf
riscv64-unknown-elf-objdump -D $(TARGET).elf > $(TARGET).elf.objdump
$(TARGET).elf: $(TARGET).S Makefile
riscv64-unknown-elf-gcc -g -o $(TARGET) -march=rv32i_zicsr -mabi=ilp32 -mcmodel=medany \
-nostartfiles -T../../link/link.ld $(TARGET).S -o $(TARGET).elf
# simulate in ImperasDV lockstep
sim: $(TARGET).elf.objdump
wsim rv32gc $(TARGET).elf --lockstepverbose
clean:
rm -f $(TARGET).elf*

View file

@ -0,0 +1,20 @@
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
csrr a0, cycle # read cycle register before computation
# add up numbers from 1 to 10. Place result in s0
li s0, 0 # initialize sum to 0 in s0
li s1, 1 # initialize loop variable i to 1 in s1
li t0, 10 # temporary for maximum number
loop:
add s0, s0, s1 # sum = sum + i
addi s1, s1, 1 # i = i + 1
ble s1, t0, loop # repeat while i <= 10
csrr a1, cycle # read cycle register after computation
sub a0, a1, a0 # compute difference in a0
self_loop:
j self_loop

View file

@ -0,0 +1,17 @@
TARGET = 8p4
$(TARGET).elf.objdump: $(TARGET).elf
riscv64-unknown-elf-objdump -D $(TARGET).elf > $(TARGET).elf.objdump
$(TARGET).elf: $(TARGET).S Makefile
riscv64-unknown-elf-gcc -g -o $(TARGET) -march=rv32i_zicsr -mabi=ilp32 -mcmodel=medany \
-nostartfiles -T../../link/link.ld $(TARGET).S -o $(TARGET).elf
# simulate in ImperasDV lockstep
sim: $(TARGET).elf.objdump
wsim rv32gc $(TARGET).elf --lockstepverbose
clean:
rm -f $(TARGET).elf*

View file

@ -0,0 +1,29 @@
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
# set up trap trap_handler
la t0, trap_handler # address of trap trap_handler
csrw mtvec, t0 # mtvec = pointer to trap handler
la t0, trapstack # address of trap stack
csrw mscratch, t0 # mscratch = pointer to trap stack
lw t0, 1(zero) # cause access or misaligned load fault to invoke trap handler
self_loop:
j self_loop
trap_handler:
csrrw tp, mscratch, tp # swap tp and mscratch to put a trap stack pointer in tp
sw t0, 0(tp) # save t0 on trap stack
csrr t0, mepc # read mepc
addi t0, t0, 4 # mepc + 4
csrw mepc, t0 # mepc = mpec + 4 (return to next instruction)
lw t0, 0(tp) # restore t0 from trap stack
csrrw tp, mscratch, tp # restore tp and trap stack pointer
mret
trapstack:
.word 0 # room to save a register

View file

@ -0,0 +1,17 @@
TARGET = 8p5
$(TARGET).elf.objdump: $(TARGET).elf
riscv64-unknown-elf-objdump -D $(TARGET).elf > $(TARGET).elf.objdump
$(TARGET).elf: $(TARGET).S Makefile
riscv64-unknown-elf-gcc -g -o $(TARGET) -march=rv32i_zicsr -mabi=ilp32 -mcmodel=medany \
-nostartfiles -T../../link/link.ld $(TARGET).S -o $(TARGET).elf
# simulate in ImperasDV lockstep
sim: $(TARGET).elf.objdump
wsim rv32gc $(TARGET).elf --lockstepverbose
clean:
rm -f $(TARGET).elf*

View file

@ -0,0 +1,164 @@
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
# set up trap trap_handler
la t0, trap_handler # address of trap trap_handler
csrw mtvec, t0 # mtvec = pointer to trap handler
la t0, trapstack # address of trap stack
csrw mscratch, t0 # mscratch = pointer to trap stack
li t0, 7
li t1, 9
mul t2, t0, t1 # try 7 * 9. It will trap and invoke trap handler
self_loop:
j self_loop
trap_handler:
csrrw tp, mscratch, tp # swap tp and mscratch to put a trap stack pointer in tp
# save all registers on trap stack. We will need to index into them to find the arguments to emulate multiply
sw x0, 0(tp) # x0 is 0, but we might want to use it
sw x1, 4(tp)
sw x2, 8(tp)
sw x3, 12(tp)
sw x4, 16(tp)
sw x5, 20(tp)
sw x6, 24(tp)
sw x7, 28(tp)
sw x8, 32(tp)
sw x9, 36(tp)
sw x10, 40(tp)
sw x11, 44(tp)
sw x12, 48(tp)
sw x13, 52(tp)
sw x14, 56(tp)
sw x15, 60(tp)
sw x16, 64(tp)
sw x17, 68(tp)
sw x18, 72(tp)
sw x19, 76(tp)
sw x20, 80(tp)
sw x21, 84(tp)
sw x22, 88(tp)
sw x23, 92(tp)
sw x24, 96(tp)
sw x25, 100(tp)
sw x26, 104(tp)
sw x27, 108(tp)
sw x28, 112(tp)
sw x29, 116(tp)
sw x30, 120(tp)
sw x31, 124(tp)
csrr t0, mcause # check cause of trap
li t1, 2 # cause 2 is illegal instruction
bne t0, t1, exit # exit for any other trap than illegal instruction
# check if instruction is mul (op = 0110011, funct3 = 000, funct7 = 0000001)
csrr t0, mtval # fetch instruction that caused trap
andi t1, t0, 127 # get op field (instr[6:0])
xori t1, t1, 0b0110011 # set to 0 if op is 0110011
srli t2, t0, 12 # get funct3 field (instr[14:12])
andi t2, t2, 7 # mask off other bits. Should be 0 if funct3 = 000
srli t3, t0, 25 # get funct7 field (instr[31:25]). No need to mask
xori t3, t3, 0b0000001 # set to 0 if funct7 = 0000001
or t1, t1, t2 # nonzero if op or funct3 mismatch
or t1, t1, t3 # nonzero if instruction is not mul
bnez t1, exit # exit for any other instruction than mul
# emulate mul: fetch arguments
srli t1, t0, 15 # extract rs1 from instr[19:15]
andi t1, t1, 31 # mask off other bits
slli t1, t1, 2 # multiply rs1 by 4 to make it a word index
add t1, tp, t1 # find location of rs1 on trap stack
lw t1, 0(t1) # read value of rs1
srli t2, t0, 20 # extract rs2 from instr[24:20]
andi t2, t2, 31 # mask off other bits
slli t2, t2, 2 # multiply rs2 by 4 to make it a word index
add t2, tp, t2 # find location of rs2 on trap stack
lw t2, 0(t2) # read value of rs2
# emulate mul p = x * y: shift and add
# x in t1, y in t2, p in t3
// p = 0
// while (y != 0)) { # iterate until all bits of y are consumed
// if (y%2) p = p + x # add x to running total
// y = y >> 1 # go on to next bit
// x = x << 1 # shift x to double
// }
li t3, 0 # p = 0
mulloop:
beqz t2, muldone # done if y == 0
andi t4, t2, 1 # t4 = y % 2
beqz t4, skipadd # don't increment p if y%2 == 0
add t3, t3, t1 # otherwise p = p + x
skipadd:
srli t2, t2, 1 # y = y >> 1
slli t1, t1, 1 # x = x << 1
j mulloop # repeat until done
muldone:
# find rd and put result there
srli t1, t0, 7 # extract rd from instr[11:7]
andi t1, t1, 31 # mask off other bits
slli t1, t1, 2 # multiply rd by 4 to make it a word index
add t1, tp, t1 # find location of rd on trap stack
sw t3, 0(t1) # store result into rd storage on trap stack
# return to next instruction
csrr t0, mepc # read mepc
addi t0, t0, 4 # mepc + 4
csrw mepc, t0 # mepc = mpec + 4 (return to next instruction)
# restore all of the registers from the trap stack (rd could be in any one)
lw x1, 4(tp)
lw x2, 8(tp)
lw x3, 12(tp)
lw x4, 16(tp)
lw x5, 20(tp)
lw x6, 24(tp)
lw x7, 28(tp)
lw x8, 32(tp)
lw x9, 36(tp)
lw x10, 40(tp)
lw x11, 44(tp)
lw x12, 48(tp)
lw x13, 52(tp)
lw x14, 56(tp)
lw x15, 60(tp)
lw x16, 64(tp)
lw x17, 68(tp)
lw x18, 72(tp)
lw x19, 76(tp)
lw x20, 80(tp)
lw x21, 84(tp)
lw x22, 88(tp)
lw x23, 92(tp)
lw x24, 96(tp)
lw x25, 100(tp)
lw x26, 104(tp)
lw x27, 108(tp)
lw x28, 112(tp)
lw x29, 116(tp)
lw x30, 120(tp)
lw x31, 124(tp)
csrrw tp, mscratch, tp # restore tp and trap stack pointer
mret
exit:
la t1, tohost
li t0, 3 # 1 for success, 3 for failure
sw t0, 0(t1) # send fail code
j self_loop # wait
.section .tohost
tohost: # write to HTIF
.dword 0
trapstack:
.fill 32, 4 # room to save registers

View file

@ -0,0 +1,17 @@
TARGET = 8p6
$(TARGET).elf.objdump: $(TARGET).elf
riscv64-unknown-elf-objdump -D $(TARGET).elf > $(TARGET).elf.objdump
$(TARGET).elf: $(TARGET).S Makefile
riscv64-unknown-elf-gcc -g -o $(TARGET) -march=rv32im_zicsr -mabi=ilp32 -mcmodel=medany \
-nostartfiles -T../../link/link.ld $(TARGET).S -o $(TARGET).elf
# simulate with Spike
sim: $(TARGET).elf.objdump
spike --isa=rv32i_zicsr -d $(TARGET).elf
clean:
rm -f $(TARGET).elf*

View file

@ -0,0 +1,134 @@
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
# set up trap trap_handler
la t0, trap_handler # address of trap trap_handler
csrw mtvec, t0 # mtvec = pointer to trap handler
la t0, trapstack # address of trap stack
csrw mscratch, t0 # mscratch = pointer to trap stack
la t0, destination # get address to make a load
lw t0, 3(t0) # misaligned load will invoke trap handler
# should return 0x23456789 in t0
self_loop:
j self_loop
trap_handler:
csrrw tp, mscratch, tp # swap tp and mscratch to put a trap stack pointer in tp
# save all registers on trap stack. We will need to index into them to find the arguments to emulate multiply
sw x0, 0(tp) # x0 is 0, but we might want to use it
sw x1, 4(tp)
sw x2, 8(tp)
sw x3, 12(tp)
sw x4, 16(tp)
sw x5, 20(tp)
sw x6, 24(tp)
sw x7, 28(tp)
sw x8, 32(tp)
sw x9, 36(tp)
sw x10, 40(tp)
sw x11, 44(tp)
sw x12, 48(tp)
sw x13, 52(tp)
sw x14, 56(tp)
sw x15, 60(tp)
sw x16, 64(tp)
sw x17, 68(tp)
sw x18, 72(tp)
sw x19, 76(tp)
sw x20, 80(tp)
sw x21, 84(tp)
sw x22, 88(tp)
sw x23, 92(tp)
sw x24, 96(tp)
sw x25, 100(tp)
sw x26, 104(tp)
sw x27, 108(tp)
sw x28, 112(tp)
sw x29, 116(tp)
sw x30, 120(tp)
sw x31, 124(tp)
csrr t0, mcause # check cause of trap
li t1, 4 # cause 4 is misaligned load
bne t0, t1, trap_return # return for any other cause
# check if instruction is lw (op=0000011, funct3 = 010)
csrr t0, mepc # address of faulting instruction
lw t3, 0(t0) # fetch the instruction. It must have been a load.
srli t1, t3, 12 # get funct3 field (instr[14:12])
andi t1, t1, 7 # mask off other bits.
xori t1, t1, 0b010 # should produce 0 if funct3 = 010
bnez t1, trap_return # return if any other kind of load
# emulate lw by performing four byte loads
csrr t0, mtval # address of load instruction
lbu t1, 0(t0) # read zeroth byte
lbu t2, 1(t0) # read the first byte
slli t2, t2, 8 # shift into position
or t1, t1, t2 # merge with zeroth byte
lbu t2, 2(t0) # read the second byte
slli t2, t2, 16 # shift into position
or t1, t1, t2 # merge with previous two bytes
lbu t2, 3(t0) # read the third byte
slli t2, t2, 24 # shift into position
or t2, t1, t2 # merge with previous three bytes
# find rd and put result there
srli t1, t3, 7 # extract rd from instr[11:7]
andi t1, t1, 31 # mask off other bits
slli t1, t1, 2 # multiply rd by 4 to make it a word index
add t1, tp, t1 # find location of rd on trap stack
sw t2, 0(t1) # store result into rd storage on trap stack
# return to next instruction
trap_return:
csrr t0, mepc # read mepc
addi t0, t0, 4 # mepc + 4
csrw mepc, t0 # mepc = mpec + 4 (return to next instruction)
# restore all of the registers from the trap stack (rd could be in any one)
lw x1, 4(tp)
lw x2, 8(tp)
lw x3, 12(tp)
lw x4, 16(tp)
lw x5, 20(tp)
lw x6, 24(tp)
lw x7, 28(tp)
lw x8, 32(tp)
lw x9, 36(tp)
lw x10, 40(tp)
lw x11, 44(tp)
lw x12, 48(tp)
lw x13, 52(tp)
lw x14, 56(tp)
lw x15, 60(tp)
lw x16, 64(tp)
lw x17, 68(tp)
lw x18, 72(tp)
lw x19, 76(tp)
lw x20, 80(tp)
lw x21, 84(tp)
lw x22, 88(tp)
lw x23, 92(tp)
lw x24, 96(tp)
lw x25, 100(tp)
lw x26, 104(tp)
lw x27, 108(tp)
lw x28, 112(tp)
lw x29, 116(tp)
lw x30, 120(tp)
lw x31, 124(tp)
csrrw tp, mscratch, tp # restore tp and trap stack pointer
mret
destination:
.dword 0x0123456789ABCDEF # fill destination with some stuff
trapstack:
.fill 32, 4 # room to save registers

View file

@ -0,0 +1,17 @@
TARGET = 8p7
$(TARGET).elf.objdump: $(TARGET).elf
riscv64-unknown-elf-objdump -D $(TARGET).elf > $(TARGET).elf.objdump
$(TARGET).elf: $(TARGET).S Makefile
riscv64-unknown-elf-gcc -g -o $(TARGET) -march=rv32im_zicsr -mabi=ilp32 -mcmodel=medany \
-nostartfiles -T../../link/link.ld $(TARGET).S -o $(TARGET).elf
# simulate with Spike
sim: $(TARGET).elf.objdump
spike --isa=rv32i_zicsr -d $(TARGET).elf
clean:
rm -f $(TARGET).elf*

View file

@ -0,0 +1,56 @@
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
# set up trap trap_handler
la t0, trap_handler # address of trap trap_handler
csrw mtvec, t0 # mtvec = pointer to trap handler
la t0, trapstack # address of trap stack
csrw mscratch, t0 # mscratch = pointer to trap stack
sw zero, 12(t0) # size of buffer
wait:
nop
j wait # wait for uart communication
self_loop:
j self_loop
trap_handler:
csrrw tp, mscratch, tp # swap tp and mscratch to put a trap stack pointer in tp
# save some registers on trap stack. ß
sw t0, 0(tp)
sw t1, 4(tp)
sw t2, 8(tp)
lw t0, 12(tp) # get current length of buffer
li t1, 0x10000000 # UART base address
lbu t1, 0(t1) # fetch next character
add t2, tp, t0 # address in buffer
sb t1, 0(t2) # store character in buffer
li t2, 79 # maximum buffer length
beq t0, t2, skip # is buffer full?
addi t0, t0, 1 # increase buffer pointer
skip:
sw t0, 12(tp) # update buffer length
trap_return: # return to next instruction
csrr t0, mepc # read mepc
addi t0, t0, 4 # mepc + 4
csrw mepc, t0 # mepc = mpec + 4 (return to next instruction)
# restore all of the registers from the trap stack (rd could be in any one)
lw t0, 0(tp)
lw t1, 4(tp)
lw t2, 8(tp)
csrrw tp, mscratch, tp # restore tp and trap stack pointer
mret
buffer:
.fill 80, 1 # room for buffer
trapstack:
.fill 34, 4 # room to save registers and buffer length

View file

@ -0,0 +1,17 @@
TARGET = 8p8
$(TARGET).elf.objdump: $(TARGET).elf
riscv64-unknown-elf-objdump -D $(TARGET).elf > $(TARGET).elf.objdump
$(TARGET).elf: $(TARGET).S Makefile
riscv64-unknown-elf-gcc -g -o $(TARGET) -march=rv32im_zicsr -mabi=ilp32 -mcmodel=medany \
-nostartfiles -T../../link/link.ld $(TARGET).S -o $(TARGET).elf
# simulate in Spike
sim: $(TARGET).elf.objdump
spike --isa=rv32i_zicsr -d $(TARGET).elf
clean:
rm -f $(TARGET).elf*

View file

@ -0,0 +1,61 @@
.section .text.init
.globl rvtest_entry_point
# register to write for GPIO output pins
.equ GPIO_OUTPUT_VAL, 0x1006000C
.equ CLINT_MTIMECMP, 0x02004000
.equ PERIOD, 500
# register use:
# s0: address of GPIO_OUTPUT_VAL
# s1: adress of CLINT_MTIME_CMP
# s2: PERIOD
rvtest_entry_point:
# initialize LED to off
li s0, GPIO_OUTPUT_VAL
sw zero, 0(s0) # LEDs off
# configure timer interrupt
li s2, PERIOD
csrr t0, time # read lower 32 bits of timer
csrr t1, timeh # read upper 32 bits of timer
add t0, t0, s2 # increment by PERIOD
li s1, CLINT_MTIMECMP # set timer for next toggle
sw t0, 0(s1) # CLINT_MTIMECMP = time + PERIOD
sw zero, 4(s1) # upper word = 0 (this is only because program is just starting)
# csrci mstatus, 8 # clear mstatus.MIE so interrupts are globally disabled
li t0, 128 # 1 in mie.MTIE
csrw mie, t0 # enable timer interrupts
li s3, 4 # loop counter
/*
# enter user mode
li t0, 0b11 # 3
slli t0, t0, 11 # 11 in bits 12:11
csrc mstatus, t0 # mstatus.MPP = 00 (for user mode)
la t0, user_start #
csrw mepc, t0 # where to go when entering user mode
mret
*/
#user_start: # loop with wfi
wait_loop:
csrr t0, time # check time before timer fires
wfi # wait until timer interrupt fires.
csrr t0, time # check time again after timer fires for debugging
# interrupts are globally disabled, so when the timer fires,
# wfi will advance here rather than going to an interrupt handler
lw t0, 0(s0) # read GPIO_OUTPUT_VAL
xori t0, t0, 1 # toggle least significant bits
sw t0, 0(s0) # update GPIO_OUTPUT_VAL to turn LED off->on or on->off
lw t0, 0(s1) # read CLINT_MTIME_CMP
add t0, t0, s2 # add PERIOD
sw t0, 0(s1) # CLINT_MTIME_CMP = CLINT_MTIME_CMP + PERIOD
addi s3, s3, -1 # decrement loop counter
bnez s3, wait_loop # repeat
self_loop:
j self_loop

View file

@ -0,0 +1,17 @@
TARGET = 8p9
$(TARGET).elf.objdump: $(TARGET).elf
riscv64-unknown-elf-objdump -D $(TARGET).elf > $(TARGET).elf.objdump
$(TARGET).elf: $(TARGET).S Makefile
riscv64-unknown-elf-gcc -g -o $(TARGET) -march=rv32im_zicsr -mabi=ilp32 -mcmodel=medany \
-nostartfiles -T../../link/link.ld $(TARGET).S -o $(TARGET).elf
# simulate in ImperasDV lockstep
sim: $(TARGET).elf.objdump
wsim rv32gc 8p9.elf --lockstepverbose > log
clean:
rm -f $(TARGET).elf*

View file

@ -100,8 +100,10 @@ $(DISASSEMBLY_DIR)/%.objdump: $(IMAGE_DIR)/% | $(DISASSEMBLY_DIR)
$(WALLY)/bin/extractFunctionRadix.sh $@
# Disassemble binaries ending in .elf
# Add -D flag back to disassemble all sections (instead of just code sections)
# once objdump bug is fixed and the pinned version of the toolchain is updated.
$(DISASSEMBLY_DIR)/%.objdump: $(IMAGE_DIR)/%.elf | $(DISASSEMBLY_DIR)
riscv64-unknown-elf-objdump -SD $< >> $@
riscv64-unknown-elf-objdump -S $< >> $@
$(WALLY)/bin/extractFunctionRadix.sh $@
# Load wally buildroot configuration

View file

@ -14,5 +14,5 @@ proc GetLineNum {fname target} {
}
close $f
return -code error \
"target string not found"
[append "target string not found " $target " not found by GetLineNum.do for coverage exclusion in " $fname]
}

View file

@ -347,11 +347,6 @@ coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLi
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboz"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboaccess"]
# IMMU PMP only makes 4-byte accesses
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "SizeBytesMinus1 = 3'd0"] -item bs 1
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "SizeBytesMinus1 = 3'd1"] -item bs 1
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "SizeBytesMinus1 = 3'd7"] -item bs 1
# No irom
set line [GetLineNum ${SRC}/ifu/ifu.sv "~ITLBMissF & ~CacheableF & ~SelIROM"]
coverage exclude -scope /dut/core/ifu -linerange $line-$line -item c 1 -feccondrow 6

View file

@ -1,20 +1,31 @@
#!/bin/csh
# site-setup.csh
# System Admin should install this into $RISCV/site-setup.csh
# It is automatically placed in the $RISCV directory by wally-toolchain-install.sh
# $RISCV is typically /opt/riscv or ~/riscv
# System Admin must update the licenses and paths for localization.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
# License servers and commercial CAD tool paths
# Must edit these based on your local environment. Ask your sysadmin.
setenv MGLS_LICENSE_FILE 27002@zircon.eng.hmc.edu # Change this to your Siemens license server
setenv SNPSLMD_LICENSE_FILE 27020@zircon.eng.hmc.edu # Change this to your Synopsys license server
setenv QUESTAPATH /cad/mentor/questa_sim-2022.4_2/questasim/bin # Change this for your path to Questa
setenv SNPSPATH /cad/synopsys/SYN/bin # Change this for your path to Design Compiler
setenv VCSPATH /cad/synopsys/vcs/U-2023.03-SP2-4/bin # Change this for your path to Synopsys VCS
setenv QUESTAPATH /cad/mentor/QUESTA/bin # Change this for your path to Questa
setenv DCPATH /cad/synopsys/SYN/bin # Change this for your path to Design Compiler
setenv VCSPATH /cad/synopsys/VCS/bin # Change this for your path to Synopsys VCS
setenv BREKER_HOME /cad/breker/TREK # Change this for your path to Breker Trek
setenv SPYGLASS_HOME /cad/synopsys/SPYGLASS_HOME # Change this for your path to Synopsys Spyglass
# Tools
# Questa and Synopsys
extend PATH $QUESTAPATH
extend PATH $SNPSPATH
extend PATH $DCPATH
extend PATH $VCSPATH
extend PATH $SPYGLASS_HOME/bin
# Synopsys Spyglass
setenv SNPSLMD_QUEUE 1
# GCC
if ( ! $?LD_LIBRARY_PATH ) then
@ -58,6 +69,8 @@ if ($?IDV) then
endif
# Use newer gcc version for older distros
if ( -e $RISCV/gcc-10 ) then
prepend PATH \$RISCV/gcc-10/bin # Ubuntu 20.04 LTS
if ( -e $RISCV/gcc-13 ) then
prepend PATH $RISCV/gcc-13/bin # SUSE Family
elseif ( -e $RISCV/gcc-10 ) then
prepend PATH $RISCV/gcc-10/bin # Ubuntu 20.04 LTS
endif

View file

@ -23,10 +23,13 @@ export QUESTA_HOME=/cad/mentor/QUESTA # Change thi
export DC_HOME=/cad/synopsys/SYN # Change this for your path to Synopsys DC, excluding bin
export VCS_HOME=/cad/synopsys/VCS # Change this for your path to Synopsys VCS, excluding bin
export BREKER_HOME=/cad/breker/TREK # Change this for your path to Breker Trek
export SPYGLASS_HOME=/cad/synopsys/SPYGLASS_HOME # Change this for your path to Synopsys Spyglass
# Tools
# Questa and Synopsys
export PATH=$QUESTA_HOME/bin:$DC_HOME/bin:$VCS_HOME/bin:$PATH
export PATH=$QUESTA_HOME/bin:$DC_HOME/bin:$VCS_HOME/bin:$SPYGLASS_HOME/bin:$PATH
# Synopsys Spyglass
export SNPSLMD_QUEUE=1
# Environmental variables for SoC
export SYN_pdk=/proj/models/tsmc28/libraries/28nmtsmc/tcbn28hpcplusbwp30p140_190a/
@ -39,12 +42,7 @@ export SYN_memory=/home/jstine/WallyMem/rv64gc/
#export osumemory=/import/yukari1/pdk/TSMC/WallyMem/rv64gc/
# GCC
if [ -z "$LD_LIBRARY_PATH" ]; then
export LD_LIBRARY_PATH=$RISCV/riscv64-unknown-elf/lib
else
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RISCV/riscv64-unknown-elf/lib
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}$RISCV/riscv64-unknown-elf/lib
# RISC-V Tools
export LD_LIBRARY_PATH=$RISCV/lib:$RISCV/lib64:$LD_LIBRARY_PATH:$RISCV/lib/x86_64-linux-gnu/
export PATH=$PATH:$RISCV/bin

View file

@ -95,6 +95,7 @@ typedef struct packed {
// Legal number of PMP entries are 0, 16, or 64
int PMP_ENTRIES;
int PMP_G; // grain
// Address space
logic [63:0] RESET_VECTOR;

View file

@ -40,31 +40,22 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
input logic PAgePMPAdrIn,
output logic PAgePMPAdrOut,
output logic Match,
output logic [P.PA_BITS-1:0] PMPTop,
output logic L, X, W, R
);
// define PMP addressing mode codes
localparam TOR = 2'b01;
localparam NA4 = 2'b10;
localparam NAPOT = 2'b11;
logic TORMatch, NAMatch;
logic PAltPMPAdr;
logic [P.PA_BITS-1:0] CurrentAdrFull;
logic [1:0] AdrMode;
logic [P.PA_BITS-1:0] PMPTop1, PMPTopTOR, PMPTopNaturallyAligned;
assign AdrMode = PMPCfg[4:3];
// The two lsb of the physical address don't matter for this checking.
// The following code includes them, but hardwires the PMP checker lsbs to 00
// and masks them later. Logic synthesis should optimize away these bottom bits.
// Top-of-range (TOR)
// Append two implicit trailing 0's to PMPAdr value
assign CurrentAdrFull = {PMPAdr, 2'b00};
assign PAltPMPAdr = {1'b0, PhysicalAddress} < {1'b0, CurrentAdrFull}; // unsigned comparison
assign PAltPMPAdr = {1'b0, PhysicalAddress} < {1'b0, PMPAdr, 2'b00}; // unsigned comparison
assign PAgePMPAdrOut = ~PAltPMPAdr;
assign TORMatch = PAgePMPAdrIn & PAltPMPAdr; // exclusion-tag: PAgePMPAdrIn
@ -80,15 +71,8 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
// finally pick the appropriate match for the access type
assign Match = (AdrMode == TOR) ? TORMatch :
(AdrMode == NA4 | AdrMode == NAPOT) ? NAMatch :
1'b0;
// Report top of region for first matching region
// PMP should match but fail if the size is too big (8-byte accesses spanning to TOR or NA4 region)
assign PMPTopTOR = {PMPAdr-1, 2'b11}; // TOR goes to (pmpaddr << 2) - 1
assign PMPTopNaturallyAligned = {PMPAdr,2'b00} | NAMask; // top of the pmp region for NA4 and NAPOT. All 1s in the lower bits. Used to check the address doesn't pass the top
assign PMPTop1 = (AdrMode == TOR) ? PMPTopTOR : PMPTopNaturallyAligned;
assign PMPTop = FirstMatch ? PMPTop1 : '0; // AND portion of distributed AND-OR mux (OR portion in pmpchhecker)
(AdrMode[1]) ? NAMatch : // NA4 or NAPOT
1'b0; // OFF never matches
assign L = PMPCfg[7];
assign X = PMPCfg[2];

View file

@ -41,7 +41,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
// keyword, the compiler warns us that it's interpreting the signal as a var,
// which we might not intend.
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0],
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0],
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0],
input logic ExecuteAccessF, WriteAccessM, ReadAccessM,
input logic [1:0] Size,
input logic [3:0] CMOpM,
@ -56,12 +56,10 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
logic [P.PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address.
logic [P.PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set
logic [P.PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
logic [P.PA_BITS-1:0] PMPTop[P.PMP_ENTRIES-1:0]; // Upper end of each region, for checking that the access is fully within the region
logic PMPCMOAccessFault, PMPCBOMAccessFault, PMPCBOZAccessFault;
logic [2:0] SizeBytesMinus1;
logic MatchingR, MatchingW, MatchingX, MatchingL;
logic [P.PA_BITS-1:0] MatchingPMPTop, PhysicalAddressTop;
logic TooBig;
if (P.PMP_ENTRIES > 0) begin: pmp // prevent complaints about array of no elements when PMP_ENTRIES = 0
pmpadrdec #(P) pmpadrdecs[P.PMP_ENTRIES-1:0](
@ -72,31 +70,16 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
.FirstMatch,
.PAgePMPAdrIn({PAgePMPAdr[P.PMP_ENTRIES-2:0], 1'b1}),
.PAgePMPAdrOut(PAgePMPAdr),
.Match, .PMPTop, .L, .X, .W, .R);
.Match, .L, .X, .W, .R);
end
priorityonehot #(P.PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the address decoders to find the first one that matches.
// Distributed AND-OR mux to select the first matching results
// If the access does not match all bytes of the PMP region, it is too big and the matches are disabled
assign MatchingR = |(R & FirstMatch) & ~TooBig;
assign MatchingW = |(W & FirstMatch) & ~TooBig;
assign MatchingX = |(X & FirstMatch) & ~TooBig;
assign MatchingR = |(R & FirstMatch);
assign MatchingW = |(W & FirstMatch);
assign MatchingX = |(X & FirstMatch);
assign MatchingL = |(L & FirstMatch);
or_rows #(P.PMP_ENTRIES, P.PA_BITS) PTEOr(PMPTop, MatchingPMPTop);
// Matching PMP entry must match all bytes of an access, or the access fails (Priv Spec 3.7.1.3)
// First find the size of the access in terms of the offset to the most significant byte
always_comb
case (Size)
2'b00: SizeBytesMinus1 = 3'd0;
2'b01: SizeBytesMinus1 = 3'd1;
2'b10: SizeBytesMinus1 = 3'd3;
2'b11: SizeBytesMinus1 = 3'd7;
endcase
// Then find the top of the access and see if it is beyond the top of the region
assign PhysicalAddressTop = PhysicalAddress + {{P.PA_BITS-3{1'b0}}, SizeBytesMinus1}; // top of the access range
assign TooBig = PhysicalAddressTop > MatchingPMPTop; // check if the access goes beyond the top of the PMP region
// Only enforce PMP checking for effective S and U modes (accounting for mstatus.MPRV) or in Machine mode when L bit is set in selected region
assign EnforcePMP = (EffectivePrivilegeModeW != P.M_MODE) | MatchingL;

View file

@ -46,14 +46,15 @@ module csrm import cvw::*; #(parameter cvw_t P) (
output logic [15:0] MEDELEG_REGW,
output logic [11:0] MIDELEG_REGW,
/* verilator lint_off UNDRIVEN */ // PMP registers are only used when PMP_ENTRIES > 0
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0],
output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0],
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0],
/* verilator lint_on UNDRIVEN */
output logic WriteMSTATUSM, WriteMSTATUSHM,
output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM,
output logic [63:0] MENVCFG_REGW
);
logic [P.PA_BITS-3:0] PMPADDR_ARRAY_PREGRAIN_REGW[P.PMP_ENTRIES-1:0];
logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW;
logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW;
logic [P.XLEN-1:0] MENVCFGH_REGW;
@ -103,6 +104,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
// when compressed instructions are supported, there can't be misaligned instructions
localparam MEDELEG_MASK = P.ZCA_SUPPORTED ? 16'hB3FE : 16'hB3FF;
localparam MIDELEG_MASK = 12'h222; // we choose to not make machine interrupts delegable
localparam Gm1 = P.PMP_G > 0 ? P.PMP_G - 1 : 0; // max(G-1, 0)
// There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
genvar i;
@ -112,8 +114,9 @@ module csrm import cvw::*; #(parameter cvw_t P) (
logic [7:0] CSRPMPWriteValM[P.PMP_ENTRIES-1:0];
logic [7:0] CSRPMPLegalizedWriteValM[P.PMP_ENTRIES-1:0];
logic [1:0] CSRPMPWRLegalizedWriteValM[P.PMP_ENTRIES-1:0];
logic [1:0] CSRPMPALegalizedWriteValM[P.PMP_ENTRIES-1:0];
logic [P.PMP_ENTRIES-1:0] ADDRLocked, CFGLocked;
for(i=0; i<P.PMP_ENTRIES; i++) begin
for(i=0; i<P.PMP_ENTRIES; i++) begin:pmp
// when the lock bit is set, don't allow writes to the PMPCFG or PMPADDR
// also, when the lock bit of the next entry is set and the next entry is TOR, don't allow writes to this entry PMPADDR
assign CFGLocked[i] = PMPCFG_ARRAY_REGW[i][7];
@ -123,7 +126,8 @@ module csrm import cvw::*; #(parameter cvw_t P) (
assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7] | (PMPCFG_ARRAY_REGW[i+1][7] & PMPCFG_ARRAY_REGW[i+1][4:3] == 2'b01);
assign WritePMPADDRM[i] = (CSRMWriteM & (CSRAdrM == (PMPADDR0+i))) & ~ADDRLocked[i];
flopenr #(P.PA_BITS-2) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM[P.PA_BITS-3:0], PMPADDR_ARRAY_REGW[i]);
// PMPADDR_ARRAY_PREGRAIN_REGW flip-flops hold all the bits even though all but G-1 lsbs can be controlled by PMP mode and granularity
flopenr #(P.PA_BITS-2) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM[P.PA_BITS-3:0], PMPADDR_ARRAY_PREGRAIN_REGW[i]);
if (P.XLEN==64) begin
assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+2*(i/8)))) & ~CFGLocked[i];
assign CSRPMPWriteValM[i] = CSRWriteValM[(i%8)*8+7:(i%8)*8];
@ -132,8 +136,9 @@ module csrm import cvw::*; #(parameter cvw_t P) (
assign CSRPMPWriteValM[i] = CSRWriteValM[(i%4)*8+7:(i%4)*8];
end
assign CSRPMPALegalizedWriteValM[i] = ((P.PMP_G > 0) & (CSRPMPWriteValM[i][4:3] == 2'b10)) ? PMPCFG_ARRAY_REGW[i][4:3] : CSRPMPWriteValM[i][4:3]; // WARL A field keeps its old value when attempting to write unselectable NA4 mode
assign CSRPMPWRLegalizedWriteValM[i] = {(CSRPMPWriteValM[i][1] & CSRPMPWriteValM[i][0]), CSRPMPWriteValM[i][0]}; // legalize WR fields (reserved 10 written as 00)
assign CSRPMPLegalizedWriteValM[i] = {CSRPMPWriteValM[i][7], 2'b00, CSRPMPWriteValM[i][4:2], CSRPMPWRLegalizedWriteValM[i]};
assign CSRPMPLegalizedWriteValM[i] = {CSRPMPWriteValM[i][7], 2'b00, CSRPMPALegalizedWriteValM[i], CSRPMPWriteValM[i][2], CSRPMPWRLegalizedWriteValM[i]};
flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRPMPLegalizedWriteValM[i], PMPCFG_ARRAY_REGW[i]);
end
end
@ -214,6 +219,15 @@ module csrm import cvw::*; #(parameter cvw_t P) (
assign MENVCFGH_REGW = '0;
end
// Grain alignment for PMPADDR read values.
for(i=0; i<P.PMP_ENTRIES; i++)
always_comb begin
logic [P.XLEN-1:0] pmpaddr;
pmpaddr = {{(P.XLEN-(P.PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_PREGRAIN_REGW[i]}; // raw value in PMP registers
if (PMPCFG_ARRAY_REGW[i][4]) PMPADDR_ARRAY_REGW[i] = {pmpaddr[P.PA_BITS-3:Gm1], {Gm1 {1'b1}}}; // in NAPOT/NA4, bottom G-1 bits read as all 1s (but no bits affected for NA4)
else PMPADDR_ARRAY_REGW[i] = {pmpaddr[P.PA_BITS-3:P.PMP_G], {P.PMP_G{1'b0}}}; // in TOR/OFF, bottom G bits read as 0s
end
// Read machine mode CSRs
// verilator lint_off WIDTH
logic [5:0] entry;
@ -221,8 +235,8 @@ module csrm import cvw::*; #(parameter cvw_t P) (
entry = '0;
CSRMReadValM = '0;
IllegalCSRMAccessM = !(P.S_SUPPORTED) & (CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
if ($unsigned(CSRAdrM) >= PMPADDR0 & $unsigned(CSRAdrM) < PMPADDR0 + P.PMP_ENTRIES) // reading a PMP entry
CSRMReadValM = {{(P.XLEN-(P.PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]};
if ($unsigned(CSRAdrM) >= PMPADDR0 & $unsigned(CSRAdrM) < PMPADDR0 + P.PMP_ENTRIES)
CSRMReadValM = {{(P.XLEN-(P.PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]}; // read PMPADDR entry with lsbs aligned to grain based on NAPOT vs. TOR
else if ($unsigned(CSRAdrM) >= PMPCFG0 & $unsigned(CSRAdrM) < PMPCFG0 + P.PMP_ENTRIES/4 & (P.XLEN==32 | CSRAdrM[0] == 0)) begin
// only odd-numbered PMPCFG entries exist in RV64
if (P.XLEN==64) begin

View file

@ -31,7 +31,7 @@
module privdec import cvw::*; #(parameter cvw_t P) (
input logic clk, reset,
input logic StallW, FlushW,
input logic [31:15] InstrM, // privileged instruction function field
input logic [31:7 ] InstrM, // privileged instruction function field
input logic PrivilegedM, // is this a privileged instruction (from IEU controller)
input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction
input logic IllegalCSRAccessM, // Not a legal CSR access
@ -43,26 +43,31 @@ module privdec import cvw::*; #(parameter cvw_t P) (
output logic wfiM, wfiW, sfencevmaM // wfi / sfence.vma / sinval.vma instructions
);
logic rs1zeroM; // rs1 field = 0
logic rs1zeroM, rdzeroM; // rs1 / rd field = 0
logic IllegalPrivilegedInstrM; // privileged instruction isn't a legal one or in legal mode
logic WFITimeoutM; // WFI reaches timeout threshold
logic ebreakM, ecallM; // ebreak / ecall instructions
logic sinvalvmaM; // sinval.vma
logic presfencevmaM; // sfence.vma before checking privilege mode
logic sfencewinvalM, sfenceinvalirM; // sfence.w.inval, sfence.inval.ir
logic invalM; // any of the svinval instructions
logic vmaM; // sfence.vma or sinval.vma
logic fenceinvalM; // sfence.w.inval or sfence.inval.ir
///////////////////////////////////////////
// Decode privileged instructions
///////////////////////////////////////////
assign rs1zeroM = InstrM[19:15] == 5'b0;
assign rdzeroM = InstrM[11:7] == 5'b0;
// svinval instructions
// any svinval instruction is treated as sfence.vma on Wally
assign sinvalvmaM = (InstrM[31:25] == 7'b0001011);
assign sfencewinvalM = (InstrM[31:20] == 12'b000110000000) & rs1zeroM;
assign sfenceinvalirM = (InstrM[31:20] == 12'b000110000001) & rs1zeroM;
assign invalM = P.SVINVAL_SUPPORTED & (sinvalvmaM | sfencewinvalM | sfenceinvalirM);
assign sinvalvmaM = (InstrM[31:25] == 7'b0001011) & rdzeroM;
assign sfencewinvalM = (InstrM[31:20] == 12'b000110000000) & rs1zeroM & rdzeroM;
assign sfenceinvalirM = (InstrM[31:20] == 12'b000110000001) & rs1zeroM & rdzeroM;
assign presfencevmaM = (InstrM[31:25] == 7'b0001001) & rdzeroM;
assign vmaM = presfencevmaM | (sinvalvmaM & P.SVINVAL_SUPPORTED); // sfence.vma or sinval.vma
assign fenceinvalM = (sfencewinvalM | sfenceinvalirM) & P.SVINVAL_SUPPORTED; // sfence.w.inval or sfence.inval.ir
assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & rs1zeroM & P.S_SUPPORTED &
(PrivilegeModeW == P.M_MODE | PrivilegeModeW == P.S_MODE & ~STATUS_TSR);
@ -71,8 +76,11 @@ module privdec import cvw::*; #(parameter cvw_t P) (
assign ecallM = PrivilegedM & (InstrM[31:20] == 12'b000000000000) & rs1zeroM;
assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001) & rs1zeroM;
assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101) & rs1zeroM;
assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001 | invalM) &
(PrivilegeModeW == P.M_MODE | (PrivilegeModeW == P.S_MODE & ~STATUS_TVM)) & P.VIRTMEM_SUPPORTED;
// all of sinval.vma, sfence.w.inval, sfence.inval.ir are treated as sfence.vma
assign sfencevmaM = PrivilegedM & P.VIRTMEM_SUPPORTED &
((PrivilegeModeW == P.M_MODE & (vmaM | fenceinvalM)) |
(PrivilegeModeW == P.S_MODE & (vmaM & ~STATUS_TVM | fenceinvalM))); // sfence.w.inval & sfence.inval.ir not affected by TVM
///////////////////////////////////////////
// WFI timeout Privileged Spec 3.1.6.5

View file

@ -127,7 +127,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
.STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW);
// decode privileged instructions
privdec #(P) pmd(.clk, .reset, .StallW, .FlushW, .InstrM(InstrM[31:15]),
privdec #(P) pmd(.clk, .reset, .StallW, .FlushW, .InstrM(InstrM[31:7]),
.PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM,
.PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM,
.EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .RetM, .wfiM, .wfiW, .sfencevmaM);

162
src/uncore/trickbox_apb.sv Normal file
View file

@ -0,0 +1,162 @@
///////////////////////////////////////////
// trickbox_apb.sv
//
// Written: David_Harris@hmc.edu 20 May 2025
// Modified:
//
// Purpose: Trickbox, superset of CLINT
// https://docs.google.com/document/d/1erHBVchBtwmgZ0bCNjb88spYfN7CpRbhmSNFH6cO8CY/edit?tab=t.0
//
// Documentation: RISC-V System on Chip Design
//
// A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
//
// 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.
////////////////////////////////////////////////////////////////////////////////////////////////
module trickbox_apb import cvw::*; #(parameter XLEN = 64, NUM_HARTS = 1) (
input logic PCLK, PRESETn,
input logic PSEL,
input logic [15:0] PADDR,
input logic [XLEN-1:0] PWDATA,
input logic [XLEN/8-1:0] PSTRB,
input logic PWRITE,
input logic PENABLE,
output logic [XLEN-1:0] PRDATA,
output logic PREADY,
input logic [63:0] MTIME_IN,
input logic [NUM_HARTS-1:0] MTIP_IN, MSIP_IN, SSIP_IN, MEIP_IN, SEIP_IN,
input var logic [XLEN-1:0] HGEIP_IN[NUM_HARTS-1:0],
output logic [63:0] MTIME_OUT,
output logic [NUM_HARTS-1:0] MTIP_OUT, MSIP_OUT, SSIP_OUT, MEIP_OUT, SEIP_OUT,
output var logic [XLEN-1:0] HGEIP_OUT[NUM_HARTS-1:0],
output logic [XLEN-1:0] TOHOST_OUT
);
// register map
localparam CLINT_MSIP = 16'h0000;
localparam CLINT_MTIMECMP = 16'h4000;
localparam CLINT_MTIME = 16'hBFF8;
logic [63:0] MTIMECMP[NUM_HARTS-1:0];
logic [7:0] TRICKEN;
logic [63:0] MTIME;
logic [NUM_HARTS-1:0] MTIP, MSIP, SSIP, MEIP, SEIP;
logic [XLEN-1:0] TOHOST;
logic [XLEN-1:0] HGEIP[NUM_HARTS-1:0];
logic [15:0] entry;
logic [9:0] hart; // which hart is being accessed
logic memwrite;
logic [63:0] RD;
genvar i;
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
assign hart = PADDR[12:3]; // middle bits of address allow control of up to 1024 harts
// read circuitry
// 64-bit accesses, then reduce to 32-bit for RV32
always_ff @(posedge PCLK) begin
case (PADDR[15:13])
3'b000: RD <= {63'b0, MSIP[hart]}; // *** memory map
3'b001: RD <= {63'b0, SSIP[hart]};
3'b010: RD <= MTIMECMP[hart];
3'b011: RD <= {63'b0, MEIP[hart]};
3'b100: RD <= {63'b0, SEIP[hart]};
3'b101: case (hart)
10'b0000000000: RD <= TOHOST;
10'b0000000001: RD <= '0; // Reading COM1 has no effect; busy bit not yet implemented. Later add busy bit
10'b0000000010: RD <= {56'b0, TRICKEN};
10'b1111111111: RD <= MTIME;
default: RD <= '0;
endcase
3'b110: RD <= HGEIP[hart];
default: RD <= '0;
endcase
end
// word aligned reads
if (XLEN == 64) assign PRDATA = RD;
else assign PRDATA = RD[PADDR[2]*32 +: 32]; // 32-bit register access to upper or lower half
// write circuitry
always_ff @(posedge PCLK)
if (~PRESETn) begin
MSIP <= '0;
SSIP <= '0;
MEIP <= '0;
SEIP <= '0;
TOHOST <= '0;
TRICKEN <= '0;
end else if (memwrite) begin
case (PADDR[15:13])
3'b000: MSIP[hart] <= PWDATA[0];
3'b001: SSIP[hart] <= PWDATA[0];
3'b011: MEIP[hart] <= PWDATA[0];
3'b100: SEIP[hart] <= PWDATA[0];
3'b101: case (hart)
10'b0000000000: TOHOST <= PWDATA;
10'b0000000001: $display("%c", PWDATA[7:0]); // COM1 prints to simulation console. Eventually allow it to be redirected to a UART, and provide a busy bit.
10'b0000000010: TRICKEN <= PWDATA[7:0];
endcase
endcase
end
// generate loop write circuits for MTIMECMP and HGEIP
for (i=0; i<NUM_HARTS; i++)
always_ff @(posedge PCLK)
if (~PRESETn) begin
MTIMECMP[i] <= 64'hFFFFFFFFFFFFFFFF; // Spec says MTIMECMP is not reset, but we reset to maximum value to prevent spurious timer interrupts
HGEIP[i] <= 0;
end else if (memwrite & (hart == i)) begin
if (PADDR[15:13] == 3'b010) begin
if (XLEN == 64) MTIMECMP[hart] <= PWDATA; // 64-bit write
else MTIMECMP[hart][PADDR[2]*32 +: 32] <= PWDATA; // 32-bit write
end else if (PADDR[15:13] == 3'b110) begin
HGEIP[hart] <= PWDATA;
end
end
// mtime register
always_ff @(posedge PCLK)
if (~PRESETn) begin
MTIME <= '0;
end else if (memwrite & (PADDR[15:13] == 3'b101 && hart == 10'b1111111111)) begin
if (XLEN == 64) MTIME <= PWDATA; // 64-bit write
else MTIME <= MTIME[PADDR[2]*32 +: 32]; // 32-bit write
end else MTIME <= MTIME + 1;
// timer interrupt when MTIME >= MTIMECMP (unsigned)
for (i=0;i<NUM_HARTS;i++)
assign MTIP[i] = ({1'b0, MTIME} >= {1'b0, MTIMECMP[i]});
// TRICKEN controls whether outputs come from TrickBox or are daisy-chained from elsewhere
always_comb begin
MSIP_OUT = TRICKEN[0] ? MSIP : MSIP_IN;
SSIP_OUT = TRICKEN[1] ? SSIP : SSIP_IN;
MEIP_OUT = TRICKEN[2] ? MEIP : MEIP_IN;
SEIP_OUT = TRICKEN[3] ? SEIP : SEIP_IN;
MTIP_OUT = TRICKEN[4] ? MTIP : MTIP_IN;
MTIME_OUT = TRICKEN[5] ? MTIME : MTIME_IN;
TOHOST_OUT = TRICKEN[7] ? TOHOST : '0;
// NO COM1
end
for (i=0; i<NUM_HARTS;i++)
assign HGEIP_OUT[i] = TRICKEN[6] ? HGEIP[i] : HGEIP_IN[i];
endmodule

View file

@ -1,4 +1,4 @@
#!/usr/bin/env -S perl -w
#!/usr/bin/env perl
###########################################
## extractArea.pl

34
synthDC/spyglass/cvw.prj Normal file
View file

@ -0,0 +1,34 @@
#
# Synopsys SpyGlass Lint Flow
# james.stine@okstate.edu 11 June 2025
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
#
set WALLY $::env(WALLY)
set WALLY_CONFIG $::env(WALLY_CONFIG)
# Sets directory for output reports
set_option projectwdir ${WALLY}/synthDC/spyglass/lint-spyglass-reports/${WALLY_CONFIG}
set_option language_mode mixed
set_option designread_enable_synthesis no
set_option designread_disable_flatten no
set_option active_methodology $SPYGLASS_HOME/GuideWare/latest/block/rtl_handoff
set_option enableSV12 yes
set_option handlememory yes
set_option top wallywrapper
set_parameter handle_large_bus yes
# Include DIR
set_option incdir ${WALLY}/config/${WALLY_CONFIG}
set_option incdir ${WALLY}/config/shared
# main CVW
read_file -type verilog ${WALLY}/src/cvw.sv
read_file -type verilog ${WALLY}/testbench/wallywrapper.sv
read_file -type awl ${WALLY}/synthDC/spyglass/waivers.tcl
# generic read of Wally src files
read_file -type verilog ${WALLY}/src/*/*
read_file -type verilog ${WALLY}/src/*/*/*
current_methodology $SPYGLASS_HOME/GuideWare/latest/block/rtl_handoff

View file

@ -0,0 +1,11 @@
#
# Synopsys SpyGlass Lint Waivers
# james.stine@okstate.edu 11 June 2025
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
#
# Add waivers that are not neededed to be checked
waive -rule { W240 W528 W123 W287b }
# Add waiver for undriven outputs for items like Uncore
waive -du { {rom1p1r} {uncore} } -rule { {UndrivenInTerm-ML} }

View file

@ -22,13 +22,17 @@
module riscvassertions import cvw::*; #(parameter cvw_t P);
initial begin
assert (P.PMP_ENTRIES == 0 | P.PMP_ENTRIES==16 | P.PMP_ENTRIES==64) else $fatal(1, "Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
assert (P.S_SUPPORTED | P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "Virtual memory requires S mode support");
// assert (P.PMP_G > 0 | P.XLEN == 32 | P.PMP_ENTRIES == 0) else $fatal(1, "RV64 requires PMP_G at least 1 to avoid checking for 8-byte accesses to 4-byte region");
// assert ((P.PMP_G >= $clog2(P.DCACHE_LINELENINBITS/8)-2) | !P.ZICCLSM_SUPPORTED | P.PMP_ENTRIES == 0) else $fatal(1, "Systems that support misaligned data with PMP must have grain size of at least one cache line so accesses that span grains will also cause spills");
// assert ((P.PMP_G >= $clog2(P.ICACHE_LINELENINBITS/8)-2) | !P.ZCA_SUPPORTED | (P.PMP_ENTRIES == 0) | !P.ICACHE_SUPPORTED) else $fatal(1, "Systems that support compressed instructions with PMP must have grain size of at least one cache line so fetches that span grains will also cause spills");
assert (P.PMP_G < P.PA_BITS-2 | P.PMP_ENTRIES == 0) else $fatal(1, "PMP granularity must be less than the number of physical address bits");
assert (P.IDIV_BITSPERCYCLE == 1 | P.IDIV_BITSPERCYCLE==2 | P.IDIV_BITSPERCYCLE==4) else $fatal(1, "Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");
assert (P.F_SUPPORTED | ~P.D_SUPPORTED) else $fatal(1, "Can't support double fp (D) without supporting float (F)");
assert (P.D_SUPPORTED | ~P.Q_SUPPORTED) else $fatal(1, "Can't support quad fp (Q) without supporting double (D)");
assert (P.F_SUPPORTED | ~P.ZFH_SUPPORTED) else $fatal(1, "Can't support half-precision fp (ZFH) without supporting float (F)");
assert (P.DCACHE_SUPPORTED | ~P.F_SUPPORTED | P.FLEN <= P.XLEN) else $fatal(1, "Data cache required to support FLEN > XLEN because AHB/DTIM bus width is XLEN");
assert (P.F_SUPPORTED | !P.D_SUPPORTED) else $fatal(1, "Can't support double fp (D) without supporting float (F)");
assert (P.D_SUPPORTED | !P.Q_SUPPORTED) else $fatal(1, "Can't support quad fp (Q) without supporting double (D)");
assert (P.F_SUPPORTED | !P.ZFH_SUPPORTED) else $fatal(1, "Can't support half-precision fp (ZFH) without supporting float (F)");
assert (P.DCACHE_SUPPORTED | !P.F_SUPPORTED | P.FLEN <= P.XLEN) else $fatal(1, "Data cache required to support FLEN > XLEN because AHB/DTIM bus width is XLEN");
assert (P.I_SUPPORTED ^ P.E_SUPPORTED) else $fatal(1, "Exactly one of I and E must be supported");
assert (P.S_SUPPORTED | P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "Virtual memory requires S mode support");
assert (P.DCACHE_WAYSIZEINBYTES <= 4096 | (!P.DCACHE_SUPPORTED) | P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and virtual memory is enabled (to prevent aliasing)");
assert (P.DCACHE_LINELENINBITS >= 128 | (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
assert (P.DCACHE_LINELENINBITS < P.DCACHE_WAYSIZEINBYTES*8) else $fatal(1, "DCACHE_LINELENINBITS must be smaller than way size");

View file

@ -280,7 +280,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
// PMPADDR CSRs 3B0 to 3EF
for(genvar pmpAddrID = 0; pmpAddrID < P.PMP_ENTRIES; pmpAddrID++) begin
`CONNECT_CSR(PMPADDR``pmpAddrID, 12'h3B0 + pmpAddrID, testbench.dut.core.priv.priv.csr.csrm.PMPADDR_ARRAY_REGW[pmpAddrID]);
`CONNECT_CSR(PMPADDR``pmpAddrID, 12'h3B0 + pmpAddrID, testbench.dut.core.priv.priv.csr.csrm.PMPADDR_ARRAY_REGW[pmpAddrID]); // aligned to grain
end
end

View file

@ -918,14 +918,12 @@ end
end
if (P.ZICSR_SUPPORTED) begin
always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3]));
if (P.S_SUPPORTED) begin
always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1]));
end
always @(dut.core.priv.priv.trap.ValidIntsM[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.trap.ValidIntsM[7]));
always @(dut.core.priv.priv.trap.ValidIntsM[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.trap.ValidIntsM[11]));
always @(dut.core.priv.priv.trap.ValidIntsM[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.trap.ValidIntsM[3]));
always @(dut.core.priv.priv.trap.ValidIntsM[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.trap.ValidIntsM[5]));
always @(dut.core.priv.priv.trap.ValidIntsM[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.trap.ValidIntsM[9]));
always @(dut.core.priv.priv.trap.ValidIntsM[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.trap.ValidIntsM[1]));
end
final begin

View file

@ -153,25 +153,25 @@ string arch32pmp[] = '{
`RISCVARCHTEST,
"rv32i_m/pmp32/src/pmp-CFG-reg.S",
"rv32i_m/pmp32/src/pmp-CSR-access.S",
"rv32i_m/pmp32/src/pmp-NA4-R-priority-level-2.S",
"rv32i_m/pmp32/src/pmp-NA4-R-priority.S",
"rv32i_m/pmp32/src/pmp-NA4-R.S",
"rv32i_m/pmp32/src/pmp-NA4-RW-priority-level-2.S",
"rv32i_m/pmp32/src/pmp-NA4-RW-priority.S",
"rv32i_m/pmp32/src/pmp-NA4-RW.S",
//"rv32i_m/pmp32/src/pmp-NA4-R-priority-level-2.S", *** restore when BLOCKED is removed after tests work with G > 0
//"rv32i_m/pmp32/src/pmp-NA4-R-priority.S",
//"rv32i_m/pmp32/src/pmp-NA4-R.S",
//"rv32i_m/pmp32/src/pmp-NA4-RW-priority-level-2.S",
//"rv32i_m/pmp32/src/pmp-NA4-RW-priority.S",
//"rv32i_m/pmp32/src/pmp-NA4-RW.S",
"rv32i_m/pmp32/src/pmp-NA4-RWX.S",
"rv32i_m/pmp32/src/pmp-NA4-RX-priority-level-2.S",
"rv32i_m/pmp32/src/pmp-NA4-RX-priority.S",
"rv32i_m/pmp32/src/pmp-NA4-RX.S",
"rv32i_m/pmp32/src/pmp-NA4-X-priority-level-2.S",
"rv32i_m/pmp32/src/pmp-NA4-X-priority.S",
"rv32i_m/pmp32/src/pmp-NA4-X.S",
"rv32i_m/pmp32/src/pmp-NAPOT-R-priority-level-2.S",
"rv32i_m/pmp32/src/pmp-NAPOT-R-priority.S",
"rv32i_m/pmp32/src/pmp-NAPOT-R.S",
"rv32i_m/pmp32/src/pmp-NAPOT-RW-priority-level-2.S",
"rv32i_m/pmp32/src/pmp-NAPOT-RW-priority.S",
"rv32i_m/pmp32/src/pmp-NAPOT-RW.S",
//"rv32i_m/pmp32/src/pmp-NA4-RX-priority-level-2.S",
//"rv32i_m/pmp32/src/pmp-NA4-RX-priority.S",
//"rv32i_m/pmp32/src/pmp-NA4-RX.S",
//"rv32i_m/pmp32/src/pmp-NA4-X-priority-level-2.S",
//"rv32i_m/pmp32/src/pmp-NA4-X-priority.S",
//"rv32i_m/pmp32/src/pmp-NA4-X.S",
//"rv32i_m/pmp32/src/pmp-NAPOT-R-priority-level-2.S",
//"rv32i_m/pmp32/src/pmp-NAPOT-R-priority.S",
//"rv32i_m/pmp32/src/pmp-NAPOT-R.S",
//"rv32i_m/pmp32/src/pmp-NAPOT-RW-priority-level-2.S",
//"rv32i_m/pmp32/src/pmp-NAPOT-RW-priority.S",
//"rv32i_m/pmp32/src/pmp-NAPOT-RW.S",
"rv32i_m/pmp32/src/pmp-NAPOT-RWX.S",
"rv32i_m/pmp32/src/pmp-NAPOT-RX-priority-level-2.S",
"rv32i_m/pmp32/src/pmp-NAPOT-RX-priority.S",
@ -197,10 +197,10 @@ string arch32pmp[] = '{
string arch64pmp[] = '{
`RISCVARCHTEST,
"rv64i_m/pmp/src/pmp64-CSR-ALL-MODES.S",
"rv64i_m/pmp/src/pmp64-NA4-M.S",
"rv64i_m/pmp/src/pmp64-NA4-S.S",
"rv64i_m/pmp/src/pmp64-NA4-U.S",
"rv64i_m/pmp/src/pmp64-NAPOT-M.S",
//"rv64i_m/pmp/src/pmp64-NA4-M.S", *** restore when PMP tests work with G > 0
//"rv64i_m/pmp/src/pmp64-NA4-S.S",
//"rv64i_m/pmp/src/pmp64-NA4-U.S",
//"rv64i_m/pmp/src/pmp64-NAPOT-M.S",
"rv64i_m/pmp/src/pmp64-NAPOT-S.S",
"rv64i_m/pmp/src/pmp64-NAPOT-U.S",
"rv64i_m/pmp/src/pmp64-TOR-M.S",
@ -213,8 +213,8 @@ string arch32vm_sv32[] = '{
"rv32i_m/vm_sv32/src/mstatus_tvm_test.S",
"rv32i_m/vm_sv32/src/pmp_check_on_pa_S_mode.S",
"rv32i_m/vm_sv32/src/pmp_check_on_pa_U_mode.S",
"rv32i_m/vm_sv32/src/pmp_check_on_pte_S_mode.S",
"rv32i_m/vm_sv32/src/pmp_check_on_pte_U_mode.S",
//"rv32i_m/vm_sv32/src/pmp_check_on_pte_S_mode.S", *** restore when PMP tests work with G > 0
//"rv32i_m/vm_sv32/src/pmp_check_on_pte_U_mode.S",
"rv32i_m/vm_sv32/src/satp_access_tests.S",
"rv32i_m/vm_sv32/src/vm_A_and_D_S_mode.S",
"rv32i_m/vm_sv32/src/vm_A_and_D_U_mode.S",

View file

@ -39,6 +39,11 @@ rvtest_entry_point:
csrw mtvec, t0 # Initialize MTVEC to trap_handler
csrw mideleg, zero # Don't delegate interrupts
csrw medeleg, zero # Don't delegate exceptions
# The following three lines are needed to initalize the timer for Spike to run correctly,
# but are not necessary for Wally to run lockstep.
# Unfortunately, they throw off the program addresses for tests/coverage/pmp.S,
# causing it to fail. Ideally, pmp.S would become more robust or be replaced by
# functional coverage tests, and these three lines will be restored.
# li t0, -1 # set mtimecmp to biggest number so it doesnt interrupt again
# li t1, 0x02004000 # MTIMECMP in CLINT
# sd t0, 0(t1)

View file

@ -32,6 +32,11 @@ main:
bseti t0, zero, 14 # turn on FPU
csrs mstatus, t0
# fsqrt with Y = 0 to check divby0 flags
fcvt.s.w f0, zero
fli.s f1, 1
fsqrt.s f2, f1
#Pull denormalized FP number from memory and pass it to fclass.S for coverage
la t0, TestData1
flw ft0, 0(t0)

View file

@ -17,7 +17,7 @@ main:
// Configuration
# | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments
# |0 | 0x2000003f | 0x83 | 1 | 00 | 0 | 1 | 1 | 0
# |0 | 0x20000040 | 0x83 | 1 | 00 | 0 | 1 | 1 | 0
# |1 | 0x2000007f | 0x8b | 1 | 01 | 0 | 1 | 1 | 1
# |2 | 0x200000be | 0x93 | 1 | 10 | 0 | 1 | 1 | 2
# |3 | 0x2000011e | 0x9b | 1 | 11 | 0 | 1 | 1 | 3
@ -34,7 +34,10 @@ main:
# |14 | 0x200003be | 0x10 | 0 | 10 | 0 | 0 | 0 | 14
# |15 | 0x2000041e | 0x18 | 0 | 11 | 0 | 0 | 0 | 15
# configure the pmp address of register 0 in mode 0
li t5, 536870975
# changed from 2000003F to 20000040 5/22/25 david_harris@hmc.edu
# to prevent access fault to trap handler when grain size is large
# may result in lower coverage.
li t5, 0x20000040
csrw pmpaddr0, t5
# configure the pmp address of register 1 in mode 1
@ -101,6 +104,7 @@ csrw pmpaddr15, t5
# write pmpcfg0, output 0x191109019b938b83
li t4, 1806234828062034819
csrw pmpcfg0, t4
csrr t5, pmpcfg0
# write pmpcfg2, output 0x181008001c140c04
li t4, 1733894653101739012
@ -923,6 +927,7 @@ li t4, 1806234828062034819
csrw pmpcfg2, t4
// Testing
// END Configuration and Testing Starting at Register: 8

View file

@ -42,6 +42,7 @@
"base": 33554432,
"size": 786432
},
"clock_frequency": 1000000000,
"instructions_per_tick": 2,
"wfi_is_nop": true
},
@ -184,13 +185,19 @@
"Zhinx": {
"supported": false
},
"Zhinxmin": {
"supported": false
},
"Zvbb": {
"supported": false
},
"Zvbc": {
"supported": false
},
"Zvkb": {
"supported": false
},
"Zvbc": {
"Zvkg": {
"supported": false
},
"Zvkned": {

View file

@ -42,6 +42,7 @@
"base": 33554432,
"size": 786432
},
"clock_frequency": 1000000000,
"instructions_per_tick": 2,
"wfi_is_nop": true
},
@ -184,13 +185,19 @@
"Zhinx": {
"supported": false
},
"Zhinxmin": {
"supported": false
},
"Zvbb": {
"supported": false
},
"Zvbc": {
"supported": false
},
"Zvkb": {
"supported": false
},
"Zvbc": {
"Zvkg": {
"supported": false
},
"Zvkned": {

View file

@ -143,6 +143,12 @@ class spike(pluginTemplate):
#TODO: The following assumes you are using the riscv-gcc toolchain. If
# not please change appropriately
self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else ('ilp32e ' if "E" in ispec["ISA"] else 'ilp32 '))
if 'pmp-grain' in ispec['PMP']:
# if the PMP granularity is specified in the isa yaml, then we use that value
# convert from G to bytes: g = 2^(G+2) bytes
self.granularity = pow(2, ispec['PMP']['pmp-grain']+2)
else:
self.granularity = 4 # default granularity is 4 bytes
def runTests(self, testList):
@ -198,7 +204,7 @@ class spike(pluginTemplate):
reference_output = re.sub("/src/","/references/", re.sub(".S",".reference_output", test))
simcmd = f'cut -c-{8:g} {reference_output} > {sig_file}' #use cut to remove comments when copying
else:
simcmd = self.dut_exe + f' {"--misaligned" if self.xlen == "64" else ""} --isa={self.isa} +signature={sig_file} +signature-granularity=4 {elf}'
simcmd = self.dut_exe + f' {"--misaligned" if self.xlen == "64" else ""} --isa={self.isa} --pmpgranularity={self.granularity} +signature={sig_file} +signature-granularity=4 {elf}'
else:
simcmd = 'echo "NO RUN"'

View file

@ -30,5 +30,5 @@ hart0:
implemented: True
pmp-grain: 0
pmp-count: 16
pmp-writable: 12
pmp-writable: 16

View file

@ -32,4 +32,4 @@ hart0:
implemented: True
pmp-grain: 0
pmp-count: 16
pmp-writable: 12
pmp-writable: 16

View file

@ -73,7 +73,7 @@ test_cases:
# write pmpcfg regs with the information in the table above. this should also write the value of these registers to the output.
.4byte 0x0, 0x0009001F, write_pmpcfg_0 # write pmpcfg0, output 0x0009001F
.4byte 0x1, 0x0018900C, write_pmpcfg_1 # write pmpcfg1, output 0x0018900C
.4byte 0x1, 0x0018900C, write_pmpcfg_1 # write pmpcfg1, output 0x0018980C because NA4 reads as NAPOT with G > 0
# pmpcfg2 is zeroed out, so it doesn't need a write
.4byte 0x3, 0x1F000000, write_pmpcfg_3 # write pmpcfg3, output 0x1F000000
@ -117,8 +117,8 @@ test_cases:
.4byte 0x80100010, 0x600DAA, read32_test # read correct value out
# test read and write fault on region with no access
.4byte 0x80100208, 0x600D15, write32_test # Write fault on no-access range (PMP6)
.4byte 0x80100208, 0x600D15, read32_test # read fault on no-access range (PMP6)
.4byte 0x80100208, 0x600D17, write32_test # Write fault on no-access range (PMP4)
.4byte 0x80100208, 0x600D17, read32_test # read fault on no-access range (PMP4)
# test jalr to region with X=0 causes access fault
.4byte 0x80100020, 0xbad, executable_test # execute fault on no-execute range (PMP2)

View file

@ -71,7 +71,7 @@ test_cases:
.8byte 0xF, 0x2FFFFFFF, write_pmpaddr_15 # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX|
# write pmpcfg regs with the information in the table above. this should also write the value of these registers to the output.
.8byte 0x0, 0x0018900C0009001F, write_pmpcfg_0 # write pmpcfg0, output 0x0018900C0009001F
.8byte 0x0, 0x0018900C0009001F, write_pmpcfg_0 # write pmpcfg0, output 0x0018980C0009001F because NA4 writes as NAPOT
.8byte 0x2, 0x1F00000000000000, write_pmpcfg_2 # write pmpcfg2, output 0x1F00000000000000
# write known values to memory where W=0. This should be possible since we're in machine mode.