mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-06-28 01:32:49 -04:00
Resolved pmpaddrdec merge
This commit is contained in:
commit
e3ae285a8e
203 changed files with 6075 additions and 521 deletions
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
|
@ -21,7 +21,7 @@ jobs:
|
||||||
name: Lint (Python ${{matrix.version}})
|
name: Lint (Python ${{matrix.version}})
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
version: [39, 312] # Test on oldest and newest verions used in wally-package-install.sh
|
version: [39, 312] # Test on oldest and newest versions used in wally-package-install.sh
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -82,6 +82,7 @@ synthDC/Summary.csv
|
||||||
|
|
||||||
# Benchmarks
|
# Benchmarks
|
||||||
benchmarks/embench/wally*.json
|
benchmarks/embench/wally*.json
|
||||||
|
benchmarks/embench/actual_embench_results/wally*.json
|
||||||
benchmarks/embench/run*
|
benchmarks/embench/run*
|
||||||
benchmarks/coremark/coremark_results.csv
|
benchmarks/coremark/coremark_results.csv
|
||||||
|
|
||||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -33,3 +33,6 @@
|
||||||
path = addins/berkeley-testfloat-3
|
path = addins/berkeley-testfloat-3
|
||||||
url = https://github.com/ucb-bar/berkeley-testfloat-3
|
url = https://github.com/ucb-bar/berkeley-testfloat-3
|
||||||
ignore = untracked
|
ignore = untracked
|
||||||
|
[submodule "addins/cvw-riscv-arch-test"]
|
||||||
|
path = addins/cvw-riscv-arch-test
|
||||||
|
url = https://github.com/jordancarlin/riscv-arch-test
|
||||||
|
|
1
addins/cvw-riscv-arch-test
Submodule
1
addins/cvw-riscv-arch-test
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 44832a9d3bea991b099c6beb4c962e5b7c1ad3a3
|
|
@ -33,6 +33,13 @@ import csv
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
WALLY = os.environ.get("WALLY")
|
||||||
|
|
||||||
|
# Set working directory to where the Makefile is
|
||||||
|
coremark_dir = os.path.join(WALLY, "benchmarks/coremark")
|
||||||
|
os.chdir(coremark_dir)
|
||||||
|
|
||||||
|
|
||||||
# list of architectures to run.
|
# list of architectures to run.
|
||||||
arch_list = [
|
arch_list = [
|
||||||
"rv32i_zicsr",
|
"rv32i_zicsr",
|
||||||
|
@ -54,7 +61,8 @@ mt_regex = r"Elapsed MTIME: (\d+).*?Elapsed MINSTRET: (\d+).*?COREMARK/MHz Score
|
||||||
#cpi_regex = r"CPI: \d+ / \d+ = (\d+\.\d+)"
|
#cpi_regex = r"CPI: \d+ / \d+ = (\d+\.\d+)"
|
||||||
#cmhz_regex = r"COREMARK/MHz Score: [\d,]+ / [\d,]+ = (\d+\.\d+)"
|
#cmhz_regex = r"COREMARK/MHz Score: [\d,]+ / [\d,]+ = (\d+\.\d+)"
|
||||||
# Open a CSV file to write the results
|
# Open a CSV file to write the results
|
||||||
resultfile = 'coremark_results.csv'
|
resultfile = os.path.join(coremark_dir, 'coremark_results.csv')
|
||||||
|
# resultfile = 'coremark_results.csv'
|
||||||
with open(resultfile, mode='w', newline='') as csvfile:
|
with open(resultfile, mode='w', newline='') as csvfile:
|
||||||
fieldnames = ['Architecture', 'CM / MHz','CPI','MTIME','MINSTRET','Load Stalls','Store Stalls','D$ Accesses',
|
fieldnames = ['Architecture', 'CM / MHz','CPI','MTIME','MINSTRET','Load Stalls','Store Stalls','D$ Accesses',
|
||||||
'D$ Misses','I$ Accesses','I$ Misses','Branches','Branch Mispredicts','BTB Misses',
|
'D$ Misses','I$ Accesses','I$ Misses','Branches','Branch Mispredicts','BTB Misses',
|
||||||
|
|
13
benchmarks/coremark/expected_coremark_results.csv
Normal file
13
benchmarks/coremark/expected_coremark_results.csv
Normal file
|
@ -0,0 +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
|
|
|
@ -194,7 +194,7 @@ void stop_time(void) {
|
||||||
|
|
||||||
Actual value returned may be cpu cycles, milliseconds or any other value,
|
Actual value returned may be cpu cycles, milliseconds or any other value,
|
||||||
as long as it can be converted to seconds by <time_in_secs>.
|
as long as it can be converted to seconds by <time_in_secs>.
|
||||||
This methodology is taken to accomodate any hardware or simulated platform.
|
This methodology is taken to accommodate any hardware or simulated platform.
|
||||||
The sample implementation returns millisecs by default,
|
The sample implementation returns millisecs by default,
|
||||||
and the resolution is controlled by <TIMER_RES_DIVIDER>
|
and the resolution is controlled by <TIMER_RES_DIVIDER>
|
||||||
*/
|
*/
|
||||||
|
@ -213,7 +213,7 @@ CORE_TICKS get_time(void) {
|
||||||
/* Function: time_in_secs
|
/* Function: time_in_secs
|
||||||
Convert the value returned by get_time to seconds.
|
Convert the value returned by get_time to seconds.
|
||||||
|
|
||||||
The <secs_ret> type is used to accomodate systems with no support for floating point.
|
The <secs_ret> type is used to accommodate systems with no support for floating point.
|
||||||
Default implementation implemented by the EE_TICKS_PER_SEC macro above.
|
Default implementation implemented by the EE_TICKS_PER_SEC macro above.
|
||||||
*/
|
*/
|
||||||
secs_ret time_in_secs(CORE_TICKS ticks) {
|
secs_ret time_in_secs(CORE_TICKS ticks) {
|
||||||
|
|
|
@ -99,7 +99,7 @@ typedef clock_t CORE_TICKS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Data Types:
|
/* Data Types:
|
||||||
To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in <core_portme.h>.
|
To avoid compiler issues, define the data types that need to be used for 8b, 16b and 32b in <core_portme.h>.
|
||||||
|
|
||||||
*Imprtant*:
|
*Imprtant*:
|
||||||
ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!!
|
ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!!
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
/* The OUTPUT_ARCH command specifies the machine architecture where the
|
/* The OUTPUT_ARCH command specifies the machine architecture where the
|
||||||
argument is one of the names used in the BFD library. More
|
argument is one of the names used in the BFD library. More
|
||||||
specifically one of the entires in bfd/cpu-mips.c */
|
specifically one of the entries in bfd/cpu-mips.c */
|
||||||
|
|
||||||
OUTPUT_ARCH( "riscv" )
|
OUTPUT_ARCH( "riscv" )
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
@ -60,7 +60,7 @@ SECTIONS
|
||||||
*(.tbss.end)
|
*(.tbss.end)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of uninitalized data segement */
|
/* End of uninitialized data segment */
|
||||||
_end = .;
|
_end = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,15 +63,19 @@ spike: buildspeed spike_run speed
|
||||||
spike_run:
|
spike_run:
|
||||||
find $(embench_dir)/bd_*opt_speed/ -type f -name "*.elf" | while read f; do spike --isa=rv32imac +signature=$$f.spike.output +signature-granularity=4 $$f; done
|
find $(embench_dir)/bd_*opt_speed/ -type f -name "*.elf" | while read f; do spike --isa=rv32imac +signature=$$f.spike.output +signature-granularity=4 $$f; done
|
||||||
|
|
||||||
|
# creates the directory to store the results of the embench tests
|
||||||
|
actual_embench_results:
|
||||||
|
mkdir -p actual_embench_results
|
||||||
|
|
||||||
# python wrapper to present results of embench size benchmark
|
# python wrapper to present results of embench size benchmark
|
||||||
size: buildsize
|
size: actual_embench_results buildsize
|
||||||
$(embench_dir)/benchmark_size.py --builddir=bd_speedopt_size --json-output > wallySpeedOpt_size.json
|
$(embench_dir)/benchmark_size.py --builddir=bd_speedopt_size --json-output > actual_embench_results/wallySpeedOpt_size.json
|
||||||
$(embench_dir)/benchmark_size.py --builddir=bd_sizeopt_size --json-output > wallySizeOpt_size.json
|
$(embench_dir)/benchmark_size.py --builddir=bd_sizeopt_size --json-output > actual_embench_results/wallySizeOpt_size.json
|
||||||
|
|
||||||
# python wrapper to present results of embench speed benchmark
|
# python wrapper to present results of embench speed benchmark
|
||||||
speed:
|
speed: actual_embench_results
|
||||||
$(embench_dir)/benchmark_speed.py --builddir=bd_sizeopt_speed --target-module run_wally --cpu-mhz=1 --json-output > wallySizeOpt_speed.json
|
$(embench_dir)/benchmark_speed.py --builddir=bd_sizeopt_speed --target-module run_wally --cpu-mhz=1 --json-output > actual_embench_results/wallySizeOpt_speed.json
|
||||||
$(embench_dir)/benchmark_speed.py --builddir=bd_speedopt_speed --target-module run_wally --cpu-mhz=1 --json-output > wallySpeedOpt_speed.json
|
$(embench_dir)/benchmark_speed.py --builddir=bd_speedopt_speed --target-module run_wally --cpu-mhz=1 --json-output > actual_embench_results/wallySpeedOpt_speed.json
|
||||||
|
|
||||||
# deletes all files
|
# deletes all files
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{ "size results" :
|
||||||
|
{ "detailed size results" :
|
||||||
|
{ "aha-mont64" : 0.96,
|
||||||
|
"crc32" : 0.74,
|
||||||
|
"cubic" : 2.01,
|
||||||
|
"edn" : 1.09,
|
||||||
|
"huffbench" : 1.16,
|
||||||
|
"matmult-int" : 0.87,
|
||||||
|
"md5sum" : 1.00,
|
||||||
|
"minver" : 0.87,
|
||||||
|
"nbody" : 0.92,
|
||||||
|
"nettle-aes" : 1.26,
|
||||||
|
"nettle-sha256" : 1.62,
|
||||||
|
"nsichneu" : 1.42,
|
||||||
|
"picojpeg" : 1.14,
|
||||||
|
"primecount" : 0.73,
|
||||||
|
"qrduino" : 1.03,
|
||||||
|
"sglib-combined" : 1.01,
|
||||||
|
"slre" : 1.05,
|
||||||
|
"st" : 0.93,
|
||||||
|
"statemate" : 0.82,
|
||||||
|
"tarfind" : 0.95,
|
||||||
|
"ud" : 0.96,
|
||||||
|
"wikisort" : 0.94
|
||||||
|
},
|
||||||
|
"size geometric mean" : 1.04,
|
||||||
|
"size geometric standard deviation" : 1.26
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{ "speed results" :
|
||||||
|
{ "detailed speed results" :
|
||||||
|
{ "aha-mont64" : 0.81,
|
||||||
|
"crc32" : 1.00,
|
||||||
|
"cubic" : 0.42,
|
||||||
|
"edn" : 0.88,
|
||||||
|
"huffbench" : 1.38,
|
||||||
|
"matmult-int" : 1.11,
|
||||||
|
"md5sum" : 2.00,
|
||||||
|
"minver" : 0.63,
|
||||||
|
"nbody" : 0.67,
|
||||||
|
"nettle-aes" : 0.82,
|
||||||
|
"nettle-sha256" : 0.96,
|
||||||
|
"nsichneu" : 1.14,
|
||||||
|
"picojpeg" : 0.79,
|
||||||
|
"primecount" : 1.30,
|
||||||
|
"qrduino" : 1.22,
|
||||||
|
"sglib-combined" : 1.17,
|
||||||
|
"slre" : 1.25,
|
||||||
|
"st" : 0.84,
|
||||||
|
"statemate" : 2.15,
|
||||||
|
"tarfind" : 2.42,
|
||||||
|
"ud" : 0.88,
|
||||||
|
"wikisort" : 1.71
|
||||||
|
},
|
||||||
|
"speed geometric mean" : 1.07,
|
||||||
|
"speed geometric standard deviation" : 1.51
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{ "size results" :
|
||||||
|
{ "detailed size results" :
|
||||||
|
{ "aha-mont64" : 1.50,
|
||||||
|
"crc32" : 0.70,
|
||||||
|
"cubic" : 2.04,
|
||||||
|
"edn" : 1.10,
|
||||||
|
"huffbench" : 1.27,
|
||||||
|
"matmult-int" : 1.15,
|
||||||
|
"md5sum" : 1.18,
|
||||||
|
"minver" : 1.10,
|
||||||
|
"nbody" : 1.12,
|
||||||
|
"nettle-aes" : 1.37,
|
||||||
|
"nettle-sha256" : 1.71,
|
||||||
|
"nsichneu" : 1.51,
|
||||||
|
"picojpeg" : 1.67,
|
||||||
|
"primecount" : 0.73,
|
||||||
|
"qrduino" : 1.43,
|
||||||
|
"sglib-combined" : 1.13,
|
||||||
|
"slre" : 1.28,
|
||||||
|
"st" : 1.29,
|
||||||
|
"statemate" : 0.87,
|
||||||
|
"tarfind" : 1.09,
|
||||||
|
"ud" : 1.14,
|
||||||
|
"wikisort" : 1.13
|
||||||
|
},
|
||||||
|
"size geometric mean" : 1.21,
|
||||||
|
"size geometric standard deviation" : 1.28
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{ "speed results" :
|
||||||
|
{ "detailed speed results" :
|
||||||
|
{ "aha-mont64" : 0.84,
|
||||||
|
"crc32" : 1.05,
|
||||||
|
"cubic" : 0.42,
|
||||||
|
"edn" : 1.06,
|
||||||
|
"huffbench" : 1.58,
|
||||||
|
"matmult-int" : 1.11,
|
||||||
|
"md5sum" : 1.92,
|
||||||
|
"minver" : 0.65,
|
||||||
|
"nbody" : 0.67,
|
||||||
|
"nettle-aes" : 0.93,
|
||||||
|
"nettle-sha256" : 0.99,
|
||||||
|
"nsichneu" : 0.70,
|
||||||
|
"picojpeg" : 0.99,
|
||||||
|
"primecount" : 1.41,
|
||||||
|
"qrduino" : 1.32,
|
||||||
|
"sglib-combined" : 1.41,
|
||||||
|
"slre" : 1.54,
|
||||||
|
"st" : 0.86,
|
||||||
|
"statemate" : 3.13,
|
||||||
|
"tarfind" : 3.31,
|
||||||
|
"ud" : 0.94,
|
||||||
|
"wikisort" : 1.74
|
||||||
|
},
|
||||||
|
"speed geometric mean" : 1.15,
|
||||||
|
"speed geometric standard deviation" : 1.61
|
||||||
|
}
|
||||||
|
}
|
|
@ -95,10 +95,10 @@ def main():
|
||||||
embenchSizeOpt_SizeData = {}
|
embenchSizeOpt_SizeData = {}
|
||||||
embenchSpeedOpt_SizeData = {}
|
embenchSpeedOpt_SizeData = {}
|
||||||
coremarkData = loadCoremark(coremarkData)
|
coremarkData = loadCoremark(coremarkData)
|
||||||
embenchSpeedOpt_SpeedData = loadEmbench("embench/wallySpeedOpt_speed.json", embenchSpeedOpt_SpeedData)
|
embenchSpeedOpt_SpeedData = loadEmbench("embench/actual_embench_results/wallySpeedOpt_speed.json", embenchSpeedOpt_SpeedData)
|
||||||
embenchSizeOpt_SpeedData = loadEmbench("embench/wallySizeOpt_speed.json", embenchSizeOpt_SpeedData)
|
embenchSizeOpt_SpeedData = loadEmbench("embench/actual_embench_results/wallySizeOpt_speed.json", embenchSizeOpt_SpeedData)
|
||||||
embenchSpeedOpt_SizeData = loadEmbench("embench/wallySpeedOpt_size.json", embenchSpeedOpt_SizeData)
|
embenchSpeedOpt_SizeData = loadEmbench("embench/actual_embench_results/wallySpeedOpt_size.json", embenchSpeedOpt_SizeData)
|
||||||
embenchSizeOpt_SizeData = loadEmbench("embench/wallySizeOpt_size.json", embenchSizeOpt_SizeData)
|
embenchSizeOpt_SizeData = loadEmbench("embench/actual_embench_results/wallySizeOpt_size.json", embenchSizeOpt_SizeData)
|
||||||
|
|
||||||
graphEmbench(embenchSpeedOpt_SpeedData, embenchSizeOpt_SpeedData, embenchSpeedOpt_SizeData, embenchSizeOpt_SizeData)
|
graphEmbench(embenchSpeedOpt_SpeedData, embenchSizeOpt_SpeedData, embenchSpeedOpt_SizeData, embenchSizeOpt_SizeData)
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ for(my $i=0; $i<=$#ARGV; $i++) {
|
||||||
# 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+(.*)/) { # 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+(.*)/) {
|
if (/^\s*(\S\S\S\S\S\S\S\S):\s+(.*)/) {
|
||||||
$address = &fixadr($1);
|
$address = &fixadr($1);
|
||||||
# print "addresss $address maxaddress $maxaddress\n";
|
# print "address $address maxaddress $maxaddress\n";
|
||||||
if ($address > $maxaddress) { $maxaddress = $address; }
|
if ($address > $maxaddress) { $maxaddress = $address; }
|
||||||
#print "test $address $1 $2\n";
|
#print "test $address $1 $2\n";
|
||||||
my $lineorig = $2;
|
my $lineorig = $2;
|
||||||
|
@ -157,7 +157,7 @@ for(my $i=0; $i<=$#ARGV; $i++) {
|
||||||
print("\n");
|
print("\n");
|
||||||
|
|
||||||
sub emitData {
|
sub emitData {
|
||||||
# print the data portion of the ELF into a memroy file, including 0s for empty stuff
|
# print the data portion of the ELF into a memory file, including 0s for empty stuff
|
||||||
# deal with endianness
|
# deal with endianness
|
||||||
my $address = shift;
|
my $address = shift;
|
||||||
my $payload = shift;
|
my $payload = shift;
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
## Created: March 1, 2021
|
## Created: March 1, 2021
|
||||||
## Modified: March 10, 2021
|
## Modified: March 10, 2021
|
||||||
##
|
##
|
||||||
## Purpose: Processes all compiled object files into 2 types of files which assist in debuging applications.
|
## Purpose: Processes all compiled object files into 2 types of files which assist in debugging applications.
|
||||||
## File 1: .addr: A sorted list of function starting addresses.
|
## File 1: .addr: A sorted list of function starting addresses.
|
||||||
## When a the PCE is greater than or equal to the function's starting address, the label will be associated with this address.
|
## When a the PCE is greater than or equal to the function's starting address, the label will be associated with this address.
|
||||||
## File 2: .lab: A sorted list of funciton labels. The names of functions. Modelsim will display these names rather than the function address.
|
## File 2: .lab: A sorted list of function labels. The names of functions. Modelsim will display these names rather than the function address.
|
||||||
##
|
##
|
||||||
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
##
|
##
|
||||||
|
|
|
@ -35,7 +35,7 @@ def search_log_for_mismatches(logfile):
|
||||||
return os.system(grepcmd) == 0
|
return os.system(grepcmd) == 0
|
||||||
|
|
||||||
def run_test_case(elf):
|
def run_test_case(elf):
|
||||||
"""Run the given test case, and return 0 if the test suceeds and 1 if it fails"""
|
"""Run the given test case, and return 0 if the test succeeds and 1 if it fails"""
|
||||||
WALLY = os.environ.get("WALLY")
|
WALLY = os.environ.get("WALLY")
|
||||||
fields = elf.rsplit("/", 3)
|
fields = elf.rsplit("/", 3)
|
||||||
if fields[2] == "ref":
|
if fields[2] == "ref":
|
||||||
|
@ -70,7 +70,7 @@ parser.add_argument("--config", help="Configuration", default="rv64gc")
|
||||||
parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "vcs"], default="questa")
|
parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "vcs"], default="questa")
|
||||||
parser.add_argument("--coverage", "-c", help="Code & Functional Coverage", action="store_true")
|
parser.add_argument("--coverage", "-c", help="Code & Functional Coverage", action="store_true")
|
||||||
parser.add_argument("--fcov", "-f", help="Code & Functional Coverage", action="store_true")
|
parser.add_argument("--fcov", "-f", help="Code & Functional Coverage", action="store_true")
|
||||||
parser.add_argument("--exclude", help="Exclude files with this sufix", default="my.elf")
|
parser.add_argument("--exclude", help="Exclude files with this suffix", default="my.elf")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# find all ELF files in directory
|
# find all ELF files in directory
|
||||||
|
|
|
@ -167,7 +167,7 @@ class FolderManager:
|
||||||
None
|
None
|
||||||
"""
|
"""
|
||||||
cvw = folder.joinpath("cvw")
|
cvw = folder.joinpath("cvw")
|
||||||
tmp_folder = os.path.join(cvw, "tmp") # temprorary files will be stored in here
|
tmp_folder = os.path.join(cvw, "tmp") # temporary files will be stored in here
|
||||||
if not cvw.exists():
|
if not cvw.exists():
|
||||||
os.system(f"git clone --recurse-submodules {repo_url} {cvw}")
|
os.system(f"git clone --recurse-submodules {repo_url} {cvw}")
|
||||||
os.makedirs(tmp_folder)
|
os.makedirs(tmp_folder)
|
||||||
|
@ -196,7 +196,7 @@ class TestRunner:
|
||||||
folder: the "nightly-runs/repos/"
|
folder: the "nightly-runs/repos/"
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if the script is copied successfuly, False otherwise.
|
bool: True if the script is copied successfully, False otherwise.
|
||||||
"""
|
"""
|
||||||
# Get today's date in YYYY-MM-DD format
|
# Get today's date in YYYY-MM-DD format
|
||||||
self.todays_date = datetime.now().strftime("%Y-%m-%d")
|
self.todays_date = datetime.now().strftime("%Y-%m-%d")
|
||||||
|
@ -346,9 +346,9 @@ class TestRunner:
|
||||||
result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True, shell=True, executable="/bin/bash")
|
result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True, shell=True, executable="/bin/bash")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"There was an error in running the tests in the run_tests function: {e}")
|
self.logger.error(f"There was an error in running the tests in the run_tests function: {e}")
|
||||||
# Check if the command executed successfuly
|
# Check if the command executed successfully
|
||||||
if result.returncode or result.returncode == 0:
|
if result.returncode or result.returncode == 0:
|
||||||
self.logger.info(f"Test ran successfuly. Test name: {test_name}, test extension: {' '.join(test_extensions)}")
|
self.logger.info(f"Test ran successfully. Test name: {test_name}, test extension: {' '.join(test_extensions)}")
|
||||||
return True, output_file
|
return True, output_file
|
||||||
else:
|
else:
|
||||||
self.logger.error(f"Error making test. Test name: {test_name}, test extension: {' '.join(test_extensions)}")
|
self.logger.error(f"Error making test. Test name: {test_name}, test extension: {' '.join(test_extensions)}")
|
||||||
|
@ -763,7 +763,7 @@ def main():
|
||||||
|
|
||||||
output_log_list = [] # a list where the output markdown file locations will be saved to
|
output_log_list = [] # a list where the output markdown file locations will be saved to
|
||||||
total_number_failures = 0 # an integer where the total number failures from all of the tests will be collected
|
total_number_failures = 0 # an integer where the total number failures from all of the tests will be collected
|
||||||
total_number_success = 0 # an integer where the total number of sucess will be collected
|
total_number_success = 0 # an integer where the total number of successes will be collected
|
||||||
|
|
||||||
total_failures = []
|
total_failures = []
|
||||||
total_success = []
|
total_success = []
|
||||||
|
@ -772,21 +772,21 @@ def main():
|
||||||
|
|
||||||
check, output_location = test_runner.run_tests(test_type=test_type, test_name=test_name, test_extensions=test_extensions)
|
check, output_location = test_runner.run_tests(test_type=test_type, test_name=test_name, test_extensions=test_extensions)
|
||||||
try:
|
try:
|
||||||
if check: # this checks if the test actually ran successfuly
|
if check: # this checks if the test actually ran successfully
|
||||||
output_log_list.append(output_location)
|
output_log_list.append(output_location)
|
||||||
logger.info(f"{test_name} ran successfuly. Output location: {output_location}")
|
logger.info(f"{test_name} ran successfully. Output location: {output_location}")
|
||||||
# format tests to markdown
|
# format tests to markdown
|
||||||
try:
|
try:
|
||||||
passed, failed = test_runner.clean_format_output(input_file = output_location)
|
passed, failed = test_runner.clean_format_output(input_file = output_location)
|
||||||
logger.info(f"{test_name} has been formatted to markdown")
|
logger.info(f"{test_name} has been formatted to markdown")
|
||||||
except:
|
except:
|
||||||
logger.error(f"Error occured with formatting {test_name}")
|
logger.error(f"Error occurred with formatting {test_name}")
|
||||||
|
|
||||||
logger.info(f"The # of failures are for {test_name}: {len(failed)}")
|
logger.info(f"The # of failures are for {test_name}: {len(failed)}")
|
||||||
total_number_failures+= len(failed)
|
total_number_failures+= len(failed)
|
||||||
total_failures.append(failed)
|
total_failures.append(failed)
|
||||||
|
|
||||||
logger.info(f"The # of sucesses are for {test_name}: {len(passed)}")
|
logger.info(f"The # of successes are for {test_name}: {len(passed)}")
|
||||||
total_number_success += len(passed)
|
total_number_success += len(passed)
|
||||||
total_success.append(passed)
|
total_success.append(passed)
|
||||||
test_runner.rewrite_to_markdown(test_name, passed, failed)
|
test_runner.rewrite_to_markdown(test_name, passed, failed)
|
||||||
|
@ -797,7 +797,7 @@ def main():
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"There was an error in running the tests: {e}")
|
logger.error(f"There was an error in running the tests: {e}")
|
||||||
|
|
||||||
logger.info(f"The total sucesses for all tests ran are: {total_number_success}")
|
logger.info(f"The total successes for all tests ran are: {total_number_success}")
|
||||||
logger.info(f"The total failures for all tests ran are: {total_number_failures}")
|
logger.info(f"The total failures for all tests ran are: {total_number_failures}")
|
||||||
|
|
||||||
# Copy actual test logs from sim/questa, sim/verilator, sim/vcs
|
# Copy actual test logs from sim/questa, sim/verilator, sim/vcs
|
||||||
|
@ -830,14 +830,14 @@ def main():
|
||||||
#############################################
|
#############################################
|
||||||
# DELETE REPOSITORY OF PREVIOUS NIGHTLYS #
|
# DELETE REPOSITORY OF PREVIOUS NIGHTLYS #
|
||||||
#############################################
|
#############################################
|
||||||
threshold = time.time() - 86400*1
|
threshold = time.time() - 86400*7 # 1 week
|
||||||
|
|
||||||
for log_dir in os.listdir(args.path):
|
for log_dir in os.listdir(args.path):
|
||||||
try:
|
try:
|
||||||
cvw_dir = os.path.join(args.path,log_dir,"cvw")
|
cvw_dir = os.path.join(args.path,log_dir,"cvw")
|
||||||
cvw_mtime = os.stat(cvw_dir).st_mtime
|
cvw_mtime = os.stat(cvw_dir).st_mtime
|
||||||
if cvw_mtime < threshold:
|
if cvw_mtime < threshold:
|
||||||
logger.info(f"Found {cvw_dir} older than 1 day, removing")
|
logger.info(f"Found {cvw_dir} older than 1 week, removing")
|
||||||
shutil.rmtree(cvw_dir)
|
shutil.rmtree(cvw_dir)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if os.path.exists(cvw_dir):
|
if os.path.exists(cvw_dir):
|
||||||
|
|
|
@ -45,7 +45,7 @@ RefDataBTB = [('BTBCModel6', 'BTBCModel', 64, 128, 1.51480272475844), ('BTBCMode
|
||||||
|
|
||||||
def ParseBranchListFile(path):
|
def ParseBranchListFile(path):
|
||||||
'''Take the path to the list of Questa Sim log files containing the performance counters outputs. File
|
'''Take the path to the list of Questa Sim log files containing the performance counters outputs. File
|
||||||
is formated in row columns. Each row is a trace with the file, branch predictor type, and the parameters.
|
is formatted in row columns. Each row is a trace with the file, branch predictor type, and the parameters.
|
||||||
parameters can be any number and depend on the predictor type. Returns a list of lists.'''
|
parameters can be any number and depend on the predictor type. Returns a list of lists.'''
|
||||||
lst = []
|
lst = []
|
||||||
with open(path) as BranchList:
|
with open(path) as BranchList:
|
||||||
|
@ -59,7 +59,7 @@ def ParseBranchListFile(path):
|
||||||
return lst
|
return lst
|
||||||
|
|
||||||
def ProcessFile(fileName):
|
def ProcessFile(fileName):
|
||||||
'''Extract preformance counters from a modelsim log. Outputs a list of tuples for each test/benchmark.
|
'''Extract performance counters from a modelsim log. Outputs a list of tuples for each test/benchmark.
|
||||||
The tuple contains the test name, optimization characteristics, and dictionary of performance counters.'''
|
The tuple contains the test name, optimization characteristics, and dictionary of performance counters.'''
|
||||||
# 1 find lines with Read memfile and extract test name
|
# 1 find lines with Read memfile and extract test name
|
||||||
# 2 parse counters into a list of (name, value) tuples (dictionary maybe?)
|
# 2 parse counters into a list of (name, value) tuples (dictionary maybe?)
|
||||||
|
@ -328,23 +328,23 @@ def ReportAsGraph(benchmarkDict, bar, FileName):
|
||||||
markers = ['x', '.', '+', '*', '^', 'o', ',', 's']
|
markers = ['x', '.', '+', '*', '^', 'o', ',', 's']
|
||||||
colors = ['blue', 'black', 'gray', 'dodgerblue', 'lightsteelblue', 'turquoise', 'black', 'blue']
|
colors = ['blue', 'black', 'gray', 'dodgerblue', 'lightsteelblue', 'turquoise', 'black', 'blue']
|
||||||
|
|
||||||
# the benchmarkDict['Mean'] contains sequencies of results for multiple
|
# the benchmarkDict['Mean'] contains sequences of results for multiple
|
||||||
# branch predictors with various parameterizations
|
# branch predictors with various parameterizations
|
||||||
# group the parameterizations by the common typ.
|
# group the parameterizations by the common typ.
|
||||||
sequencies = {}
|
sequences = {}
|
||||||
for (name, typ, entries, size, value) in benchmarkDict['Mean']:
|
for (name, typ, entries, size, value) in benchmarkDict['Mean']:
|
||||||
if typ not in sequencies:
|
if typ not in sequences:
|
||||||
sequencies[typ] = [(entries if not args.size else int(size/8), value)]
|
sequences[typ] = [(entries if not args.size else int(size/8), value)]
|
||||||
else:
|
else:
|
||||||
sequencies[typ].append((entries if not args.size else int(size/8) ,value))
|
sequences[typ].append((entries if not args.size else int(size/8) ,value))
|
||||||
# then graph the common typ as a single line+scatter plot
|
# then graph the common typ as a single line+scatter plot
|
||||||
# finally repeat for all typs of branch predictors and overlay
|
# finally repeat for all typs of branch predictors and overlay
|
||||||
fig, axes = plt.subplots()
|
fig, axes = plt.subplots()
|
||||||
index = 0
|
index = 0
|
||||||
if(args.invert): plt.title(titlesInvert[ReportPredictorType])
|
if(args.invert): plt.title(titlesInvert[ReportPredictorType])
|
||||||
else: plt.title(titles[ReportPredictorType])
|
else: plt.title(titles[ReportPredictorType])
|
||||||
for branchPredName in sequencies:
|
for branchPredName in sequences:
|
||||||
data = sequencies[branchPredName]
|
data = sequences[branchPredName]
|
||||||
(xdata, ydata) = zip(*data)
|
(xdata, ydata) = zip(*data)
|
||||||
if args.invert: ydata = [100 - x for x in ydata]
|
if args.invert: ydata = [100 - x for x in ydata]
|
||||||
axes.plot(xdata, ydata, color=colors[index])
|
axes.plot(xdata, ydata, color=colors[index])
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
# David_Harris@Hmc.edu 25 January 2021
|
# David_Harris@Hmc.edu 25 January 2021
|
||||||
# Modified by Jarred Allen <jaallen@g.hmc.edu> and many others
|
# Modified by Jarred Allen <jaallen@g.hmc.edu> and many others
|
||||||
# jcarlin@hmc.edu December 2024
|
# jcarlin@hmc.edu December 2024
|
||||||
|
# sanarayanan@hmc.edu April 2025
|
||||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
#
|
#
|
||||||
# Run a regression with multiple configurations in parallel and exit with
|
# Run a regression with multiple configurations in parallel and exit with
|
||||||
|
@ -278,7 +279,7 @@ lockstepwaivers = [
|
||||||
# Data Types & Functions
|
# Data Types & Functions
|
||||||
##################################
|
##################################
|
||||||
|
|
||||||
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr', 'grepfile'])
|
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr', 'grepfile', 'altcommand'], defaults=[None]) # applies the None default to altcommand
|
||||||
# name: the name of this test configuration (used in printing human-readable
|
# name: the name of this test configuration (used in printing human-readable
|
||||||
# output and picking logfile names)
|
# output and picking logfile names)
|
||||||
# cmd: the command to run to test (should include the logfile as '{}', and
|
# cmd: the command to run to test (should include the logfile as '{}', and
|
||||||
|
@ -287,7 +288,8 @@ TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr', 'grepfil
|
||||||
# grep finds that string in the logfile (is used by grep, so it may
|
# grep finds that string in the logfile (is used by grep, so it may
|
||||||
# be any pattern grep accepts, see `man 1 grep` for more info).
|
# be any pattern grep accepts, see `man 1 grep` for more info).
|
||||||
# grepfile: a string containing the location of the file to be searched for output
|
# grepfile: a string containing the location of the file to be searched for output
|
||||||
|
# altcommand: the command, if enabled, performs a validation check other than grep
|
||||||
|
# on the log files. None by default, and if specified the command will be run
|
||||||
class bcolors:
|
class bcolors:
|
||||||
HEADER = '\033[95m'
|
HEADER = '\033[95m'
|
||||||
OKBLUE = '\033[94m'
|
OKBLUE = '\033[94m'
|
||||||
|
@ -368,12 +370,31 @@ def search_log_for_text(text, grepfile):
|
||||||
def run_test_case(config, dryrun: bool = False):
|
def run_test_case(config, dryrun: bool = False):
|
||||||
grepfile = config.grepfile
|
grepfile = config.grepfile
|
||||||
cmd = config.cmd
|
cmd = config.cmd
|
||||||
|
altcommand = config.altcommand
|
||||||
if dryrun:
|
if dryrun:
|
||||||
print(f"Executing {cmd}", flush=True)
|
print(f"Executing {cmd}", flush=True)
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
os.system(cmd)
|
ret_code = os.system(cmd)
|
||||||
if search_log_for_text(config.grepstr, grepfile):
|
if ret_code != 0:
|
||||||
|
print(f"{bcolors.FAIL}{cmd}: Execution failed{bcolors.ENDC}", flush=True)
|
||||||
|
print(f" Check {grepfile} for more details.", flush=True)
|
||||||
|
return 1
|
||||||
|
elif altcommand:
|
||||||
|
sim_log = config.grepfile
|
||||||
|
check_ret_code = os.system(altcommand)
|
||||||
|
with open(sim_log, 'a') as f:
|
||||||
|
if check_ret_code == 0:
|
||||||
|
# Success message
|
||||||
|
print(f"{bcolors.OKGREEN}{cmd}: Success{bcolors.ENDC}", flush=True)
|
||||||
|
f.write("Validation Tests completed with 0 errors\n") # Write success message to the log
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
# Failure message
|
||||||
|
print(f"{bcolors.FAIL}{cmd}: Failures detected in output. Check {sim_log}.{bcolors.ENDC}", flush=True)
|
||||||
|
f.write("ERROR: There is a difference detected in the output\n") # Write failure message to the log
|
||||||
|
return 1
|
||||||
|
elif search_log_for_text(config.grepstr, grepfile):
|
||||||
# Flush is needed to flush output to stdout when running in multiprocessing Pool
|
# Flush is needed to flush output to stdout when running in multiprocessing Pool
|
||||||
print(f"{bcolors.OKGREEN}{cmd}: Success{bcolors.ENDC}", flush=True)
|
print(f"{bcolors.OKGREEN}{cmd}: Success{bcolors.ENDC}", flush=True)
|
||||||
return 0
|
return 0
|
||||||
|
@ -394,6 +415,7 @@ def parse_args():
|
||||||
parser.add_argument("--branch", help="Run branch predictor accuracy tests", action="store_true")
|
parser.add_argument("--branch", help="Run branch predictor accuracy tests", action="store_true")
|
||||||
parser.add_argument("--breker", help="Run Breker tests", action="store_true") # Requires a license for the breker tool. See tests/breker/README.md for details
|
parser.add_argument("--breker", help="Run Breker tests", action="store_true") # Requires a license for the breker tool. See tests/breker/README.md for details
|
||||||
parser.add_argument("--dryrun", help="Print commands invoked to console without running regression", action="store_true")
|
parser.add_argument("--dryrun", help="Print commands invoked to console without running regression", action="store_true")
|
||||||
|
parser.add_argument("--performance", help="Check for performance changes or discrepancies in embench and coremark", action="store_true")
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
@ -421,8 +443,8 @@ def process_args(args):
|
||||||
TIMEOUT_DUR = 30*60 # seconds
|
TIMEOUT_DUR = 30*60 # seconds
|
||||||
elif args.branch:
|
elif args.branch:
|
||||||
TIMEOUT_DUR = 120*60 # seconds
|
TIMEOUT_DUR = 120*60 # seconds
|
||||||
elif args.nightly:
|
elif args.nightly or args.performance:
|
||||||
TIMEOUT_DUR = 30*60 # seconds
|
TIMEOUT_DUR = 60*60 # seconds
|
||||||
else:
|
else:
|
||||||
TIMEOUT_DUR = 10*60 # seconds
|
TIMEOUT_DUR = 10*60 # seconds
|
||||||
|
|
||||||
|
@ -462,10 +484,10 @@ def selectTests(args, sims, coverStr):
|
||||||
addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv32i_m/vm_sv32", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
|
addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv32i_m/vm_sv32", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
|
||||||
# addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv32i_m/pmp32", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1) TODO: Add when working in lockstep
|
# addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv32i_m/pmp32", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1) TODO: Add when working in lockstep
|
||||||
# addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/pmp", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1) TODO: Add when working in lockstep
|
# addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/pmp", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1) TODO: Add when working in lockstep
|
||||||
# run riscv-arch-test tests in functional coverage mode
|
# run cvw-riscv-arch-test tests in functional coverage mode
|
||||||
if args.fcov_act:
|
if args.fcov_act:
|
||||||
addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv32i_m", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
|
addTestsByDir(f"{WALLY}/tests/riscof/work/cvw-riscv-arch-test/rv32i", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
|
||||||
addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
|
addTestsByDir(f"{WALLY}/tests/riscof/work/cvw-riscv-arch-test/rv64i", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
|
||||||
# run branch predictor tests
|
# run branch predictor tests
|
||||||
if args.branch:
|
if args.branch:
|
||||||
addTests(bpredtests, defaultsim, coverStr, configs)
|
addTests(bpredtests, defaultsim, coverStr, configs)
|
||||||
|
@ -503,6 +525,55 @@ def selectTests(args, sims, coverStr):
|
||||||
grepstr="All Tests completed with 0 errors",
|
grepstr="All Tests completed with 0 errors",
|
||||||
grepfile = sim_log)
|
grepfile = sim_log)
|
||||||
configs.append(tc)
|
configs.append(tc)
|
||||||
|
|
||||||
|
if (args.performance or args.nightly):
|
||||||
|
# RUNNING THE EMBENCH TEST
|
||||||
|
actual_embench_directory = f"{WALLY}/benchmarks/embench/actual_embench_results/"
|
||||||
|
expected_embench_directory = f"{WALLY}/benchmarks/embench/expected_embench_results/"
|
||||||
|
embench_logfile_path = os.path.expandvars("$WALLY/benchmarks/embench/run.log")
|
||||||
|
# Create the file if it doesn't exist
|
||||||
|
with open(embench_logfile_path, 'w'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Combine everything into the embench_test command
|
||||||
|
# finds any differences between the two embench directories and appends them to the log file
|
||||||
|
embench_test = TestCase(
|
||||||
|
name="embench",
|
||||||
|
variant="rv32gc",
|
||||||
|
cmd=(
|
||||||
|
f"cd $WALLY/benchmarks/embench && "
|
||||||
|
f"make run >> {embench_logfile_path} 2>&1"
|
||||||
|
),
|
||||||
|
grepstr=None,
|
||||||
|
grepfile=embench_logfile_path,
|
||||||
|
altcommand=f"diff -ru {actual_embench_directory} {expected_embench_directory} >> {embench_logfile_path}"
|
||||||
|
)
|
||||||
|
configs.append(embench_test)
|
||||||
|
|
||||||
|
|
||||||
|
# RUNNING THE COREMARK TEST
|
||||||
|
sim_log = f"{regressionDir}/{defaultsim}/logs/validation.log"
|
||||||
|
coremark_logfile_path = os.path.expandvars(sim_log)
|
||||||
|
# Create the directory (and file) if it doesn't exist
|
||||||
|
os.makedirs(os.path.dirname(coremark_logfile_path), exist_ok=True)
|
||||||
|
with open(coremark_logfile_path, 'w'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
coremark_sweep_test_file = f"{WALLY}/benchmarks/coremark/coremark_sweep.py"
|
||||||
|
actual_coremark_values_csv = f"{WALLY}/benchmarks/coremark/coremark_results.csv"
|
||||||
|
expected_coremark_values_csv = f"{WALLY}/benchmarks/coremark/expected_coremark_results.csv"
|
||||||
|
|
||||||
|
# calculates the difference between the coremark expected outcomes and appends them to the log file
|
||||||
|
coremark_test = TestCase(
|
||||||
|
name="validate_coremark_sweep",
|
||||||
|
variant="coremark check",
|
||||||
|
cmd=(f"python3 {coremark_sweep_test_file}"),
|
||||||
|
grepstr=None,
|
||||||
|
grepfile=coremark_logfile_path,
|
||||||
|
altcommand=f"diff -u {actual_coremark_values_csv} {expected_coremark_values_csv} >> {coremark_logfile_path}"
|
||||||
|
)
|
||||||
|
configs.append(coremark_test)
|
||||||
|
|
||||||
return configs
|
return configs
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
## Created: 30 June 2024
|
## Created: 30 June 2024
|
||||||
## Modified:
|
## Modified:
|
||||||
##
|
##
|
||||||
## Purpose: Check for compatible Linux distibution and set variables accordingly
|
## Purpose: Check for compatible Linux distribution and set variables accordingly
|
||||||
##
|
##
|
||||||
## A component of the CORE-V-WALLY configurable RISC-V project.
|
## A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
## https://github.com/openhwgroup/cvw
|
## https://github.com/openhwgroup/cvw
|
||||||
|
|
|
@ -62,7 +62,7 @@ case "$FAMILY" in
|
||||||
SPIKE_PACKAGES+=(dtc boost-regex boost-system)
|
SPIKE_PACKAGES+=(dtc boost-regex boost-system)
|
||||||
VERILATOR_PACKAGES+=(gperftools mold)
|
VERILATOR_PACKAGES+=(gperftools mold)
|
||||||
BUILDROOT_PACKAGES+=(ncurses ncurses-base ncurses-libs ncurses-devel gcc-gfortran) # gcc-gfortran is only needed for compiling spec benchmarks on buildroot linux
|
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 availale in rhel8, nice for Verilator
|
# Extra packages not available in rhel8, nice for Verilator
|
||||||
if (( RHEL_VERSION >= 9 )); then
|
if (( RHEL_VERSION >= 9 )); then
|
||||||
VERILATOR_PACKAGES+=(perl-doc)
|
VERILATOR_PACKAGES+=(perl-doc)
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -236,9 +236,9 @@ pip install --upgrade pip && pip install --upgrade -r "$dir"/requirements.txt
|
||||||
source "$RISCV"/riscv-python/bin/activate # reload python virtual environment
|
source "$RISCV"/riscv-python/bin/activate # reload python virtual environment
|
||||||
echo -e "${SUCCESS_COLOR}Python environment successfully configured!${ENDC}"
|
echo -e "${SUCCESS_COLOR}Python environment successfully configured!${ENDC}"
|
||||||
|
|
||||||
# Extra dependecies needed for older distros that don't have new enough versions available from package manager
|
# Extra dependencies needed for older distros that don't have new enough versions available from package manager
|
||||||
if (( RHEL_VERSION == 8 )) || (( UBUNTU_VERSION == 20 )); then
|
if (( RHEL_VERSION == 8 )) || (( UBUNTU_VERSION == 20 )); then
|
||||||
# Newer versin of glib required for QEMU.
|
# Newer version of glib required for QEMU.
|
||||||
# Anything newer than this won't build on red hat 8
|
# Anything newer than this won't build on red hat 8
|
||||||
STATUS="glib"
|
STATUS="glib"
|
||||||
if [ ! -e "$RISCV"/include/glib-2.0 ]; then
|
if [ ! -e "$RISCV"/include/glib-2.0 ]; then
|
||||||
|
@ -480,7 +480,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
# Buildroot and Linux testvectors
|
# Buildroot and Linux testvectors
|
||||||
# Buildroot is used to boot a minimal versio of Linux on Wally.
|
# Buildroot is used to boot a minimal version of Linux on Wally.
|
||||||
# Testvectors are generated using QEMU.
|
# Testvectors are generated using QEMU.
|
||||||
if [ ! "$no_buidroot" ]; then
|
if [ ! "$no_buidroot" ]; then
|
||||||
section_header "Installing Buildroot and Creating Linux testvectors"
|
section_header "Installing Buildroot and Creating Linux testvectors"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
QUESTA_HOME?=/cad/mentor/questa_sim-2023.4
|
QUESTA_HOME?=/cad/mentor/questa_sim-2023.4
|
||||||
CVW_GIT?=""
|
CVW_GIT?=""
|
||||||
|
|
||||||
commanline:
|
commandline:
|
||||||
podman run -it --rm \
|
podman run -it --rm \
|
||||||
-v cvw_temp:/home/cad/cvw \
|
-v cvw_temp:/home/cad/cvw \
|
||||||
-v $(QUESTA_HOME):/cad/mentor/questa_sim-xxxx.x_x \
|
-v $(QUESTA_HOME):/cad/mentor/questa_sim-xxxx.x_x \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Consistant Build of Toolchain for Wally
|
# Consistent Build of Toolchain for Wally
|
||||||
|
|
||||||
`Dockerfile.*` contains a ~~multi-stage~~ build for all the toolchains that are required for Wally's open-source features.
|
`Dockerfile.*` contains a ~~multi-stage~~ build for all the toolchains that are required for Wally's open-source features.
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ Files at this folder can help you to build/fetch environment you need to run wal
|
||||||
Here are some common use cases, it will **provides you an environment with RISC-V toolchains** that required by this project:
|
Here are some common use cases, it will **provides you an environment with RISC-V toolchains** that required by this project:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# By default, we assume that you have cloned the cvw respository and running the script at relative path `docs/docker`
|
# By default, we assume that you have cloned the cvw repository and running the script at relative path `docs/docker`
|
||||||
|
|
||||||
# For HMC students, /opt/riscv is available and nothing needs to be built
|
# For HMC students, /opt/riscv is available and nothing needs to be built
|
||||||
TOOLCHAINS_MOUNT=/opt/riscv QUESTA=/cad/mentor/questa_sim-2023.4 ./start.sh
|
TOOLCHAINS_MOUNT=/opt/riscv QUESTA=/cad/mentor/questa_sim-2023.4 ./start.sh
|
||||||
|
@ -265,7 +265,7 @@ There are at least two ways to solve this problem:
|
||||||
|
|
||||||
There are stages in the old Dockerfile:
|
There are stages in the old Dockerfile:
|
||||||
|
|
||||||
- debian-based package installtion
|
- debian-based package installation
|
||||||
- apt package
|
- apt package
|
||||||
- python3 package
|
- python3 package
|
||||||
- user and its group configuration
|
- user and its group configuration
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
/* The OUTPUT_ARCH command specifies the machine architecture where the
|
/* The OUTPUT_ARCH command specifies the machine architecture where the
|
||||||
argument is one of the names used in the BFD library. More
|
argument is one of the names used in the BFD library. More
|
||||||
specifically one of the entires in bfd/cpu-mips.c */
|
specifically one of the entries in bfd/cpu-mips.c */
|
||||||
|
|
||||||
OUTPUT_ARCH( "riscv" )
|
OUTPUT_ARCH( "riscv" )
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
@ -60,7 +60,7 @@ SECTIONS
|
||||||
_tbss_end = .;
|
_tbss_end = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of uninitalized data segement */
|
/* End of uninitialized data segment */
|
||||||
_end = .;
|
_end = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ int main(void) {
|
||||||
int tmp = Y[i];
|
int tmp = Y[i];
|
||||||
printf("Y[%d] = %d\n", i, tmp);
|
printf("Y[%d] = %d\n", i, tmp);
|
||||||
}
|
}
|
||||||
// verifyDouble doesn't work exaclty because of rounding, so check for almost equal
|
// verifyDouble doesn't work exactly because of rounding, so check for almost equal
|
||||||
for (int i=0; i<15; i++) {
|
for (int i=0; i<15; i++) {
|
||||||
if (fabs(Y[i] - Yexpected[i]) > 1e-10) {
|
if (fabs(Y[i] - Yexpected[i]) > 1e-10) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -273,7 +273,7 @@ void mixColumn(unsigned char *column) {
|
||||||
column[3] = b[3] ^ a[2] ^ a[1] ^ gfmul(a[0], 3);
|
column[3] = b[3] ^ a[2] ^ a[1] ^ gfmul(a[0], 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The rounds in the specifcation of CIPHER() are composed of the following 4 byte-oriented
|
// The rounds in the specification of CIPHER() are composed of the following 4 byte-oriented
|
||||||
// transformations on the state (Section 5.1 of FIPS 197) - outputs hex after each step
|
// transformations on the state (Section 5.1 of FIPS 197) - outputs hex after each step
|
||||||
void aes_cipher(unsigned char *state, unsigned char *roundKey) {
|
void aes_cipher(unsigned char *state, unsigned char *roundKey) {
|
||||||
subBytes(state);
|
subBytes(state);
|
||||||
|
|
|
@ -230,11 +230,11 @@ set verilogout_no_tri true
|
||||||
set verilogout_equation false
|
set verilogout_equation false
|
||||||
|
|
||||||
# setting to generate output files
|
# setting to generate output files
|
||||||
set write_v 1 ;# generates structual netlist
|
set write_v 1 ;# generates structural netlist
|
||||||
set write_sdc 1 ;# generates synopsys design constraint file for p&r
|
set write_sdc 1 ;# generates synopsys design constraint file for p&r
|
||||||
set write_ddc 1 ;# compiler file in ddc format
|
set write_ddc 1 ;# compiler file in ddc format
|
||||||
set write_sdf 1 ;# sdf file for backannotated timing sim
|
set write_sdf 1 ;# sdf file for backannotated timing sim
|
||||||
set write_pow 1 ;# genrates estimated power report
|
set write_pow 1 ;# generates estimated power report
|
||||||
set write_rep 1 ;# generates estimated area and timing report
|
set write_rep 1 ;# generates estimated area and timing report
|
||||||
set write_cst 1 ;# generate report of constraints
|
set write_cst 1 ;# generate report of constraints
|
||||||
set write_hier 1 ;# generate hierarchy report
|
set write_hier 1 ;# generate hierarchy report
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
create_debug_core u_ila_0 ila
|
create_debug_core u_ila_0 ila
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set_property C_DATA_DEPTH 16384 [get_debug_cores u_ila_0]
|
set_property C_DATA_DEPTH 16384 [get_debug_cores u_ila_0]
|
||||||
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
|
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
|
||||||
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
|
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
|
||||||
|
@ -14,7 +17,8 @@ set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ]
|
||||||
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ]
|
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ]
|
||||||
set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ]
|
set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ]
|
||||||
endgroup
|
endgroup
|
||||||
connect_debug_port u_ila_0/clk [get_nets [list xlnx_ddr4_c0/inst/u_ddr4_infrastructure/addn_ui_clkout1 ]]
|
connect_debug_port u_ila_0/clk [get_nets CPUCLK]
|
||||||
|
|
||||||
set_property port_width 64 [get_debug_ports u_ila_0/probe0]
|
set_property port_width 64 [get_debug_ports u_ila_0/probe0]
|
||||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0]
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0]
|
||||||
connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/lsu/LSUHWDATA[0]} {wallypipelinedsoc/core/lsu/LSUHWDATA[1]} {wallypipelinedsoc/core/lsu/LSUHWDATA[2]} {wallypipelinedsoc/core/lsu/LSUHWDATA[3]} {wallypipelinedsoc/core/lsu/LSUHWDATA[4]} {wallypipelinedsoc/core/lsu/LSUHWDATA[5]} {wallypipelinedsoc/core/lsu/LSUHWDATA[6]} {wallypipelinedsoc/core/lsu/LSUHWDATA[7]} {wallypipelinedsoc/core/lsu/LSUHWDATA[8]} {wallypipelinedsoc/core/lsu/LSUHWDATA[9]} {wallypipelinedsoc/core/lsu/LSUHWDATA[10]} {wallypipelinedsoc/core/lsu/LSUHWDATA[11]} {wallypipelinedsoc/core/lsu/LSUHWDATA[12]} {wallypipelinedsoc/core/lsu/LSUHWDATA[13]} {wallypipelinedsoc/core/lsu/LSUHWDATA[14]} {wallypipelinedsoc/core/lsu/LSUHWDATA[15]} {wallypipelinedsoc/core/lsu/LSUHWDATA[16]} {wallypipelinedsoc/core/lsu/LSUHWDATA[17]} {wallypipelinedsoc/core/lsu/LSUHWDATA[18]} {wallypipelinedsoc/core/lsu/LSUHWDATA[19]} {wallypipelinedsoc/core/lsu/LSUHWDATA[20]} {wallypipelinedsoc/core/lsu/LSUHWDATA[21]} {wallypipelinedsoc/core/lsu/LSUHWDATA[22]} {wallypipelinedsoc/core/lsu/LSUHWDATA[23]} {wallypipelinedsoc/core/lsu/LSUHWDATA[24]} {wallypipelinedsoc/core/lsu/LSUHWDATA[25]} {wallypipelinedsoc/core/lsu/LSUHWDATA[26]} {wallypipelinedsoc/core/lsu/LSUHWDATA[27]} {wallypipelinedsoc/core/lsu/LSUHWDATA[28]} {wallypipelinedsoc/core/lsu/LSUHWDATA[29]} {wallypipelinedsoc/core/lsu/LSUHWDATA[30]} {wallypipelinedsoc/core/lsu/LSUHWDATA[31]} {wallypipelinedsoc/core/lsu/LSUHWDATA[32]} {wallypipelinedsoc/core/lsu/LSUHWDATA[33]} {wallypipelinedsoc/core/lsu/LSUHWDATA[34]} {wallypipelinedsoc/core/lsu/LSUHWDATA[35]} {wallypipelinedsoc/core/lsu/LSUHWDATA[36]} {wallypipelinedsoc/core/lsu/LSUHWDATA[37]} {wallypipelinedsoc/core/lsu/LSUHWDATA[38]} {wallypipelinedsoc/core/lsu/LSUHWDATA[39]} {wallypipelinedsoc/core/lsu/LSUHWDATA[40]} {wallypipelinedsoc/core/lsu/LSUHWDATA[41]} {wallypipelinedsoc/core/lsu/LSUHWDATA[42]} {wallypipelinedsoc/core/lsu/LSUHWDATA[43]} {wallypipelinedsoc/core/lsu/LSUHWDATA[44]} {wallypipelinedsoc/core/lsu/LSUHWDATA[45]} {wallypipelinedsoc/core/lsu/LSUHWDATA[46]} {wallypipelinedsoc/core/lsu/LSUHWDATA[47]} {wallypipelinedsoc/core/lsu/LSUHWDATA[48]} {wallypipelinedsoc/core/lsu/LSUHWDATA[49]} {wallypipelinedsoc/core/lsu/LSUHWDATA[50]} {wallypipelinedsoc/core/lsu/LSUHWDATA[51]} {wallypipelinedsoc/core/lsu/LSUHWDATA[52]} {wallypipelinedsoc/core/lsu/LSUHWDATA[53]} {wallypipelinedsoc/core/lsu/LSUHWDATA[54]} {wallypipelinedsoc/core/lsu/LSUHWDATA[55]} {wallypipelinedsoc/core/lsu/LSUHWDATA[56]} {wallypipelinedsoc/core/lsu/LSUHWDATA[57]} {wallypipelinedsoc/core/lsu/LSUHWDATA[58]} {wallypipelinedsoc/core/lsu/LSUHWDATA[59]} {wallypipelinedsoc/core/lsu/LSUHWDATA[60]} {wallypipelinedsoc/core/lsu/LSUHWDATA[61]} {wallypipelinedsoc/core/lsu/LSUHWDATA[62]} {wallypipelinedsoc/core/lsu/LSUHWDATA[63]} ]]
|
connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/lsu/LSUHWDATA[0]} {wallypipelinedsoc/core/lsu/LSUHWDATA[1]} {wallypipelinedsoc/core/lsu/LSUHWDATA[2]} {wallypipelinedsoc/core/lsu/LSUHWDATA[3]} {wallypipelinedsoc/core/lsu/LSUHWDATA[4]} {wallypipelinedsoc/core/lsu/LSUHWDATA[5]} {wallypipelinedsoc/core/lsu/LSUHWDATA[6]} {wallypipelinedsoc/core/lsu/LSUHWDATA[7]} {wallypipelinedsoc/core/lsu/LSUHWDATA[8]} {wallypipelinedsoc/core/lsu/LSUHWDATA[9]} {wallypipelinedsoc/core/lsu/LSUHWDATA[10]} {wallypipelinedsoc/core/lsu/LSUHWDATA[11]} {wallypipelinedsoc/core/lsu/LSUHWDATA[12]} {wallypipelinedsoc/core/lsu/LSUHWDATA[13]} {wallypipelinedsoc/core/lsu/LSUHWDATA[14]} {wallypipelinedsoc/core/lsu/LSUHWDATA[15]} {wallypipelinedsoc/core/lsu/LSUHWDATA[16]} {wallypipelinedsoc/core/lsu/LSUHWDATA[17]} {wallypipelinedsoc/core/lsu/LSUHWDATA[18]} {wallypipelinedsoc/core/lsu/LSUHWDATA[19]} {wallypipelinedsoc/core/lsu/LSUHWDATA[20]} {wallypipelinedsoc/core/lsu/LSUHWDATA[21]} {wallypipelinedsoc/core/lsu/LSUHWDATA[22]} {wallypipelinedsoc/core/lsu/LSUHWDATA[23]} {wallypipelinedsoc/core/lsu/LSUHWDATA[24]} {wallypipelinedsoc/core/lsu/LSUHWDATA[25]} {wallypipelinedsoc/core/lsu/LSUHWDATA[26]} {wallypipelinedsoc/core/lsu/LSUHWDATA[27]} {wallypipelinedsoc/core/lsu/LSUHWDATA[28]} {wallypipelinedsoc/core/lsu/LSUHWDATA[29]} {wallypipelinedsoc/core/lsu/LSUHWDATA[30]} {wallypipelinedsoc/core/lsu/LSUHWDATA[31]} {wallypipelinedsoc/core/lsu/LSUHWDATA[32]} {wallypipelinedsoc/core/lsu/LSUHWDATA[33]} {wallypipelinedsoc/core/lsu/LSUHWDATA[34]} {wallypipelinedsoc/core/lsu/LSUHWDATA[35]} {wallypipelinedsoc/core/lsu/LSUHWDATA[36]} {wallypipelinedsoc/core/lsu/LSUHWDATA[37]} {wallypipelinedsoc/core/lsu/LSUHWDATA[38]} {wallypipelinedsoc/core/lsu/LSUHWDATA[39]} {wallypipelinedsoc/core/lsu/LSUHWDATA[40]} {wallypipelinedsoc/core/lsu/LSUHWDATA[41]} {wallypipelinedsoc/core/lsu/LSUHWDATA[42]} {wallypipelinedsoc/core/lsu/LSUHWDATA[43]} {wallypipelinedsoc/core/lsu/LSUHWDATA[44]} {wallypipelinedsoc/core/lsu/LSUHWDATA[45]} {wallypipelinedsoc/core/lsu/LSUHWDATA[46]} {wallypipelinedsoc/core/lsu/LSUHWDATA[47]} {wallypipelinedsoc/core/lsu/LSUHWDATA[48]} {wallypipelinedsoc/core/lsu/LSUHWDATA[49]} {wallypipelinedsoc/core/lsu/LSUHWDATA[50]} {wallypipelinedsoc/core/lsu/LSUHWDATA[51]} {wallypipelinedsoc/core/lsu/LSUHWDATA[52]} {wallypipelinedsoc/core/lsu/LSUHWDATA[53]} {wallypipelinedsoc/core/lsu/LSUHWDATA[54]} {wallypipelinedsoc/core/lsu/LSUHWDATA[55]} {wallypipelinedsoc/core/lsu/LSUHWDATA[56]} {wallypipelinedsoc/core/lsu/LSUHWDATA[57]} {wallypipelinedsoc/core/lsu/LSUHWDATA[58]} {wallypipelinedsoc/core/lsu/LSUHWDATA[59]} {wallypipelinedsoc/core/lsu/LSUHWDATA[60]} {wallypipelinedsoc/core/lsu/LSUHWDATA[61]} {wallypipelinedsoc/core/lsu/LSUHWDATA[62]} {wallypipelinedsoc/core/lsu/LSUHWDATA[63]} ]]
|
||||||
|
@ -366,7 +370,7 @@ connect_debug_port u_ila_0/probe69 [get_nets [list {wallypipelinedsoc/core/priv.
|
||||||
create_debug_port u_ila_0 probe
|
create_debug_port u_ila_0 probe
|
||||||
set_property port_width 1 [get_debug_ports u_ila_0/probe70]
|
set_property port_width 1 [get_debug_ports u_ila_0/probe70]
|
||||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe70]
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe70]
|
||||||
connect_debug_port u_ila_0/probe70 [get_nets [list wallypipelinedsoc/core/lsu/ITLBMissF]]
|
connect_debug_port u_ila_0/probe70 [get_nets [list wallypipelinedsoc/core/lsu/ITLBMissOrUpdateAF]]
|
||||||
|
|
||||||
create_debug_port u_ila_0 probe
|
create_debug_port u_ila_0 probe
|
||||||
set_property port_width 1 [get_debug_ports u_ila_0/probe71]
|
set_property port_width 1 [get_debug_ports u_ila_0/probe71]
|
||||||
|
@ -547,3 +551,19 @@ create_debug_port u_ila_0 probe
|
||||||
set_property port_width 48 [get_debug_ports u_ila_0/probe105]
|
set_property port_width 48 [get_debug_ports u_ila_0/probe105]
|
||||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe105]
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe105]
|
||||||
connect_debug_port u_ila_0/probe105 [get_nets [list {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[0]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[1]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[2]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[3]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[4]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[5]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[6]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[7]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[8]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[9]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[10]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[11]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[12]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[13]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[14]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[15]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[16]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[17]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[18]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[19]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[20]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[21]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[22]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[23]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[24]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[25]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[26]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[27]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[28]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[29]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[30]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[31]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[32]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[33]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[34]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[35]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[36]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[37]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[38]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[39]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[40]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[41]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[42]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[43]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[60]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[61]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[62]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[63]}]]
|
connect_debug_port u_ila_0/probe105 [get_nets [list {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[0]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[1]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[2]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[3]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[4]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[5]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[6]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[7]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[8]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[9]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[10]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[11]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[12]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[13]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[14]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[15]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[16]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[17]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[18]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[19]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[20]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[21]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[22]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[23]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[24]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[25]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[26]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[27]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[28]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[29]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[30]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[31]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[32]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[33]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[34]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[35]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[36]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[37]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[38]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[39]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[40]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[41]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[42]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[43]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[60]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[61]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[62]} {wallypipelinedsoc/core/lsu/hptw.hptw/SATP_REGW[63]}]]
|
||||||
|
|
||||||
|
create_debug_port u_ila_0 probe
|
||||||
|
set_property port_width 64 [get_debug_ports u_ila_0/probe106]
|
||||||
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe106]
|
||||||
|
connect_debug_port u_ila_0/probe106 [get_nets [list {wallypipelinedsoc/core/ieu/dp/ALUResultE[0]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[1]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[2]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[3]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[4]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[5]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[6]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[7]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[8]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[9]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[10]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[11]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[12]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[13]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[14]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[15]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[16]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[17]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[18]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[19]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[20]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[21]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[22]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[23]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[24]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[25]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[26]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[27]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[28]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[29]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[30]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[31]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[32]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[33]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[34]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[35]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[36]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[37]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[38]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[39]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[40]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[41]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[42]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[43]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[44]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[45]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[46]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[47]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[48]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[49]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[50]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[51]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[52]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[53]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[54]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[55]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[56]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[57]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[58]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[59]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[60]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[61]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[62]} {wallypipelinedsoc/core/ieu/dp/ALUResultE[63]} ]]
|
||||||
|
|
||||||
|
create_debug_port u_ila_0 probe
|
||||||
|
set_property port_width 56 [get_debug_ports u_ila_0/probe107]
|
||||||
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe107]
|
||||||
|
connect_debug_port u_ila_0/probe107 [get_nets [list {wallypipelinedsoc/core/lsu/PAdrM[0]} {wallypipelinedsoc/core/lsu/PAdrM[1]} {wallypipelinedsoc/core/lsu/PAdrM[2]} {wallypipelinedsoc/core/lsu/PAdrM[3]} {wallypipelinedsoc/core/lsu/PAdrM[4]} {wallypipelinedsoc/core/lsu/PAdrM[5]} {wallypipelinedsoc/core/lsu/PAdrM[6]} {wallypipelinedsoc/core/lsu/PAdrM[7]} {wallypipelinedsoc/core/lsu/PAdrM[8]} {wallypipelinedsoc/core/lsu/PAdrM[9]} {wallypipelinedsoc/core/lsu/PAdrM[10]} {wallypipelinedsoc/core/lsu/PAdrM[11]} {wallypipelinedsoc/core/lsu/PAdrM[12]} {wallypipelinedsoc/core/lsu/PAdrM[13]} {wallypipelinedsoc/core/lsu/PAdrM[14]} {wallypipelinedsoc/core/lsu/PAdrM[15]} {wallypipelinedsoc/core/lsu/PAdrM[16]} {wallypipelinedsoc/core/lsu/PAdrM[17]} {wallypipelinedsoc/core/lsu/PAdrM[18]} {wallypipelinedsoc/core/lsu/PAdrM[19]} {wallypipelinedsoc/core/lsu/PAdrM[20]} {wallypipelinedsoc/core/lsu/PAdrM[21]} {wallypipelinedsoc/core/lsu/PAdrM[22]} {wallypipelinedsoc/core/lsu/PAdrM[23]} {wallypipelinedsoc/core/lsu/PAdrM[24]} {wallypipelinedsoc/core/lsu/PAdrM[25]} {wallypipelinedsoc/core/lsu/PAdrM[26]} {wallypipelinedsoc/core/lsu/PAdrM[27]} {wallypipelinedsoc/core/lsu/PAdrM[28]} {wallypipelinedsoc/core/lsu/PAdrM[29]} {wallypipelinedsoc/core/lsu/PAdrM[30]} {wallypipelinedsoc/core/lsu/PAdrM[31]} {wallypipelinedsoc/core/lsu/PAdrM[32]} {wallypipelinedsoc/core/lsu/PAdrM[33]} {wallypipelinedsoc/core/lsu/PAdrM[34]} {wallypipelinedsoc/core/lsu/PAdrM[35]} {wallypipelinedsoc/core/lsu/PAdrM[36]} {wallypipelinedsoc/core/lsu/PAdrM[37]} {wallypipelinedsoc/core/lsu/PAdrM[38]} {wallypipelinedsoc/core/lsu/PAdrM[39]} {wallypipelinedsoc/core/lsu/PAdrM[40]} {wallypipelinedsoc/core/lsu/PAdrM[41]} {wallypipelinedsoc/core/lsu/PAdrM[42]} {wallypipelinedsoc/core/lsu/PAdrM[43]} {wallypipelinedsoc/core/lsu/PAdrM[44]} {wallypipelinedsoc/core/lsu/PAdrM[45]} {wallypipelinedsoc/core/lsu/PAdrM[46]} {wallypipelinedsoc/core/lsu/PAdrM[47]} {wallypipelinedsoc/core/lsu/PAdrM[48]} {wallypipelinedsoc/core/lsu/PAdrM[49]} {wallypipelinedsoc/core/lsu/PAdrM[50]} {wallypipelinedsoc/core/lsu/PAdrM[51]} {wallypipelinedsoc/core/lsu/PAdrM[52]} {wallypipelinedsoc/core/lsu/PAdrM[53]} {wallypipelinedsoc/core/lsu/PAdrM[54]} {wallypipelinedsoc/core/lsu/PAdrM[55]} ]]
|
||||||
|
|
||||||
|
|
||||||
|
create_debug_port u_ila_0 probe
|
||||||
|
set_property port_width 64 [get_debug_ports u_ila_0/probe108]
|
||||||
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe108]
|
||||||
|
connect_debug_port u_ila_0/probe108 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[0]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[1]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[2]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[3]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[4]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[5]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[6]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[7]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[8]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[9]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[10]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[11]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[12]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[13]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[14]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[15]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[16]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[17]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[18]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[19]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[20]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[21]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[22]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[23]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[24]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[25]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[26]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[27]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[28]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[29]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[30]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[31]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[32]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[33]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[34]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[35]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[36]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[37]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[38]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[39]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[40]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[41]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[42]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[43]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[44]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[45]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[46]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[47]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[48]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[49]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[50]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[51]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[52]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[53]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[54]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[55]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[56]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[57]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[58]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[59]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[60]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[61]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[62]} {wallypipelinedsoc/core/priv.priv/csr/MENVCFG_REGW[63]} ]]
|
||||||
|
|
135
fpga/constraints/marked_debug_debug6.txt
Normal file
135
fpga/constraints/marked_debug_debug6.txt
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
lsu/lsu.sv: logic IEUAdrM
|
||||||
|
lsu/lsu.sv: logic PAdrM
|
||||||
|
lsu/lsu.sv: logic WriteDataM
|
||||||
|
lsu/lsu.sv: logic LSUHADDR
|
||||||
|
lsu/lsu.sv: logic HRDATA
|
||||||
|
lsu/lsu.sv: logic LSUHWDATA
|
||||||
|
lsu/lsu.sv: logic LSUHREADY
|
||||||
|
lsu/lsu.sv: logic LSUHWRITE
|
||||||
|
lsu/lsu.sv: logic LSUHSIZE
|
||||||
|
lsu/lsu.sv: logic LSUHBURST
|
||||||
|
lsu/lsu.sv: logic LSUHTRANS
|
||||||
|
lsu/lsu.sv: logic LSUHWSTRB
|
||||||
|
lsu/lsu.sv: logic IHAdrM
|
||||||
|
ieu/regfile.sv: logic rf
|
||||||
|
ieu/datapath.sv: logic RegWriteW
|
||||||
|
hazard/hazard.sv: logic BPPredWrongE
|
||||||
|
hazard/hazard.sv: logic LoadStallD
|
||||||
|
hazard/hazard.sv: logic FCvtIntStallD
|
||||||
|
hazard/hazard.sv: logic DivBusyE
|
||||||
|
hazard/hazard.sv: logic EcallFaultM
|
||||||
|
hazard/hazard.sv: logic WFIStallM
|
||||||
|
hazard/hazard.sv: logic StallF
|
||||||
|
hazard/hazard.sv: logic FlushD
|
||||||
|
cache/cachefsm.sv: statetype CurrState
|
||||||
|
wally/wallypipelinedcore.sv: logic TrapM
|
||||||
|
wally/wallypipelinedcore.sv: logic SrcAM
|
||||||
|
wally/wallypipelinedcore.sv: logic InstrM
|
||||||
|
wally/wallypipelinedcore.sv: logic PCM
|
||||||
|
wally/wallypipelinedcore.sv: logic MemRWM
|
||||||
|
wally/wallypipelinedcore.sv: logic InstrValidM
|
||||||
|
wally/wallypipelinedcore.sv: logic WriteDataM
|
||||||
|
wally/wallypipelinedcore.sv: logic IEUAdrM
|
||||||
|
ieu/datapath.sv: logic ALUResultE
|
||||||
|
wally/wallypipelinedcore.sv: logic HRDATA
|
||||||
|
ifu/spill.sv: statetype CurrState
|
||||||
|
ifu/ifu.sv: logic IFUStallF
|
||||||
|
ifu/ifu.sv: logic IFUHADDR
|
||||||
|
ifu/ifu.sv: logic HRDATA
|
||||||
|
ifu/ifu.sv: logic IFUHREADY
|
||||||
|
ifu/ifu.sv: logic IFUHWRITE
|
||||||
|
ifu/ifu.sv: logic IFUHSIZE
|
||||||
|
ifu/ifu.sv: logic IFUHBURST
|
||||||
|
ifu/ifu.sv: logic IFUHTRANS
|
||||||
|
ifu/ifu.sv: logic PCF
|
||||||
|
ifu/ifu.sv: logic PCNextF
|
||||||
|
ifu/ifu.sv: logic PCPF
|
||||||
|
ifu/ifu.sv: logic PostSpillInstrRawF
|
||||||
|
mmu/hptw.sv: logic ITLBMissOrUpdateAF
|
||||||
|
mmu/hptw.sv: statetype WalkerState
|
||||||
|
mmu/hptw.sv: logic ValidPTE
|
||||||
|
privileged/csrs.sv: logic CSRSReadValM
|
||||||
|
privileged/csrs.sv: logic SEPC_REGW
|
||||||
|
privileged/csrs.sv: logic MIP_REGW
|
||||||
|
privileged/csrs.sv: logic SSCRATCH_REGW
|
||||||
|
privileged/csrs.sv: logic SCAUSE_REGW
|
||||||
|
privileged/csr.sv: logic CSRReadValM
|
||||||
|
privileged/csr.sv: logic CSRSrcM
|
||||||
|
privileged/csr.sv: logic CSRWriteValM
|
||||||
|
privileged/csr.sv: logic MSTATUS_REGW
|
||||||
|
privileged/trap.sv: logic InstrMisalignedFaultM
|
||||||
|
privileged/trap.sv: logic BreakpointFaultM
|
||||||
|
privileged/trap.sv: logic LoadAccessFaultM
|
||||||
|
privileged/trap.sv: logic LoadPageFaultM
|
||||||
|
privileged/trap.sv: logic mretM
|
||||||
|
privileged/trap.sv: logic MIP_REGW
|
||||||
|
privileged/trap.sv: logic PendingIntsM
|
||||||
|
privileged/privileged.sv: logic CSRReadM
|
||||||
|
privileged/csr.sv: logic MENVCFG_REGW
|
||||||
|
privileged/privileged.sv: logic InterruptM
|
||||||
|
privileged/csrc.sv: logic HPMCOUNTER_REGW
|
||||||
|
privileged/csri.sv: logic MExtInt
|
||||||
|
privileged/csri.sv: logic MIP_REGW_writeabl
|
||||||
|
privileged/csrm.sv: logic MIP_REGW
|
||||||
|
privileged/csrm.sv: logic MEPC_REGW
|
||||||
|
privileged/csrm.sv: logic MEDELEG_REGW
|
||||||
|
privileged/csrm.sv: logic MIDELEG_REGW
|
||||||
|
privileged/csrm.sv: logic MSCRATCH_REGW
|
||||||
|
privileged/csrm.sv: logic MCAUSE_REGW
|
||||||
|
uncore/uart_apb.sv: logic SIN
|
||||||
|
uncore/uart_apb.sv: logic SOUT
|
||||||
|
uncore/uart_apb.sv: logic OUT1b
|
||||||
|
uncore/uartPC16550D.sv: logic RBR
|
||||||
|
uncore/uartPC16550D.sv: logic FCR
|
||||||
|
uncore/uartPC16550D.sv: logic IER
|
||||||
|
uncore/uartPC16550D.sv: logic MCR
|
||||||
|
uncore/uartPC16550D.sv: logic baudpulse
|
||||||
|
uncore/uartPC16550D.sv: statetype rxstate
|
||||||
|
uncore/uartPC16550D.sv: logic rxfifo
|
||||||
|
uncore/uartPC16550D.sv: logic txfifo
|
||||||
|
uncore/uartPC16550D.sv: logic rxfifohead
|
||||||
|
uncore/uartPC16550D.sv: logic rxfifoentries
|
||||||
|
uncore/uartPC16550D.sv: logic RXBR
|
||||||
|
uncore/uartPC16550D.sv: logic rxtimeoutcnt
|
||||||
|
uncore/uartPC16550D.sv: logic rxparityerr
|
||||||
|
uncore/uartPC16550D.sv: logic rxdataready
|
||||||
|
uncore/uartPC16550D.sv: logic rxfifoempty
|
||||||
|
uncore/uartPC16550D.sv: logic rxdata
|
||||||
|
uncore/uartPC16550D.sv: logic RXerrbit
|
||||||
|
uncore/uartPC16550D.sv: logic rxfullbitunwrapped
|
||||||
|
uncore/uartPC16550D.sv: logic txdata
|
||||||
|
uncore/uartPC16550D.sv: logic txnextbit
|
||||||
|
uncore/uartPC16550D.sv: logic txfifoempty
|
||||||
|
uncore/uartPC16550D.sv: logic fifoenabled
|
||||||
|
uncore/uartPC16550D.sv: logic RXerr
|
||||||
|
uncore/uartPC16550D.sv: logic THRE
|
||||||
|
uncore/uartPC16550D.sv: logic rxdataavailintr
|
||||||
|
uncore/uartPC16550D.sv: logic intrID
|
||||||
|
uncore/uncore.sv: logic HSELEXTSDCD
|
||||||
|
uncore/plic_apb.sv: logic MExtInt
|
||||||
|
uncore/plic_apb.sv: logic Din
|
||||||
|
uncore/plic_apb.sv: logic requests
|
||||||
|
uncore/plic_apb.sv: logic intPriority
|
||||||
|
uncore/plic_apb.sv: logic intInProgress
|
||||||
|
uncore/plic_apb.sv: logic intThreshold
|
||||||
|
uncore/plic_apb.sv: logic intEn
|
||||||
|
uncore/plic_apb.sv: logic intClaim
|
||||||
|
uncore/plic_apb.sv: logic irqMatrix
|
||||||
|
uncore/plic_apb.sv: logic priorities_with_irqs
|
||||||
|
uncore/plic_apb.sv: logic max_priority_with_irqs
|
||||||
|
uncore/plic_apb.sv: logic irqs_at_max_priority
|
||||||
|
uncore/plic_apb.sv: logic threshMask
|
||||||
|
uncore/clint_apb.sv: logic MTIME
|
||||||
|
uncore/clint_apb.sv: logic MTIMECMP
|
||||||
|
ebu/ebu.sv: logic HCLK
|
||||||
|
ebu/ebu.sv: logic HREADY
|
||||||
|
ebu/ebu.sv: logic HRESP
|
||||||
|
ebu/ebu.sv: logic HADDR
|
||||||
|
ebu/ebu.sv: logic HWRITE
|
||||||
|
ebu/ebu.sv: logic HSIZE
|
||||||
|
ebu/ebu.sv: logic HBURST
|
||||||
|
ebu/ebu.sv: logic HPROT
|
||||||
|
ebu/ebu.sv: logic HTRANS
|
||||||
|
ebu/ebu.sv: logic HMASTLOC
|
||||||
|
ebu/buscachefsm.sv: busstatetype CurrState
|
||||||
|
ebu/busfsm.sv: busstatetype CurrState
|
|
@ -169,7 +169,7 @@ int main(int argc, char **argv){
|
||||||
if (ioctl(sockfd, SIOCGIFINDEX, &ifopts) < 0)
|
if (ioctl(sockfd, SIOCGIFINDEX, &ifopts) < 0)
|
||||||
perror("SIOCGIFINDEX");
|
perror("SIOCGIFINDEX");
|
||||||
|
|
||||||
/* Allow the socket to be reused - incase connection is closed prematurely */
|
/* Allow the socket to be reused - in case connection is closed prematurely */
|
||||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
|
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
|
||||||
perror("setsockopt");
|
perror("setsockopt");
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
|
|
|
@ -223,7 +223,7 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 0)
|
||||||
// the ddr3 mig7 requires 2 input clocks
|
// the ddr3 mig7 requires 2 input clocks
|
||||||
// 1. sys clock which is 167 MHz = ddr3 clock / 4
|
// 1. sys clock which is 167 MHz = ddr3 clock / 4
|
||||||
// 2. a second clock which is 200 MHz
|
// 2. a second clock which is 200 MHz
|
||||||
// Wally requires a slower clock. At this point I don't know what speed the atrix 7 will run so I'm initially targetting 25Mhz.
|
// Wally requires a slower clock. At this point I don't know what speed the atrix 7 will run so I'm initially targeting 25Mhz.
|
||||||
// the mig will output a clock at 1/4 the sys clock or 41Mhz which might work with wally so we may be able to simplify the logic a lot.
|
// the mig will output a clock at 1/4 the sys clock or 41Mhz which might work with wally so we may be able to simplify the logic a lot.
|
||||||
mmcm mmcm(.clk_out1(clk167),
|
mmcm mmcm(.clk_out1(clk167),
|
||||||
.clk_out2(clk200),
|
.clk_out2(clk200),
|
||||||
|
@ -486,7 +486,7 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 0)
|
||||||
localparam [31:0] RVVI_INIT_TIME_OUT = 32'd100000000;
|
localparam [31:0] RVVI_INIT_TIME_OUT = 32'd100000000;
|
||||||
localparam [31:0] RVVI_PACKET_DELAY = 32'd400;
|
localparam [31:0] RVVI_PACKET_DELAY = 32'd400;
|
||||||
|
|
||||||
// pipeline controlls
|
// pipeline controls
|
||||||
logic StallE, StallM, StallW, FlushE, FlushM, FlushW;
|
logic StallE, StallM, StallW, FlushE, FlushM, FlushW;
|
||||||
// required
|
// required
|
||||||
logic [P.XLEN-1:0] PCM;
|
logic [P.XLEN-1:0] PCM;
|
||||||
|
|
|
@ -51,7 +51,7 @@ int gpt_load_partitions() {
|
||||||
BYTE lba2_buf[512];
|
BYTE lba2_buf[512];
|
||||||
ret = disk_read(lba2_buf, (LBA_t)lba1->partition_entries_lba, 1);
|
ret = disk_read(lba2_buf, (LBA_t)lba1->partition_entries_lba, 1);
|
||||||
|
|
||||||
// Load parition entries for the relevant boot partitions.
|
// Load partition entries for the relevant boot partitions.
|
||||||
partition_entries_t *fdt = (partition_entries_t *)(lba2_buf);
|
partition_entries_t *fdt = (partition_entries_t *)(lba2_buf);
|
||||||
partition_entries_t *opensbi = (partition_entries_t *)(lba2_buf + 128);
|
partition_entries_t *opensbi = (partition_entries_t *)(lba2_buf + 128);
|
||||||
partition_entries_t *kernel = (partition_entries_t *)(lba2_buf + 256);
|
partition_entries_t *kernel = (partition_entries_t *)(lba2_buf + 256);
|
||||||
|
|
|
@ -93,7 +93,7 @@ uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make interrupt pending after response fifo receives the correct
|
// Make interrupt pending after response fifo receives the correct
|
||||||
// response length. Probably unecessary so let's wait and see what
|
// response length. Probably unnecessary so let's wait and see what
|
||||||
// happens.
|
// happens.
|
||||||
// write_reg(SPI_RXMARK, response_len);
|
// write_reg(SPI_RXMARK, response_len);
|
||||||
|
|
||||||
|
|
|
@ -38,5 +38,5 @@ qemu-system-riscv64 \
|
||||||
-kernel "$IMAGES"/Image \
|
-kernel "$IMAGES"/Image \
|
||||||
-initrd "$IMAGES"/rootfs.cpio \
|
-initrd "$IMAGES"/rootfs.cpio \
|
||||||
-dtb "$IMAGES"/wally-virt.dtb \
|
-dtb "$IMAGES"/wally-virt.dtb \
|
||||||
-cpu rva22s64,zicond=true,zfa=true,zfh=true,zcb=true,zbc=true,zkn=true,sstc=true,svadu=true,svnapot=true \
|
-cpu rva22s64,zicond=true,zfa=true,zfh=true,zcb=true,zbc=true,zkn=true,sstc=true,svadu=true,svnapot=true,pmp=on,debug=off \
|
||||||
$GDB_FLAG
|
$GDB_FLAG
|
||||||
|
|
23
setup.sh
23
setup.sh
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
# setup.sh
|
# setup.sh
|
||||||
# David_Harris@hmc.edu and kekim@hmc.edu 1 December 2021
|
# David_Harris@hmc.edu and kekim@hmc.edu 1 December 2021
|
||||||
|
# jcarlin@hmc.edu 2025
|
||||||
# Set up tools for cvw
|
# Set up tools for cvw
|
||||||
|
|
||||||
# optionally have .bashrc or .bash_profile source this file with
|
# optionally have .bashrc or .bash_profile source this file with
|
||||||
|
@ -11,6 +12,11 @@
|
||||||
|
|
||||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
|
||||||
|
# Colors for terminal output
|
||||||
|
WARNING_COLOR='\033[93m'
|
||||||
|
FAIL_COLOR='\033[91m'
|
||||||
|
ENDC='\033[0m' # Reset to default color
|
||||||
|
|
||||||
echo "Executing Wally setup.sh"
|
echo "Executing Wally setup.sh"
|
||||||
|
|
||||||
# Path to RISC-V Tools
|
# Path to RISC-V Tools
|
||||||
|
@ -21,14 +27,15 @@ elif [ -d ~/riscv ]; then
|
||||||
else
|
else
|
||||||
# set the $RISCV directory here and remove the subsequent two lines
|
# set the $RISCV directory here and remove the subsequent two lines
|
||||||
# export RISCV=
|
# export RISCV=
|
||||||
echo "\$RISCV directory not found. Checked /opt/riscv and ~/riscv. Edit setup.sh to point to your custom \$RISCV directory."
|
echo -e "${FAIL_COLOR}\$RISCV directory not found. Checked /opt/riscv and ~/riscv. Edit setup.sh to point to your custom \$RISCV directory.${ENDC}"
|
||||||
exit 1
|
return 1
|
||||||
fi
|
fi
|
||||||
echo \$RISCV set to "${RISCV}"
|
echo \$RISCV set to "${RISCV}"
|
||||||
|
|
||||||
# Path to Wally repository
|
# Path to Wally repository
|
||||||
WALLY=$(dirname "${BASH_SOURCE[0]:-$0}")
|
WALLY=$(dirname "${BASH_SOURCE[0]:-$0}")
|
||||||
export WALLY=$(cd "$WALLY" && pwd)
|
WALLY=$(cd "$WALLY" && pwd)
|
||||||
|
export WALLY
|
||||||
echo \$WALLY set to "${WALLY}"
|
echo \$WALLY set to "${WALLY}"
|
||||||
# utility functions in Wally repository
|
# utility functions in Wally repository
|
||||||
export PATH=$WALLY/bin:$PATH
|
export PATH=$WALLY/bin:$PATH
|
||||||
|
@ -37,7 +44,7 @@ export PATH=$WALLY/bin:$PATH
|
||||||
if [ -e "${WALLY}"/addins/cvw-arch-verif/setup.sh ]; then
|
if [ -e "${WALLY}"/addins/cvw-arch-verif/setup.sh ]; then
|
||||||
source "${WALLY}"/addins/cvw-arch-verif/setup.sh
|
source "${WALLY}"/addins/cvw-arch-verif/setup.sh
|
||||||
else
|
else
|
||||||
echo "setup.sh not found in \$WALLY/addins/cvw-arch-verif directory. Make sure you cloned the submodules."
|
echo -e "${WARNING_COLOR}setup.sh not found in \$WALLY/addins/cvw-arch-verif directory. Make sure you cloned the submodules.${ENDC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verilator needs a larger core file size to simulate CORE-V Wally
|
# Verilator needs a larger core file size to simulate CORE-V Wally
|
||||||
|
@ -47,15 +54,15 @@ ulimit -c 300000
|
||||||
if [ -e "${RISCV}"/site-setup.sh ]; then
|
if [ -e "${RISCV}"/site-setup.sh ]; then
|
||||||
source "${RISCV}"/site-setup.sh
|
source "${RISCV}"/site-setup.sh
|
||||||
else
|
else
|
||||||
echo "site-setup.sh not found in \$RISCV directory. Rerun wally-toolchain-install.sh to automatically download it."
|
echo -e "${ERROR_COLOR}site-setup.sh not found in \$RISCV directory. Rerun wally-toolchain-install.sh to automatically download it.${ENDC}"
|
||||||
exit 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -e "${WALLY}/.git/hooks/pre-commit" ]; then
|
if [ ! -e "${WALLY}/.git/hooks/pre-commit" ]; then
|
||||||
pushd "${WALLY}" || exit 1
|
pushd "${WALLY}" || return 1
|
||||||
echo "Installing pre-commit hooks"
|
echo "Installing pre-commit hooks"
|
||||||
pre-commit install
|
pre-commit install
|
||||||
popd || exit
|
popd || return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "setup done"
|
echo "setup done"
|
||||||
|
|
|
@ -197,7 +197,7 @@ coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$lin
|
||||||
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-tim"]
|
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-tim"]
|
||||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
||||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
||||||
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-cachable"]
|
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-cacheable"]
|
||||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
|
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
|
||||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
|
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
|
||||||
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-idempotent"]
|
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-idempotent"]
|
||||||
|
@ -440,7 +440,7 @@ coverage exclude -scope /dut/core/hzu -linerange [GetLineNum ${SRC}/hazard/hazar
|
||||||
# Privileged
|
# Privileged
|
||||||
####################
|
####################
|
||||||
|
|
||||||
# Instruction Misaligned never asserted because compresssed instructions are accepted
|
# Instruction Misaligned never asserted because compressed instructions are accepted
|
||||||
coverage exclude -scope /dut/core/priv/priv/trap -linerange [GetLineNum ${SRC}/privileged/trap.sv "assign ExceptionM"] -item e 1 -fecexprrow 2
|
coverage exclude -scope /dut/core/priv/priv/trap -linerange [GetLineNum ${SRC}/privileged/trap.sv "assign ExceptionM"] -item e 1 -fecexprrow 2
|
||||||
|
|
||||||
# Attempting to access fflags, frm, fcsr with mstatus.FS = 0 traps, so checking for (STATUS_FS != 2'b00)
|
# Attempting to access fflags, frm, fcsr with mstatus.FS = 0 traps, so checking for (STATUS_FS != 2'b00)
|
||||||
|
|
|
@ -75,7 +75,7 @@ set SVLib ""
|
||||||
set GUI 0
|
set GUI 0
|
||||||
set accFlag ""
|
set accFlag ""
|
||||||
|
|
||||||
# Need to be able to pass arguments to vopt. Unforunately argv does not work because
|
# Need to be able to pass arguments to vopt. Unfortunately argv does not work because
|
||||||
# it takes on different values if vsim and the do file are called from the command line or
|
# it takes on different values if vsim and the do file are called from the command line or
|
||||||
# if the do file is called from questa sim directly. This chunk of code uses the $n variables
|
# if the do file is called from questa sim directly. This chunk of code uses the $n variables
|
||||||
# and compacts them into a single list for passing to vopt. Shift is used to move the arguments
|
# and compacts them into a single list for passing to vopt. Shift is used to move the arguments
|
||||||
|
|
|
@ -22,7 +22,7 @@ TESTBENCH?=testbench
|
||||||
|
|
||||||
# constants
|
# constants
|
||||||
# assume WALLY variable is correctly configured in the shell environment
|
# assume WALLY variable is correctly configured in the shell environment
|
||||||
# INCLUDE_PATH are pathes that Verilator should search for files it needs
|
# INCLUDE_PATH are paths that Verilator should search for files it needs
|
||||||
INCLUDE_PATH="-I${WALLY}/config/shared" "-I${WALLY}/config/$(WALLYCONF)" "-I${WALLY}/config/deriv/$(WALLYCONF)"
|
INCLUDE_PATH="-I${WALLY}/config/shared" "-I${WALLY}/config/$(WALLYCONF)" "-I${WALLY}/config/deriv/$(WALLYCONF)"
|
||||||
# SOURCES are source files
|
# SOURCES are source files
|
||||||
SOURCES=${WALLY}/src/cvw.sv ${WALLY}/testbench/${TESTBENCH}.sv ${WALLY}/testbench/common/*.sv ${WALLY}/src/*/*.sv ${WALLY}/src/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv
|
SOURCES=${WALLY}/src/cvw.sv ${WALLY}/testbench/${TESTBENCH}.sv ${WALLY}/testbench/common/*.sv ${WALLY}/src/*/*.sv ${WALLY}/src/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv
|
||||||
|
|
|
@ -2,20 +2,27 @@
|
||||||
|
|
||||||
# site-setup.sh
|
# site-setup.sh
|
||||||
# David_Harris@hmc.edu and kekim@hmc.edu 1 December 2021
|
# David_Harris@hmc.edu and kekim@hmc.edu 1 December 2021
|
||||||
|
# jcarlin@hmc.edu 2025
|
||||||
# System Admin should install this into $RISCV/site-setup.sh
|
# System Admin should install this into $RISCV/site-setup.sh
|
||||||
# $RISCV is typically /opt/riscv
|
# 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.
|
# System Admin must update the licenses and paths for localization.
|
||||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
|
||||||
|
# Colors for terminal output
|
||||||
|
FAIL_COLOR='\033[91m'
|
||||||
|
ENDC='\033[0m' # Reset to default color
|
||||||
|
|
||||||
# license servers and commercial CAD tool paths
|
# license servers and commercial CAD tool paths
|
||||||
# Must edit these based on your local environment.
|
# Must edit these based on your local environment.
|
||||||
export MGLS_LICENSE_FILE=27002@zircon.eng.hmc.edu # Change this to your Siemens license server for Questa
|
export MGLS_LICENSE_FILE=27002@zircon.eng.hmc.edu # Change this to your Siemens license server for Questa
|
||||||
export SNPSLMD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Synopsys license server
|
export SNPSLMD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Synopsys license server
|
||||||
export IMPERASD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Imperas license server
|
export IMPERASD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Imperas license server
|
||||||
export QUESTA_HOME=/cad/mentor/questa_sim-2023.4/questasim # Change this for your path to Questa, excluding bin
|
export BREKER_LICENSE_FILE=1819@zircon.eng.hmc.edu # Change this to your Breker license server
|
||||||
|
export QUESTA_HOME=/cad/mentor/QUESTA # Change this for your path to Questa, excluding bin
|
||||||
export DC_HOME=/cad/synopsys/SYN # Change this for your path to Synopsys DC, excluding bin
|
export DC_HOME=/cad/synopsys/SYN # Change this for your path to Synopsys DC, excluding bin
|
||||||
export VCS_HOME=/cad/synopsys/vcs/U-2023.03-SP2-4 # Change this for your path to Synopsys VCS, excluding bin
|
export VCS_HOME=/cad/synopsys/VCS # Change this for your path to Synopsys VCS, excluding bin
|
||||||
export BREKER_HOME=/cad/breker/trek5-2.1.11-GCC6_el7 # Change this for your path to Breker Trek
|
export BREKER_HOME=/cad/breker/TREK # Change this for your path to Breker Trek
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
# Questa and Synopsys
|
# Questa and Synopsys
|
||||||
|
@ -31,10 +38,6 @@ export SYN_MW=/home/jstine/MW
|
||||||
export SYN_memory=/home/jstine/WallyMem/rv64gc/
|
export SYN_memory=/home/jstine/WallyMem/rv64gc/
|
||||||
#export osumemory=/import/yukari1/pdk/TSMC/WallyMem/rv64gc/
|
#export osumemory=/import/yukari1/pdk/TSMC/WallyMem/rv64gc/
|
||||||
|
|
||||||
# Environmental variables for CTG (https://github.com/riscv-software-src/riscv-ctg)
|
|
||||||
export RISCVCTG=/home/harris/repos/riscv-ctg
|
|
||||||
|
|
||||||
|
|
||||||
# GCC
|
# GCC
|
||||||
if [ -z "$LD_LIBRARY_PATH" ]; then
|
if [ -z "$LD_LIBRARY_PATH" ]; then
|
||||||
export LD_LIBRARY_PATH=$RISCV/riscv64-unknown-elf/lib
|
export LD_LIBRARY_PATH=$RISCV/riscv64-unknown-elf/lib
|
||||||
|
@ -50,36 +53,34 @@ export PATH=$PATH:$RISCV/bin
|
||||||
if [ -e "$RISCV"/riscv-python/bin/activate ]; then
|
if [ -e "$RISCV"/riscv-python/bin/activate ]; then
|
||||||
source "$RISCV"/riscv-python/bin/activate
|
source "$RISCV"/riscv-python/bin/activate
|
||||||
else
|
else
|
||||||
echo "Python virtual environment not found. Rerun wally-toolchain-install.sh to automatically create it."
|
echo -e "${FAIL_COLOR}Python virtual environment not found. Rerun wally-toolchain-install.sh to automatically create it.${ENDC}"
|
||||||
exit 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Environment variables needed for RISCV-DV
|
# Environment variables needed for RISCV-DV
|
||||||
export RISCV_GCC=$(which riscv64-unknown-elf-gcc) # Copy this as it is
|
export RISCV_GCC=$(which riscv64-unknown-elf-gcc)
|
||||||
export RISCV_OBJCOPY=$(which riscv64-unknown-elf-objcopy) # Copy this as it is
|
export RISCV_OBJCOPY=$(which riscv64-unknown-elf-objcopy)
|
||||||
export SPIKE_PATH=$RISCV/bin # Copy this as it is
|
export SPIKE_PATH=$RISCV/bin
|
||||||
|
|
||||||
# Imperas OVPsim; put this in if you are using it
|
|
||||||
#export PATH=$RISCV/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64:$PATH
|
|
||||||
#export LD_LIBRARY_PATH=$RISCV/imperas_riscv_tests/riscv-ovpsim-plus/bin/Linux64:$LD_LIBRARY_PATH
|
|
||||||
|
|
||||||
# Imperas DV setup
|
# Imperas DV setup
|
||||||
export IDV=$RISCV/ImperasDV-OpenHW
|
export IMPERAS_HOME=$RISCV/ImperasDV-OpenHW
|
||||||
if [ -e "$IDV" ]; then
|
if [ -e "$IMPERAS_HOME" ]; then
|
||||||
# echo "Imperas exists"
|
|
||||||
export IMPERAS_HOME=$IDV
|
|
||||||
export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC
|
export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC
|
||||||
export ROOTDIR=~/
|
source "${IMPERAS_HOME}"/bin/setup.sh &> /dev/null || {
|
||||||
source "${IMPERAS_HOME}"/bin/setup.sh
|
echo -e "${FAIL_COLOR}ImperasDV setup failed${ENDC}"
|
||||||
setupImperas "${IMPERAS_HOME}"
|
return 1
|
||||||
export PATH=$IDV/scripts/cvw:$PATH
|
}
|
||||||
|
setupImperas "${IMPERAS_HOME}" &> /dev/null || {
|
||||||
|
echo -e "${FAIL_COLOR}setupImperas failed${ENDC}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Use newer gcc version for older distros
|
# Use newer gcc version for older distros
|
||||||
if [ -e /opt/rh/gcc-toolset-13/enable ]; then
|
if [ -e /opt/rh/gcc-toolset-13/enable ]; then
|
||||||
source /opt/rh/gcc-toolset-13/enable # Red Hat Family
|
source /opt/rh/gcc-toolset-13/enable # Red Hat Family
|
||||||
elif [ -e $RISCV/gcc-13 ]; then
|
elif [ -e "$RISCV"/gcc-13 ]; then
|
||||||
export PATH=$RISCV/gcc-13/bin:$PATH # SUSE Family
|
export PATH=$RISCV/gcc-13/bin:$PATH # SUSE Family
|
||||||
elif [ -e $RISCV/gcc-10 ]; then
|
elif [ -e "$RISCV"/gcc-10 ]; then
|
||||||
export PATH=$RISCV/gcc-10/bin:$PATH # Ubuntu 20.04 LTS
|
export PATH=$RISCV/gcc-10/bin:$PATH # Ubuntu 20.04 LTS
|
||||||
fi
|
fi
|
||||||
|
|
6
src/cache/cachefsm.sv
vendored
6
src/cache/cachefsm.sv
vendored
|
@ -62,7 +62,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
||||||
output logic ClearDirty, // Clear the dirty bit in the selected way and set
|
output logic ClearDirty, // Clear the dirty bit in the selected way and set
|
||||||
output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
|
output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
|
||||||
output logic LRUWriteEn, // Update the LRU state
|
output logic LRUWriteEn, // Update the LRU state
|
||||||
output logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
|
output logic SelVictim, // Overrides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
|
||||||
output logic FlushAdrCntEn, // Enable the counter for Flush Adr
|
output logic FlushAdrCntEn, // Enable the counter for Flush Adr
|
||||||
output logic FlushWayCntEn, // Enable the way counter during a flush
|
output logic FlushWayCntEn, // Enable the way counter during a flush
|
||||||
output logic FlushCntRst, // Reset both flush counters
|
output logic FlushCntRst, // Reset both flush counters
|
||||||
|
@ -83,7 +83,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
||||||
STATE_FETCH,
|
STATE_FETCH,
|
||||||
STATE_WRITEBACK,
|
STATE_WRITEBACK,
|
||||||
STATE_WRITE_LINE,
|
STATE_WRITE_LINE,
|
||||||
STATE_ADDRESS_SETUP, // required for back to back reads. structural hazard on writting SRAM
|
STATE_ADDRESS_SETUP, // required for back to back reads. structural hazard on writing SRAM
|
||||||
// flush cache
|
// flush cache
|
||||||
STATE_FLUSH,
|
STATE_FLUSH,
|
||||||
STATE_FLUSH_WRITEBACK
|
STATE_FLUSH_WRITEBACK
|
||||||
|
@ -165,7 +165,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
||||||
(CurrState == STATE_WRITE_LINE & (CacheRW[0])) |
|
(CurrState == STATE_WRITE_LINE & (CacheRW[0])) |
|
||||||
(CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck));
|
(CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck));
|
||||||
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty
|
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty
|
||||||
(CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
|
(CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocol. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
|
||||||
// Flush and eviction controls
|
// Flush and eviction controls
|
||||||
CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck;
|
CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck;
|
||||||
assign SelVictim = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
|
assign SelVictim = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
|
||||||
|
|
2
src/cache/cacheway.sv
vendored
2
src/cache/cacheway.sv
vendored
|
@ -42,7 +42,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||||
input logic SetValid, // Set the valid bit in the selected way and set
|
input logic SetValid, // Set the valid bit in the selected way and set
|
||||||
input logic ClearValid, // Clear the valid bit in the selected way and set
|
input logic ClearValid, // Clear the valid bit in the selected way and set
|
||||||
input logic SetDirty, // Set the dirty bit in the selected way and set
|
input logic SetDirty, // Set the dirty bit in the selected way and set
|
||||||
input logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
|
input logic SelVictim, // Overrides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
|
||||||
input logic ClearDirty, // Clear the dirty bit in the selected way and set
|
input logic ClearDirty, // Clear the dirty bit in the selected way and set
|
||||||
input logic FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
|
input logic FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
|
||||||
input logic VictimWay, // LRU selected this way as victim to evict
|
input logic VictimWay, // LRU selected this way as victim to evict
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Usiing global `define statements isn't ideal in a large SystemVerilog system because
|
// Using global `define statements isn't ideal in a large SystemVerilog system because
|
||||||
// of the risk of `define name conflicts across different subsystems.
|
// of the risk of `define name conflicts across different subsystems.
|
||||||
// Instead, CORE-V-Wally loads the appropriate configuration one time and places it in a package
|
// Instead, CORE-V-Wally loads the appropriate configuration one time and places it in a package
|
||||||
// that is referenced by all Wally modules but not by other subsystems.
|
// that is referenced by all Wally modules but not by other subsystems.
|
||||||
|
|
|
@ -53,7 +53,7 @@ module ahbcacheinterface import cvw::*; #(
|
||||||
input logic [P.PA_BITS-1:0] CacheBusAdr, // Address of cache line
|
input logic [P.PA_BITS-1:0] CacheBusAdr, // Address of cache line
|
||||||
input logic [P.LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
|
input logic [P.LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
|
||||||
input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$
|
input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$
|
||||||
input logic Cacheable, // Memory operation is cachable
|
input logic Cacheable, // Memory operation is cacheable
|
||||||
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
|
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
|
||||||
output logic CacheBusAck, // Handshake to $ indicating bus transaction completed
|
output logic CacheBusAck, // Handshake to $ indicating bus transaction completed
|
||||||
output logic [LINELEN-1:0] FetchBuffer, // Register to hold beats of cache line as the arrive from bus
|
output logic [LINELEN-1:0] FetchBuffer, // Register to hold beats of cache line as the arrive from bus
|
||||||
|
|
|
@ -91,7 +91,7 @@ module ebu import cvw::*; #(parameter cvw_t P) (
|
||||||
assign HRESETn = ~reset;
|
assign HRESETn = ~reset;
|
||||||
|
|
||||||
// if two requests come in at once pick one to select and save the others Address phase
|
// if two requests come in at once pick one to select and save the others Address phase
|
||||||
// inputs. Abritration scheme is LSU always goes first.
|
// inputs. Arbitration scheme is LSU always goes first.
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// input stages and muxing for IFU and LSU
|
// input stages and muxing for IFU and LSU
|
||||||
|
|
|
@ -59,7 +59,7 @@ module ebufsmarb (
|
||||||
logic [3:0] Threshold; // Number of beats derived from HBURST
|
logic [3:0] Threshold; // Number of beats derived from HBURST
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Aribtration scheme
|
// Arbitration scheme
|
||||||
// FSM decides if arbitration needed. Arbitration is held until the last beat of
|
// FSM decides if arbitration needed. Arbitration is held until the last beat of
|
||||||
// a burst is completed.
|
// a burst is completed.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -87,7 +87,7 @@ module ebufsmarb (
|
||||||
// Once the LSU request is done the fsm returns to IDLE. To prevent the LSU from regaining
|
// Once the LSU request is done the fsm returns to IDLE. To prevent the LSU from regaining
|
||||||
// priority and re-issuing the same memory operation, the delayed IFUReqDelay squashes the LSU request.
|
// priority and re-issuing the same memory operation, the delayed IFUReqDelay squashes the LSU request.
|
||||||
// This is necessary because the pipeline is stalled for the entire duration of both transactions,
|
// This is necessary because the pipeline is stalled for the entire duration of both transactions,
|
||||||
// and the LSU memory request will stil be active.
|
// and the LSU memory request will still be active.
|
||||||
flopr #(1) ifureqreg(HCLK, ~HRESETn, IFUReq, IFUReqDelay);
|
flopr #(1) ifureqreg(HCLK, ~HRESETn, IFUReq, IFUReqDelay);
|
||||||
assign LSUDisable = (CurrState == ARBITRATE) ? 1'b0 : (IFUReqDelay & ~(HREADY & FinalBeatD));
|
assign LSUDisable = (CurrState == ARBITRATE) ? 1'b0 : (IFUReqDelay & ~(HREADY & FinalBeatD));
|
||||||
assign LSUSelect = (NextState == ARBITRATE) ? 1'b1: LSUReq;
|
assign LSUSelect = (NextState == ARBITRATE) ? 1'b1: LSUReq;
|
||||||
|
|
|
@ -60,8 +60,8 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||||
// register control signals
|
// register control signals
|
||||||
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
|
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
|
||||||
output logic FWriteIntE, FWriteIntM, // Write to integer register
|
output logic FWriteIntE, FWriteIntM, // Write to integer register
|
||||||
output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input
|
output logic [4:0] Adr1D, Adr2D, Adr3D, // addresses of each input
|
||||||
output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input
|
output logic [4:0] Adr1E, Adr2E, Adr3E, // addresses of each input
|
||||||
// other control signals
|
// other control signals
|
||||||
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
|
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
|
||||||
output logic FDivStartE, IDivStartE // Start division or squareroot
|
output logic FDivStartE, IDivStartE // Start division or squareroot
|
||||||
|
@ -355,12 +355,12 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||||
// 01 - negate sign
|
// 01 - negate sign
|
||||||
// 10 - xor sign
|
// 10 - xor sign
|
||||||
|
|
||||||
// rename input adresses for readability
|
// rename input addresses for readability
|
||||||
assign Adr1D = InstrD[19:15];
|
assign Adr1D = InstrD[19:15];
|
||||||
assign Adr2D = InstrD[24:20];
|
assign Adr2D = InstrD[24:20];
|
||||||
assign Adr3D = InstrD[31:27];
|
assign Adr3D = InstrD[31:27];
|
||||||
|
|
||||||
// D/E pipleine register
|
// D/E pipeline register
|
||||||
flopenrc #(`FCTRLW+2+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
|
flopenrc #(`FCTRLW+2+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
|
||||||
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD, ZfaD, ZfaFRoundNXD, ~IllegalFPUInstrD},
|
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD, ZfaD, ZfaFRoundNXD, ~IllegalFPUInstrD},
|
||||||
{FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE, ZfaFRoundNXE, FPUActiveE});
|
{FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE, ZfaFRoundNXE, FPUActiveE});
|
||||||
|
@ -372,7 +372,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||||
if (P.M_SUPPORTED & P.IDIV_ON_FPU) assign IDivStartE = IntDivE;
|
if (P.M_SUPPORTED & P.IDIV_ON_FPU) assign IDivStartE = IntDivE;
|
||||||
else assign IDivStartE = 1'b0;
|
else assign IDivStartE = 1'b0;
|
||||||
|
|
||||||
// E/M pipleine register
|
// E/M pipeline register
|
||||||
flopenrc #(14+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
|
flopenrc #(14+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
|
||||||
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE},
|
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE},
|
||||||
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, FCvtIntM, ZfaM});
|
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, FCvtIntM, ZfaM});
|
||||||
|
@ -380,7 +380,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||||
// renameing for readability
|
// renameing for readability
|
||||||
assign FpLoadStoreM = FResSelM[1];
|
assign FpLoadStoreM = FResSelM[1];
|
||||||
|
|
||||||
// M/W pipleine register
|
// M/W pipeline register
|
||||||
flopenrc #(4) MWCtrlReg(clk, reset, FlushW, ~StallW,
|
flopenrc #(4) MWCtrlReg(clk, reset, FlushW, ~StallW,
|
||||||
{FRegWriteM, FResSelM, FCvtIntM},
|
{FRegWriteM, FResSelM, FCvtIntM},
|
||||||
{FRegWriteW, FResSelW, FCvtIntW});
|
{FRegWriteW, FResSelW, FCvtIntW});
|
||||||
|
|
|
@ -32,10 +32,10 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic [P.NF:0] Xm, // input's fraction
|
input logic [P.NF:0] Xm, // input's fraction
|
||||||
input logic [P.XLEN-1:0] Int, // integer input - from IEU
|
input logic [P.XLEN-1:0] Int, // integer input - from IEU
|
||||||
input logic [2:0] OpCtrl, // choose which operation (look below for values)
|
input logic [2:0] OpCtrl, // choose which operation (look below for values)
|
||||||
input logic ToInt, // is fp->int (since it's writting to the integer register)
|
input logic ToInt, // is fp->int (since it's writing to the integer register)
|
||||||
input logic XZero, // is the input zero
|
input logic XZero, // is the input zero
|
||||||
input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
|
input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
|
||||||
output logic [P.NE:0] Ce, // the calculated expoent
|
output logic [P.NE:0] Ce, // the calculated exponent
|
||||||
output logic [P.LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
|
output logic [P.LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
|
||||||
output logic ResSubnormUf, // does the result underflow or is subnormal
|
output logic ResSubnormUf, // does the result underflow or is subnormal
|
||||||
output logic Cs, // the result's sign
|
output logic Cs, // the result's sign
|
||||||
|
@ -64,7 +64,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
||||||
logic [P.CVTLEN:0] LzcInFull; // input to the Leading Zero Counter (priority encoder)
|
logic [P.CVTLEN:0] LzcInFull; // input to the Leading Zero Counter (priority encoder)
|
||||||
logic [P.LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
|
logic [P.LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
|
||||||
|
|
||||||
// seperate OpCtrl for code readability
|
// separate OpCtrl for code readability
|
||||||
assign Signed = OpCtrl[0];
|
assign Signed = OpCtrl[0];
|
||||||
assign Int64 = OpCtrl[1];
|
assign Int64 = OpCtrl[1];
|
||||||
assign IntToFp = OpCtrl[2];
|
assign IntToFp = OpCtrl[2];
|
||||||
|
@ -80,7 +80,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// negation
|
// negation
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// 1) negate the input if the input is a negative singed integer
|
// 1) negate the input if the input is a negative signed integer
|
||||||
// 2) trim the input to the proper size (kill the 32 most significant zeroes if needed)
|
// 2) trim the input to the proper size (kill the 32 most significant zeroes if needed)
|
||||||
|
|
||||||
assign PosInt = Cs ? -Int : Int;
|
assign PosInt = Cs ? -Int : Int;
|
||||||
|
@ -150,20 +150,20 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
||||||
// - XExp - Largest bias + new bias - (LeadingZeros+1)
|
// - XExp - Largest bias + new bias - (LeadingZeros+1)
|
||||||
// only do ^ if the input was subnormal
|
// only do ^ if the input was subnormal
|
||||||
// - convert the expoenent to the final preciaion (Exp - oldBias + newBias)
|
// - convert the expoenent to the final preciaion (Exp - oldBias + newBias)
|
||||||
// - correct the expoent when there is a normalization shift ( + LeadingZeros+1)
|
// - correct the exponent when there is a normalization shift ( + LeadingZeros+1)
|
||||||
// - the plus 1 is built into the leading zeros by counting the leading zeroes in the mantissa rather than the fraction
|
// - the plus 1 is built into the leading zeros by counting the leading zeroes in the mantissa rather than the fraction
|
||||||
// fp -> int : XExp - Largest Bias + 1 - (LeadingZeros+1)
|
// fp -> int : XExp - Largest Bias + 1 - (LeadingZeros+1)
|
||||||
// | P.XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
|
// | P.XLEN zeros | Mantissa | 0's if necessary | << CalcExp
|
||||||
// process:
|
// process:
|
||||||
// - start
|
// - start
|
||||||
// | P.XLEN zeros | Mantissa | 0's if nessisary |
|
// | P.XLEN zeros | Mantissa | 0's if necessary |
|
||||||
//
|
//
|
||||||
// - shift left 1 (1)
|
// - shift left 1 (1)
|
||||||
// | P.XLEN-1 zeros |bit| frac | 0's if nessisary |
|
// | P.XLEN-1 zeros |bit| frac | 0's if necessary |
|
||||||
// . <- binary point
|
// . <- binary point
|
||||||
//
|
//
|
||||||
// - shift left till unbiased exponent is 0 (XExp - Largest Bias)
|
// - shift left till unbiased exponent is 0 (XExp - Largest Bias)
|
||||||
// | 0's | Mantissa | 0's if nessisary |
|
// | 0's | Mantissa | 0's if necessary |
|
||||||
// | keep |
|
// | keep |
|
||||||
//
|
//
|
||||||
// - if the input is subnormal then we dont shift... so the "- LeadingZeros" is just leftovers from other options
|
// - if the input is subnormal then we dont shift... so the "- LeadingZeros" is just leftovers from other options
|
||||||
|
@ -199,7 +199,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
||||||
// - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0
|
// - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0
|
||||||
// ??? -> fp:
|
// ??? -> fp:
|
||||||
// - shift left by LeadingZeros - to shift till the result is normalized
|
// - shift left by LeadingZeros - to shift till the result is normalized
|
||||||
// - only shift fp -> fp if the intital value is subnormal
|
// - only shift fp -> fp if the initial value is subnormal
|
||||||
// - this is a problem because the input to the lzc was the fraction rather than the mantissa
|
// - this is a problem because the input to the lzc was the fraction rather than the mantissa
|
||||||
// - rather have a few and-gates than an extra bit in the priority encoder???
|
// - rather have a few and-gates than an extra bit in the priority encoder???
|
||||||
always_comb
|
always_comb
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu
|
// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu
|
||||||
// Modified:13 January 2022
|
// Modified:13 January 2022
|
||||||
//
|
//
|
||||||
// Purpose: Exponent caclulation for divide and square root
|
// Purpose: Exponent calculation for divide and square root
|
||||||
//
|
//
|
||||||
// Documentation: RISC-V System on Chip Design
|
// Documentation: RISC-V System on Chip Design
|
||||||
//
|
//
|
||||||
|
|
|
@ -88,7 +88,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
||||||
assign AsE = AE[P.XLEN-1] & SignedDivE;
|
assign AsE = AE[P.XLEN-1] & SignedDivE;
|
||||||
assign BsE = BE[P.XLEN-1] & SignedDivE;
|
assign BsE = BE[P.XLEN-1] & SignedDivE;
|
||||||
|
|
||||||
// Force integer inputs to be postiive
|
// Force integer inputs to be positive
|
||||||
mux2 #(P.XLEN) posamux(AE, -AE, AsE, PosA);
|
mux2 #(P.XLEN) posamux(AE, -AE, AsE, PosA);
|
||||||
mux2 #(P.XLEN) posbmux(BE, -BE, BsE, PosB);
|
mux2 #(P.XLEN) posbmux(BE, -BE, BsE, PosB);
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
||||||
// Then multiply by R is left shift by r (1 or 2 for radix 2 or 4)
|
// Then multiply by R is left shift by r (1 or 2 for radix 2 or 4)
|
||||||
// This is optimized in hardware by first right shifting by 0 or 1 bit (instead of 1 or 2), then left shifting by (r-1), then subtracting 2 or 4
|
// This is optimized in hardware by first right shifting by 0 or 1 bit (instead of 1 or 2), then left shifting by (r-1), then subtracting 2 or 4
|
||||||
// Subtracting 2 is equivalent to adding 1110. Subtracting 4 is equivalent to adding 1100. Prepend leading 1s to do a free subtraction.
|
// Subtracting 2 is equivalent to adding 1110. Subtracting 4 is equivalent to adding 1100. Prepend leading 1s to do a free subtraction.
|
||||||
// This also means only one extra fractional bit is needed becaue we never shift right by more than 1.
|
// This also means only one extra fractional bit is needed because we never shift right by more than 1.
|
||||||
// Radix Exponent odd Exponent Even
|
// Radix Exponent odd Exponent Even
|
||||||
// 2 x-2 = 2(x/2 - 1) x/2 - 2 = 2(x/4 - 1)
|
// 2 x-2 = 2(x/2 - 1) x/2 - 2 = 2(x/4 - 1)
|
||||||
// 4 2(x)-4 = 4(x/2 - 1)) 2(x/2)-4 = 4(x/4 - 1)
|
// 4 2(x)-4 = 4(x/2 - 1)) 2(x/2)-4 = 4(x/4 - 1)
|
||||||
|
@ -194,7 +194,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
||||||
mux2 #(P.DIVb+4) prexmux(DivX, SqrtX, SqrtE, PreShiftX);
|
mux2 #(P.DIVb+4) prexmux(DivX, SqrtX, SqrtE, PreShiftX);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// Selet integer or floating-point operands
|
// Select integer or floating-point operands
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (P.IDIV_ON_FPU) begin
|
if (P.IDIV_ON_FPU) begin
|
||||||
|
@ -203,7 +203,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
||||||
assign X = PreShiftX;
|
assign X = PreShiftX;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Divisior register
|
// Divisor register
|
||||||
flopen #(P.DIVb+4) dreg(clk, IFDivStartE, {3'b000, Dnorm}, D);
|
flopen #(P.DIVb+4) dreg(clk, IFDivStartE, {3'b000, Dnorm}, D);
|
||||||
|
|
||||||
// Floating-point exponent
|
// Floating-point exponent
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
module fhazard(
|
module fhazard(
|
||||||
input logic [4:0] Adr1D, Adr2D, Adr3D, // read data adresses
|
input logic [4:0] Adr1D, Adr2D, Adr3D, // read data addresses
|
||||||
input logic [4:0] Adr1E, Adr2E, Adr3E, // read data adresses
|
input logic [4:0] Adr1E, Adr2E, Adr3E, // read data addresses
|
||||||
input logic FRegWriteE, FRegWriteM, FRegWriteW, // is the fp register being written to
|
input logic FRegWriteE, FRegWriteM, FRegWriteW, // is the fp register being written to
|
||||||
input logic [4:0] RdE, RdM, RdW, // the adress being written to
|
input logic [4:0] RdE, RdM, RdW, // the address being written to
|
||||||
input logic [1:0] FResSelM, // the result being selected
|
input logic [1:0] FResSelM, // the result being selected
|
||||||
input logic XEnD, YEnD, ZEnD, // are the inputs needed
|
input logic XEnD, YEnD, ZEnD, // are the inputs needed
|
||||||
output logic FPUStallD, // stall the decode stage
|
output logic FPUStallD, // stall the decode stage
|
||||||
|
|
|
@ -31,11 +31,11 @@ module fmaadd import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic [3*P.NF+5:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1)
|
input logic [3*P.NF+5:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1)
|
||||||
input logic [P.NE-1:0] Ze, // exponent of Z
|
input logic [P.NE-1:0] Ze, // exponent of Z
|
||||||
input logic Ps, // the product sign and the alligend addeded's sign (Modified Z sign for other operations)
|
input logic Ps, // the product sign and the alligend addeded's sign (Modified Z sign for other operations)
|
||||||
input logic [P.NE+1:0] Pe, // product's exponet
|
input logic [P.NE+1:0] Pe, // product's exponent
|
||||||
input logic [2*P.NF+1:0] Pm, // the product's mantissa
|
input logic [2*P.NF+1:0] Pm, // the product's mantissa
|
||||||
input logic InvA, // invert the aligned addend
|
input logic InvA, // invert the aligned addend
|
||||||
input logic KillProd, // should the product be set to 0
|
input logic KillProd, // should the product be set to 0
|
||||||
input logic ASticky, // Alighed addend's sticky bit
|
input logic ASticky, // Aligned addend's sticky bit
|
||||||
output logic [3*P.NF+5:0] AmInv, // aligned addend possibly inverted
|
output logic [3*P.NF+5:0] AmInv, // aligned addend possibly inverted
|
||||||
output logic [2*P.NF+1:0] PmKilled, // the product's mantissa possibly killed
|
output logic [2*P.NF+1:0] PmKilled, // the product's mantissa possibly killed
|
||||||
output logic Ss, // sum's sign
|
output logic Ss, // sum's sign
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu
|
// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu
|
||||||
// Modified:
|
// Modified:
|
||||||
//
|
//
|
||||||
// Purpose: FMA alginment shift
|
// Purpose: FMA alignment shift
|
||||||
//
|
//
|
||||||
// Documentation: RISC-V System on Chip Design
|
// Documentation: RISC-V System on Chip Design
|
||||||
//
|
//
|
||||||
|
@ -32,7 +32,7 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic [P.NF:0] Zm, // significand in U(0.NF) format]
|
input logic [P.NF:0] Zm, // significand in U(0.NF) format]
|
||||||
input logic XZero, YZero, ZZero, // is the input zero
|
input logic XZero, YZero, ZZero, // is the input zero
|
||||||
output logic [P.FMALEN-1:0] Am, // addend aligned for addition in U(NF+5.2NF+1)
|
output logic [P.FMALEN-1:0] Am, // addend aligned for addition in U(NF+5.2NF+1)
|
||||||
output logic ASticky, // Sticky bit calculated from the aliged addend
|
output logic ASticky, // Sticky bit calculated from the aligned addend
|
||||||
output logic KillProd // should the product be set to zero
|
output logic KillProd // should the product be set to zero
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
|
||||||
// This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed
|
// This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed
|
||||||
assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)} + (P.NE+2)'(P.NF+3) - {2'b0, Ze};
|
assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)} + (P.NE+2)'(P.NF+3) - {2'b0, Ze};
|
||||||
|
|
||||||
// Default Addition with only inital left shift
|
// Default Addition with only initial left shift
|
||||||
// extra bit at end and beginning so the correct guard bit is calculated when subtracting
|
// extra bit at end and beginning so the correct guard bit is calculated when subtracting
|
||||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
// | 54'b0 | 106'b(product) | 2'b0 |
|
||||||
// | addnend |
|
// | addnend |
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
module fmasign(
|
module fmasign(
|
||||||
input logic [2:0] OpCtrl, // operation contol
|
input logic [2:0] OpCtrl, // operation control
|
||||||
input logic Xs, Ys, Zs, // sign of the inputs
|
input logic Xs, Ys, Zs, // sign of the inputs
|
||||||
output logic Ps, // the product's sign - takes operation into account
|
output logic Ps, // the product's sign - takes operation into account
|
||||||
output logic As, // aligned addend sign used in fma - takes operation into account
|
output logic As, // aligned addend sign used in fma - takes operation into account
|
||||||
|
|
|
@ -78,8 +78,8 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
||||||
logic [2:0] OpCtrlE, OpCtrlM; // Select which operation to do in each component
|
logic [2:0] OpCtrlE, OpCtrlM; // Select which operation to do in each component
|
||||||
logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage
|
logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage
|
||||||
logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
|
logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
|
||||||
logic [4:0] Adr1D, Adr2D, Adr3D; // register adresses of each input
|
logic [4:0] Adr1D, Adr2D, Adr3D; // register addresses of each input
|
||||||
logic [4:0] Adr1E, Adr2E, Adr3E; // register adresses of each input
|
logic [4:0] Adr1E, Adr2E, Adr3E; // register addresses of each input
|
||||||
logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation
|
logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation
|
||||||
logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation
|
logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation
|
||||||
logic FRegWriteE; // Write floating-point register
|
logic FRegWriteE; // Write floating-point register
|
||||||
|
@ -129,7 +129,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
||||||
logic [$clog2(P.FMALEN+1)-1:0] SCntE, SCntM; // LZA sum leading zero count
|
logic [$clog2(P.FMALEN+1)-1:0] SCntE, SCntM; // LZA sum leading zero count
|
||||||
|
|
||||||
// Cvt Signals
|
// Cvt Signals
|
||||||
logic [P.NE:0] CeE, CeM; // convert intermediate expoent
|
logic [P.NE:0] CeE, CeM; // convert intermediate exponent
|
||||||
logic [P.LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by
|
logic [P.LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by
|
||||||
logic CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal
|
logic CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal
|
||||||
logic CsE, CsM; // convert result sign
|
logic CsE, CsM; // convert result sign
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
module fregfile #(parameter FLEN) (
|
module fregfile #(parameter FLEN) (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic we4, // write enable
|
input logic we4, // write enable
|
||||||
input logic [4:0] a1, a2, a3, a4, // adresses
|
input logic [4:0] a1, a2, a3, a4, // addresses
|
||||||
input logic [FLEN-1:0] wd4, // write data
|
input logic [FLEN-1:0] wd4, // write data
|
||||||
output logic [FLEN-1:0] rd1, rd2, rd3 // read data
|
output logic [FLEN-1:0] rd1, rd2, rd3 // read data
|
||||||
);
|
);
|
||||||
|
|
|
@ -30,12 +30,12 @@
|
||||||
module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic XZero, // is the input zero?
|
input logic XZero, // is the input zero?
|
||||||
input logic ToInt, // to integer conversion?
|
input logic ToInt, // to integer conversion?
|
||||||
input logic IntToFp, // interger to floating point conversion?
|
input logic IntToFp, // integer to floating point conversion?
|
||||||
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
||||||
input logic [P.NE:0] CvtCe, // the calculated expoent
|
input logic [P.NE:0] CvtCe, // the calculated exponent
|
||||||
input logic [P.NF:0] Xm, // input mantissas
|
input logic [P.NF:0] Xm, // input mantissas
|
||||||
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||||
input logic CvtResSubnormUf, // is the conversion result subnormal or underlows
|
input logic CvtResSubnormUf, // is the conversion result subnormal or underflows
|
||||||
output logic CvtResUf, // does the cvt result unerflow
|
output logic CvtResUf, // does the cvt result unerflow
|
||||||
output logic [P.CVTLEN+P.NF:0] CvtShiftIn // number to be shifted
|
output logic [P.CVTLEN+P.NF:0] CvtShiftIn // number to be shifted
|
||||||
);
|
);
|
||||||
|
@ -51,12 +51,12 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||||
// | P.XLEN zeros | mantissa | 0's if necessary |
|
// | P.XLEN zeros | mantissa | 0's if necessary |
|
||||||
// .
|
// .
|
||||||
// Other problems:
|
// Other problems:
|
||||||
// - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later durring rounding)
|
// - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later during rounding)
|
||||||
// - we do however want to keep the one in the sticky bit so set one of bits in the sticky bit area to 1
|
// - we do however want to keep the one in the sticky bit so set one of bits in the sticky bit area to 1
|
||||||
// - ex: for the case 0010000.... (double)
|
// - ex: for the case 0010000.... (double)
|
||||||
// ??? -> fp:
|
// ??? -> fp:
|
||||||
// - if result is subnormal or underflowed then we want to shift right i.e. shift right then shift left:
|
// - if result is subnormal or underflowed then we want to shift right i.e. shift right then shift left:
|
||||||
// | P.NF-1 zeros | mantissa | 0's if nessisary |
|
// | P.NF-1 zeros | mantissa | 0's if necessary |
|
||||||
// .
|
// .
|
||||||
// - otherwise:
|
// - otherwise:
|
||||||
// | LzcInM | 0's if necessary |
|
// | LzcInM | 0's if necessary |
|
||||||
|
|
|
@ -57,8 +57,8 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||||
// 00000000.xxxxxxx... << NF Exp = DivUe+1
|
// 00000000.xxxxxxx... << NF Exp = DivUe+1
|
||||||
// 00000000x.xxxxxx... << NF Exp = DivUe (extra shift done afterwards)
|
// 00000000x.xxxxxx... << NF Exp = DivUe (extra shift done afterwards)
|
||||||
// 00000000xx.xxxxx... << 1? Exp = DivUe-1 (determined after)
|
// 00000000xx.xxxxx... << 1? Exp = DivUe-1 (determined after)
|
||||||
// inital Left shift amount = NF
|
// initial Left shift amount = NF
|
||||||
// shift one more if the it's a minimally redundent radix 4 - one entire cycle needed for integer bit
|
// shift one more if the it's a minimally redundant radix 4 - one entire cycle needed for integer bit
|
||||||
assign NormShift = (P.LOGNORMSHIFTSZ)'(P.NF);
|
assign NormShift = (P.LOGNORMSHIFTSZ)'(P.NF);
|
||||||
|
|
||||||
// if the shift amount is negative then don't shift (keep sticky bit)
|
// if the shift amount is negative then don't shift (keep sticky bit)
|
||||||
|
|
|
@ -47,7 +47,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic IntToFp, // convert integer to floating point
|
input logic IntToFp, // convert integer to floating point
|
||||||
input logic Int64, // convert to 64 bit integer
|
input logic Int64, // convert to 64 bit integer
|
||||||
input logic Signed, // convert to a signed integer
|
input logic Signed, // convert to a signed integer
|
||||||
input logic [P.NE:0] CvtCe, // the calculated expoent - Cvt
|
input logic [P.NE:0] CvtCe, // the calculated exponent - Cvt
|
||||||
input logic [1:0] CvtNegResMsbs, // the negative integer result's most significant bits
|
input logic [1:0] CvtNegResMsbs, // the negative integer result's most significant bits
|
||||||
// divsqrt
|
// divsqrt
|
||||||
input logic DivOp, // conversion operation?
|
input logic DivOp, // conversion operation?
|
||||||
|
@ -70,7 +70,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
||||||
logic FmaInvalid; // integer invalid flag
|
logic FmaInvalid; // integer invalid flag
|
||||||
logic DivInvalid; // integer invalid flag
|
logic DivInvalid; // integer invalid flag
|
||||||
logic Underflow; // Underflow flag
|
logic Underflow; // Underflow flag
|
||||||
logic ResExpGteMax; // is the result greater than or equal to the maximum floating point expoent
|
logic ResExpGteMax; // is the result greater than or equal to the maximum floating point exponent
|
||||||
logic ShiftGtIntSz; // is the shift greater than the the integer size (use Re to account for possible rounding "shift")
|
logic ShiftGtIntSz; // is the shift greater than the the integer size (use Re to account for possible rounding "shift")
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -81,7 +81,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
||||||
// the shift amount is greater than the integers size (for cvt to int)
|
// the shift amount is greater than the integers size (for cvt to int)
|
||||||
// ShiftGtIntSz calculation:
|
// ShiftGtIntSz calculation:
|
||||||
// a left shift of intlen+1 is still in range but any more than that is an overflow
|
// a left shift of intlen+1 is still in range but any more than that is an overflow
|
||||||
// inital: | 64 0's | XLEN |
|
// initial: | 64 0's | XLEN |
|
||||||
// | 64 0's | XLEN | << 64
|
// | 64 0's | XLEN | << 64
|
||||||
// | XLEN | 00000... |
|
// | XLEN | 00000... |
|
||||||
// 65 = ...0 0 0 0 0 1 0 0 0 0 0 1
|
// 65 = ...0 0 0 0 0 1 0 0 0 0 0 1
|
||||||
|
@ -89,8 +89,8 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
||||||
// 33 = ...0 0 0 0 0 0 1 0 0 0 0 1
|
// 33 = ...0 0 0 0 0 0 1 0 0 0 0 1
|
||||||
// | or | | or |
|
// | or | | or |
|
||||||
// larger or equal if:
|
// larger or equal if:
|
||||||
// - any of the bits after the most significan 1 is one
|
// - any of the bits after the most significant 1 is one
|
||||||
// - the most signifcant in 65 or 33 is still a one in the number and
|
// - the most significant in 65 or 33 is still a one in the number and
|
||||||
// one of the later bits is one
|
// one of the later bits is one
|
||||||
if (P.FPSIZES == 1) begin
|
if (P.FPSIZES == 1) begin
|
||||||
assign ResExpGteMax = &FullRe[P.NE-1:0] | FullRe[P.NE];
|
assign ResExpGteMax = &FullRe[P.NE-1:0] | FullRe[P.NE];
|
||||||
|
@ -121,7 +121,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
||||||
assign ShiftGtIntSz = (|FullRe[P.Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
|
assign ShiftGtIntSz = (|FullRe[P.Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
|
||||||
end
|
end
|
||||||
|
|
||||||
// calulate overflow flag:
|
// calculate overflow flag:
|
||||||
// if the result is greater than or equal to the max exponent(not taking into account sign)
|
// if the result is greater than or equal to the max exponent(not taking into account sign)
|
||||||
// | and the exponent isn't negative
|
// | and the exponent isn't negative
|
||||||
// | | if the input isnt infinity or NaN
|
// | | if the input isnt infinity or NaN
|
||||||
|
@ -146,8 +146,8 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
||||||
// Inexact
|
// Inexact
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Set Inexact flag if the result is diffrent from what would be outputed given infinite precision
|
// Set Inexact flag if the result is different from what would be outputted given infinite precision
|
||||||
// - Don't set the underflow flag if an underflowed res isn't outputed
|
// - Don't set the underflow flag if an underflowed res isn't outputted
|
||||||
assign FpInexact = (Sticky|Guard|Overflow|Round)&~(InfIn|NaNIn|DivByZero|Invalid);
|
assign FpInexact = (Sticky|Guard|Overflow|Round)&~(InfIn|NaNIn|DivByZero|Invalid);
|
||||||
|
|
||||||
// if the res is too small to be represented and not 0
|
// if the res is too small to be represented and not 0
|
||||||
|
|
|
@ -34,7 +34,7 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic [$clog2(P.FMALEN+1)-1:0] FmaSCnt, // normalization shift count
|
input logic [$clog2(P.FMALEN+1)-1:0] FmaSCnt, // normalization shift count
|
||||||
output logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
|
output logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||||
output logic FmaSZero, // is the sum zero
|
output logic FmaSZero, // is the sum zero
|
||||||
output logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
output logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA correction
|
||||||
output logic [$clog2(P.FMALEN+1)-1:0] FmaShiftAmt // normalization shift count
|
output logic [$clog2(P.FMALEN+1)-1:0] FmaShiftAmt // normalization shift count
|
||||||
);
|
);
|
||||||
logic [P.NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the P.FLEN bias
|
logic [P.NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the P.FLEN bias
|
||||||
|
|
|
@ -56,7 +56,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic [P.NE:0] CvtCe, // the calculated exponent
|
input logic [P.NE:0] CvtCe, // the calculated exponent
|
||||||
input logic CvtResSubnormUf, // the convert result is subnormal or underflows
|
input logic CvtResSubnormUf, // the convert result is subnormal or underflows
|
||||||
input logic [P.LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by
|
input logic [P.LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by
|
||||||
input logic ToInt, // is fp->int (since it's writting to the integer register)
|
input logic ToInt, // is fp->int (since it's writing to the integer register)
|
||||||
input logic Zfa, // Zfa operation (fcvtmod.w.d)
|
input logic Zfa, // Zfa operation (fcvtmod.w.d)
|
||||||
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||||
input logic IntZero, // is the integer input zero
|
input logic IntZero, // is the integer input zero
|
||||||
|
@ -77,7 +77,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||||
logic UfPlus1; // do you add one (for determining underflow flag)
|
logic UfPlus1; // do you add one (for determining underflow flag)
|
||||||
logic [P.LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount
|
logic [P.LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount
|
||||||
logic [P.NORMSHIFTSZ-1:0] ShiftIn; // input to normalization shift
|
logic [P.NORMSHIFTSZ-1:0] ShiftIn; // input to normalization shift
|
||||||
logic [P.NORMSHIFTSZ-1:0] Shifted; // the ouput of the normalized shifter (before shift correction)
|
logic [P.NORMSHIFTSZ-1:0] Shifted; // the output of the normalized shifter (before shift correction)
|
||||||
logic Plus1; // add one to the final result?
|
logic Plus1; // add one to the final result?
|
||||||
logic Overflow; // overflow flag used to select results
|
logic Overflow; // overflow flag used to select results
|
||||||
logic Invalid; // invalid flag used to select results
|
logic Invalid; // invalid flag used to select results
|
||||||
|
@ -87,14 +87,14 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||||
logic [P.NE+1:0] FmaMe; // exponent of the normalized sum
|
logic [P.NE+1:0] FmaMe; // exponent of the normalized sum
|
||||||
logic FmaSZero; // is the sum zero
|
logic FmaSZero; // is the sum zero
|
||||||
logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results
|
logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||||
logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection
|
logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA correction
|
||||||
logic [$clog2(P.FMALEN+1)-1:0] FmaShiftAmt; // normalization shift amount for fma
|
logic [$clog2(P.FMALEN+1)-1:0] FmaShiftAmt; // normalization shift amount for fma
|
||||||
// division signals
|
// division signals
|
||||||
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
|
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shift amount
|
||||||
logic [P.NE+1:0] Ue; // divsqrt corrected exponent after corretion shift
|
logic [P.NE+1:0] Ue; // divsqrt corrected exponent after correction shift
|
||||||
logic DivByZero; // divide by zero flag
|
logic DivByZero; // divide by zero flag
|
||||||
logic DivResSubnorm; // is the divsqrt result subnormal
|
logic DivResSubnorm; // is the divsqrt result subnormal
|
||||||
logic DivSubnormShiftPos; // is the divsqrt subnorm shift amout positive (not underflowed)
|
logic DivSubnormShiftPos; // is the divsqrt subnorm shift amount positive (not underflowed)
|
||||||
// conversion signals
|
// conversion signals
|
||||||
logic [P.CVTLEN+P.NF:0] CvtShiftIn; // number to be shifted for converter
|
logic [P.CVTLEN+P.NF:0] CvtShiftIn; // number to be shifted for converter
|
||||||
logic [1:0] CvtNegResMsbs; // most significant bits of possibly negated int result
|
logic [1:0] CvtNegResMsbs; // most significant bits of possibly negated int result
|
||||||
|
@ -107,7 +107,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||||
logic Int64; // is the integer 64 bits?
|
logic Int64; // is the integer 64 bits?
|
||||||
logic Signed; // is the operation with a signed integer?
|
logic Signed; // is the operation with a signed integer?
|
||||||
logic IntToFp; // is the operation an int->fp conversion?
|
logic IntToFp; // is the operation an int->fp conversion?
|
||||||
logic CvtOp; // convertion operation
|
logic CvtOp; // conversion operation
|
||||||
logic FmaOp; // fma operation
|
logic FmaOp; // fma operation
|
||||||
logic DivOp; // divider operation
|
logic DivOp; // divider operation
|
||||||
logic InfIn; // are any of the inputs infinity
|
logic InfIn; // are any of the inputs infinity
|
||||||
|
@ -187,7 +187,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||||
// round to infinity
|
// round to infinity
|
||||||
// round to nearest max magnitude
|
// round to nearest max magnitude
|
||||||
|
|
||||||
// calulate result sign used in rounding unit
|
// calculate result sign used in rounding unit
|
||||||
roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
|
roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
|
||||||
|
|
||||||
round #(P) round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Ue,
|
round #(P) round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Ue,
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
module resultsign(
|
module resultsign(
|
||||||
input logic [2:0] Frm, // rounding mode
|
input logic [2:0] Frm, // rounding mode
|
||||||
input logic FmaOp, // is the operation an Fma
|
input logic FmaOp, // is the operation an Fma
|
||||||
input logic Mult, // is the fma operation multipy
|
input logic Mult, // is the fma operation multiply
|
||||||
input logic ZInf, // is Z infinity
|
input logic ZInf, // is Z infinity
|
||||||
input logic InfIn, // are any of the inputs infinity
|
input logic InfIn, // are any of the inputs infinity
|
||||||
input logic FmaSZero, // is the fma sum zero
|
input logic FmaSZero, // is the fma sum zero
|
||||||
|
@ -48,12 +48,12 @@ module resultsign(
|
||||||
|
|
||||||
// determine the sign for a result of 0
|
// determine the sign for a result of 0
|
||||||
// The IEEE754-2019 standard specifies:
|
// The IEEE754-2019 standard specifies:
|
||||||
// - the sign of an exact zero sum (with operands of diffrent signs) should be positive unless rounding toward negative infinity
|
// - the sign of an exact zero sum (with operands of different signs) should be positive unless rounding toward negative infinity
|
||||||
// - when the exact result of an FMA operation is non-zero, but is zero due to rounding, use the sign of the exact result
|
// - when the exact result of an FMA operation is non-zero, but is zero due to rounding, use the sign of the exact result
|
||||||
// - if x = +0 or -0 then x+x=x and x-(-x)=x
|
// - if x = +0 or -0 then x+x=x and x-(-x)=x
|
||||||
// - the sign of a product is the exclisive or or the opperand's signs
|
// - the sign of a product is the exclisive or or the opperand's signs
|
||||||
// Zero sign will only be selected if:
|
// Zero sign will only be selected if:
|
||||||
// - P=Z and a cancelation occurs - exact zero
|
// - P=Z and a cancellation occurs - exact zero
|
||||||
// - Z is zero and P is zero - exact zero
|
// - Z is zero and P is zero - exact zero
|
||||||
// - P is killed and Z is zero - Psgn
|
// - P is killed and Z is zero - Psgn
|
||||||
// - Z is killed and P is zero - impossible
|
// - Z is killed and P is zero - impossible
|
||||||
|
|
|
@ -40,13 +40,13 @@ module round import cvw::*; #(parameter cvw_t P) (
|
||||||
// divsqrt
|
// divsqrt
|
||||||
input logic DivOp, // is a division operation being done
|
input logic DivOp, // is a division operation being done
|
||||||
input logic DivSticky, // divsqrt sticky bit
|
input logic DivSticky, // divsqrt sticky bit
|
||||||
input logic [P.NE+1:0] Ue, // the divsqrt calculated expoent
|
input logic [P.NE+1:0] Ue, // the divsqrt calculated exponent
|
||||||
// cvt
|
// cvt
|
||||||
input logic CvtOp, // is a convert operation being done
|
input logic CvtOp, // is a convert operation being done
|
||||||
input logic ToInt, // is the cvt op a cvt to integer
|
input logic ToInt, // is the cvt op a cvt to integer
|
||||||
input logic CvtResSubnormUf, // is the cvt result subnormal or underflow
|
input logic CvtResSubnormUf, // is the cvt result subnormal or underflow
|
||||||
input logic CvtResUf, // does the cvt result underflow
|
input logic CvtResUf, // does the cvt result underflow
|
||||||
input logic [P.NE:0] CvtCe, // the cvt calculated expoent
|
input logic [P.NE:0] CvtCe, // the cvt calculated exponent
|
||||||
// outputs
|
// outputs
|
||||||
output logic [P.NE+1:0] Me, // normalied fraction
|
output logic [P.NE+1:0] Me, // normalied fraction
|
||||||
output logic UfPlus1, // do you add one to the result if given an unbounded exponent
|
output logic UfPlus1, // do you add one to the result if given an unbounded exponent
|
||||||
|
@ -172,7 +172,7 @@ module round import cvw::*; #(parameter cvw_t P) (
|
||||||
(|Mf[P.NORMSHIFTSZ-P.XLEN-2:P.NORMSHIFTSZ-P.Q_NF-1]&(~(OutFmt==P.Q_FMT)|IntRes)) |
|
(|Mf[P.NORMSHIFTSZ-P.XLEN-2:P.NORMSHIFTSZ-P.Q_NF-1]&(~(OutFmt==P.Q_FMT)|IntRes)) |
|
||||||
(|Mf[P.NORMSHIFTSZ-P.Q_NF-2:0]);
|
(|Mf[P.NORMSHIFTSZ-P.Q_NF-2:0]);
|
||||||
// 3: NF > NF1 > XLEN
|
// 3: NF > NF1 > XLEN
|
||||||
// The extra XLEN bit will be ored later when caculating the final sticky bit - the ufplus1 not needed for integer
|
// The extra XLEN bit will be ored later when calculating the final sticky bit - the ufplus1 not needed for integer
|
||||||
if (XLENPOS == 3) assign NormSticky = (|Mf[P.NORMSHIFTSZ-P.H_NF-2:P.NORMSHIFTSZ-P.S_NF-1]&FpRes&(OutFmt==P.H_FMT)) |
|
if (XLENPOS == 3) assign NormSticky = (|Mf[P.NORMSHIFTSZ-P.H_NF-2:P.NORMSHIFTSZ-P.S_NF-1]&FpRes&(OutFmt==P.H_FMT)) |
|
||||||
(|Mf[P.NORMSHIFTSZ-P.S_NF-2:P.NORMSHIFTSZ-P.XLEN-1]&FpRes&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT))) |
|
(|Mf[P.NORMSHIFTSZ-P.S_NF-2:P.NORMSHIFTSZ-P.XLEN-1]&FpRes&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT))) |
|
||||||
(|Mf[P.NORMSHIFTSZ-P.XLEN-2:P.NORMSHIFTSZ-P.D_NF-1]&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT)|IntRes)) |
|
(|Mf[P.NORMSHIFTSZ-P.XLEN-2:P.NORMSHIFTSZ-P.D_NF-1]&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT)|IntRes)) |
|
||||||
|
|
|
@ -44,7 +44,7 @@ module roundsign(
|
||||||
// calculate divsqrt sign
|
// calculate divsqrt sign
|
||||||
assign Qs = Xs^(Ys&~Sqrt);
|
assign Qs = Xs^(Ys&~Sqrt);
|
||||||
|
|
||||||
// Select sign for rounding calulation
|
// Select sign for rounding calculation
|
||||||
assign Ms = (FmaSs&FmaOp) | (CvtCs&CvtOp) | (Qs&DivOp);
|
assign Ms = (FmaSs&FmaOp) | (CvtCs&CvtOp) | (Qs&DivOp);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -37,7 +37,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||||
//fma
|
//fma
|
||||||
input logic FmaOp, // is it an fma operation
|
input logic FmaOp, // is it an fma operation
|
||||||
input logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
|
input logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||||
input logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
input logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA correction
|
||||||
input logic FmaSZero,
|
input logic FmaSZero,
|
||||||
// output
|
// output
|
||||||
output logic [P.NE+1:0] FmaMe, // exponent of the normalized sum
|
output logic [P.NE+1:0] FmaMe, // exponent of the normalized sum
|
||||||
|
@ -61,10 +61,10 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||||
assign LZAPlus1 = Shifted[P.NORMSHIFTSZ-1];
|
assign LZAPlus1 = Shifted[P.NORMSHIFTSZ-1];
|
||||||
|
|
||||||
// correct the shifting of the divsqrt caused by producing a result in (0.5, 2) range
|
// correct the shifting of the divsqrt caused by producing a result in (0.5, 2) range
|
||||||
// condition: if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm)
|
// condition: if the msb is 1 or the exponent was one, but the shifted quotient was < 1 (Subnorm)
|
||||||
assign LeftShiftQm = (LZAPlus1|(DivUe==1&~LZAPlus1));
|
assign LeftShiftQm = (LZAPlus1|(DivUe==1&~LZAPlus1));
|
||||||
|
|
||||||
// Determine the shif for either FMA or divsqrt
|
// Determine the shift for either FMA or divsqrt
|
||||||
assign RightShift = FmaOp ? LZAPlus1 : LeftShiftQm;
|
assign RightShift = FmaOp ? LZAPlus1 : LeftShiftQm;
|
||||||
|
|
||||||
// possible one bit right shift for FMA or division
|
// possible one bit right shift for FMA or division
|
||||||
|
@ -79,8 +79,8 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||||
// main exponent issues:
|
// main exponent issues:
|
||||||
// - LZA was one too large
|
// - LZA was one too large
|
||||||
// - LZA was two too large
|
// - LZA was two too large
|
||||||
// - if the result was calulated to be subnorm but it's norm and the LZA was off by 1
|
// - if the result was calculated to be subnorm but it's norm and the LZA was off by 1
|
||||||
// - if the result was calulated to be subnorm but it's norm and the LZA was off by 2
|
// - if the result was calculated to be subnorm but it's norm and the LZA was off by 2
|
||||||
// if plus1 If plus2 kill if the result Zero or actually subnormal
|
// if plus1 If plus2 kill if the result Zero or actually subnormal
|
||||||
// | | |
|
// | | |
|
||||||
assign FmaMe = (NormSumExp+{{P.NE+1{1'b0}}, LZAPlus1} +{{P.NE+1{1'b0}}, FmaPreResultSubnorm}) & {P.NE+2{~(FmaSZero|ResSubnorm)}};
|
assign FmaMe = (NormSumExp+{{P.NE+1{1'b0}}, LZAPlus1} +{{P.NE+1{1'b0}}, FmaPreResultSubnorm}) & {P.NE+2{~(FmaSZero|ResSubnorm)}};
|
||||||
|
@ -88,8 +88,8 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||||
// recalculate if the result is subnormal after LZA correction
|
// recalculate if the result is subnormal after LZA correction
|
||||||
assign ResSubnorm = FmaPreResultSubnorm&~Shifted[P.NORMSHIFTSZ-2]&~Shifted[P.NORMSHIFTSZ-1];
|
assign ResSubnorm = FmaPreResultSubnorm&~Shifted[P.NORMSHIFTSZ-2]&~Shifted[P.NORMSHIFTSZ-1];
|
||||||
|
|
||||||
// the quotent is in the range (.5,2) if there is no early termination
|
// the quotient is in the range (.5,2) if there is no early termination
|
||||||
// if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift
|
// if the quotient < 1 and not Subnormal then subtract 1 to account for the normalization shift
|
||||||
assign Ue = (DivResSubnorm & DivSubnormShiftPos) ? 0 : DivUe - {(P.NE+1)'(0), ~LZAPlus1};
|
assign Ue = (DivResSubnorm & DivSubnormShiftPos) ? 0 : DivUe - {(P.NE+1)'(0), ~LZAPlus1};
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic Int64, // is the integer 64 bits
|
input logic Int64, // is the integer 64 bits
|
||||||
input logic Signed, // is the integer signed
|
input logic Signed, // is the integer signed
|
||||||
input logic Zfa, // Zfa conversion operation: fcvtmod.w.d
|
input logic Zfa, // Zfa conversion operation: fcvtmod.w.d
|
||||||
input logic [P.NE:0] CvtCe, // the calculated expoent for cvt
|
input logic [P.NE:0] CvtCe, // the calculated exponent for cvt
|
||||||
input logic IntInvalid, // integer invalid flag to choose the result
|
input logic IntInvalid, // integer invalid flag to choose the result
|
||||||
input logic CvtResUf, // does the convert result underflow
|
input logic CvtResUf, // does the convert result underflow
|
||||||
input logic [P.XLEN+1:0] CvtNegRes, // the possibly negated of the integer result
|
input logic [P.XLEN+1:0] CvtNegRes, // the possibly negated of the integer result
|
||||||
|
@ -240,7 +240,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
// determine if you shoould kill the res - Cvt
|
// determine if you should kill the res - Cvt
|
||||||
// - do so if the res underflows, is zero (the exp doesnt calculate correctly). or the integer input is 0
|
// - do so if the res underflows, is zero (the exp doesnt calculate correctly). or the integer input is 0
|
||||||
// - dont set to zero if fp input is zero but not using the fp input
|
// - dont set to zero if fp input is zero but not using the fp input
|
||||||
// - dont set to zero if int input is zero but not using the int input
|
// - dont set to zero if int input is zero but not using the int input
|
||||||
|
@ -334,7 +334,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
||||||
end
|
end
|
||||||
|
|
||||||
// fcvtmod.w.d logic
|
// fcvtmod.w.d logic
|
||||||
// fcvtmod.w.d is like fcvt.w.d excep thtat it takes bits [31:0] and sign extends the rest,
|
// fcvtmod.w.d is like fcvt.w.d excep that it takes bits [31:0] and sign extends the rest,
|
||||||
// and converts +/-inf and NaN to zero.
|
// and converts +/-inf and NaN to zero.
|
||||||
|
|
||||||
if (P.ZFA_SUPPORTED & P.D_SUPPORTED) // fcvtmod.w.d support
|
if (P.ZFA_SUPPORTED & P.D_SUPPORTED) // fcvtmod.w.d support
|
||||||
|
@ -358,7 +358,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
||||||
// - if the input underflows
|
// - if the input underflows
|
||||||
// - if rounding and signed operation and negative input, output -1
|
// - if rounding and signed operation and negative input, output -1
|
||||||
// - otherwise output a rounded 0
|
// - otherwise output a rounded 0
|
||||||
// - otherwise output the normal res (trmined and sign extended if nessisary)
|
// - otherwise output the normal res (trmined and sign extended if necessary)
|
||||||
always_comb
|
always_comb
|
||||||
if(SelCvtOfRes) FCvtIntRes = OfIntRes2;
|
if(SelCvtOfRes) FCvtIntRes = OfIntRes2;
|
||||||
else if(CvtCe[P.NE])
|
else if(CvtCe[P.NE])
|
||||||
|
|
|
@ -88,10 +88,10 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
||||||
end else
|
end else
|
||||||
PostBox = In;
|
PostBox = In;
|
||||||
|
|
||||||
// choose sign bit depending on format - 1=larger precsion 0=smaller precision
|
// choose sign bit depending on format - 1=larger precision 0=smaller precision
|
||||||
assign Sgn = Fmt ? In[P.FLEN-1] : (BadNaNBox ? 0 : In[P.LEN1-1]); // improperly boxed NaNs are treated as positive
|
assign Sgn = Fmt ? In[P.FLEN-1] : (BadNaNBox ? 0 : In[P.LEN1-1]); // improperly boxed NaNs are treated as positive
|
||||||
|
|
||||||
// extract the fraction, add trailing zeroes to the mantissa if nessisary
|
// extract the fraction, add trailing zeroes to the mantissa if necessary
|
||||||
assign Frac = Fmt ? In[P.NF-1:0] : {In[P.NF1-1:0], (P.NF-P.NF1)'(0)};
|
assign Frac = Fmt ? In[P.NF-1:0] : {In[P.NF1-1:0], (P.NF-P.NF1)'(0)};
|
||||||
|
|
||||||
// is the exponent non-zero
|
// is the exponent non-zero
|
||||||
|
@ -105,14 +105,14 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
||||||
// dexp = 0bdd dbbb bbbb
|
// dexp = 0bdd dbbb bbbb
|
||||||
// also need to take into account possible zero/Subnorm/inf/NaN values
|
// also need to take into account possible zero/Subnorm/inf/NaN values
|
||||||
|
|
||||||
// extract the exponent, converting the smaller exponent into the larger precision if nessisary
|
// extract the exponent, converting the smaller exponent into the larger precision if necessary
|
||||||
// - if the original precision had a Subnormal number convert the exponent value 1
|
// - if the original precision had a Subnormal number convert the exponent value 1
|
||||||
assign Exp = Fmt ? {In[P.FLEN-2:P.NF+1], In[P.NF]|~ExpNonZero} : {In[P.LEN1-2], {P.NE-P.NE1{~In[P.LEN1-2]}}, In[P.LEN1-3:P.NF1+1], In[P.NF1]|~ExpNonZero};
|
assign Exp = Fmt ? {In[P.FLEN-2:P.NF+1], In[P.NF]|~ExpNonZero} : {In[P.LEN1-2], {P.NE-P.NE1{~In[P.LEN1-2]}}, In[P.LEN1-3:P.NF1+1], In[P.NF1]|~ExpNonZero};
|
||||||
|
|
||||||
// is the exponent all 1's
|
// is the exponent all 1's
|
||||||
assign ExpMax = Fmt ? &In[P.FLEN-2:P.NF] : &In[P.LEN1-2:P.NF1];
|
assign ExpMax = Fmt ? &In[P.FLEN-2:P.NF] : &In[P.LEN1-2:P.NF1];
|
||||||
|
|
||||||
end else if (P.FPSIZES == 3) begin // three floating point precsions supported
|
end else if (P.FPSIZES == 3) begin // three floating point precisions supported
|
||||||
|
|
||||||
// largest format | larger format | smallest format
|
// largest format | larger format | smallest format
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
|
@ -171,8 +171,8 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
||||||
always_comb
|
always_comb
|
||||||
case (Fmt)
|
case (Fmt)
|
||||||
P.FMT: ExpNonZero = |In[P.FLEN-2:P.NF]; // if input is largest precision (P.FLEN - ie quad or double)
|
P.FMT: ExpNonZero = |In[P.FLEN-2:P.NF]; // if input is largest precision (P.FLEN - ie quad or double)
|
||||||
P.FMT1: ExpNonZero = |In[P.LEN1-2:P.NF1]; // if input is larger precsion (P.LEN1 - double or single)
|
P.FMT1: ExpNonZero = |In[P.LEN1-2:P.NF1]; // if input is larger precision (P.LEN1 - double or single)
|
||||||
P.FMT2: ExpNonZero = |In[P.LEN2-2:P.NF2]; // if input is smallest precsion (P.LEN2 - single or half)
|
P.FMT2: ExpNonZero = |In[P.LEN2-2:P.NF2]; // if input is smallest precision (P.LEN2 - single or half)
|
||||||
default: ExpNonZero = 1'bx;
|
default: ExpNonZero = 1'bx;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
||||||
// dexp = 0bdd dbbb bbbb
|
// dexp = 0bdd dbbb bbbb
|
||||||
// also need to take into account possible zero/Subnorm/inf/NaN values
|
// also need to take into account possible zero/Subnorm/inf/NaN values
|
||||||
|
|
||||||
// convert the double precsion exponent into quad precsion
|
// convert the double precision exponent into quad precision
|
||||||
// 1 is added to the exponent if the input is zero or subnormal
|
// 1 is added to the exponent if the input is zero or subnormal
|
||||||
always_comb
|
always_comb
|
||||||
case (Fmt)
|
case (Fmt)
|
||||||
|
@ -294,7 +294,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
||||||
assign FracZero = ~|Frac & ~BadNaNBox; // is the fraction zero?
|
assign FracZero = ~|Frac & ~BadNaNBox; // is the fraction zero?
|
||||||
assign Man = {ExpNonZero, Frac}; // add the assumed one (or zero if Subnormal or zero) to create the significand
|
assign Man = {ExpNonZero, Frac}; // add the assumed one (or zero if Subnormal or zero) to create the significand
|
||||||
assign NaN = ((ExpMax & ~FracZero)|BadNaNBox)&En; // is the input a NaN?
|
assign NaN = ((ExpMax & ~FracZero)|BadNaNBox)&En; // is the input a NaN?
|
||||||
assign SNaN = NaN&~Frac[P.NF-1]&~BadNaNBox; // is the input a singnaling NaN?
|
assign SNaN = NaN&~Frac[P.NF-1]&~BadNaNBox; // is the input a signaling NaN?
|
||||||
assign Inf = ExpMax & FracZero & En; // is the input infinity?
|
assign Inf = ExpMax & FracZero & En; // is the input infinity?
|
||||||
assign Zero = ~ExpNonZero & FracZero; // is the input zero?
|
assign Zero = ~ExpNonZero & FracZero; // is the input zero?
|
||||||
assign Subnorm = ~ExpNonZero & ~FracZero & ~BadNaNBox; // is the input subnormal
|
assign Subnorm = ~ExpNonZero & ~FracZero & ~BadNaNBox; // is the input subnormal
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// ram1p1rwbe_64x22.sv
|
// ram1p1rwbe_64x22.sv
|
||||||
//
|
//
|
||||||
// Written: james.stine@okstate.edu 2 Feburary 2023
|
// Written: james.stine@okstate.edu 2 February 2023
|
||||||
// Modified:
|
// Modified:
|
||||||
//
|
//
|
||||||
// Purpose: RAM wrapper for instantiating RAM IP
|
// Purpose: RAM wrapper for instantiating RAM IP
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Written: tfleming@hmc.edu & jtorrey@hmc.edu 7 April 2021
|
// Written: tfleming@hmc.edu & jtorrey@hmc.edu 7 April 2021
|
||||||
// Modified: Teo Ene 15 Apr 2021:
|
// Modified: Teo Ene 15 Apr 2021:
|
||||||
// Temporarily removed paramterized priority encoder for non-parameterized one
|
// Temporarily removed parameterized priority encoder for non-parameterized one
|
||||||
// To get synthesis working quickly
|
// To get synthesis working quickly
|
||||||
// Kmacsaigoren@hmc.edu 28 May 2021:
|
// Kmacsaigoren@hmc.edu 28 May 2021:
|
||||||
// Added working version of parameterized priority encoder.
|
// Added working version of parameterized priority encoder.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// David_Harris@Hmc.edu switched to one-hot output
|
// David_Harris@Hmc.edu switched to one-hot output
|
||||||
//
|
//
|
||||||
// Purpose: Priority circuit producing a thermometer code output.
|
// Purpose: Priority circuit producing a thermometer code output.
|
||||||
// with 1's in all the least signficant bits of the output
|
// with 1's in all the least significant bits of the output
|
||||||
// until the column where the least significant 1 occurs in the input.
|
// until the column where the least significant 1 occurs in the input.
|
||||||
//
|
//
|
||||||
// Example: msb lsb
|
// Example: msb lsb
|
||||||
|
|
|
@ -67,7 +67,7 @@ module hazard (
|
||||||
// Trap returns (RetM) also flush the entire pipeline after the RetM (all stages except W) because all the subsequent instructions must be discarded.
|
// Trap returns (RetM) also flush the entire pipeline after the RetM (all stages except W) because all the subsequent instructions must be discarded.
|
||||||
// Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents
|
// Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents
|
||||||
// Branch misprediction is found in the Execute stage and must flush the next two instructions.
|
// Branch misprediction is found in the Execute stage and must flush the next two instructions.
|
||||||
// However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divde must still complete
|
// However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divide must still complete
|
||||||
// When a WFI is interrupted and causes a trap, it flushes the rest of the pipeline but not the W stage, because the WFI needs to commit
|
// When a WFI is interrupted and causes a trap, it flushes the rest of the pipeline but not the W stage, because the WFI needs to commit
|
||||||
assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE;
|
assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE;
|
||||||
assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE));
|
assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE));
|
||||||
|
@ -75,7 +75,7 @@ module hazard (
|
||||||
assign FlushWCause = TrapM & ~WFIInterruptedM;
|
assign FlushWCause = TrapM & ~WFIInterruptedM;
|
||||||
|
|
||||||
// Stall causes
|
// Stall causes
|
||||||
// Most data depenency stalls are identified in the decode stage
|
// Most data dependency stalls are identified in the decode stage
|
||||||
// Division stalls in the execute stage
|
// Division stalls in the execute stage
|
||||||
// Flushing any stage has priority over the corresponding stage stall.
|
// Flushing any stage has priority over the corresponding stage stall.
|
||||||
// Even if the register gave clear priority over enable, various FSMs still need to disable the stall, so it's best to gate the stall here with flush
|
// Even if the register gave clear priority over enable, various FSMs still need to disable the stall, so it's best to gate the stall here with flush
|
||||||
|
|
|
@ -37,7 +37,7 @@ module aes64ks1i(
|
||||||
logic [31:0] rcon, rs1Rotate;
|
logic [31:0] rcon, rs1Rotate;
|
||||||
|
|
||||||
rconlut32 rc(round, rcon); // Get rcon value from lookup table
|
rconlut32 rc(round, rcon); // Get rcon value from lookup table
|
||||||
assign rs1Rotate = {rs1[39:32], rs1[63:40]}; // Get rotated value fo ruse in tmp2
|
assign rs1Rotate = {rs1[39:32], rs1[63:40]}; // Get rotated value for use in tmp2
|
||||||
assign finalround = (round == 4'b1010); // round 10 is the last one
|
assign finalround = (round == 4'b1010); // round 10 is the last one
|
||||||
assign SboxKIn = finalround ? rs1[63:32] : rs1Rotate; // Don't rotate on the last round
|
assign SboxKIn = finalround ? rs1[63:32] : rs1Rotate; // Don't rotate on the last round
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) (
|
||||||
logic [P.XLEN-1:0] MaskB; // BitMask of B
|
logic [P.XLEN-1:0] MaskB; // BitMask of B
|
||||||
logic [P.XLEN-1:0] RevA; // Bit-reversed A
|
logic [P.XLEN-1:0] RevA; // Bit-reversed A
|
||||||
logic Mask; // Indicates if it is ZBS instruction
|
logic Mask; // Indicates if it is ZBS instruction
|
||||||
logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction
|
logic PreShift; // Indicates if it is sh1add, sh2add, sh3add instruction
|
||||||
logic [1:0] PreShiftAmt; // Amount to Pre-Shift A
|
logic [1:0] PreShiftAmt; // Amount to Pre-Shift A
|
||||||
logic [P.XLEN-1:0] CondZextA; // A Conditional Extend Intermediary Signal
|
logic [P.XLEN-1:0] CondZextA; // A Conditional Extend Intermediary Signal
|
||||||
logic [P.XLEN-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity
|
logic [P.XLEN-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity
|
||||||
|
|
|
@ -35,8 +35,8 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic ALUOpD, // Regular ALU Operation
|
input logic ALUOpD, // Regular ALU Operation
|
||||||
output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage
|
output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage
|
||||||
output logic BALUSrcBD, // Indicates if it is an I/IW (non auipc) type B instruction in Decode Stage
|
output logic BALUSrcBD, // Indicates if it is an I/IW (non auipc) type B instruction in Decode Stage
|
||||||
output logic BW64D, // Indiciates if it is a W type B instruction in Decode Stage
|
output logic BW64D, // Indicates if it is a W type B instruction in Decode Stage
|
||||||
output logic BUW64D, // Indiciates if it is a .uw type B instruction in Decode Stage
|
output logic BUW64D, // Indicates if it is a .uw type B instruction in Decode Stage
|
||||||
output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage
|
output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage
|
||||||
output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage
|
output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage
|
||||||
// Execute stage control signals
|
// Execute stage control signals
|
||||||
|
|
|
@ -158,7 +158,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
||||||
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
|
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
|
||||||
logic FCvtIntStallD, MDUStallD, CSRRdStallD; // Stall due to conversion, load, multiply/divide, CSR read
|
logic FCvtIntStallD, MDUStallD, CSRRdStallD; // Stall due to conversion, load, multiply/divide, CSR read
|
||||||
logic FunctCZeroD; // Funct7 and Funct3 indicate czero.* (not including Op check)
|
logic FunctCZeroD; // Funct7 and Funct3 indicate czero.* (not including Op check)
|
||||||
logic BUW64D; // Indiciates if it is a .uw type B instruction in Decode Stage
|
logic BUW64D; // Indicates if it is a .uw type B instruction in Decode Stage
|
||||||
|
|
||||||
// Extract fields
|
// Extract fields
|
||||||
assign OpD = InstrD[6:0];
|
assign OpD = InstrD[6:0];
|
||||||
|
@ -401,7 +401,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
||||||
IFUPrefetchD = 1'b0;
|
IFUPrefetchD = 1'b0;
|
||||||
LSUPrefetchD = 1'b0;
|
LSUPrefetchD = 1'b0;
|
||||||
ImmSrcD = PreImmSrcD;
|
ImmSrcD = PreImmSrcD;
|
||||||
if (P.ZICBOP_SUPPORTED & (InstrD[14:0] == 15'b110_00000_0010011)) begin // ori with destiation x0 is hint for Prefetch
|
if (P.ZICBOP_SUPPORTED & (InstrD[14:0] == 15'b110_00000_0010011)) begin // ori with destination x0 is hint for Prefetch
|
||||||
/* verilator lint_off CASEINCOMPLETE */
|
/* verilator lint_off CASEINCOMPLETE */
|
||||||
case (Rs2D) // which type of prefectch? Note: prefetch.r and .w are handled the same in Wally
|
case (Rs2D) // which type of prefectch? Note: prefetch.r and .w are handled the same in Wally
|
||||||
5'b00000: IFUPrefetchD = 1'b1; // prefetch.i
|
5'b00000: IFUPrefetchD = 1'b1; // prefetch.i
|
||||||
|
|
|
@ -60,7 +60,7 @@ module shifter import cvw::*; #(parameter cvw_t P) (
|
||||||
if (P.ZBB_SUPPORTED | P.ZBKB_SUPPORTED) begin: rotfunnel64 // rv64 shifter with rotates
|
if (P.ZBB_SUPPORTED | P.ZBKB_SUPPORTED) begin: rotfunnel64 // rv64 shifter with rotates
|
||||||
// shifter rotate source select mux
|
// shifter rotate source select mux
|
||||||
logic [P.XLEN-1:0] RotA; // rotate source
|
logic [P.XLEN-1:0] RotA; // rotate source
|
||||||
mux2 #(P.XLEN) rotmux(A, {A[31:0], A[31:0]}, W64, RotA); // W64 rotatons
|
mux2 #(P.XLEN) rotmux(A, {A[31:0], A[31:0]}, W64, RotA); // W64 rotations
|
||||||
always_comb // funnel mux
|
always_comb // funnel mux
|
||||||
case ({Right, Rotate})
|
case ({Right, Rotate})
|
||||||
2'b00: Z = {A64[63:0],{63'b0}};
|
2'b00: Z = {A64[63:0],{63'b0}};
|
||||||
|
|
|
@ -55,7 +55,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic InstrValidD, InstrValidE,
|
input logic InstrValidD, InstrValidE,
|
||||||
input logic BranchD, BranchE,
|
input logic BranchD, BranchE,
|
||||||
input logic JumpD, JumpE,
|
input logic JumpD, JumpE,
|
||||||
input logic PCSrcE, // Executation stage branch is taken
|
input logic PCSrcE, // Execution stage branch is taken
|
||||||
input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address
|
input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address
|
||||||
input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address
|
input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address
|
||||||
input logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
input logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
||||||
|
@ -188,7 +188,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
||||||
mux2 #(P.XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
|
mux2 #(P.XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
|
||||||
|
|
||||||
// If the fence/csrw was predicted as a taken branch then we select PCF, rather than PCE.
|
// If the fence/csrw was predicted as a taken branch then we select PCF, rather than PCE.
|
||||||
// Effectively this is PCM+4 or the non-existant PCLinkM
|
// Effectively this is PCM+4 or the non-existent PCLinkM
|
||||||
if(`INSTR_CLASS_PRED) mux2 #(P.XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
|
if(`INSTR_CLASS_PRED) mux2 #(P.XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
|
||||||
else assign NextValidPCE = PCE;
|
else assign NextValidPCE = PCE;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// Modified: 24 January 2023
|
// Modified: 24 January 2023
|
||||||
//
|
//
|
||||||
// Purpose: Branch Target Buffer (BTB). The BTB predicts the target address of all control flow instructions.
|
// Purpose: Branch Target Buffer (BTB). The BTB predicts the target address of all control flow instructions.
|
||||||
// It also guesses the type of instrution; jalr(r), return, jump (jr), or branch.
|
// It also guesses the type of instruction; jalr(r), return, jump (jr), or branch.
|
||||||
//
|
//
|
||||||
// Documentation: RISC-V System on Chip Design
|
// Documentation: RISC-V System on Chip Design
|
||||||
//
|
//
|
||||||
|
|
|
@ -49,7 +49,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||||
output logic [P.XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW
|
output logic [P.XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW
|
||||||
// Execute
|
// Execute
|
||||||
output logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
output logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
||||||
input logic PCSrcE, // Executation stage branch is taken
|
input logic PCSrcE, // Execution stage branch is taken
|
||||||
input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address
|
input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address
|
||||||
input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address
|
input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address
|
||||||
output logic [P.XLEN-1:0] PCE, // Execution stage instruction address
|
output logic [P.XLEN-1:0] PCE, // Execution stage instruction address
|
||||||
|
@ -78,7 +78,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||||
output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP
|
output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP
|
||||||
output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
||||||
// mmu management
|
// mmu management
|
||||||
input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage
|
input logic [1:0] PrivilegeModeW, // Privilege mode in Writeback stage
|
||||||
input logic [P.XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
|
input logic [P.XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
|
||||||
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
|
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
|
||||||
input logic ITLBWriteF, // Writes PTE and PageType to ITLB
|
input logic ITLBWriteF, // Writes PTE and PageType to ITLB
|
||||||
|
@ -208,7 +208,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// CommittedM tells the CPU's privileged unit the current instruction
|
// CommittedM tells the CPU's privileged unit the current instruction
|
||||||
// in the memory stage is a memory operaton and that memory operation is either completed
|
// in the memory stage is a memory operation and that memory operation is either completed
|
||||||
// or is partially executed. Partially completed memory operations need to prevent an interrupts.
|
// or is partially executed. Partially completed memory operations need to prevent an interrupts.
|
||||||
// There is not a clean way to restore back to a partial executed instruction. CommiteedM will
|
// There is not a clean way to restore back to a partial executed instruction. CommiteedM will
|
||||||
// delay the interrupt until the LSU is in a clean state.
|
// delay the interrupt until the LSU is in a clean state.
|
||||||
|
|
|
@ -40,7 +40,7 @@ module irom import cvw::*; #(parameter cvw_t P) (
|
||||||
logic [31:0] RawIROMInstrF;
|
logic [31:0] RawIROMInstrF;
|
||||||
logic [2:1] AdrD;
|
logic [2:1] AdrD;
|
||||||
|
|
||||||
// preload IROM with the FPGA bootloader by default so that it syntehsizes to something, avoiding having the IEU optimized away because instructions are all 0
|
// preload IROM with the FPGA bootloader by default so that it synthesizes to something, avoiding having the IEU optimized away because instructions are all 0
|
||||||
// the testbench replaces these dummy contents with the actual program of interest during simulation
|
// the testbench replaces these dummy contents with the actual program of interest during simulation
|
||||||
rom1p1r #(ADDR_WDITH, P.XLEN, 1) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull));
|
rom1p1r #(ADDR_WDITH, P.XLEN, 1) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull));
|
||||||
if (P.XLEN == 32) assign RawIROMInstrF = IROMInstrFFull;
|
if (P.XLEN == 32) assign RawIROMInstrF = IROMInstrFFull;
|
||||||
|
@ -50,7 +50,7 @@ module irom import cvw::*; #(parameter cvw_t P) (
|
||||||
flopen #(1) AdrReg2(clk, ce, Adr[2], AdrD[2]);
|
flopen #(1) AdrReg2(clk, ce, Adr[2], AdrD[2]);
|
||||||
assign RawIROMInstrF = AdrD[2] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0];
|
assign RawIROMInstrF = AdrD[2] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0];
|
||||||
end
|
end
|
||||||
// If the memory addres is aligned to 2 bytes return the upper 2 bytes in the lower 2 bytes.
|
// If the memory address is aligned to 2 bytes return the upper 2 bytes in the lower 2 bytes.
|
||||||
// The spill logic will handle merging the two together.
|
// The spill logic will handle merging the two together.
|
||||||
if (P.ZCA_SUPPORTED) begin
|
if (P.ZCA_SUPPORTED) begin
|
||||||
flopen #(1) AdrReg1(clk, ce, Adr[1], AdrD[1]);
|
flopen #(1) AdrReg1(clk, ce, Adr[1], AdrD[1]);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// Modified: 26 October 2023
|
// Modified: 26 October 2023
|
||||||
//
|
//
|
||||||
// Purpose: This module implements native alignment support for the Zicclsm extension
|
// Purpose: This module implements native alignment support for the Zicclsm extension
|
||||||
// It is simlar to the IFU's spill module and probably could be merged together with
|
// It is similar to the IFU's spill module and probably could be merged together with
|
||||||
// some effort.
|
// some effort.
|
||||||
//
|
//
|
||||||
// Documentation: RISC-V System on Chip Design
|
// Documentation: RISC-V System on Chip Design
|
||||||
|
@ -52,6 +52,7 @@ module align import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
output logic [P.XLEN-1:0] IEUAdrSpillE, // The next PCF for one of the two memory addresses of the spill
|
output logic [P.XLEN-1:0] IEUAdrSpillE, // The next PCF for one of the two memory addresses of the spill
|
||||||
output logic [P.XLEN-1:0] IEUAdrSpillM, // IEUAdrM for one of the two memory addresses of the spill
|
output logic [P.XLEN-1:0] IEUAdrSpillM, // IEUAdrM for one of the two memory addresses of the spill
|
||||||
|
output logic [P.XLEN-1:0] IEUAdrxTvalM, // IEUAdrM or spilled and aligned to next page
|
||||||
output logic SelSpillE, // During the transition between the two spill operations, the IFU should stall the pipeline
|
output logic SelSpillE, // During the transition between the two spill operations, the IFU should stall the pipeline
|
||||||
output logic [P.LLEN-1:0] DCacheReadDataWordSpillM, // The final 32 bit instruction after merging the two spilled fetches into 1 instruction
|
output logic [P.LLEN-1:0] DCacheReadDataWordSpillM, // The final 32 bit instruction after merging the two spilled fetches into 1 instruction
|
||||||
output logic SpillStallM);
|
output logic SpillStallM);
|
||||||
|
@ -80,10 +81,13 @@ module align import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
|
|
||||||
/* verilator lint_off WIDTHEXPAND */
|
/* verilator lint_off WIDTHEXPAND */
|
||||||
|
//assign IEUAdrIncrementM = {IEUAdrM[P.XLEN-1:OFFSET_LEN], {{OFFSET_LEN}{1'b0}}} + LLENINBYTES;
|
||||||
assign IEUAdrIncrementM = IEUAdrM + LLENINBYTES;
|
assign IEUAdrIncrementM = IEUAdrM + LLENINBYTES;
|
||||||
/* verilator lint_on WIDTHEXPAND */
|
/* verilator lint_on WIDTHEXPAND */
|
||||||
mux2 #(P.XLEN) ieuadrspillemux(.d0(IEUAdrE), .d1(IEUAdrIncrementM), .s(SelSpillE), .y(IEUAdrSpillE));
|
mux2 #(P.XLEN) ieuadrspillemux(.d0(IEUAdrE), .d1(IEUAdrIncrementM), .s(SelSpillE), .y(IEUAdrSpillE));
|
||||||
mux2 #(P.XLEN) ieuadrspillmmux(.d0(IEUAdrM), .d1(IEUAdrIncrementM), .s(SelSpillM), .y(IEUAdrSpillM));
|
mux2 #(P.XLEN) ieuadrspillmmux(.d0(IEUAdrM), .d1(IEUAdrIncrementM), .s(SelSpillM), .y(IEUAdrSpillM));
|
||||||
|
//assign IEUAdrxTvalM = {IEUAdrSpillM[P.XLEN-1:OFFSET_LEN], {{OFFSET_LEN}{1'b0}}};
|
||||||
|
mux2 #(P.XLEN) ieuadrxtvalmmux(.d0(IEUAdrM), .d1({IEUAdrIncrementM[P.XLEN-1:OFFSET_LEN], {{OFFSET_LEN}{1'b0}}}), .s(SelSpillM), .y(IEUAdrxTvalM));
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Detect spill
|
// Detect spill
|
||||||
|
@ -94,7 +98,7 @@ module align import cvw::*; #(parameter cvw_t P) (
|
||||||
// 2) offset
|
// 2) offset
|
||||||
// 3) access location within the cacheline
|
// 3) access location within the cacheline
|
||||||
|
|
||||||
// compute misalignement
|
// compute misalignment
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case (Funct3M & {FpLoadStoreM, 2'b11})
|
case (Funct3M & {FpLoadStoreM, 2'b11})
|
||||||
3'b000: AccessByteOffsetM = '0; // byte access
|
3'b000: AccessByteOffsetM = '0; // byte access
|
||||||
|
@ -148,7 +152,7 @@ module align import cvw::*; #(parameter cvw_t P) (
|
||||||
flopenr #(P.LLEN) SpillDataReg(clk, reset, SpillSaveM, DCacheReadDataWordM[P.LLEN-1:0], ReadDataWordFirstHalfM);
|
flopenr #(P.LLEN) SpillDataReg(clk, reset, SpillSaveM, DCacheReadDataWordM[P.LLEN-1:0], ReadDataWordFirstHalfM);
|
||||||
|
|
||||||
// merge together
|
// merge together
|
||||||
mux2 #(2*P.LLEN) postspillmux(DCacheReadDataWordM, {DCacheReadDataWordM[P.LLEN-1:0], ReadDataWordFirstHalfM}, SelSpillM, ReadDataWordSpillAllM);
|
mux2 #(2*P.LLEN) postspillmux(DCacheReadDataWordM, {DCacheReadDataWordM[P.LLEN-1:0], ReadDataWordFirstHalfM}, SelSpillM & ~SelHPTW, ReadDataWordSpillAllM);
|
||||||
|
|
||||||
|
|
||||||
// shifter (4:1 mux for 32 bit, 8:1 mux for 64 bit)
|
// shifter (4:1 mux for 32 bit, 8:1 mux for 64 bit)
|
||||||
|
|
|
@ -36,7 +36,7 @@ module lrsc import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic MemReadM, // Memory read
|
input logic MemReadM, // Memory read
|
||||||
input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write
|
input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write
|
||||||
output logic [1:0] LSURWM, // Memory operation after potential squash of SC
|
output logic [1:0] LSURWM, // Memory operation after potential squash of SC
|
||||||
input logic [1:0] LSUAtomicM, // Atomic memory operaiton
|
input logic [1:0] LSUAtomicM, // Atomic memory operation
|
||||||
input logic [P.PA_BITS-1:0] PAdrM, // Physical memory address
|
input logic [P.PA_BITS-1:0] PAdrM, // Physical memory address
|
||||||
output logic SquashSCW // Squash the store conditional by not allowing rf write
|
output logic SquashSCW // Squash the store conditional by not allowing rf write
|
||||||
);
|
);
|
||||||
|
|
|
@ -57,6 +57,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic BigEndianM, // Swap byte order to big endian
|
input logic BigEndianM, // Swap byte order to big endian
|
||||||
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
||||||
output logic DCacheStallM, // D$ busy with multicycle operation
|
output logic DCacheStallM, // D$ busy with multicycle operation
|
||||||
|
output logic [P.XLEN-1:0] IEUAdrxTvalM, // IEUAdrM, but could be spilled onto the next cacheline or virtual page.
|
||||||
// fpu
|
// fpu
|
||||||
input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU
|
input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU
|
||||||
input logic FpLoadStoreM, // Selects FPU as store for write data
|
input logic FpLoadStoreM, // Selects FPU as store for write data
|
||||||
|
@ -141,7 +142,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
logic DTLBMissM; // DTLB miss causes HPTW walk
|
logic DTLBMissM; // DTLB miss causes HPTW walk
|
||||||
logic DTLBWriteM; // Writes PTE and PageType to DTLB
|
logic DTLBWriteM; // Writes PTE and PageType to DTLB
|
||||||
logic LSULoadAccessFaultM; // Load acces fault
|
logic LSULoadAccessFaultM; // Load access fault
|
||||||
logic LSUStoreAmoAccessFaultM; // Store access fault
|
logic LSUStoreAmoAccessFaultM; // Store access fault
|
||||||
logic HPTWFlushW; // HPTW needs to flush operation
|
logic HPTWFlushW; // HPTW needs to flush operation
|
||||||
logic LSUFlushW; // HPTW or hazard unit flushes operation
|
logic LSUFlushW; // HPTW or hazard unit flushes operation
|
||||||
|
@ -158,12 +159,13 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
flopenrc #(P.XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
|
flopenrc #(P.XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
|
||||||
if(MISALIGN_SUPPORT) begin : ziccslm_align
|
if(MISALIGN_SUPPORT) begin : ziccslm_align
|
||||||
logic [P.XLEN-1:0] IEUAdrSpillE, IEUAdrSpillM;
|
logic [P.XLEN-1:0] IEUAdrSpillE;
|
||||||
|
logic [P.XLEN-1:0] IEUAdrSpillM;
|
||||||
align #(P) align(.clk, .reset, .StallM, .FlushM, .IEUAdrE, .IEUAdrM, .Funct3M, .FpLoadStoreM,
|
align #(P) align(.clk, .reset, .StallM, .FlushM, .IEUAdrE, .IEUAdrM, .Funct3M, .FpLoadStoreM,
|
||||||
.MemRWM,
|
.MemRWM,
|
||||||
.DCacheReadDataWordM, .CacheBusHPWTStall, .SelHPTW,
|
.DCacheReadDataWordM, .CacheBusHPWTStall, .SelHPTW,
|
||||||
.ByteMaskM, .ByteMaskExtendedM, .LSUWriteDataM, .ByteMaskSpillM, .LSUWriteDataSpillM,
|
.ByteMaskM, .ByteMaskExtendedM, .LSUWriteDataM, .ByteMaskSpillM, .LSUWriteDataSpillM,
|
||||||
.IEUAdrSpillE, .IEUAdrSpillM, .SelSpillE, .DCacheReadDataWordSpillM, .SpillStallM);
|
.IEUAdrSpillE, .IEUAdrSpillM, .IEUAdrxTvalM, .SelSpillE, .DCacheReadDataWordSpillM, .SpillStallM);
|
||||||
assign IEUAdrExtM = {2'b00, IEUAdrSpillM};
|
assign IEUAdrExtM = {2'b00, IEUAdrSpillM};
|
||||||
assign IEUAdrExtE = {2'b00, IEUAdrSpillE};
|
assign IEUAdrExtE = {2'b00, IEUAdrSpillE};
|
||||||
end else begin : no_ziccslm_align
|
end else begin : no_ziccslm_align
|
||||||
|
@ -175,6 +177,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||||
assign LSUWriteDataSpillM = LSUWriteDataM;
|
assign LSUWriteDataSpillM = LSUWriteDataM;
|
||||||
assign MemRWSpillM = MemRWM;
|
assign MemRWSpillM = MemRWM;
|
||||||
assign {SpillStallM} = 1'b0;
|
assign {SpillStallM} = 1'b0;
|
||||||
|
assign IEUAdrxTvalM = IEUAdrM;
|
||||||
end
|
end
|
||||||
|
|
||||||
if(P.ZICBOZ_SUPPORTED) begin : cboz
|
if(P.ZICBOZ_SUPPORTED) begin : cboz
|
||||||
|
@ -300,7 +303,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||||
logic [P.PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback.
|
logic [P.PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback.
|
||||||
logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache
|
logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache
|
||||||
logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback
|
logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback
|
||||||
logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount
|
logic SelBusBeat; // ahbcacheinterface selects position in cacheline with BeatCount
|
||||||
logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface
|
logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface
|
||||||
logic [1:0] BusRW; // Uncached bus memory access
|
logic [1:0] BusRW; // Uncached bus memory access
|
||||||
logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush
|
logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush
|
||||||
|
@ -350,7 +353,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||||
mux3 #(P.LLEN) UnCachedDataMux(.d0(DCacheReadDataWordSpillM), .d1({LLENPOVERAHBW{FetchBuffer[P.XLEN-1:0]}}),
|
mux3 #(P.LLEN) UnCachedDataMux(.d0(DCacheReadDataWordSpillM), .d1({LLENPOVERAHBW{FetchBuffer[P.XLEN-1:0]}}),
|
||||||
.d2({{P.LLEN-P.XLEN{1'b0}}, DTIMReadDataWordM[P.XLEN-1:0]}),
|
.d2({{P.LLEN-P.XLEN{1'b0}}, DTIMReadDataWordM[P.XLEN-1:0]}),
|
||||||
.s({SelDTIM, ~(CacheableOrFlushCacheM)}), .y(ReadDataWordMuxM));
|
.s({SelDTIM, ~(CacheableOrFlushCacheM)}), .y(ReadDataWordMuxM));
|
||||||
end else begin : passthrough // No Cache, use simple ahbinterface instad of ahbcacheinterface
|
end else begin : passthrough // No Cache, use simple ahbinterface instead of ahbcacheinterface
|
||||||
logic [1:0] BusRW; // Non-DTIM memory access, ignore cacheableM
|
logic [1:0] BusRW; // Non-DTIM memory access, ignore cacheableM
|
||||||
logic [P.XLEN-1:0] FetchBuffer;
|
logic [P.XLEN-1:0] FetchBuffer;
|
||||||
assign BusRW = ~SelDTIM ? LSURWM : 0;
|
assign BusRW = ~SelDTIM ? LSURWM : 0;
|
||||||
|
|
|
@ -78,7 +78,7 @@ module div import cvw::*; #(parameter cvw_t P) (
|
||||||
assign DinE = ForwardedSrcBE;
|
assign DinE = ForwardedSrcBE;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Extract sign bits and check fo division by zero
|
// Extract sign bits and check for division by zero
|
||||||
assign SignDE = DivSignedE & DinE[P.XLEN-1];
|
assign SignDE = DivSignedE & DinE[P.XLEN-1];
|
||||||
assign SignXE = DivSignedE & XinE[P.XLEN-1];
|
assign SignXE = DivSignedE & XinE[P.XLEN-1];
|
||||||
assign NegQE = SignDE ^ SignXE;
|
assign NegQE = SignDE ^ SignXE;
|
||||||
|
|
|
@ -33,7 +33,7 @@ module mdu import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic FlushE, FlushM, FlushW,
|
input logic FlushE, FlushM, FlushW,
|
||||||
input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output
|
input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output
|
||||||
input logic [2:0] Funct3E, Funct3M, // type of MDU operation
|
input logic [2:0] Funct3E, Funct3M, // type of MDU operation
|
||||||
input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions
|
input logic IntDivE, W64E, // Integer division/remainder, and W-type instructions
|
||||||
input logic MDUActiveE, // Mul/Div instruction being executed
|
input logic MDUActiveE, // Mul/Div instruction being executed
|
||||||
output logic [P.XLEN-1:0] MDUResultW, // multiply/divide result
|
output logic [P.XLEN-1:0] MDUResultW, // multiply/divide result
|
||||||
output logic DivBusyE // busy signal to stall pipeline in Execute stage
|
output logic DivBusyE // busy signal to stall pipeline in Execute stage
|
||||||
|
|
|
@ -200,8 +200,8 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
||||||
assign InvalidOp = DTLBWalk ? (InvalidRead | InvalidWrite) : ~Executable;
|
assign InvalidOp = DTLBWalk ? (InvalidRead | InvalidWrite) : ~Executable;
|
||||||
assign OtherPageFault = ImproperPrivilege | InvalidOp | UpperBitsUnequalD | Misaligned | ~Valid;
|
assign OtherPageFault = ImproperPrivilege | InvalidOp | UpperBitsUnequalD | Misaligned | ~Valid;
|
||||||
|
|
||||||
// hptw needs to know if there is a Dirty or Access fault occuring on this
|
// hptw needs to know if there is a Dirty or Access fault occurring on this
|
||||||
// memory access. If there is the PTE needs to be updated seting Access
|
// memory access. If there is the PTE needs to be updated setting Access
|
||||||
// and possibly also Dirty. Dirty is set if the operation is a store/amo.
|
// and possibly also Dirty. Dirty is set if the operation is a store/amo.
|
||||||
// However any other fault should not cause the update, and updates are in software when ENVCFG_ADUE = 0
|
// However any other fault should not cause the update, and updates are in software when ENVCFG_ADUE = 0
|
||||||
assign HPTWUpdateDA = ValidLeafPTE & (~Accessed | SetDirty) & ENVCFG_ADUE & ~OtherPageFault;
|
assign HPTWUpdateDA = ValidLeafPTE & (~Accessed | SetDirty) & ENVCFG_ADUE & ~OtherPageFault;
|
||||||
|
@ -316,7 +316,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
||||||
// HTPW address/data/control muxing
|
// HTPW address/data/control muxing
|
||||||
|
|
||||||
// Once the walk is done and it is time to update the TLB we need to switch back
|
// Once the walk is done and it is time to update the TLB we need to switch back
|
||||||
// to the orignal data virtual address.
|
// to the original data virtual address.
|
||||||
assign SelHPTWAdr = SelHPTW & ~(DTLBWriteM | ITLBWriteF);
|
assign SelHPTWAdr = SelHPTW & ~(DTLBWriteM | ITLBWriteF);
|
||||||
|
|
||||||
// multiplex the outputs to LSU
|
// multiplex the outputs to LSU
|
||||||
|
|
|
@ -47,7 +47,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
||||||
input logic TLBFlush, // Invalidate all TLB entries
|
input logic TLBFlush, // Invalidate all TLB entries
|
||||||
output logic [P.PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation
|
output logic [P.PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation
|
||||||
output logic TLBMiss, // Miss TLB
|
output logic TLBMiss, // Miss TLB
|
||||||
output logic Cacheable, // PMA indicates memory address is cachable
|
output logic Cacheable, // PMA indicates memory address is cacheable
|
||||||
output logic Idempotent, // PMA indicates memory address is idempotent
|
output logic Idempotent, // PMA indicates memory address is idempotent
|
||||||
output logic SelTIM, // Select a tightly integrated memory
|
output logic SelTIM, // Select a tightly integrated memory
|
||||||
// Faults
|
// Faults
|
||||||
|
@ -105,8 +105,8 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
||||||
assign TLBPAdr = '0;
|
assign TLBPAdr = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
// If translation is occuring, select translated physical address from TLB
|
// If translation is occurring, select translated physical address from TLB
|
||||||
// the lower 12 bits are the page offset. These are never changed from the orginal
|
// the lower 12 bits are the page offset. These are never changed from the original
|
||||||
// non translated address.
|
// non translated address.
|
||||||
mux2 #(P.PA_BITS-12) addressmux(VAdr[P.PA_BITS-1:12], TLBPAdr[P.PA_BITS-1:12], Translate, PhysicalAddress[P.PA_BITS-1:12]);
|
mux2 #(P.PA_BITS-12) addressmux(VAdr[P.PA_BITS-1:12], TLBPAdr[P.PA_BITS-1:12], Translate, PhysicalAddress[P.PA_BITS-1:12]);
|
||||||
assign PhysicalAddress[11:0] = VAdr[11:0];
|
assign PhysicalAddress[11:0] = VAdr[11:0];
|
||||||
|
@ -141,7 +141,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
||||||
2'b10: DataMisalignedM = VAdr[1] | VAdr[0]; // lw, sw, flw, fsw, lwu
|
2'b10: DataMisalignedM = VAdr[1] | VAdr[0]; // lw, sw, flw, fsw, lwu
|
||||||
2'b11: DataMisalignedM = |VAdr[2:0]; // ld, sd, fld, fsd
|
2'b11: DataMisalignedM = |VAdr[2:0]; // ld, sd, fld, fsd
|
||||||
endcase
|
endcase
|
||||||
// When ZiCCLSM_SUPPORTED, misalgined cachable loads and stores are handled in hardware so they do not throw a misaligned fault
|
// When ZiCCLSM_SUPPORTED, misalgined cacheable loads and stores are handled in hardware so they do not throw a misaligned fault
|
||||||
assign LoadMisalignedFaultM = DataMisalignedM & ReadNoAmoAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable) & ~TLBMiss;
|
assign LoadMisalignedFaultM = DataMisalignedM & ReadNoAmoAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable) & ~TLBMiss;
|
||||||
assign StoreAmoMisalignedFaultM = DataMisalignedM & WriteAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable) & ~TLBMiss; // Store and AMO both assert WriteAccess
|
assign StoreAmoMisalignedFaultM = DataMisalignedM & WriteAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable) & ~TLBMiss; // Store and AMO both assert WriteAccess
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,8 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
||||||
// Determine which region of physical memory (if any) is being accessed
|
// Determine which region of physical memory (if any) is being accessed
|
||||||
adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWXC, Size, SelRegions);
|
adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWXC, Size, SelRegions);
|
||||||
|
|
||||||
// Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable
|
// Only non-core RAM/ROM memory regions are cacheable. PBMT can override cacheable; NC and IO are uncachable
|
||||||
assign CacheableRegion = SelRegions[3] | SelRegions[4] | SelRegions[5]; // exclusion-tag: unused-cachable
|
assign CacheableRegion = SelRegions[3] | SelRegions[4] | SelRegions[5]; // exclusion-tag: unused-cacheable
|
||||||
assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 1'b0;
|
assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 1'b0;
|
||||||
|
|
||||||
// Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly
|
// Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly
|
||||||
|
|
|
@ -75,11 +75,19 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
assign PMPAdrNAPOTGrain = {PMPAdr[P.PA_BITS-3:Gm1], {Gm1{1'b1}}}; // in NAPOT, if G >= 2, bottom G-1 bits read as all 1s
|
assign PMPAdrNAPOTGrain = {PMPAdr[P.PA_BITS-3:Gm1], {Gm1{1'b1}}}; // in NAPOT, if G >= 2, bottom G-1 bits read as all 1s
|
||||||
assign NAMask[1:0] = {2'b11};
|
assign NAMask[1:0] = {2'b11};
|
||||||
|
|
||||||
|
// assign NAMask[P.PA_BITS-1:2] = (PMPAdr + {{(P.PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdr;
|
||||||
assign NAMask[P.PA_BITS-1:2] = (PMPAdrNAPOTGrain + {{(P.PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdrNAPOTGrain;
|
assign NAMask[P.PA_BITS-1:2] = (PMPAdrNAPOTGrain + {{(P.PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdrNAPOTGrain;
|
||||||
// form a mask where the bottom k bits are 1, corresponding to a size of 2^k bytes for this memory region.
|
// form a mask where the bottom k bits are 1, corresponding to a size of 2^k bytes for this memory region.
|
||||||
// This assumes we're using at least an NA4 region, but works for any size NAPOT region.
|
// This assumes we're using at least an NA4 region, but works for any size NAPOT region.
|
||||||
|
|
||||||
|
|
||||||
|
/* in progress, fix soon dh 5/8/25
|
||||||
assign NABase = {(PMPAdrNAPOTGrain & ~NAMask[P.PA_BITS-1:2]), 2'b00}; // base physical address of the pmp region
|
assign NABase = {(PMPAdrNAPOTGrain & ~NAMask[P.PA_BITS-1:2]), 2'b00}; // base physical address of the pmp region
|
||||||
assign NAMatch = &((NABase ~^ PhysicalAddress) | NAMask); // check if upper bits of base address match, ignore lower bits correspoonding to inside the memory range
|
assign NAMatch = &((NABase ~^ PhysicalAddress) | NAMask); // check if upper bits of base address match, ignore lower bits correspoonding to inside the memory range
|
||||||
|
*/
|
||||||
|
assign NABase = {(PMPAdr & ~NAMask[P.PA_BITS-1:2]), 2'b00}; // base physical address of the pmp region
|
||||||
|
assign NAMatch = &((NABase ~^ PhysicalAddress) | NAMask); // check if upper bits of base address match, ignore lower bits corresponding to inside the memory range
|
||||||
|
|
||||||
// finally pick the appropriate match for the access type
|
// finally pick the appropriate match for the access type
|
||||||
assign Match = (AdrMode == TOR) ? TORMatch :
|
assign Match = (AdrMode == TOR) ? TORMatch :
|
||||||
|
|
|
@ -75,7 +75,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
|
||||||
.Match, .PMPTop, .L, .X, .W, .R);
|
.Match, .PMPTop, .L, .X, .W, .R);
|
||||||
end
|
end
|
||||||
|
|
||||||
priorityonehot #(P.PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
|
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
|
// 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
|
// If the access does not match all bytes of the PMP region, it is too big and the matches are disabled
|
||||||
|
|
|
@ -71,7 +71,7 @@ module tlbcamline import cvw::*; #(parameter cvw_t P,
|
||||||
// Calculate the actual match value based on the input vpn and the page type.
|
// Calculate the actual match value based on the input vpn and the page type.
|
||||||
// For example, a megapage in SV32 only cares about VPN[1], so VPN[0]
|
// For example, a megapage in SV32 only cares about VPN[1], so VPN[0]
|
||||||
// should automatically match.
|
// should automatically match.
|
||||||
assign Match0 = (Query0 == Key0) | (PageType[0]); // least signifcant section
|
assign Match0 = (Query0 == Key0) | (PageType[0]); // least significant section
|
||||||
assign Match1 = (Query1 == Key1);
|
assign Match1 = (Query1 == Key1);
|
||||||
|
|
||||||
assign Match = Match0 & Match1 & MatchASID & Valid;
|
assign Match = Match0 & Match1 & MatchASID & Valid;
|
||||||
|
|
|
@ -115,7 +115,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
|
||||||
assign PreUpdateDA = ~PTE_A | WriteAccess & ~PTE_D;
|
assign PreUpdateDA = ~PTE_A | WriteAccess & ~PTE_D;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Determine wheter to update DA bits. With SVADU, it is done in hardware
|
// Determine whether to update DA bits. With SVADU, it is done in hardware
|
||||||
assign UpdateDA = P.SVADU_SUPPORTED & PreUpdateDA & Translate & TLBHit & ~TLBPageFault & ENVCFG_ADUE;
|
assign UpdateDA = P.SVADU_SUPPORTED & PreUpdateDA & Translate & TLBHit & ~TLBPageFault & ENVCFG_ADUE;
|
||||||
|
|
||||||
// Determine whether page fault occurs
|
// Determine whether page fault occurs
|
||||||
|
|
|
@ -63,7 +63,7 @@ module tlbmixer import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
// In Svnapot, when N=1, use bottom bits of VPN for contiugous translations
|
// In Svnapot, when N=1, use bottom bits of VPN for contiugous translations
|
||||||
if (P.SVNAPOT_SUPPORTED) begin
|
if (P.SVNAPOT_SUPPORTED) begin
|
||||||
// 64 KiB contiguous NAPOT translations suported
|
// 64 KiB contiguous NAPOT translations supported
|
||||||
logic [3:0] PPNMixedBot;
|
logic [3:0] PPNMixedBot;
|
||||||
mux2 #(4) napotmux(PPNMixed[3:0], VPN[3:0], PTE_N, PPNMixedBot);
|
mux2 #(4) napotmux(PPNMixed[3:0], VPN[3:0], PTE_N, PPNMixedBot);
|
||||||
assign PPNMixed2 = {PPNMixed[P.PPN_BITS-1:4], PPNMixedBot};
|
assign PPNMixed2 = {PPNMixed[P.PPN_BITS-1:4], PPNMixedBot};
|
||||||
|
|
|
@ -36,7 +36,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic [31:0] InstrM, // current instruction
|
input logic [31:0] InstrM, // current instruction
|
||||||
input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
|
input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
|
||||||
input logic [P.XLEN-1:0] PCM, // program counter, next PC going to trap/return logic
|
input logic [P.XLEN-1:0] PCM, // program counter, next PC going to trap/return logic
|
||||||
input logic [P.XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU
|
input logic [P.XLEN-1:0] SrcAM, IEUAdrxTvalM, // SrcA and memory address from IEU
|
||||||
input logic CSRReadM, CSRWriteM, // read or write CSR
|
input logic CSRReadM, CSRWriteM, // read or write CSR
|
||||||
input logic TrapM, // trap is occurring
|
input logic TrapM, // trap is occurring
|
||||||
input logic mretM, sretM, // return instruction
|
input logic mretM, sretM, // return instruction
|
||||||
|
@ -142,7 +142,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
||||||
else case (CauseM)
|
else case (CauseM)
|
||||||
12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint
|
12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint
|
||||||
2: NextFaultMtvalM = {{(P.XLEN-32){1'b0}}, InstrOrigM}; // Illegal instruction fault
|
2: NextFaultMtvalM = {{(P.XLEN-32){1'b0}}, InstrOrigM}; // Illegal instruction fault
|
||||||
0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrM; // Instruction misaligned, Load/Store Misaligned/page/access faults
|
0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrxTvalM; // Instruction misaligned, Load/Store Misaligned/page/access faults
|
||||||
default: NextFaultMtvalM = '0; // Ecall, interrupts
|
default: NextFaultMtvalM = '0; // Ecall, interrupts
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
|
|
@ -90,14 +90,14 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
||||||
end
|
end
|
||||||
|
|
||||||
// hardwired STATUS bits
|
// hardwired STATUS bits
|
||||||
assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported
|
assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override register with 0 if supervisor mode not supported
|
||||||
assign STATUS_TW = P.U_SUPPORTED & STATUS_TW_INT; // override register with 0 if only machine mode supported
|
assign STATUS_TW = P.U_SUPPORTED & STATUS_TW_INT; // override register with 0 if only machine mode supported
|
||||||
assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported
|
assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override register with 0 if supervisor mode not supported
|
||||||
assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported
|
assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override register with 0 if supervisor mode not supported
|
||||||
// SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not
|
// SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not
|
||||||
assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported
|
assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported
|
||||||
assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
|
assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
|
||||||
assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported
|
assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override register with 0 if supervisor mode not supported
|
||||||
assign STATUS_MPRV = P.U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported
|
assign STATUS_MPRV = P.U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported
|
||||||
assign STATUS_FS = P.F_SUPPORTED ? STATUS_FS_INT : 2'b00; // off if no FP
|
assign STATUS_FS = P.F_SUPPORTED ? STATUS_FS_INT : 2'b00; // off if no FP
|
||||||
assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic
|
assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic
|
||||||
|
|
|
@ -83,7 +83,7 @@ module privdec import cvw::*; #(parameter cvw_t P) (
|
||||||
assign WFICountPlus1 = wfiM ? WFICount + 1 : '0; // restart counting on WFI
|
assign WFICountPlus1 = wfiM ? WFICount + 1 : '0; // restart counting on WFI
|
||||||
flopr #(P.WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, WFICountPlus1, WFICount); // count while in WFI
|
flopr #(P.WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, WFICountPlus1, WFICount); // count while in WFI
|
||||||
// coverage off -item e 1 -fecexprrow 1
|
// coverage off -item e 1 -fecexprrow 1
|
||||||
// WFI Timout trap will not occur when STATUS_TW is low while in supervisor mode, so the system gets stuck waiting for an interrupt and triggers a watchdog timeout.
|
// WFI Timeout trap will not occur when STATUS_TW is low while in supervisor mode, so the system gets stuck waiting for an interrupt and triggers a watchdog timeout.
|
||||||
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != P.M_MODE) | (P.S_SUPPORTED & PrivilegeModeW == P.U_MODE)) & WFICount[P.WFI_TIMEOUT_BIT];
|
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != P.M_MODE) | (P.S_SUPPORTED & PrivilegeModeW == P.U_MODE)) & WFICount[P.WFI_TIMEOUT_BIT];
|
||||||
// coverage on
|
// coverage on
|
||||||
end else assign WFITimeoutM = 1'b0;
|
end else assign WFITimeoutM = 1'b0;
|
||||||
|
|
|
@ -37,7 +37,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic [P.XLEN-1:0] SrcAM, // GPR register to write
|
input logic [P.XLEN-1:0] SrcAM, // GPR register to write
|
||||||
input logic [31:0] InstrM, // Instruction
|
input logic [31:0] InstrM, // Instruction
|
||||||
input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
|
input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
|
||||||
input logic [P.XLEN-1:0] IEUAdrM, // address from IEU
|
input logic [P.XLEN-1:0] IEUAdrxTvalM, // address from IEU
|
||||||
input logic [P.XLEN-1:0] PCM, // program counter
|
input logic [P.XLEN-1:0] PCM, // program counter
|
||||||
// control signals
|
// control signals
|
||||||
input logic InstrValidM, // Current instruction is valid (not flushed)
|
input logic InstrValidM, // Current instruction is valid (not flushed)
|
||||||
|
@ -51,7 +51,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic DCacheStallM, // D cache stalled
|
input logic DCacheStallM, // D cache stalled
|
||||||
input logic BPDirWrongM, // branch predictor guessed wrong direction
|
input logic BPDirWrongM, // branch predictor guessed wrong direction
|
||||||
input logic BTAWrongM, // branch predictor guessed wrong target
|
input logic BTAWrongM, // branch predictor guessed wrong target
|
||||||
input logic RASPredPCWrongM, // return adddress stack guessed wrong target
|
input logic RASPredPCWrongM, // return address stack guessed wrong target
|
||||||
input logic IClassWrongM, // branch predictor guessed wrong instruction class
|
input logic IClassWrongM, // branch predictor guessed wrong instruction class
|
||||||
input logic BPWrongM, // branch predictor is wrong
|
input logic BPWrongM, // branch predictor is wrong
|
||||||
input logic [3:0] IClassM, // actual instruction class
|
input logic [3:0] IClassM, // actual instruction class
|
||||||
|
@ -113,7 +113,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
||||||
logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits
|
logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits
|
||||||
logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return
|
logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return
|
||||||
logic DelegateM; // trap should be delegated
|
logic DelegateM; // trap should be delegated
|
||||||
logic InterruptM; // interrupt occuring
|
logic InterruptM; // interrupt occurring
|
||||||
logic ExceptionM; // Memory stage instruction caused a fault
|
logic ExceptionM; // Memory stage instruction caused a fault
|
||||||
logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE
|
logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE
|
||||||
logic HPTWInstrPageFaultM; // Hardware page table page fault while fetching instruction PTE
|
logic HPTWInstrPageFaultM; // Hardware page table page fault while fetching instruction PTE
|
||||||
|
@ -133,7 +133,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
// Control and Status Registers
|
// Control and Status Registers
|
||||||
csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
|
csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
|
||||||
.InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM,
|
.InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrxTvalM,
|
||||||
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM,
|
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM,
|
||||||
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
|
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
|
||||||
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD,
|
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD,
|
||||||
|
|
|
@ -48,7 +48,7 @@ module trap import cvw::*; #(parameter cvw_t P) (
|
||||||
output logic [3:0] CauseM // trap cause
|
output logic [3:0] CauseM // trap cause
|
||||||
);
|
);
|
||||||
|
|
||||||
logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables
|
logic MIntGlobalEnM, SIntGlobalEnM; // Global interrupt enables
|
||||||
logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted
|
logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted
|
||||||
logic BothInstrAccessFaultM, BothInstrPageFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
|
logic BothInstrAccessFaultM, BothInstrPageFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
|
||||||
logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
|
logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue