mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-06-27 08:50:26 -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}})
|
||||
strategy:
|
||||
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
|
||||
|
||||
steps:
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -82,6 +82,7 @@ synthDC/Summary.csv
|
|||
|
||||
# Benchmarks
|
||||
benchmarks/embench/wally*.json
|
||||
benchmarks/embench/actual_embench_results/wally*.json
|
||||
benchmarks/embench/run*
|
||||
benchmarks/coremark/coremark_results.csv
|
||||
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -33,3 +33,6 @@
|
|||
path = addins/berkeley-testfloat-3
|
||||
url = https://github.com/ucb-bar/berkeley-testfloat-3
|
||||
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 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.
|
||||
arch_list = [
|
||||
"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+)"
|
||||
#cmhz_regex = r"COREMARK/MHz Score: [\d,]+ / [\d,]+ = (\d+\.\d+)"
|
||||
# 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:
|
||||
fieldnames = ['Architecture', 'CM / MHz','CPI','MTIME','MINSTRET','Load Stalls','Store Stalls','D$ Accesses',
|
||||
'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,
|
||||
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,
|
||||
and the resolution is controlled by <TIMER_RES_DIVIDER>
|
||||
*/
|
||||
|
@ -213,7 +213,7 @@ CORE_TICKS get_time(void) {
|
|||
/* Function: time_in_secs
|
||||
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.
|
||||
*/
|
||||
secs_ret time_in_secs(CORE_TICKS ticks) {
|
||||
|
|
|
@ -99,7 +99,7 @@ typedef clock_t CORE_TICKS;
|
|||
#endif
|
||||
|
||||
/* 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*:
|
||||
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
|
||||
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" )
|
||||
ENTRY(_start)
|
||||
|
@ -60,7 +60,7 @@ SECTIONS
|
|||
*(.tbss.end)
|
||||
}
|
||||
|
||||
/* End of uninitalized data segement */
|
||||
/* End of uninitialized data segment */
|
||||
_end = .;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,15 +63,19 @@ spike: buildspeed spike_run speed
|
|||
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
|
||||
|
||||
# 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
|
||||
size: buildsize
|
||||
$(embench_dir)/benchmark_size.py --builddir=bd_speedopt_size --json-output > wallySpeedOpt_size.json
|
||||
$(embench_dir)/benchmark_size.py --builddir=bd_sizeopt_size --json-output > wallySizeOpt_size.json
|
||||
size: actual_embench_results buildsize
|
||||
$(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 > actual_embench_results/wallySizeOpt_size.json
|
||||
|
||||
# python wrapper to present results of embench speed benchmark
|
||||
speed:
|
||||
$(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_speedopt_speed --target-module run_wally --cpu-mhz=1 --json-output > wallySpeedOpt_speed.json
|
||||
speed: actual_embench_results
|
||||
$(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 > actual_embench_results/wallySpeedOpt_speed.json
|
||||
|
||||
# deletes all files
|
||||
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 = {}
|
||||
embenchSpeedOpt_SizeData = {}
|
||||
coremarkData = loadCoremark(coremarkData)
|
||||
embenchSpeedOpt_SpeedData = loadEmbench("embench/wallySpeedOpt_speed.json", embenchSpeedOpt_SpeedData)
|
||||
embenchSizeOpt_SpeedData = loadEmbench("embench/wallySizeOpt_speed.json", embenchSizeOpt_SpeedData)
|
||||
embenchSpeedOpt_SizeData = loadEmbench("embench/wallySpeedOpt_size.json", embenchSpeedOpt_SizeData)
|
||||
embenchSizeOpt_SizeData = loadEmbench("embench/wallySizeOpt_size.json", embenchSizeOpt_SizeData)
|
||||
embenchSpeedOpt_SpeedData = loadEmbench("embench/actual_embench_results/wallySpeedOpt_speed.json", embenchSpeedOpt_SpeedData)
|
||||
embenchSizeOpt_SpeedData = loadEmbench("embench/actual_embench_results/wallySizeOpt_speed.json", embenchSizeOpt_SpeedData)
|
||||
embenchSpeedOpt_SizeData = loadEmbench("embench/actual_embench_results/wallySpeedOpt_size.json", embenchSpeedOpt_SizeData)
|
||||
embenchSizeOpt_SizeData = loadEmbench("embench/actual_embench_results/wallySizeOpt_size.json", 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+(.*)/) {
|
||||
$address = &fixadr($1);
|
||||
# print "addresss $address maxaddress $maxaddress\n";
|
||||
# print "address $address maxaddress $maxaddress\n";
|
||||
if ($address > $maxaddress) { $maxaddress = $address; }
|
||||
#print "test $address $1 $2\n";
|
||||
my $lineorig = $2;
|
||||
|
@ -157,7 +157,7 @@ for(my $i=0; $i<=$#ARGV; $i++) {
|
|||
print("\n");
|
||||
|
||||
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
|
||||
my $address = shift;
|
||||
my $payload = shift;
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
## Created: March 1, 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.
|
||||
## 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
|
||||
##
|
||||
|
|
|
@ -35,7 +35,7 @@ def search_log_for_mismatches(logfile):
|
|||
return os.system(grepcmd) == 0
|
||||
|
||||
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")
|
||||
fields = elf.rsplit("/", 3)
|
||||
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("--coverage", "-c", 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()
|
||||
|
||||
# find all ELF files in directory
|
||||
|
|
|
@ -167,7 +167,7 @@ class FolderManager:
|
|||
None
|
||||
"""
|
||||
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():
|
||||
os.system(f"git clone --recurse-submodules {repo_url} {cvw}")
|
||||
os.makedirs(tmp_folder)
|
||||
|
@ -196,7 +196,7 @@ class TestRunner:
|
|||
folder: the "nightly-runs/repos/"
|
||||
|
||||
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
|
||||
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")
|
||||
except Exception as 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:
|
||||
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
|
||||
else:
|
||||
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
|
||||
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_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)
|
||||
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)
|
||||
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
|
||||
try:
|
||||
passed, failed = test_runner.clean_format_output(input_file = output_location)
|
||||
logger.info(f"{test_name} has been formatted to markdown")
|
||||
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)}")
|
||||
total_number_failures+= len(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_success.append(passed)
|
||||
test_runner.rewrite_to_markdown(test_name, passed, failed)
|
||||
|
@ -797,7 +797,7 @@ def main():
|
|||
except Exception as 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}")
|
||||
|
||||
# Copy actual test logs from sim/questa, sim/verilator, sim/vcs
|
||||
|
@ -830,14 +830,14 @@ def main():
|
|||
#############################################
|
||||
# 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):
|
||||
try:
|
||||
cvw_dir = os.path.join(args.path,log_dir,"cvw")
|
||||
cvw_mtime = os.stat(cvw_dir).st_mtime
|
||||
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)
|
||||
except Exception as e:
|
||||
if os.path.exists(cvw_dir):
|
||||
|
|
|
@ -45,7 +45,7 @@ RefDataBTB = [('BTBCModel6', 'BTBCModel', 64, 128, 1.51480272475844), ('BTBCMode
|
|||
|
||||
def ParseBranchListFile(path):
|
||||
'''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.'''
|
||||
lst = []
|
||||
with open(path) as BranchList:
|
||||
|
@ -59,7 +59,7 @@ def ParseBranchListFile(path):
|
|||
return lst
|
||||
|
||||
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.'''
|
||||
# 1 find lines with Read memfile and extract test name
|
||||
# 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']
|
||||
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
|
||||
# group the parameterizations by the common typ.
|
||||
sequencies = {}
|
||||
sequences = {}
|
||||
for (name, typ, entries, size, value) in benchmarkDict['Mean']:
|
||||
if typ not in sequencies:
|
||||
sequencies[typ] = [(entries if not args.size else int(size/8), value)]
|
||||
if typ not in sequences:
|
||||
sequences[typ] = [(entries if not args.size else int(size/8), value)]
|
||||
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
|
||||
# finally repeat for all typs of branch predictors and overlay
|
||||
fig, axes = plt.subplots()
|
||||
index = 0
|
||||
if(args.invert): plt.title(titlesInvert[ReportPredictorType])
|
||||
else: plt.title(titles[ReportPredictorType])
|
||||
for branchPredName in sequencies:
|
||||
data = sequencies[branchPredName]
|
||||
for branchPredName in sequences:
|
||||
data = sequences[branchPredName]
|
||||
(xdata, ydata) = zip(*data)
|
||||
if args.invert: ydata = [100 - x for x in ydata]
|
||||
axes.plot(xdata, ydata, color=colors[index])
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
# David_Harris@Hmc.edu 25 January 2021
|
||||
# Modified by Jarred Allen <jaallen@g.hmc.edu> and many others
|
||||
# jcarlin@hmc.edu December 2024
|
||||
# sanarayanan@hmc.edu April 2025
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
#
|
||||
# Run a regression with multiple configurations in parallel and exit with
|
||||
|
@ -278,7 +279,7 @@ lockstepwaivers = [
|
|||
# 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
|
||||
# output and picking logfile names)
|
||||
# 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
|
||||
# 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
|
||||
|
||||
# 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:
|
||||
HEADER = '\033[95m'
|
||||
OKBLUE = '\033[94m'
|
||||
|
@ -368,12 +370,31 @@ def search_log_for_text(text, grepfile):
|
|||
def run_test_case(config, dryrun: bool = False):
|
||||
grepfile = config.grepfile
|
||||
cmd = config.cmd
|
||||
altcommand = config.altcommand
|
||||
if dryrun:
|
||||
print(f"Executing {cmd}", flush=True)
|
||||
return 0
|
||||
else:
|
||||
os.system(cmd)
|
||||
if search_log_for_text(config.grepstr, grepfile):
|
||||
ret_code = os.system(cmd)
|
||||
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
|
||||
print(f"{bcolors.OKGREEN}{cmd}: Success{bcolors.ENDC}", flush=True)
|
||||
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("--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("--performance", help="Check for performance changes or discrepancies in embench and coremark", action="store_true")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
|
@ -421,8 +443,8 @@ def process_args(args):
|
|||
TIMEOUT_DUR = 30*60 # seconds
|
||||
elif args.branch:
|
||||
TIMEOUT_DUR = 120*60 # seconds
|
||||
elif args.nightly:
|
||||
TIMEOUT_DUR = 30*60 # seconds
|
||||
elif args.nightly or args.performance:
|
||||
TIMEOUT_DUR = 60*60 # seconds
|
||||
else:
|
||||
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/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
|
||||
# run riscv-arch-test tests in functional coverage mode
|
||||
# run cvw-riscv-arch-test tests in functional coverage mode
|
||||
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/riscv-arch-test/rv64i_m", "rv64gc", 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/cvw-riscv-arch-test/rv64i", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
|
||||
# run branch predictor tests
|
||||
if args.branch:
|
||||
addTests(bpredtests, defaultsim, coverStr, configs)
|
||||
|
@ -503,6 +525,55 @@ def selectTests(args, sims, coverStr):
|
|||
grepstr="All Tests completed with 0 errors",
|
||||
grepfile = sim_log)
|
||||
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
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
## Created: 30 June 2024
|
||||
## 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.
|
||||
## https://github.com/openhwgroup/cvw
|
||||
|
|
|
@ -62,7 +62,7 @@ case "$FAMILY" in
|
|||
SPIKE_PACKAGES+=(dtc boost-regex boost-system)
|
||||
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
|
||||
# Extra packages not availale in rhel8, nice for Verilator
|
||||
# Extra packages not available in rhel8, nice for Verilator
|
||||
if (( RHEL_VERSION >= 9 )); then
|
||||
VERILATOR_PACKAGES+=(perl-doc)
|
||||
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
|
||||
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
|
||||
# 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
|
||||
STATUS="glib"
|
||||
if [ ! -e "$RISCV"/include/glib-2.0 ]; then
|
||||
|
@ -480,7 +480,7 @@ fi
|
|||
|
||||
|
||||
# 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.
|
||||
if [ ! "$no_buidroot" ]; then
|
||||
section_header "Installing Buildroot and Creating Linux testvectors"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
QUESTA_HOME?=/cad/mentor/questa_sim-2023.4
|
||||
CVW_GIT?=""
|
||||
|
||||
commanline:
|
||||
commandline:
|
||||
podman run -it --rm \
|
||||
-v cvw_temp:/home/cad/cvw \
|
||||
-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.
|
||||
|
||||
|
@ -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:
|
||||
|
||||
```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
|
||||
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:
|
||||
|
||||
- debian-based package installtion
|
||||
- debian-based package installation
|
||||
- apt package
|
||||
- python3 package
|
||||
- user and its group configuration
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/* The OUTPUT_ARCH command specifies the machine architecture where the
|
||||
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" )
|
||||
ENTRY(_start)
|
||||
|
@ -60,7 +60,7 @@ SECTIONS
|
|||
_tbss_end = .;
|
||||
}
|
||||
|
||||
/* End of uninitalized data segement */
|
||||
/* End of uninitialized data segment */
|
||||
_end = .;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ int main(void) {
|
|||
int tmp = Y[i];
|
||||
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++) {
|
||||
if (fabs(Y[i] - Yexpected[i]) > 1e-10) {
|
||||
return 1;
|
||||
|
|
|
@ -273,7 +273,7 @@ void mixColumn(unsigned char *column) {
|
|||
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
|
||||
void aes_cipher(unsigned char *state, unsigned char *roundKey) {
|
||||
subBytes(state);
|
||||
|
|
|
@ -230,11 +230,11 @@ set verilogout_no_tri true
|
|||
set verilogout_equation false
|
||||
|
||||
# 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_ddc 1 ;# compiler file in ddc format
|
||||
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_cst 1 ;# generate report of constraints
|
||||
set write_hier 1 ;# generate hierarchy report
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
create_debug_core u_ila_0 ila
|
||||
|
||||
|
||||
|
||||
|
||||
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_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_CNT 4 [get_debug_cores u_ila_0 ]
|
||||
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 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]} ]]
|
||||
|
@ -366,7 +370,7 @@ connect_debug_port u_ila_0/probe69 [get_nets [list {wallypipelinedsoc/core/priv.
|
|||
create_debug_port u_ila_0 probe
|
||||
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]
|
||||
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
|
||||
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 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]}]]
|
||||
|
||||
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)
|
||||
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) {
|
||||
perror("setsockopt");
|
||||
close(sockfd);
|
||||
|
|
|
@ -223,7 +223,7 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 0)
|
|||
// the ddr3 mig7 requires 2 input clocks
|
||||
// 1. sys clock which is 167 MHz = ddr3 clock / 4
|
||||
// 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.
|
||||
mmcm mmcm(.clk_out1(clk167),
|
||||
.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_PACKET_DELAY = 32'd400;
|
||||
|
||||
// pipeline controlls
|
||||
// pipeline controls
|
||||
logic StallE, StallM, StallW, FlushE, FlushM, FlushW;
|
||||
// required
|
||||
logic [P.XLEN-1:0] PCM;
|
||||
|
|
|
@ -51,7 +51,7 @@ int gpt_load_partitions() {
|
|||
BYTE lba2_buf[512];
|
||||
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 *opensbi = (partition_entries_t *)(lba2_buf + 128);
|
||||
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
|
||||
// response length. Probably unecessary so let's wait and see what
|
||||
// response length. Probably unnecessary so let's wait and see what
|
||||
// happens.
|
||||
// write_reg(SPI_RXMARK, response_len);
|
||||
|
||||
|
|
|
@ -38,5 +38,5 @@ qemu-system-riscv64 \
|
|||
-kernel "$IMAGES"/Image \
|
||||
-initrd "$IMAGES"/rootfs.cpio \
|
||||
-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
|
||||
|
|
23
setup.sh
23
setup.sh
|
@ -2,6 +2,7 @@
|
|||
|
||||
# setup.sh
|
||||
# David_Harris@hmc.edu and kekim@hmc.edu 1 December 2021
|
||||
# jcarlin@hmc.edu 2025
|
||||
# Set up tools for cvw
|
||||
|
||||
# optionally have .bashrc or .bash_profile source this file with
|
||||
|
@ -11,6 +12,11 @@
|
|||
|
||||
# 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"
|
||||
|
||||
# Path to RISC-V Tools
|
||||
|
@ -21,14 +27,15 @@ elif [ -d ~/riscv ]; then
|
|||
else
|
||||
# set the $RISCV directory here and remove the subsequent two lines
|
||||
# export RISCV=
|
||||
echo "\$RISCV directory not found. Checked /opt/riscv and ~/riscv. Edit setup.sh to point to your custom \$RISCV directory."
|
||||
exit 1
|
||||
echo -e "${FAIL_COLOR}\$RISCV directory not found. Checked /opt/riscv and ~/riscv. Edit setup.sh to point to your custom \$RISCV directory.${ENDC}"
|
||||
return 1
|
||||
fi
|
||||
echo \$RISCV set to "${RISCV}"
|
||||
|
||||
# Path to Wally repository
|
||||
WALLY=$(dirname "${BASH_SOURCE[0]:-$0}")
|
||||
export WALLY=$(cd "$WALLY" && pwd)
|
||||
WALLY=$(cd "$WALLY" && pwd)
|
||||
export WALLY
|
||||
echo \$WALLY set to "${WALLY}"
|
||||
# utility functions in Wally repository
|
||||
export PATH=$WALLY/bin:$PATH
|
||||
|
@ -37,7 +44,7 @@ export PATH=$WALLY/bin:$PATH
|
|||
if [ -e "${WALLY}"/addins/cvw-arch-verif/setup.sh ]; then
|
||||
source "${WALLY}"/addins/cvw-arch-verif/setup.sh
|
||||
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
|
||||
|
||||
# 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
|
||||
source "${RISCV}"/site-setup.sh
|
||||
else
|
||||
echo "site-setup.sh not found in \$RISCV directory. Rerun wally-toolchain-install.sh to automatically download it."
|
||||
exit 1
|
||||
echo -e "${ERROR_COLOR}site-setup.sh not found in \$RISCV directory. Rerun wally-toolchain-install.sh to automatically download it.${ENDC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -e "${WALLY}/.git/hooks/pre-commit" ]; then
|
||||
pushd "${WALLY}" || exit 1
|
||||
pushd "${WALLY}" || return 1
|
||||
echo "Installing pre-commit hooks"
|
||||
pre-commit install
|
||||
popd || exit
|
||||
popd || return
|
||||
fi
|
||||
|
||||
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"]
|
||||
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
|
||||
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/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
|
||||
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
|
||||
####################
|
||||
|
||||
# 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
|
||||
|
||||
# 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 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
|
||||
# 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
|
||||
|
|
|
@ -22,7 +22,7 @@ TESTBENCH?=testbench
|
|||
|
||||
# constants
|
||||
# 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)"
|
||||
# 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
|
||||
|
|
|
@ -2,20 +2,27 @@
|
|||
|
||||
# site-setup.sh
|
||||
# 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
|
||||
# $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.
|
||||
# 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
|
||||
# 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 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 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 VCS_HOME=/cad/synopsys/vcs/U-2023.03-SP2-4 # 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 VCS_HOME=/cad/synopsys/VCS # Change this for your path to Synopsys VCS, excluding bin
|
||||
export BREKER_HOME=/cad/breker/TREK # Change this for your path to Breker Trek
|
||||
|
||||
# Tools
|
||||
# Questa and Synopsys
|
||||
|
@ -31,10 +38,6 @@ export SYN_MW=/home/jstine/MW
|
|||
export SYN_memory=/home/jstine/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
|
||||
if [ -z "$LD_LIBRARY_PATH" ]; then
|
||||
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
|
||||
source "$RISCV"/riscv-python/bin/activate
|
||||
else
|
||||
echo "Python virtual environment not found. Rerun wally-toolchain-install.sh to automatically create it."
|
||||
exit 1
|
||||
echo -e "${FAIL_COLOR}Python virtual environment not found. Rerun wally-toolchain-install.sh to automatically create it.${ENDC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Environment variables needed for RISCV-DV
|
||||
export RISCV_GCC=$(which riscv64-unknown-elf-gcc) # Copy this as it is
|
||||
export RISCV_OBJCOPY=$(which riscv64-unknown-elf-objcopy) # Copy this as it is
|
||||
export SPIKE_PATH=$RISCV/bin # Copy this as it is
|
||||
|
||||
# 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
|
||||
export RISCV_GCC=$(which riscv64-unknown-elf-gcc)
|
||||
export RISCV_OBJCOPY=$(which riscv64-unknown-elf-objcopy)
|
||||
export SPIKE_PATH=$RISCV/bin
|
||||
|
||||
# Imperas DV setup
|
||||
export IDV=$RISCV/ImperasDV-OpenHW
|
||||
if [ -e "$IDV" ]; then
|
||||
# echo "Imperas exists"
|
||||
export IMPERAS_HOME=$IDV
|
||||
export IMPERAS_HOME=$RISCV/ImperasDV-OpenHW
|
||||
if [ -e "$IMPERAS_HOME" ]; then
|
||||
export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC
|
||||
export ROOTDIR=~/
|
||||
source "${IMPERAS_HOME}"/bin/setup.sh
|
||||
setupImperas "${IMPERAS_HOME}"
|
||||
export PATH=$IDV/scripts/cvw:$PATH
|
||||
source "${IMPERAS_HOME}"/bin/setup.sh &> /dev/null || {
|
||||
echo -e "${FAIL_COLOR}ImperasDV setup failed${ENDC}"
|
||||
return 1
|
||||
}
|
||||
setupImperas "${IMPERAS_HOME}" &> /dev/null || {
|
||||
echo -e "${FAIL_COLOR}setupImperas failed${ENDC}"
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
||||
# Use newer gcc version for older distros
|
||||
if [ -e /opt/rh/gcc-toolset-13/enable ]; then
|
||||
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
|
||||
elif [ -e $RISCV/gcc-10 ]; then
|
||||
elif [ -e "$RISCV"/gcc-10 ]; then
|
||||
export PATH=$RISCV/gcc-10/bin:$PATH # Ubuntu 20.04 LTS
|
||||
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 SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
|
||||
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 FlushWayCntEn, // Enable the way counter during a flush
|
||||
output logic FlushCntRst, // Reset both flush counters
|
||||
|
@ -83,7 +83,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||
STATE_FETCH,
|
||||
STATE_WRITEBACK,
|
||||
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
|
||||
STATE_FLUSH,
|
||||
STATE_FLUSH_WRITEBACK
|
||||
|
@ -165,7 +165,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||
(CurrState == STATE_WRITE_LINE & (CacheRW[0])) |
|
||||
(CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck));
|
||||
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
|
||||
CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck;
|
||||
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 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 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 FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
|
||||
input logic VictimWay, // LRU selected this way as victim to evict
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
// 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.
|
||||
// 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.
|
||||
|
|
|
@ -53,7 +53,7 @@ module ahbcacheinterface import cvw::*; #(
|
|||
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 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
|
||||
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
|
||||
|
|
|
@ -91,7 +91,7 @@ module ebu import cvw::*; #(parameter cvw_t P) (
|
|||
assign HRESETn = ~reset;
|
||||
|
||||
// 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
|
||||
|
|
|
@ -59,7 +59,7 @@ module ebufsmarb (
|
|||
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
|
||||
// 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
|
||||
// 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,
|
||||
// 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);
|
||||
assign LSUDisable = (CurrState == ARBITRATE) ? 1'b0 : (IFUReqDelay & ~(HREADY & FinalBeatD));
|
||||
assign LSUSelect = (NextState == ARBITRATE) ? 1'b1: LSUReq;
|
||||
|
|
|
@ -60,8 +60,8 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
|||
// register control signals
|
||||
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
|
||||
output logic FWriteIntE, FWriteIntM, // Write to integer register
|
||||
output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input
|
||||
output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input
|
||||
output logic [4:0] Adr1D, Adr2D, Adr3D, // addresses of each input
|
||||
output logic [4:0] Adr1E, Adr2E, Adr3E, // addresses of each input
|
||||
// other control signals
|
||||
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
|
||||
output logic FDivStartE, IDivStartE // Start division or squareroot
|
||||
|
@ -355,12 +355,12 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
|||
// 01 - negate sign
|
||||
// 10 - xor sign
|
||||
|
||||
// rename input adresses for readability
|
||||
// rename input addresses for readability
|
||||
assign Adr1D = InstrD[19:15];
|
||||
assign Adr2D = InstrD[24:20];
|
||||
assign Adr3D = InstrD[31:27];
|
||||
|
||||
// D/E pipleine register
|
||||
// D/E pipeline register
|
||||
flopenrc #(`FCTRLW+2+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
|
||||
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD, ZfaD, ZfaFRoundNXD, ~IllegalFPUInstrD},
|
||||
{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;
|
||||
else assign IDivStartE = 1'b0;
|
||||
|
||||
// E/M pipleine register
|
||||
// E/M pipeline register
|
||||
flopenrc #(14+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
|
||||
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE},
|
||||
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, FCvtIntM, ZfaM});
|
||||
|
@ -380,7 +380,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
|||
// renameing for readability
|
||||
assign FpLoadStoreM = FResSelM[1];
|
||||
|
||||
// M/W pipleine register
|
||||
// M/W pipeline register
|
||||
flopenrc #(4) MWCtrlReg(clk, reset, FlushW, ~StallW,
|
||||
{FRegWriteM, FResSelM, FCvtIntM},
|
||||
{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.XLEN-1:0] Int, // integer input - from IEU
|
||||
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 [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 ResSubnormUf, // does the result underflow or is subnormal
|
||||
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.LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
|
||||
|
||||
// seperate OpCtrl for code readability
|
||||
// separate OpCtrl for code readability
|
||||
assign Signed = OpCtrl[0];
|
||||
assign Int64 = OpCtrl[1];
|
||||
assign IntToFp = OpCtrl[2];
|
||||
|
@ -80,7 +80,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
|
||||
assign PosInt = Cs ? -Int : Int;
|
||||
|
@ -150,20 +150,20 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
|||
// - XExp - Largest bias + new bias - (LeadingZeros+1)
|
||||
// only do ^ if the input was subnormal
|
||||
// - 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
|
||||
// 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:
|
||||
// - start
|
||||
// | P.XLEN zeros | Mantissa | 0's if nessisary |
|
||||
// | P.XLEN zeros | Mantissa | 0's if necessary |
|
||||
//
|
||||
// - 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
|
||||
//
|
||||
// - 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 |
|
||||
//
|
||||
// - 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
|
||||
// ??? -> fp:
|
||||
// - 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
|
||||
// - rather have a few and-gates than an extra bit in the priority encoder???
|
||||
always_comb
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu
|
||||
// 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
|
||||
//
|
||||
|
|
|
@ -88,7 +88,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
assign AsE = AE[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) 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)
|
||||
// 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.
|
||||
// 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
|
||||
// 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)
|
||||
|
@ -194,7 +194,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
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
|
||||
|
@ -203,7 +203,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
assign X = PreShiftX;
|
||||
end
|
||||
|
||||
// Divisior register
|
||||
// Divisor register
|
||||
flopen #(P.DIVb+4) dreg(clk, IFDivStartE, {3'b000, Dnorm}, D);
|
||||
|
||||
// Floating-point exponent
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fhazard(
|
||||
input logic [4:0] Adr1D, Adr2D, Adr3D, // read data adresses
|
||||
input logic [4:0] Adr1E, Adr2E, Adr3E, // read data adresses
|
||||
input logic [4:0] Adr1D, Adr2D, Adr3D, // read data addresses
|
||||
input logic [4:0] Adr1E, Adr2E, Adr3E, // read data addresses
|
||||
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 XEnD, YEnD, ZEnD, // are the inputs needed
|
||||
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 [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 [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 InvA, // invert the aligned addend
|
||||
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 [2*P.NF+1:0] PmKilled, // the product's mantissa possibly killed
|
||||
output logic Ss, // sum's sign
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: FMA alginment shift
|
||||
// Purpose: FMA alignment shift
|
||||
//
|
||||
// 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 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 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
|
||||
);
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
||||
// | addnend |
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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
|
||||
output logic Ps, // the product's sign - 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 [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 [4:0] Adr1D, Adr2D, Adr3D; // register adresses of each input
|
||||
logic [4:0] Adr1E, Adr2E, Adr3E; // register adresses of each input
|
||||
logic [4:0] Adr1D, Adr2D, Adr3D; // register addresses 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 XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation
|
||||
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
|
||||
|
||||
// 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 CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal
|
||||
logic CsE, CsM; // convert result sign
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
module fregfile #(parameter FLEN) (
|
||||
input logic clk, reset,
|
||||
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
|
||||
output logic [FLEN-1:0] rd1, rd2, rd3 // read data
|
||||
);
|
||||
|
|
|
@ -30,12 +30,12 @@
|
|||
module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic XZero, // is the input zero?
|
||||
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.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.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 [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 |
|
||||
// .
|
||||
// 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
|
||||
// - ex: for the case 0010000.... (double)
|
||||
// ??? -> fp:
|
||||
// - 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:
|
||||
// | LzcInM | 0's if necessary |
|
||||
|
|
|
@ -57,8 +57,8 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
// 00000000.xxxxxxx... << NF Exp = DivUe+1
|
||||
// 00000000x.xxxxxx... << NF Exp = DivUe (extra shift done afterwards)
|
||||
// 00000000xx.xxxxx... << 1? Exp = DivUe-1 (determined after)
|
||||
// inital Left shift amount = NF
|
||||
// shift one more if the it's a minimally redundent radix 4 - one entire cycle needed for integer bit
|
||||
// initial Left shift amount = NF
|
||||
// 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);
|
||||
|
||||
// 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 Int64, // convert to 64 bit 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
|
||||
// divsqrt
|
||||
input logic DivOp, // conversion operation?
|
||||
|
@ -70,7 +70,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
logic FmaInvalid; // integer invalid flag
|
||||
logic DivInvalid; // integer invalid 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")
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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)
|
||||
// ShiftGtIntSz calculation:
|
||||
// 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
|
||||
// | XLEN | 00000... |
|
||||
// 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
|
||||
// | or | | or |
|
||||
// larger or equal if:
|
||||
// - any of the bits after the most significan 1 is one
|
||||
// - the most signifcant in 65 or 33 is still a one in the number and
|
||||
// - any of the bits after the most significant 1 is one
|
||||
// - the most significant in 65 or 33 is still a one in the number and
|
||||
// one of the later bits is one
|
||||
if (P.FPSIZES == 1) begin
|
||||
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));
|
||||
end
|
||||
|
||||
// calulate overflow flag:
|
||||
// calculate overflow flag:
|
||||
// if the result is greater than or equal to the max exponent(not taking into account sign)
|
||||
// | and the exponent isn't negative
|
||||
// | | if the input isnt infinity or NaN
|
||||
|
@ -146,8 +146,8 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
// Inexact
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Set Inexact flag if the result is diffrent from what would be outputed given infinite precision
|
||||
// - Don't set the underflow flag if an underflowed res isn't outputed
|
||||
// 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 outputted
|
||||
assign FpInexact = (Sticky|Guard|Overflow|Round)&~(InfIn|NaNIn|DivByZero|Invalid);
|
||||
|
||||
// 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
|
||||
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 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
|
||||
);
|
||||
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 CvtResSubnormUf, // the convert result is subnormal or underflows
|
||||
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 [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||
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 [P.LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount
|
||||
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 Overflow; // overflow 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 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 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
|
||||
// division signals
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
|
||||
logic [P.NE+1:0] Ue; // divsqrt corrected exponent after corretion shift
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shift amount
|
||||
logic [P.NE+1:0] Ue; // divsqrt corrected exponent after correction shift
|
||||
logic DivByZero; // divide by zero flag
|
||||
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
|
||||
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
|
||||
|
@ -107,7 +107,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
|||
logic Int64; // is the integer 64 bits?
|
||||
logic Signed; // is the operation with a signed integer?
|
||||
logic IntToFp; // is the operation an int->fp conversion?
|
||||
logic CvtOp; // convertion operation
|
||||
logic CvtOp; // conversion operation
|
||||
logic FmaOp; // fma operation
|
||||
logic DivOp; // divider operation
|
||||
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 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);
|
||||
|
||||
round #(P) round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Ue,
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
module resultsign(
|
||||
input logic [2:0] Frm, // rounding mode
|
||||
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 InfIn, // are any of the inputs infinity
|
||||
input logic FmaSZero, // is the fma sum zero
|
||||
|
@ -48,12 +48,12 @@ module resultsign(
|
|||
|
||||
// determine the sign for a result of 0
|
||||
// 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
|
||||
// - 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
|
||||
// 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
|
||||
// - P is killed and Z is zero - Psgn
|
||||
// - Z is killed and P is zero - impossible
|
||||
|
|
|
@ -40,13 +40,13 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
// divsqrt
|
||||
input logic DivOp, // is a division operation being done
|
||||
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
|
||||
input logic CvtOp, // is a convert operation being done
|
||||
input logic ToInt, // is the cvt op a cvt to integer
|
||||
input logic CvtResSubnormUf, // is the cvt result subnormal or 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
|
||||
output logic [P.NE+1:0] Me, // normalied fraction
|
||||
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.Q_NF-2:0]);
|
||||
// 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)) |
|
||||
(|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)) |
|
||||
|
|
|
@ -44,7 +44,7 @@ module roundsign(
|
|||
// calculate divsqrt sign
|
||||
assign Qs = Xs^(Ys&~Sqrt);
|
||||
|
||||
// Select sign for rounding calulation
|
||||
// Select sign for rounding calculation
|
||||
assign Ms = (FmaSs&FmaOp) | (CvtCs&CvtOp) | (Qs&DivOp);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -37,7 +37,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
|||
//fma
|
||||
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 FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
||||
input logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA correction
|
||||
input logic FmaSZero,
|
||||
// output
|
||||
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];
|
||||
|
||||
// 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));
|
||||
|
||||
// Determine the shif for either FMA or divsqrt
|
||||
// Determine the shift for either FMA or divsqrt
|
||||
assign RightShift = FmaOp ? LZAPlus1 : LeftShiftQm;
|
||||
|
||||
// possible one bit right shift for FMA or division
|
||||
|
@ -79,8 +79,8 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
|||
// main exponent issues:
|
||||
// - LZA was one 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 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 1
|
||||
// - 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
|
||||
// | | |
|
||||
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
|
||||
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
|
||||
// if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift
|
||||
// the quotient is in the range (.5,2) if there is no early termination
|
||||
// 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};
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
input logic Int64, // is the integer 64 bits
|
||||
input logic Signed, // is the integer signed
|
||||
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 CvtResUf, // does the convert result underflow
|
||||
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
|
||||
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
|
||||
// - 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
|
||||
|
@ -334,7 +334,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
end
|
||||
|
||||
// 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.
|
||||
|
||||
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 rounding and signed operation and negative input, output -1
|
||||
// - 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
|
||||
if(SelCvtOfRes) FCvtIntRes = OfIntRes2;
|
||||
else if(CvtCe[P.NE])
|
||||
|
|
|
@ -88,10 +88,10 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
end else
|
||||
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
|
||||
|
||||
// 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)};
|
||||
|
||||
// is the exponent non-zero
|
||||
|
@ -105,14 +105,14 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
// dexp = 0bdd dbbb bbbb
|
||||
// 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
|
||||
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
|
||||
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
|
||||
//---------------------------------------------------
|
||||
|
@ -171,8 +171,8 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
always_comb
|
||||
case (Fmt)
|
||||
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.FMT2: ExpNonZero = |In[P.LEN2-2:P.NF2]; // if input is smallest precsion (P.LEN2 - single or half)
|
||||
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 precision (P.LEN2 - single or half)
|
||||
default: ExpNonZero = 1'bx;
|
||||
endcase
|
||||
|
||||
|
@ -269,7 +269,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
// dexp = 0bdd dbbb bbbb
|
||||
// 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
|
||||
always_comb
|
||||
case (Fmt)
|
||||
|
@ -294,7 +294,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
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 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 Zero = ~ExpNonZero & FracZero; // is the input zero?
|
||||
assign Subnorm = ~ExpNonZero & ~FracZero & ~BadNaNBox; // is the input subnormal
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
///////////////////////////////////////////
|
||||
// ram1p1rwbe_64x22.sv
|
||||
//
|
||||
// Written: james.stine@okstate.edu 2 Feburary 2023
|
||||
// Written: james.stine@okstate.edu 2 February 2023
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: RAM wrapper for instantiating RAM IP
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// Written: tfleming@hmc.edu & jtorrey@hmc.edu 7 April 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
|
||||
// Kmacsaigoren@hmc.edu 28 May 2021:
|
||||
// Added working version of parameterized priority encoder.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// David_Harris@Hmc.edu switched to one-hot 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.
|
||||
//
|
||||
// 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.
|
||||
// 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.
|
||||
// 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
|
||||
assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE;
|
||||
assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE));
|
||||
|
@ -75,7 +75,7 @@ module hazard (
|
|||
assign FlushWCause = TrapM & ~WFIInterruptedM;
|
||||
|
||||
// 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
|
||||
// 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
|
||||
|
|
|
@ -37,7 +37,7 @@ module aes64ks1i(
|
|||
logic [31:0] rcon, rs1Rotate;
|
||||
|
||||
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 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] RevA; // Bit-reversed A
|
||||
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 [P.XLEN-1:0] CondZextA; // A Conditional Extend Intermediary Signal
|
||||
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
|
||||
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 BW64D, // Indiciates 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 BW64D, // Indicates if it is a W 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 IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage
|
||||
// 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 FCvtIntStallD, MDUStallD, CSRRdStallD; // Stall due to conversion, load, multiply/divide, CSR read
|
||||
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
|
||||
assign OpD = InstrD[6:0];
|
||||
|
@ -401,7 +401,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
|||
IFUPrefetchD = 1'b0;
|
||||
LSUPrefetchD = 1'b0;
|
||||
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 */
|
||||
case (Rs2D) // which type of prefectch? Note: prefetch.r and .w are handled the same in Wally
|
||||
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
|
||||
// shifter rotate source select mux
|
||||
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
|
||||
case ({Right, Rotate})
|
||||
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 BranchD, BranchE,
|
||||
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] IEUAdrM, // The branch/jump target 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);
|
||||
|
||||
// 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);
|
||||
else assign NextValidPCE = PCE;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// Modified: 24 January 2023
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
|
|
@ -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
|
||||
// Execute
|
||||
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] IEUAdrM, // The branch/jump target 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 InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
||||
// 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 [1:0] PageType, // Hardware page table walker (HPTW) writes 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
|
||||
// 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.
|
||||
// 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.
|
||||
|
|
|
@ -40,7 +40,7 @@ module irom import cvw::*; #(parameter cvw_t P) (
|
|||
logic [31:0] RawIROMInstrF;
|
||||
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
|
||||
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;
|
||||
|
@ -50,7 +50,7 @@ module irom import cvw::*; #(parameter cvw_t P) (
|
|||
flopen #(1) AdrReg2(clk, ce, Adr[2], AdrD[2]);
|
||||
assign RawIROMInstrF = AdrD[2] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0];
|
||||
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.
|
||||
if (P.ZCA_SUPPORTED) begin
|
||||
flopen #(1) AdrReg1(clk, ce, Adr[1], AdrD[1]);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// Modified: 26 October 2023
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// 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] 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 [P.LLEN-1:0] DCacheReadDataWordSpillM, // The final 32 bit instruction after merging the two spilled fetches into 1 instruction
|
||||
output logic SpillStallM);
|
||||
|
@ -80,10 +81,13 @@ module align import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
|
||||
/* verilator lint_off WIDTHEXPAND */
|
||||
//assign IEUAdrIncrementM = {IEUAdrM[P.XLEN-1:OFFSET_LEN], {{OFFSET_LEN}{1'b0}}} + LLENINBYTES;
|
||||
assign IEUAdrIncrementM = IEUAdrM + LLENINBYTES;
|
||||
/* verilator lint_on WIDTHEXPAND */
|
||||
mux2 #(P.XLEN) ieuadrspillemux(.d0(IEUAdrE), .d1(IEUAdrIncrementM), .s(SelSpillE), .y(IEUAdrSpillE));
|
||||
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
|
||||
|
@ -94,7 +98,7 @@ module align import cvw::*; #(parameter cvw_t P) (
|
|||
// 2) offset
|
||||
// 3) access location within the cacheline
|
||||
|
||||
// compute misalignement
|
||||
// compute misalignment
|
||||
always_comb begin
|
||||
case (Funct3M & {FpLoadStoreM, 2'b11})
|
||||
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);
|
||||
|
||||
// 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)
|
||||
|
|
|
@ -36,7 +36,7 @@ module lrsc import cvw::*; #(parameter cvw_t P) (
|
|||
input logic MemReadM, // Memory read
|
||||
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
|
||||
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
|
||||
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 sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
||||
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
|
||||
input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU
|
||||
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 DTLBWriteM; // Writes PTE and PageType to DTLB
|
||||
logic LSULoadAccessFaultM; // Load acces fault
|
||||
logic LSULoadAccessFaultM; // Load access fault
|
||||
logic LSUStoreAmoAccessFaultM; // Store access fault
|
||||
logic HPTWFlushW; // HPTW needs to flush 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);
|
||||
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,
|
||||
.MemRWM,
|
||||
.DCacheReadDataWordM, .CacheBusHPWTStall, .SelHPTW,
|
||||
.ByteMaskM, .ByteMaskExtendedM, .LSUWriteDataM, .ByteMaskSpillM, .LSUWriteDataSpillM,
|
||||
.IEUAdrSpillE, .IEUAdrSpillM, .SelSpillE, .DCacheReadDataWordSpillM, .SpillStallM);
|
||||
.IEUAdrSpillE, .IEUAdrSpillM, .IEUAdrxTvalM, .SelSpillE, .DCacheReadDataWordSpillM, .SpillStallM);
|
||||
assign IEUAdrExtM = {2'b00, IEUAdrSpillM};
|
||||
assign IEUAdrExtE = {2'b00, IEUAdrSpillE};
|
||||
end else begin : no_ziccslm_align
|
||||
|
@ -175,6 +177,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||
assign LSUWriteDataSpillM = LSUWriteDataM;
|
||||
assign MemRWSpillM = MemRWM;
|
||||
assign {SpillStallM} = 1'b0;
|
||||
assign IEUAdrxTvalM = IEUAdrM;
|
||||
end
|
||||
|
||||
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 [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache
|
||||
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] BusRW; // Uncached bus memory access
|
||||
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]}}),
|
||||
.d2({{P.LLEN-P.XLEN{1'b0}}, DTIMReadDataWordM[P.XLEN-1:0]}),
|
||||
.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 [P.XLEN-1:0] FetchBuffer;
|
||||
assign BusRW = ~SelDTIM ? LSURWM : 0;
|
||||
|
|
|
@ -78,7 +78,7 @@ module div import cvw::*; #(parameter cvw_t P) (
|
|||
assign DinE = ForwardedSrcBE;
|
||||
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 SignXE = DivSignedE & XinE[P.XLEN-1];
|
||||
assign NegQE = SignDE ^ SignXE;
|
||||
|
|
|
@ -33,7 +33,7 @@ module mdu import cvw::*; #(parameter cvw_t P) (
|
|||
input logic FlushE, FlushM, FlushW,
|
||||
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 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
|
||||
output logic [P.XLEN-1:0] MDUResultW, // multiply/divide result
|
||||
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 OtherPageFault = ImproperPrivilege | InvalidOp | UpperBitsUnequalD | Misaligned | ~Valid;
|
||||
|
||||
// hptw needs to know if there is a Dirty or Access fault occuring on this
|
||||
// memory access. If there is the PTE needs to be updated seting Access
|
||||
// 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 setting Access
|
||||
// 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
|
||||
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
|
||||
|
||||
// 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);
|
||||
|
||||
// multiplex the outputs to LSU
|
||||
|
|
|
@ -47,7 +47,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||
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 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 SelTIM, // Select a tightly integrated memory
|
||||
// Faults
|
||||
|
@ -105,8 +105,8 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||
assign TLBPAdr = '0;
|
||||
end
|
||||
|
||||
// If translation is occuring, select translated physical address from TLB
|
||||
// the lower 12 bits are the page offset. These are never changed from the orginal
|
||||
// If translation is occurring, select translated physical address from TLB
|
||||
// the lower 12 bits are the page offset. These are never changed from the original
|
||||
// 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]);
|
||||
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'b11: DataMisalignedM = |VAdr[2:0]; // ld, sd, fld, fsd
|
||||
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 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
|
||||
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
|
||||
assign CacheableRegion = SelRegions[3] | SelRegions[4] | SelRegions[5]; // exclusion-tag: unused-cachable
|
||||
// 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-cacheable
|
||||
assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 1'b0;
|
||||
|
||||
// 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 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;
|
||||
// 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.
|
||||
|
||||
|
||||
/* 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 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
|
||||
assign Match = (AdrMode == TOR) ? TORMatch :
|
||||
|
|
|
@ -75,7 +75,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
|
|||
.Match, .PMPTop, .L, .X, .W, .R);
|
||||
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
|
||||
// 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.
|
||||
// For example, a megapage in SV32 only cares about VPN[1], so VPN[0]
|
||||
// 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 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;
|
||||
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;
|
||||
|
||||
// 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
|
||||
if (P.SVNAPOT_SUPPORTED) begin
|
||||
// 64 KiB contiguous NAPOT translations suported
|
||||
// 64 KiB contiguous NAPOT translations supported
|
||||
logic [3:0] PPNMixedBot;
|
||||
mux2 #(4) napotmux(PPNMixed[3:0], VPN[3:0], PTE_N, 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] 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] 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 TrapM, // trap is occurring
|
||||
input logic mretM, sretM, // return instruction
|
||||
|
@ -142,7 +142,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||
else case (CauseM)
|
||||
12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint
|
||||
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
|
||||
endcase
|
||||
|
||||
|
|
|
@ -90,14 +90,14 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
|||
end
|
||||
|
||||
// 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_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster 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_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 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
|
||||
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_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_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
|
||||
|
|
|
@ -83,7 +83,7 @@ module privdec import cvw::*; #(parameter cvw_t P) (
|
|||
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
|
||||
// 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];
|
||||
// coverage on
|
||||
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 [31:0] InstrM, // Instruction
|
||||
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
|
||||
// control signals
|
||||
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 BPDirWrongM, // branch predictor guessed wrong direction
|
||||
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 BPWrongM, // branch predictor is wrong
|
||||
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 [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return
|
||||
logic DelegateM; // trap should be delegated
|
||||
logic InterruptM; // interrupt occuring
|
||||
logic InterruptM; // interrupt occurring
|
||||
logic ExceptionM; // Memory stage instruction caused a fault
|
||||
logic HPTWInstrAccessFaultM; // Hardware page table access 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
|
||||
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,
|
||||
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
|
||||
.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
|
||||
);
|
||||
|
||||
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 BothInstrAccessFaultM, BothInstrPageFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
|
||||
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