Merge branch 'main' into rvvi

This commit is contained in:
Rose Thompson 2024-03-08 10:16:31 -06:00
commit 140e64772e
338 changed files with 4858 additions and 4330 deletions

1
.gitignore vendored
View File

@ -184,3 +184,4 @@ sim/cfi/*
sim/branch/* sim/branch/*
sim/obj_dir sim/obj_dir
examples/verilog/fulladder/obj_dir examples/verilog/fulladder/obj_dir
config/deriv

View File

@ -24,18 +24,18 @@ New users may wish to do the following setup to access the server via a GUI and
Terminal on Mac, cmd on Windows, xterm on Linux Terminal on Mac, cmd on Windows, xterm on Linux
See A.1 about ssh -Y login from a terminal See A.1 about ssh -Y login from a terminal
Then clone the repo, source setup, make the tests and run regression Then fork and clone the repo, source setup, make the tests and run regression
If you don't already have a Github account, create one If you don't already have a Github account, create one
In a web browser, visit https://github.com/openhwgroup/cvw In a web browser, visit https://github.com/openhwgroup/cvw
In the upper right part of the screen, click on Fork In the upper right part of the screen, click on Fork
Create a fork, choosing the owner as your github account and the repository as cvw. Create a fork, choosing the owner as your github account
and the repository as cvw.
On the Linux computer where you will be working, log in On the Linux computer where you will be working, log in
Clone your fork of the repo and run the setup script. Change <yourgithubid> to your github id. Clone your fork of the repo and run the setup script. Change <yourgithubid> to your github id.
$ cd
$ git clone --recurse-submodules https://github.com/<yourgithubid>/cvw $ git clone --recurse-submodules https://github.com/<yourgithubid>/cvw
$ cd cvw $ cd cvw
$ git remote add upstream https://github.com/openhwgroup/cvw $ git remote add upstream https://github.com/openhwgroup/cvw

@ -1 +1 @@
Subproject commit c955abf757df98cf38809e40a62d2a6b448ea507 Subproject commit 8a52b016dbe1e2733cc168b9d6e5c93e39059d4d

View File

@ -9,6 +9,7 @@
## Computes the geometric mean for btb accuracy ## Computes the geometric mean for btb accuracy
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -9,6 +9,7 @@
## Computes the geometric mean. ## Computes the geometric mean.
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -10,6 +10,7 @@
## Purpose: Simulate a L1 D$ or I$ for comparison with Wally ## Purpose: Simulate a L1 D$ or I$ for comparison with Wally
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -12,6 +12,7 @@
## separated by benchmark application. Example names are aha-mot64bd_sizeopt_speed_branch.log ## separated by benchmark application. Example names are aha-mot64bd_sizeopt_speed_branch.log
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

133
bin/derivgen.pl Executable file
View File

@ -0,0 +1,133 @@
#!/bin/perl -W
###########################################
## derivgen.pl
##
## Written: David_Harris@hmc.edu
## Created: 29 January 2024
## Modified:
##
## Purpose: Read config/derivlist.txt and generate config/deriv/*/config.vh
## derivative configurations from the base configurations
##
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
use strict;
use warnings;
import os;
use Data::Dumper;
my $curderiv = "";
my @derivlist = ();
my %derivs;
my %basederiv;
my @derivnames = ();
if ($#ARGV != -1) {
die("Usage: $0")
}
my $derivlist = "$ENV{WALLY}/config/derivlist.txt";
open(my $fh, $derivlist) or die "Could not open file '$derivlist' $!";
foreach my $line (<$fh>) {
chomp $line;
my @tokens = split('\s+', $line);
if ($#tokens < 0 || $tokens[0] =~ /^#/) { # skip blank lines and comments
next;
}
if ($tokens[0] =~ /deriv/) { # start of a new derivative
&terminateDeriv();
$curderiv = $tokens[1];
$basederiv{$curderiv} = $tokens[2];
@derivlist = ();
if ($#tokens > 2) {
my $inherits = $derivs{$tokens[3]};
@derivlist = @{$inherits};
}
} else { # add to the current derivative
$line =~ /\s*(\S+)\s*(.*)/;
my @entry = ($1, $2);
push(@derivlist, \@entry);
}
}
&terminateDeriv();
close($fh);
#foreach my $key (keys %derivs) {
foreach my $key (@derivnames) {
my $dir = "$ENV{WALLY}/config/deriv/$key";
system("rm -rf $dir");
system("mkdir -p $dir");
my $configunmod = "$dir/config_unmod.vh";
my $config = "$dir/config.vh";
my $base = "$ENV{WALLY}/config/$basederiv{$key}/config.vh";
if (! -e $base) {
$base = "$ENV{WALLY}/config/deriv/$basederiv{$key}/config.vh";
#if (! -e $base) {
# die("Unable to find base config $base for $key\n");
#}
}
system("cp $base $configunmod");
open(my $unmod, $configunmod) or die "Could not open file '$configunmod' $!";
open(my $fh, '>>', $config) or die "Could not open file '$config' $!";
my $datestring = localtime();
my %hit = ();
print $fh "// Config $key automatically derived from $basederiv{$key} on $datestring usubg derivgen.pl\n";
foreach my $line (<$unmod>) {
foreach my $entry (@{$derivs{$key}}) {
my @ent = @{$entry};
my $param = $ent[0];
my $value = $ent[1];
if ($line =~ s/$param\s*=\s*.*;/$param = $value;/) {
$hit{$param} = 1;
# print("Hit: new line in $config for $param is $line");
}
}
print $fh $line;
}
close($fh);
close($unmod);
foreach my $entry (@{$derivs{$key}}) {
my @ent = @{$entry};
my $param = $ent[0];
if (!exists($hit{$param})) {
print("Unable to find $param in $key\n");
}
}
system("rm -f $dir/config_unmod.vh");
}
sub terminateDeriv {
if ($curderiv ne "") { # close out the previous derivative
my @dl = @derivlist;
$derivs{$curderiv} = \@dl;
push(@derivnames, $curderiv);
}
};
sub printref {
my $ref = shift;
my @array = @{$ref};
foreach my $entry (@array) {
print join('_', @{$entry}), ', ';
}
print("\n");
}

View File

@ -9,6 +9,7 @@
## Imperas and riscv-arch-test benchmarks ## Imperas and riscv-arch-test benchmarks
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -11,6 +11,7 @@
## to read into a Verilog simulation with $readmemh ## to read into a Verilog simulation with $readmemh
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

21
bin/fparchtest.sh Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/bash
#
# fparchtest.sh
# David_Harris@hmc.edu 26 December 2023
#
# Drive the riscv-isac and riscv-ctg tools to generate floating-point tests
# Set up with (not retested)
# cd ~/repos
# git clone https://github.com/riscv/riscv-ctg.git
# git clone https://github.com/riscv/riscv-isac.git
# pip3 install git+https://github.com/riscv/riscv-ctg.git
# pip3 install git+https://github.com/riscv/riscv-isac.git
# Put ~/.local/bin in $PATH to find riscv_isac and riscv_ctg
RISCVCTG=/home/harris/repos/riscv-ctg
#riscv_isac --verbose debug normalize -c $RISCVCTG/sample_cgfs/dataset.cgf -c $RISCVCTG/sample_cgfs/sample_cgfs_fext/RV32F/fadd.s.cgf -o $RISCVCTG/tests/normalizedfadd.cgf -x 32
#riscv_isac --verbose debug normalize -c $RISCVCTG/sample_cgfs/dataset.cgf -c $RISCVCTG/sample_cgfs/sample_cgfs_fext/RV32H/fadd_b1.s.cgf -o $RISCVCTG/tests/normalizedfadd16_b1.cgf -x 32
riscv_ctg -cf $RISCVCTG/tests/normalizedfadd16_b1.cgf -d $RISCVCTG/tests --base-isa rv32i --verbose debug
#riscv_ctg -cf $RISCVCTG/sample_cgfs/dataset.cgf -cf $RISCVCTG/sample_cgfs/rv32im.cgf -d $RISCVCTG/tests --base-isa rv32i # --verbose debug

View File

@ -9,6 +9,7 @@
## Purpose: One time setup script for running imperas. ## Purpose: One time setup script for running imperas.
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -13,6 +13,7 @@
## and for TSMC change the $cellname to the actual name of the inverter. ## and for TSMC change the $cellname to the actual name of the inverter.
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

693
bin/nightly_build.py Executable file
View File

@ -0,0 +1,693 @@
#!/usr/bin/python3
"""
Python Regression Build Automation Script
This Python script serves the purpose of automating nightly regression builds for a software project.
The script is designed to handle the setup, execution, and reporting aspects of the regression testing process.
Features:
1. Nightly Regression Builds: The script is scheduled to run on a nightly basis, making and executing the regression builds.
2. Markdown Report Generation: Upon completion of the regression tests, the script generates detailed reports in Markdown format.
These reports provide comprehensive insights into the test results, including test cases executed, pass/fail status, and any encountered issues.
3. Email Notification: The script is configured to send out email notifications summarizing the regression test results.
These emails serve as communication channels for stakeholders, providing them with timely updates on the software's regression status.
Usage:
- The script is designed to be scheduled and executed automatically on a nightly basis using task scheduling tools such as Cronjobs. To create a cronjob do the following:
1) Open Terminal:
Open your terminal application. This is where you'll enter the commands to create and manage cron jobs.
2) Access the Cron Table:
Type the following command and press Enter:
crontab -e
This command opens the crontab file in your default text editor. If it's your first time, you might be prompted to choose a text editor.
3) Edit the Cron Table:
The crontab file will open in your text editor. Each line in this file represents a cron job. You can now add your new cron job.
4) Syntax:
Our cron job has the following syntax:
0 3 * * * BASH_ENV=~/.bashrc bash -l -c "*WHERE YOUR CVW IS MUST PUT FULL PATH*/cvw/bin/wrapper_nightly_runs.sh > *WHERE YOU WANT TO STORE LOG FILES/cron.log 2>&1"
This cronjob sources the .bashrc file and executes the wrapper script as a user.
5) Double check:
Execute the following command to see your cronjobs:
crontab -l
Dependencies:
Python:
- os
- shutil
- datetime from datetime
- re
- markdown
- subprocess
Bash:
- mutt (email sender)
Conclusion:
In summary, this Python script facilitates the automation of nightly regression builds, providing comprehensive reporting and email notification capabilities to ensure effective communication and monitoring of regression test results.
"""
import os
import shutil
from datetime import datetime
import re
import markdown
import subprocess
class FolderManager:
"""A class for managing folders and repository cloning."""
def __init__(self):
"""
Initialize the FolderManager instance.
Args:
base_dir (str): The base directory where folders will be managed and repository will be cloned.
"""
env_extract_var = 'WALLY'
print(f"The environemntal variable is {env_extract_var}")
self.base_dir = os.environ.get(env_extract_var)
print(f"The base directory is: {self.base_dir}")
self.base_parent_dir = os.path.dirname(self.base_dir)
# print(f"The new WALLY vairable is: {os.environ.get('WALLY')}")
# print(f"The Base Directory is now : {self.base_dir}")
# print(f"The Base Parent Directory is now : {self.base_parent_dir}")
def create_preliminary_folders(self, folders):
"""
Create preliminary folders if they do not exist.
These folders are:
nightly_runs/repos/
nightly_runs/results/
Args:
folders (list): A list of folder names to be created.
Returns:
None
"""
for folder in folders:
folder_path = os.path.join(self.base_parent_dir, folder)
if not os.path.exists(folder_path):
os.makedirs(folder_path)
def create_new_folder(self, folders):
"""
Create a new folder based on the current date if it does not already exist.
Args:
folder_name (str): The base name for the new folder.
Returns:
str: The path of the newly created folder if created, None otherwise.
"""
todays_date = datetime.now().strftime("%Y-%m-%d")
return_folder_path = []
for folder in folders:
folder_path = os.path.join(self.base_parent_dir, folder, todays_date)
if not os.path.exists(folder_path):
os.makedirs(folder_path)
return_folder_path.append(folder_path)
else:
return_folder_path.append(None) # Folder already exists
return return_folder_path
def clone_repository(self, folder, repo_url):
"""
Clone a repository into the 'cvw' folder if it does not already exist.
Args:
repo_url (str): The URL of the repository to be cloned.
Returns:
None
"""
todays_date = datetime.now().strftime("%Y-%m-%d")
repo_folder = os.path.join(self.base_parent_dir, folder, todays_date, 'cvw')
tmp_folder = os.path.join(repo_folder, "tmp") # temprorary files will be stored in here
if not os.path.exists(repo_folder):
os.makedirs(repo_folder)
os.system(f"git clone --recurse-submodules {repo_url} {repo_folder}")
os.makedirs(tmp_folder)
class TestRunner:
"""A class for making, running, and formatting test results."""
def __init__(self):
self.base_dir = os.environ.get('WALLY')
self.base_parent_dir = os.path.dirname(self.base_dir)
self.current_datetime = datetime.now()
#self.temp_dir = self.base_parent_dir
#print(f"Base Directory: {self.base_parent_dir}")
def copy_setup_script(self, folder):
"""
Copy the setup script to the destination folder.
The setup script will be copied from the base directory to a specific folder structure inside the base directory.
Args:
folder: the "nightly_runs/repos/"
Returns:
bool: True if the script is copied successfully, False otherwise.
"""
# Get today's date in YYYY-MM-DD format
todays_date = datetime.now().strftime("%Y-%m-%d")
# Define the source and destination paths
source_script = os.path.join(self.base_dir, "setup_host.sh")
destination_folder = os.path.join(self.base_parent_dir, folder, todays_date, 'cvw')
# Check if the source script exists
if not os.path.exists(source_script):
print(f"Error: Source script '{source_script}' not found.")
return False
# Check if the destination folder exists, create it if necessary
if not os.path.exists(destination_folder):
print(f"Error: Destination folder '{destination_folder}' not found.")
return False
# Copy the script to the destination folder
try:
shutil.copy(source_script, destination_folder)
#print(f"Setup script copied to: {destination_folder}")
return True
except Exception as e:
print(f"Error copying setup script: {e}")
return False
def set_env_var(self, folder):
"""
Source a shell script.
Args:
script_path (str): Path to the script to be sourced.
Returns:
None
"""
# find the new repository made
todays_date = datetime.now().strftime("%Y-%m-%d")
wally_path = os.path.join(self.base_parent_dir, folder, todays_date, 'cvw')
# set the WALLY environmental variable to the new repository
os.environ["WALLY"] = wally_path
self.base_dir = os.environ.get('WALLY')
self.base_parent_dir = os.path.dirname(self.base_dir)
self.temp_dir = self.base_parent_dir
# print(f"The new WALLY vairable is: {os.environ.get('WALLY')}")
# print(f"The Base Directory is now : {self.base_dir}")
# print(f"The Base Parent Directory is now : {self.base_parent_dir}")
def execute_makefile(self, target=None):
"""
Execute a Makefile with optional target.
Args:
makefile_path (str): Path to the Makefile.
target (str, optional): Target to execute in the Makefile.
Returns:
True if the tests were made
False if the tests didnt pass
"""
# Prepare the command to execute the Makefile
make_file_path = os.path.join(self.base_dir, "sim")
os.chdir(make_file_path)
output_file = os.path.join(self.base_dir, "tmp", "make_output.log")
command = ["make"]
# Add target to the command if specified
if target:
command.append(target)
#print(f"The command is: {command}")
# Execute the command using subprocess and save the output into a file
with open(output_file, "w") as f:
formatted_datetime = self.current_datetime.strftime("%Y-%m-%d %H:%M:%S")
f.write(formatted_datetime)
f.write("\n\n")
result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True)
# Execute the command using a subprocess and not save the output
#result = subprocess.run(command, text=True)
# Check the result
if result.returncode == 0:
#print(f"Makefile executed successfully{' with target ' + target if target else ''}.")
return True
else:
#print("Error executing Makefile.")
return False
def run_tests(self, test_type=None, test_name=None, test_exctention=None):
"""
Run a script through the terminal and save the output to a file.
Args:
test_name (str): The test name will allow the function to know what test to execute in the sim directory
test_type (str): The type such as python, bash, etc
Returns:
True and the output file location
"""
# Prepare the function to execute the simulation
test_file_path = os.path.join(self.base_dir, "sim")
output_file = os.path.join(self.base_dir, "tmp", f"{test_name}-output.log")
os.chdir(test_file_path)
if test_exctention:
command = [test_type, test_name, test_exctention]
else:
command = [test_type, test_name]
# Execute the command using subprocess and save the output into a file
with open(output_file, "w") as f:
formatted_datetime = self.current_datetime.strftime("%Y-%m-%d %H:%M:%S")
f.write(formatted_datetime)
f.write("\n\n")
result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True)
# Check if the command executed successfully
if result.returncode or result.returncode == 0:
return True, output_file
else:
print("Error:", result.returncode)
return False, output_file
def clean_format_output(self, input_file, output_file=None):
"""
Clean and format the output from tests.
Args:
input_file (str): Path to the input file with raw test results.
output_file (str): Path to the file where cleaned and formatted output will be saved.
Returns:
None
"""
# Implement cleaning and formatting logic here
# Open up the file with only read permissions
with open(input_file, 'r') as input_file:
unlceaned_output = input_file.read()
# use something like this function to detect pass and fail
passed_configs = []
failed_configs = []
lines = unlceaned_output.split('\n')
index = 0
while index < len(lines):
# Remove ANSI escape codes
line = re.sub(r'\x1b\[[0-9;]*[mGK]', '', lines[index])
#print(line)
if "Success" in line:
passed_configs.append(line.split(':')[0].strip())
elif "passed lint" in line:
#print(line)
passed_configs.append(line.split(' ')[0].strip())
#passed_configs.append(line) # potentially use a space
elif "failed lint" in line:
failed_configs.append(line.split(' ')[0].strip(), "no log file")
#failed_configs.append(line)
elif "Failures detected in output" in line:
try:
config_name = line.split(':')[0].strip()
log_file = os.path.abspath("logs/"+config_name+".log")
#print(f"The log file saving to: {log_file} in the current working directory: {os.getcwd()}")
failed_configs.append((config_name, log_file))
except:
failed_configs.append((config_name, "Log file not found"))
index += 1
# alphabetically sort the configurations
if len(passed_configs) != 0:
passed_configs.sort()
if len(failed_configs) != 0:
failed_configs.sort()
#print(f"The passed configs are: {passed_configs}")
#print(f"The failed configs are {failed_configs}")
return passed_configs, failed_configs
def rewrite_to_markdown(self, test_name, passed_configs, failed_configs):
"""
Rewrite test results to markdown format.
Args:
input_file (str): Path to the input file with cleaned and formatted output.
markdown_file (str): Path to the markdown file where test results will be saved.
Returns:
None
"""
# Implement markdown rewriting logic here
timestamp = datetime.now().strftime("%Y-%m-%d")
output_directory = os.path.join(self.base_parent_dir, "../../results", timestamp)
os.chdir(output_directory)
current_directory = os.getcwd()
output_file = os.path.join(current_directory, f"{test_name}.md")
#print("Current directory:", current_directory)
#print("Output File:", output_file)
with open(output_file, 'w') as md_file:
# Title
md_file.write(f"\n\n# Regression Test Results - {timestamp}\n\n")
#md_file.write(f"\n\n<div class=\"regression\">\n# Regression Test Results - {timestamp}\n</div>\n\n")
# File Path
md_file.write(f"\n**File:** {output_file}\n\n")
if failed_configs:
md_file.write("## Failed Configurations\n\n")
for config, log_file in failed_configs:
md_file.write(f"- <span class=\"failure\" style=\"color: red;\">{config}</span> ({log_file})\n")
md_file.write("\n")
else:
md_file.write("## Failed Configurations\n")
md_file.write(f"No Failures\n")
md_file.write("\n## Passed Configurations\n")
for config in passed_configs:
md_file.write(f"- <span class=\"success\" style=\"color: green;\">{config}</span>\n")
def combine_markdown_files(self, passed_tests, failed_tests, test_list, total_number_failures, total_number_success, test_type="default", markdown_file=None):
"""
First we want to display the server properties like:
- Server full name
- Operating System
Combine the markdown files and format them to display all of the failures at the top categorized by what kind of test it was
Then display all of the successes.
Args:
passed_tests (list): a list of successful tests
failed_tests (list): a list of failed tests
test_list (list): a list of the test names.
markdown_file (str): Path to the markdown file where test results will be saved.
Returns:
None
"""
timestamp = datetime.now().strftime("%Y-%m-%d")
output_directory = os.path.join(self.base_parent_dir, "../../results", timestamp)
os.chdir(output_directory)
current_directory = os.getcwd()
output_file = os.path.join(current_directory, "results.md")
with open(output_file, 'w') as md_file:
# Title
md_file.write(f"\n\n# Nightly Test Results - {timestamp}\n\n")
# Host information
try:
# Run hostname command
hostname = subprocess.check_output(['hostname', '-A']).strip().decode('utf-8')
md_file.write(f"**Host name:** {hostname}")
md_file.write("\n")
# Run uname command to get OS information
os_info = subprocess.check_output(['uname', '-a']).strip().decode('utf-8')
md_file.write(f"\n**Operating System Information:** {os_info}")
md_file.write("\n")
except subprocess.CalledProcessError as e:
# Handle if the command fails
md_file.write(f"Failed to identify host and Operating System information: {str(e)}")
# Which tests did we run
md_file.write(f"\n**Tests made:** `make {test_type}`\n")
# File Path
md_file.write(f"\n**File:** {output_file}\n\n") # *** needs to be changed
md_file.write(f"**Total Successes: {total_number_success}**\n")
md_file.write(f"**Total Failures: {total_number_failures}**\n")
# Failed Tests
md_file.write(f"\n\n## Failed Tests")
md_file.write(f"\nTotal failed tests: {total_number_failures}")
for (test_item, item) in zip(test_list, failed_tests):
md_file.write(f"\n\n### {test_item[1]} test")
md_file.write(f"\n**General Information**\n")
md_file.write(f"\n* Test type: {test_item[0]}\n")
md_file.write(f"\n* Test name: {test_item[1]}\n")
md_file.write(f"\n* Test extension: {test_item[2]}\n\n")
md_file.write(f"**Failed Tests:**\n")
if len(item) == 0:
md_file.write("\n")
md_file.write(f"* <span class=\"no-failure\" style=\"color: green;\">No failures</span>\n")
md_file.write("\n")
else:
for failed_test in item:
config = failed_test[0]
log_file = failed_test[1]
md_file.write("\n")
md_file.write(f"* <span class=\"failure\" style=\"color: red;\">{config}</span> ({log_file})\n")
md_file.write("\n")
# Successfull Tests
md_file.write(f"\n\n## Successfull Tests")
md_file.write(f"\n**Total successfull tests: {total_number_success}**")
for (test_item, item) in zip(test_list, passed_tests):
md_file.write(f"\n\n### {test_item[1]} test")
md_file.write(f"\n**General Information**\n")
md_file.write(f"\n* Test type: {test_item[0]}")
md_file.write(f"\n* Test name: {test_item[1]}")
md_file.write(f"\n* Test extension: {test_item[2]}\n\n")
md_file.write(f"\n**Successfull Tests:**\n")
if len(item) == 0:
md_file.write("\n")
md_file.write(f"* <span class=\"no-successes\" style=\"color: red;\">No successes</span>\n")
md_file.write("\n")
else:
for passed_tests in item:
config = passed_tests
md_file.write("\n")
md_file.write(f"* <span class=\"success\" style=\"color: green;\">{config}</span>\n")
md_file.write("\n")
def convert_to_html(self, markdown_file="results.md", html_file="results.html"):
"""
Convert markdown file to HTML.
Args:
markdown_file (str): Path to the markdown file.
html_file (str): Path to the HTML file where converted output will be saved.
Returns:
None
"""
# Implement markdown to HTML conversion logic here
todays_date = self.current_datetime.strftime("%Y-%m-%d")
markdown_file_path = os.path.join(self.base_parent_dir, "../../results", todays_date)
os.chdir(markdown_file_path)
with open(markdown_file, 'r') as md_file:
md_content = md_file.read()
html_content = markdown.markdown(md_content)
with open(html_file, 'w') as html_file:
html_file.write(html_content)
def send_email(self, sender_email=None, receiver_emails=None, subject="Nightly Regression Test"):
"""
Send email with HTML content.
Args:
self: The instance of the class.
sender_email (str): The sender's email address. Defaults to None.
receiver_emails (list[str]): List of receiver email addresses. Defaults to None.
subject (str, optional): Subject of the email. Defaults to "Nightly Regression Test".
Returns:
None
"""
# check if there are any emails
if not receiver_emails:
print("No receiver emails provided.")
return
# grab thge html file
todays_date = self.current_datetime.strftime("%Y-%m-%d")
html_file_path = os.path.join(self.base_parent_dir, "../../results", todays_date)
os.chdir(html_file_path)
html_file = "results.html"
with open(html_file, 'r') as html_file:
body = html_file.read()
for receiver_email in receiver_emails:
# Compose the mutt command for each receiver email
command = [
'mutt',
'-s', subject,
'-e', 'set content_type=text/html',
'-e', 'my_hdr From: James Stine <james.stine@okstate.edu>',
'--', receiver_email
]
# Open a subprocess to run the mutt command
process = subprocess.Popen(command, stdin=subprocess.PIPE)
# Write the email body to the subprocess
process.communicate(body.encode('utf-8'))
#############################################
# SETUP #
#############################################
folder_manager = FolderManager() # creates the object
# setting the path on where to clone new repositories of cvw
path = folder_manager.create_preliminary_folders(["nightly_runs/repos/", "nightly_runs/results/"])
new_folder = folder_manager.create_new_folder(["nightly_runs/repos/", "nightly_runs/results/"])
# clone the cvw repo
folder_manager.clone_repository("nightly_runs/repos/", "https://github.com/openhwgroup/cvw.git")
#############################################
# SETUP #
#############################################
test_runner = TestRunner() # creates the object
test_runner.set_env_var("nightly_runs/repos/") # ensures that the new WALLY environmental variable is set correctly
#############################################
# MAKE TESTS #
#############################################
# target = "wally-riscv-arch-test"
target = "all"
if test_runner.execute_makefile(target = target):
print(f"The {target} tests were made successfully")
#############################################
# RUN TESTS #
#############################################
test_list = [["python", "regression-wally", "-nightly"], ["bash", "lint-wally", "-nightly"], ["bash", "coverage", "--search"]]
output_log_list = [] # a list where the output markdown file lcoations 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_failures = []
total_success = []
for test_type, test_name, test_exctention in test_list:
print("--------------------------------------------------------------")
print(f"Test type: {test_type}")
print(f"Test name: {test_name}")
print(f"Test extenction: {test_exctention}")
check, output_location = test_runner.run_tests(test_type=test_type, test_name=test_name, test_exctention=test_exctention)
print(check)
print(output_location)
if check: # this checks if the test actually ran successfully
output_log_list.append(output_location)
# format tests to markdown
try:
passed, failed = test_runner.clean_format_output(input_file = output_location)
except:
print("There was an error cleaning the data")
print(f"The # of failures are for {test_name}: {len(failed)}")
total_number_failures+= len(failed)
total_failures.append(failed)
print(f"The # of sucesses are for {test_name}: {len(passed)}")
total_number_success += len(passed)
total_success.append(passed)
test_runner.rewrite_to_markdown(test_name, passed, failed)
print(f"The total sucesses are: {total_number_success}")
print(f"The total failures are: {total_number_failures}")
#############################################
# FORMAT TESTS #
#############################################
# Combine multiple markdown files into one file
test_runner.combine_markdown_files(passed_tests = total_success, failed_tests = total_failures, test_list = test_list, total_number_failures = total_number_failures, total_number_success = total_number_success, test_type=target, markdown_file=None)
#############################################
# WRITE MD TESTS #
#############################################
test_runner.convert_to_html()
#############################################
# SEND EMAIL #
#############################################
sender_email = 'james.stine@okstate.edu'
receiver_emails = ['thomas.kidd@okstate.edu', 'james.stine@okstate.edu', 'harris@g.hmc.edu', 'rose.thompson10@okstate.edu']
test_runner.send_email(sender_email=sender_email, receiver_emails=receiver_emails)

View File

@ -8,6 +8,7 @@
## Purpose: Parses the performance counters from a modelsim trace. ## Purpose: Parses the performance counters from a modelsim trace.
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -12,6 +12,7 @@
## and count how many tests are in each ## and count how many tests are in each
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -11,6 +11,7 @@
## and generate a list of tests and signature addresses for tests.vh ## and generate a list of tests and signature addresses for tests.vh
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -11,6 +11,7 @@
## verilator should do this, but it also reports partially used signals ## verilator should do this, but it also reports partially used signals
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -10,6 +10,7 @@
## Purpose: Open source tool chain installation script ## Purpose: Open source tool chain installation script
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##
@ -68,9 +69,6 @@ fi
cd $RISCV cd $RISCV
git clone https://github.com/riscv/riscv-gnu-toolchain git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain cd riscv-gnu-toolchain
# Temporarily use the following commands until gcc-13 is part of riscv-gnu-toolchain (issue #1249)
#git clone https://github.com/gcc-mirror/gcc -b releases/gcc-13 gcc-13
#./configure --prefix=/opt/riscv --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;" --with-gcc-src=`pwd`/gcc-13
./configure --prefix=${RISCV} --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;" ./configure --prefix=${RISCV} --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
make -j ${NUM_THREADS} make -j ${NUM_THREADS}
@ -110,14 +108,15 @@ cd riscv-isa-sim/build
make -j ${NUM_THREADS} make -j ${NUM_THREADS}
make install make install
cd ../arch_test_target/spike/device cd ../arch_test_target/spike/device
sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include # dh 2/5/24: these should be obsolete
sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include #sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include
#sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include
# Wally needs Verilator 5.021 or later. # Wally needs Verilator 5.021 or later.
# Verilator needs to be built from scratch to get the latest version # Verilator needs to be built from scratch to get the latest version
# apt-get install verilator installs version 4.028 as of 6/8/23 # apt-get install verilator installs version 4.028 as of 6/8/23
sudo apt-get install -y perl g++ ccache help2man libgoogle-perftools-dev numactl perl-doc zlib1g sudo apt-get install -y perl g++ ccache help2man libgoogle-perftools-dev numactl perl-doc zlib1g
sudo apt-get install -y libfl2 libfl-dev # Ubuntu only (ignore if gives error) sudo apt-get install -y perl g++ ccache help2man libgoogle-perftools-dev numactl perl-doc zlib1g
cd $RISCV cd $RISCV
git clone https://github.com/verilator/verilator # Only first time git clone https://github.com/verilator/verilator # Only first time
# unsetenv VERILATOR_ROOT # For csh; ignore error if on bash # unsetenv VERILATOR_ROOT # For csh; ignore error if on bash
@ -172,6 +171,8 @@ sudo make install
cd $RISCV cd $RISCV
opam init -y --disable-sandboxing opam init -y --disable-sandboxing
opam update
opam upgrade
opam switch create 5.1.0 opam switch create 5.1.0
opam install sail -y opam install sail -y

28
bin/wrapper_nightly_runs.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/bash
date
# Variables
LOG=$HOME/nightly_runs/logs/from_wrapper.log # you can store your log file where you would like
PYTHON_SCRIPT=$HOME/nightly_runs/cvw/bin/ # cvw can be anywhere you would like it. Make sure to point your variable there
SETUP_SCRIPT=$HOME/nightly_runs/cvw/ # cvw can be anywhere you would like it. Make sure to point your variable there
date > $LOG 2>&1
echo "Current directory"
pwd
cd $SETUP_SCRIPT
echo "Current directory"
pwd
echo "Sourcing setup_host"
source ./setup_host.sh >> $LOG 2>&1
echo "Sourcing setup_tools"
cd $PYTHON_SCRIPT
pwd
echo "Running python file"
python nightly_build.py >> $LOG 2>&1

View File

@ -1,180 +0,0 @@
//////////////////////////////////////////
// config.vh
//
// Written: David_Harris@hmc.edu 4 January 2021
// Modified:
//
// Purpose: Specify which features are configured
// Macros to determine which modes are supported based on MISA
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
// include shared configuration
`include "BranchPredictorType.vh"
// RV32 or RV64: XLEN = 32 or 64
localparam XLEN = 32'd64;
// IEEE 754 compliance
localparam IEEE754 = 0;
localparam MISA = (32'h0014112D);
localparam ZICSR_SUPPORTED = 1;
localparam ZIFENCEI_SUPPORTED = 1;
localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1;
localparam COUNTERS = 12'd32;
localparam ZFH_SUPPORTED = 1;
localparam ZFA_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 1;
localparam ZICBOZ_SUPPORTED = 1;
localparam ZICBOP_SUPPORTED = 1;
localparam ZICCLSM_SUPPORTED = 1;
localparam ZICOND_SUPPORTED = 1;
localparam SVPBMT_SUPPORTED = 1;
localparam SVNAPOT_SUPPORTED = 1;
localparam SVINVAL_SUPPORTED = 1;
// LSU microarchitectural Features
localparam BUS_SUPPORTED = 1;
localparam DCACHE_SUPPORTED = 1;
localparam ICACHE_SUPPORTED = 1;
localparam VIRTMEM_SUPPORTED = 1;
localparam VECTORED_INTERRUPTS_SUPPORTED = 1;
localparam BIGENDIAN_SUPPORTED = 1;
// TLB configuration. Entries should be a power of 2
localparam ITLB_ENTRIES = 32'd32;
localparam DTLB_ENTRIES = 32'd32;
// Cache configuration. Sizes should be a power of two
// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines
localparam DCACHE_NUMWAYS = 32'd4;
localparam DCACHE_WAYSIZEINBYTES = 32'd4096;
localparam DCACHE_LINELENINBITS = 32'd512;
localparam ICACHE_NUMWAYS = 32'd4;
localparam ICACHE_WAYSIZEINBYTES = 32'd4096;
localparam ICACHE_LINELENINBITS = 32'd512;
localparam CACHE_SRAMLEN = 32'd128;
// Integer Divider Configuration
// IDIV_BITSPERCYCLE must be 1, 2, or 4
localparam IDIV_BITSPERCYCLE = 32'd4;
localparam IDIV_ON_FPU = 1;
// Legal number of PMP entries are 0, 16, or 64
localparam PMP_ENTRIES = 32'd16;
// Address space
localparam logic [63:0] RESET_VECTOR = 64'h0000000000001000;
// WFI Timeout Wait
localparam WFI_TIMEOUT_BIT = 32'd16;
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
localparam DTIM_SUPPORTED = 1'b0;
localparam logic [63:0] DTIM_BASE = 64'h80000000;
localparam logic [63:0] DTIM_RANGE = 64'h00001FFF;
localparam IROM_SUPPORTED = 1'b0;
localparam logic [63:0] IROM_BASE = 64'h80000000;
localparam logic [63:0] IROM_RANGE = 64'h00001FFF;
localparam BOOTROM_SUPPORTED = 1'b1;
localparam logic [63:0] BOOTROM_BASE = 64'h00001000 ;
localparam logic [63:0] BOOTROM_RANGE = 64'h00000FFF;
localparam BOOTROM_PRELOAD = 1'b1;
localparam UNCORE_RAM_SUPPORTED = 1'b1;
localparam logic [63:0] UNCORE_RAM_BASE = 64'h80000000;
localparam logic [63:0] UNCORE_RAM_RANGE = 64'h0FFFFFFF;
localparam UNCORE_RAM_PRELOAD = 1'b1;
localparam EXT_MEM_SUPPORTED = 1'b0;
localparam logic [63:0] EXT_MEM_BASE = 64'h80000000;
localparam logic [63:0] EXT_MEM_RANGE = 64'h07FFFFFF;
localparam CLINT_SUPPORTED = 1'b1;
localparam logic [63:0] CLINT_BASE = 64'h02000000;
localparam logic [63:0] CLINT_RANGE = 64'h0000FFFF;
localparam GPIO_SUPPORTED = 1'b1;
localparam logic [63:0] GPIO_BASE = 64'h10060000;
localparam logic [63:0] GPIO_RANGE = 64'h000000FF;
localparam UART_SUPPORTED = 1'b1;
localparam logic [63:0] UART_BASE = 64'h10000000;
localparam logic [63:0] UART_RANGE = 64'h00000007;
localparam PLIC_SUPPORTED = 1'b1;
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
localparam SDC_SUPPORTED = 1'b0;
localparam logic [63:0] SDC_BASE = 64'h00013000;
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
localparam SPI_SUPPORTED = 1'b1;
localparam logic [63:0] SPI_BASE = 64'h10040000;
localparam logic [63:0] SPI_RANGE = 64'h00000FFF;
// Bus Interface width
localparam AHBW = 32'd64;
// Test modes
// Tie GPIO outputs back to inputs
localparam GPIO_LOOPBACK_TEST = 0;
localparam SPI_LOOPBACK_TEST = 0;
// Hardware configuration
localparam UART_PRESCALE = 32'd0;
// Interrupt configuration
localparam PLIC_NUM_SRC = 32'd53;
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
localparam PLIC_UART_ID = 32'd10;
localparam PLIC_GPIO_ID = 32'd3;
localparam PLIC_SPI_ID = 32'd6;
localparam PLIC_SDC_ID = 32'd20;
localparam BPRED_SUPPORTED = 1;
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10;
localparam RAS_SIZE = 32'd16;
localparam SVADU_SUPPORTED = 1;
localparam ZMMUL_SUPPORTED = 0;
// FPU division architecture
localparam RADIX = 32'h4;
localparam DIVCOPIES = 32'h4;
// bit manipulation
localparam ZBA_SUPPORTED = 1;
localparam ZBB_SUPPORTED = 1;
localparam ZBC_SUPPORTED = 1;
localparam ZBS_SUPPORTED = 1;
// New compressed instructions
localparam ZCB_SUPPORTED = 1;
localparam ZCA_SUPPORTED = 0;
localparam ZCF_SUPPORTED = 0;
localparam ZCD_SUPPORTED = 0;
// Memory synthesis configuration
localparam USE_SRAM = 0;
`include "config-shared.vh"

1077
config/derivlist.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -132,6 +132,10 @@ localparam AHBW = 32'd32;
// Test modes // Test modes
// AHB
localparam RAM_LATENCY = 32'b0;
localparam BURST_EN = 1;
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
localparam GPIO_LOOPBACK_TEST = 1; localparam GPIO_LOOPBACK_TEST = 1;
localparam SPI_LOOPBACK_TEST = 0; localparam SPI_LOOPBACK_TEST = 0;
@ -154,6 +158,7 @@ localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6; localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10; localparam BTB_SIZE = 32'd10;
localparam RAS_SIZE = 32'd16; localparam RAS_SIZE = 32'd16;
localparam INSTR_CLASS_PRED = 0;
localparam SVADU_SUPPORTED = 0; localparam SVADU_SUPPORTED = 0;
localparam ZMMUL_SUPPORTED = 0; localparam ZMMUL_SUPPORTED = 0;

View File

@ -133,6 +133,10 @@ localparam AHBW = 32'd32;
// Test modes // Test modes
// AHB
localparam RAM_LATENCY = 32'b0;
localparam BURST_EN = 1;
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
localparam GPIO_LOOPBACK_TEST = 1; localparam GPIO_LOOPBACK_TEST = 1;
localparam SPI_LOOPBACK_TEST = 1; localparam SPI_LOOPBACK_TEST = 1;
@ -150,22 +154,12 @@ localparam PLIC_SPI_ID = 32'd6;
localparam PLIC_SDC_ID = 32'd9; localparam PLIC_SDC_ID = 32'd9;
localparam BPRED_SUPPORTED = 1; localparam BPRED_SUPPORTED = 1;
// this is an annoying hack for the branch predictor parameterization override.
`ifdef BPRED_OVERRIDE
localparam BPRED_TYPE = `BPRED_TYPE;
localparam BPRED_SIZE = `BPRED_SIZE;
`else
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd10; localparam BPRED_SIZE = 32'd10;
`endif
localparam BPRED_NUM_LHR = 32'd6; localparam BPRED_NUM_LHR = 32'd6;
`ifdef BTB_OVERRIDE
localparam BTB_SIZE = `BTB_SIZE;
localparam RAS_SIZE = `RAS_SIZE;
`else
localparam BTB_SIZE = 32'd10; localparam BTB_SIZE = 32'd10;
localparam RAS_SIZE = 32'd16; localparam RAS_SIZE = 32'd16;
`endif localparam INSTR_CLASS_PRED = 1;
localparam SVADU_SUPPORTED = 1; localparam SVADU_SUPPORTED = 1;
localparam ZMMUL_SUPPORTED = 0; localparam ZMMUL_SUPPORTED = 0;

View File

@ -132,6 +132,10 @@ localparam AHBW = 32'd32;
// Test modes // Test modes
// AHB
localparam RAM_LATENCY = 32'b0;
localparam BURST_EN = 1;
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
localparam GPIO_LOOPBACK_TEST = 1; localparam GPIO_LOOPBACK_TEST = 1;
localparam SPI_LOOPBACK_TEST = 1; localparam SPI_LOOPBACK_TEST = 1;
@ -155,6 +159,7 @@ localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6; localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10; localparam BTB_SIZE = 32'd10;
localparam RAS_SIZE = 32'd16; localparam RAS_SIZE = 32'd16;
localparam INSTR_CLASS_PRED = 0;
localparam SVADU_SUPPORTED = 0; localparam SVADU_SUPPORTED = 0;
localparam ZMMUL_SUPPORTED = 0; localparam ZMMUL_SUPPORTED = 0;

View File

@ -131,6 +131,10 @@ localparam AHBW = 32'd32;
// Test modes // Test modes
// AHB
localparam RAM_LATENCY = 32'b0;
localparam BURST_EN = 1;
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
localparam GPIO_LOOPBACK_TEST = 1; localparam GPIO_LOOPBACK_TEST = 1;
localparam SPI_LOOPBACK_TEST = 1; localparam SPI_LOOPBACK_TEST = 1;
@ -153,6 +157,7 @@ localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6; localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10; localparam BTB_SIZE = 32'd10;
localparam RAS_SIZE = 32'd16; localparam RAS_SIZE = 32'd16;
localparam INSTR_CLASS_PRED = 0;
localparam SVADU_SUPPORTED = 0; localparam SVADU_SUPPORTED = 0;
localparam ZMMUL_SUPPORTED = 0; localparam ZMMUL_SUPPORTED = 0;

View File

@ -1,182 +0,0 @@
//////////////////////////////////////////
// config.vh
//
// Written: David_Harris@hmc.edu 4 January 2021
// Modified:
//
// Purpose: Specify which features are configured
// Macros to determine which modes are supported based on MISA
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "BranchPredictorType.vh"
// RV32 or RV64: XLEN = 32 or 64
localparam XLEN = 32'd64;
// IEEE 754 compliance
localparam IEEE754 = 1;
// MISA RISC-V configuration per specification
localparam MISA = (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 16 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0 );
localparam ZICSR_SUPPORTED = 1;
localparam ZIFENCEI_SUPPORTED = 1;
localparam COUNTERS = 12'd32;
localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1;
localparam ZFH_SUPPORTED = 1;
localparam ZFA_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 0;
localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0;
localparam ZICCLSM_SUPPORTED = 0;
localparam ZICOND_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0;
localparam SVNAPOT_SUPPORTED = 0;
localparam SVINVAL_SUPPORTED = 1;
// LSU microarchitectural Features
localparam BUS_SUPPORTED = 1;
localparam DCACHE_SUPPORTED = 1;
localparam ICACHE_SUPPORTED = 1;
localparam VIRTMEM_SUPPORTED = 1;
localparam VECTORED_INTERRUPTS_SUPPORTED = 1 ;
localparam BIGENDIAN_SUPPORTED = 1;
// TLB configuration. Entries should be a power of 2
localparam ITLB_ENTRIES = 32'd32;
localparam DTLB_ENTRIES = 32'd32;
// Cache configuration. Sizes should be a power of two
// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines
localparam DCACHE_NUMWAYS = 32'd4;
localparam DCACHE_WAYSIZEINBYTES = 32'd4096;
localparam DCACHE_LINELENINBITS = 32'd512;
localparam ICACHE_NUMWAYS = 32'd4;
localparam ICACHE_WAYSIZEINBYTES = 32'd4096;
localparam ICACHE_LINELENINBITS = 32'd512;
localparam CACHE_SRAMLEN = 32'd128;
// Integer Divider Configuration
// IDIV_BITSPERCYCLE must be 1, 2, or 4
localparam IDIV_BITSPERCYCLE = 32'd4;
localparam IDIV_ON_FPU = 1;
// Legal number of PMP entries are 0, 16, or 64
localparam PMP_ENTRIES = 32'd16;
// Address space
localparam logic [63:0] RESET_VECTOR = 64'h0000000080000000;
// Bus Interface width
localparam AHBW = 32'd64;
// WFI Timeout Wait
localparam WFI_TIMEOUT_BIT = 32'd16;
// Peripheral Physiccal Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
localparam DTIM_SUPPORTED = 1'b0;
localparam logic [63:0] DTIM_BASE = 64'h80000000;
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;
localparam IROM_SUPPORTED = 1'b0;
localparam logic [63:0] IROM_BASE = 64'h80000000;
localparam logic [63:0] IROM_RANGE = 64'h007FFFFF;
localparam BOOTROM_SUPPORTED = 1'b1;
localparam logic [63:0] BOOTROM_BASE = 64'h00001000; // spec had been 0x1000 to 0x2FFF, but dh truncated to 0x1000 to 0x1FFF because upper half seems to be all zeros and this is easier for decoder
localparam logic [63:0] BOOTROM_RANGE = 64'h00000FFF;
localparam BOOTROM_PRELOAD = 1'b0;
localparam UNCORE_RAM_SUPPORTED = 1'b1;
localparam logic [63:0] UNCORE_RAM_BASE = 64'h80000000;
localparam logic [63:0] UNCORE_RAM_RANGE = 64'h7FFFFFFF;
localparam UNCORE_RAM_PRELOAD = 1'b0;
localparam EXT_MEM_SUPPORTED = 1'b0;
localparam logic [63:0] EXT_MEM_BASE = 64'h80000000;
localparam logic [63:0] EXT_MEM_RANGE = 64'h07FFFFFF;
localparam CLINT_SUPPORTED = 1'b1;
localparam logic [63:0] CLINT_BASE = 64'h02000000;
localparam logic [63:0] CLINT_RANGE = 64'h0000FFFF;
localparam GPIO_SUPPORTED = 1'b1;
localparam logic [63:0] GPIO_BASE = 64'h10060000;
localparam logic [63:0] GPIO_RANGE = 64'h000000FF;
localparam UART_SUPPORTED = 1'b1;
localparam logic [63:0] UART_BASE = 64'h10000000;
localparam logic [63:0] UART_RANGE = 64'h00000007;
localparam PLIC_SUPPORTED = 1'b1;
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
localparam SDC_SUPPORTED = 1'b0;
localparam logic [63:0] SDC_BASE = 64'h00013000;
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
localparam SPI_SUPPORTED = 1'b1;
localparam logic [63:0] SPI_BASE = 64'h10040000;
localparam logic [63:0] SPI_RANGE = 64'h00000FFF;
// Test modes
// Tie GPIO outputs back to inputs
localparam GPIO_LOOPBACK_TEST = 1;
localparam SPI_LOOPBACK_TEST = 1;
// Hardware configuration
localparam UART_PRESCALE = 32'd1;
// Interrupt configuration
localparam PLIC_NUM_SRC = 32'd10;
// comment out the following if >=32 sources
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
localparam PLIC_GPIO_ID = 32'd3;
localparam PLIC_UART_ID = 32'd10;
localparam PLIC_SPI_ID = 32'd6;
localparam PLIC_SDC_ID = 32'd9;
localparam BPRED_SUPPORTED = 1;
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10;
localparam RAS_SIZE = 32'd16;
localparam SVADU_SUPPORTED = 0;
localparam ZMMUL_SUPPORTED = 0;
// FPU division architecture
localparam RADIX = 32'h4;
localparam DIVCOPIES = 32'h4;
// bit manipulation
localparam ZBA_SUPPORTED = 0;
localparam ZBB_SUPPORTED = 0;
localparam ZBC_SUPPORTED = 0;
localparam ZBS_SUPPORTED = 0;
// New compressed instructions
localparam ZCB_SUPPORTED = 0;
localparam ZCA_SUPPORTED = 0;
localparam ZCF_SUPPORTED = 0;
localparam ZCD_SUPPORTED = 0;
// Memory synthesis configuration
localparam USE_SRAM = 0;
`include "config-shared.vh"

View File

@ -41,7 +41,7 @@ localparam COUNTERS = 12'd32;
localparam ZICNTR_SUPPORTED = 1; localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1; localparam ZIHPM_SUPPORTED = 1;
localparam ZFH_SUPPORTED = 1; localparam ZFH_SUPPORTED = 1;
localparam ZFA_SUPPORTED = 0; localparam ZFA_SUPPORTED = 1;
localparam SSTC_SUPPORTED = 1; localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 1; localparam ZICBOM_SUPPORTED = 1;
localparam ZICBOZ_SUPPORTED = 1; localparam ZICBOZ_SUPPORTED = 1;
@ -134,6 +134,10 @@ localparam logic [63:0] SPI_RANGE = 64'h00000FFF;
// Test modes // Test modes
// AHB
localparam RAM_LATENCY = 32'b0;
localparam BURST_EN = 1;
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
localparam GPIO_LOOPBACK_TEST = 1; localparam GPIO_LOOPBACK_TEST = 1;
localparam SPI_LOOPBACK_TEST = 1; localparam SPI_LOOPBACK_TEST = 1;
@ -156,6 +160,7 @@ localparam BPRED_NUM_LHR = 32'd6;
localparam BPRED_SIZE = 32'd10; localparam BPRED_SIZE = 32'd10;
localparam BTB_SIZE = 32'd10; localparam BTB_SIZE = 32'd10;
localparam RAS_SIZE = 32'd16; localparam RAS_SIZE = 32'd16;
localparam INSTR_CLASS_PRED = 1;
localparam SVADU_SUPPORTED = 1; localparam SVADU_SUPPORTED = 1;
localparam ZMMUL_SUPPORTED = 0; localparam ZMMUL_SUPPORTED = 0;
@ -180,3 +185,4 @@ localparam ZCD_SUPPORTED = 0;
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "config-shared.vh" `include "config-shared.vh"

View File

@ -134,6 +134,10 @@ localparam logic [63:0] SPI_RANGE = 64'h00000FFF;
// Test modes // Test modes
// AHB
localparam RAM_LATENCY = 32'b0;
localparam BURST_EN = 1;
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
localparam GPIO_LOOPBACK_TEST = 1; localparam GPIO_LOOPBACK_TEST = 1;
localparam SPI_LOOPBACK_TEST = 1; localparam SPI_LOOPBACK_TEST = 1;
@ -156,6 +160,7 @@ localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6; localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10; localparam BTB_SIZE = 32'd10;
localparam RAS_SIZE = 32'd16; localparam RAS_SIZE = 32'd16;
localparam INSTR_CLASS_PRED = 0;
localparam SVADU_SUPPORTED = 0; localparam SVADU_SUPPORTED = 0;
localparam ZMMUL_SUPPORTED = 0; localparam ZMMUL_SUPPORTED = 0;

View File

@ -94,7 +94,7 @@ localparam LOGR = $clog2(RADIX); // r = log(R
localparam RK = LOGR*DIVCOPIES; // r*k bits per cycle generated localparam RK = LOGR*DIVCOPIES; // r*k bits per cycle generated
// intermediate division parameters not directly used in fdivsqrt hardware // intermediate division parameters not directly used in fdivsqrt hardware
localparam FPDIVMINb = NF + 3; // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit to allow sqrt being shifted right localparam FPDIVMINb = NF + 2; // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit to allow sqrt being shifted right
//localparam FPDIVMINb = NF + 2 + (RADIX == 2); // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit for preshifting radix2 square root right, if radix4 doesn't use a right shift. This version saves one cycle on double-precision with R=4,k=4. However, it doesn't work yet because C is too short, so k is incorrectly calculated as a 1 in the lsb after the last step. //localparam FPDIVMINb = NF + 2 + (RADIX == 2); // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit for preshifting radix2 square root right, if radix4 doesn't use a right shift. This version saves one cycle on double-precision with R=4,k=4. However, it doesn't work yet because C is too short, so k is incorrectly calculated as a 1 in the lsb after the last step.
localparam DIVMINb = ((FPDIVMINb<XLEN) & IDIV_ON_FPU) ? XLEN : FPDIVMINb; // minimum fractional bits b = max(XLEN, FPDIVMINb) localparam DIVMINb = ((FPDIVMINb<XLEN) & IDIV_ON_FPU) ? XLEN : FPDIVMINb; // minimum fractional bits b = max(XLEN, FPDIVMINb)
localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r integer + b fractional localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r integer + b fractional
@ -103,15 +103,15 @@ localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r intege
localparam FPDUR = (RESBITS-1)/RK + 1 ; // ceiling((r+b)/rk) localparam FPDUR = (RESBITS-1)/RK + 1 ; // ceiling((r+b)/rk)
localparam DIVb = FPDUR*RK - LOGR; // divsqrt fractional bits, so total number of bits is a multiple of rk after r integer bits localparam DIVb = FPDUR*RK - LOGR; // divsqrt fractional bits, so total number of bits is a multiple of rk after r integer bits
localparam DURLEN = $clog2(FPDUR); // enough bits to count the duration localparam DURLEN = $clog2(FPDUR); // enough bits to count the duration
localparam DIVBLEN = $clog2(DIVb); // enough bits to count number of fractional bits localparam DIVBLEN = $clog2(DIVb+1); // enough bits to count number of fractional bits + 1 integer bit
// largest length in IEU/FPU // largest length in IEU/FPU
localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); // max(XLEN, NF) localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); // max(XLEN, NF)
localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($unsigned(FLEN))); localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($unsigned(FLEN)));
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1)); localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6))); localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6))); // max(CVTLEN+NF+1, DIVb + 1 + NF + 1, 3*NF+6)
localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ)); localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ));
localparam CORRSHIFTSZ = NORMSHIFTSZ-2; localparam CORRSHIFTSZ = (NORMSHIFTSZ-2 > (DIVMINb + 1 + NF)) ? NORMSHIFTSZ-2 : (DIVMINb+1+NF); // max(NORMSHIFTSZ-2, DIVMINb + 1 + NF)
// Disable spurious Verilator warnings // Disable spurious Verilator warnings

View File

@ -8,6 +8,8 @@ localparam cvw_t P = '{
IEEE754 : IEEE754, IEEE754 : IEEE754,
MISA : MISA, MISA : MISA,
AHBW : AHBW, AHBW : AHBW,
RAM_LATENCY : RAM_LATENCY,
BURST_EN : BURST_EN,
ZICSR_SUPPORTED : ZICSR_SUPPORTED, ZICSR_SUPPORTED : ZICSR_SUPPORTED,
ZIFENCEI_SUPPORTED : ZIFENCEI_SUPPORTED, ZIFENCEI_SUPPORTED : ZIFENCEI_SUPPORTED,
COUNTERS : COUNTERS, COUNTERS : COUNTERS,
@ -100,6 +102,7 @@ localparam cvw_t P = '{
BPRED_NUM_LHR : BPRED_NUM_LHR, BPRED_NUM_LHR : BPRED_NUM_LHR,
BTB_SIZE : BTB_SIZE, BTB_SIZE : BTB_SIZE,
RAS_SIZE : RAS_SIZE, RAS_SIZE : RAS_SIZE,
INSTR_CLASS_PRED : INSTR_CLASS_PRED,
RADIX : RADIX, RADIX : RADIX,
DIVCOPIES : DIVCOPIES, DIVCOPIES : DIVCOPIES,
ZBA_SUPPORTED : ZBA_SUPPORTED, ZBA_SUPPORTED : ZBA_SUPPORTED,

View File

@ -7,6 +7,7 @@
## Purpose: Dockerfile for Wally docker container creation ## Purpose: Dockerfile for Wally docker container creation
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -48,29 +48,14 @@ IP_Arty: $(dst)/xlnx_proc_sys_reset.log \
PreProcessFiles: PreProcessFiles:
$(MAKE) -C ../../sim deriv
rm -rf ../src/CopiedFiles_do_not_add_to_repo/ rm -rf ../src/CopiedFiles_do_not_add_to_repo/
cp -r ../../src/ ../src/CopiedFiles_do_not_add_to_repo/ cp -r ../../src/ ../src/CopiedFiles_do_not_add_to_repo/
mkdir ../src/CopiedFiles_do_not_add_to_repo/config/ mkdir ../src/CopiedFiles_do_not_add_to_repo/config/
cp ../../config/rv64gc/config.vh ../src/CopiedFiles_do_not_add_to_repo/config/ cp ../../config/deriv/fpga/config.vh ../src/CopiedFiles_do_not_add_to_repo/config/
./insert_debug_comment.sh ./insert_debug_comment.sh
# modify config *** RT: eventually setup for variably defined sized memory # modify config *** RT: eventually setup for variably defined sized memory
sed -i "s/ZICCLSM_SUPPORTED.*/ZICCLSM_SUPPORTED = 1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh #sed -i "s/EXT_MEM_RANGE.*/EXT_MEM_RANGE = 64'h0FFFFFFF;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/RESET_VECTOR.*/RESET_VECTOR = 64'h0000000000001000;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/BOOTROM_PRELOAD.*/BOOTROM_PRELOAD = 1'b1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/UNCORE_RAM_BASE.*/UNCORE_RAM_BASE = 64'h00002000;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/UNCORE_RAM_RANGE.*/UNCORE_RAM_RANGE = 64'h00000FFF;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/UNCORE_RAM_PRELOAD.*/UNCORE_RAM_PRELOAD = 1'b1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/EXT_MEM_SUPPORTED.*/EXT_MEM_SUPPORTED = 1'b1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/EXT_MEM_RANGE.*/EXT_MEM_RANGE = 64'h0FFFFFFF;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/SDC_SUPPORTED.*/SDC_SUPPORTED = 1'b1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/SPI_SUPPORTED.*/SPI_SUPPORTED = 1'b0;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh # *** RT: Add SPI when ready
sed -i "s/GPIO_LOOPBACK_TEST.*/GPIO_LOOPBACK_TEST = 0;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/SPI_LOOPBACK_TEST.*/SPI_LOOPBACK_TEST = 0;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/UART_PRESCALE.*/UART_PRESCALE = 32'd0;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/PLIC_NUM_SRC = .*/PLIC_NUM_SRC = 32'd53;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/PLIC_SDC_ID.*/PLIC_SDC_ID = 32'd20;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/BPRED_SIZE.*/BPRED_SIZE = 32'd12;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
sed -i "s/$\$readmemh.*/$\$readmemh(\"..\/..\/..\/fpga\/src\/boot.mem\", ROM, 0);/g" ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv
# This line allows the Bootloader to be loaded in a Block RAM on the FPGA # This line allows the Bootloader to be loaded in a Block RAM on the FPGA
sed -i "s/logic \[DATA_WIDTH-1:0\].*ROM.*/(\* rom_style=\"block\" \*) &/g" ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv sed -i "s/logic \[DATA_WIDTH-1:0\].*ROM.*/(\* rom_style=\"block\" \*) &/g" ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv

View File

@ -7,6 +7,7 @@
## Modified: 20 January 2023 ## Modified: 20 January 2023
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -7,6 +7,7 @@
## Modified: 16 August 2023 ## Modified: 16 August 2023
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -7,6 +7,7 @@
## Modified: 16 August 2023 ## Modified: 16 August 2023
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -7,6 +7,7 @@
## Modified: 16 August 2023 ## Modified: 16 August 2023
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -21,7 +21,7 @@ ROOT := ..
LIBRARY_DIRS := LIBRARY_DIRS :=
LIBRARY_FILES := LIBRARY_FILES :=
MARCH :=-march=rv64imfdc MARCH :=-march=rv64imfdc_zifencei
MABI :=-mabi=lp64d MABI :=-mabi=lp64d
LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles
LINKER :=linker.x LINKER :=linker.x

View File

@ -94,5 +94,5 @@ end_of_bios:
.globl _dtb .globl _dtb
.align 4, 0 .align 4, 0
_dtb: _dtb:
.incbin "wally-vcu118.dtb" #.incbin "wally-vcu118.dtb"

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// SDC.sv // SDC.sv
// //
// Written: Ross Thompson September 25, 2021 // Written: Rose Thompson September 25, 2021
// Modified: // Modified:
// //
// Purpose: driver for sdc reader. // Purpose: driver for sdc reader.

View File

@ -1,5 +1,6 @@
########################################### ###########################################
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -72,6 +72,13 @@ if [ ! -e "$SDCARD" ] ; then
exit 1 exit 1
fi fi
# Prefix partition with "p" for non-SCSI disks (mmcblk, nvme)
if [[ $SDCARD == "/dev/sd"* ]]; then
$PART_PREFIX=""
else
$PART_PREFIX="p"
fi
# If no images directory, images have not been built # If no images directory, images have not been built
if [ ! -d $IMAGES ] ; then if [ ! -d $IMAGES ] ; then
echo -e "$ERRORTEXT Buildroot images directory does not exist" echo -e "$ERRORTEXT Buildroot images directory does not exist"
@ -155,18 +162,18 @@ if [[ $REPLY =~ ^[Yy]$ ]] ; then
DD_FLAGS="bs=4k iflag=fullblock oflag=direct conv=fsync status=progress" DD_FLAGS="bs=4k iflag=fullblock oflag=direct conv=fsync status=progress"
echo -e "$NAME Copying device tree" echo -e "$NAME Copying device tree"
sudo dd if=$DEVICE_TREE of="$SDCARD"1 $DD_FLAGS sudo dd if=$DEVICE_TREE of="$SDCARD""$PART_PREFIX"1 $DD_FLAGS
echo -e "$NAME Copying OpenSBI" echo -e "$NAME Copying OpenSBI"
sudo dd if=$FW_JUMP of="$SDCARD"2 $DD_FLAGS sudo dd if=$FW_JUMP of="$SDCARD""$PART_PREFIX"2 $DD_FLAGS
echo -e "$NAME Copying Kernel" echo -e "$NAME Copying Kernel"
sudo dd if=$LINUX_KERNEL of="$SDCARD"3 $DD_FLAGS sudo dd if=$LINUX_KERNEL of="$SDCARD""$PART_PREFIX"3 $DD_FLAGS
sudo mkfs.ext4 "$SDCARD"4 sudo mkfs.ext4 "$SDCARD""$PART_PREFIX"4
sudo mkdir /mnt/$MNT_DIR sudo mkdir /mnt/$MNT_DIR
sudo mount -v "$SDCARD"4 /mnt/$MNT_DIR sudo mount -v "$SDCARD""$PART_PREFIX"4 /mnt/$MNT_DIR
sudo umount -v /mnt/$MNT_DIR sudo umount -v /mnt/$MNT_DIR

View File

@ -1,5 +1,5 @@
all: riscoftests memfiles coveragetests all: riscoftests memfiles coveragetests deriv benchmarks
# *** Build old tests/imperas-riscv-tests for now; # *** Build old tests/imperas-riscv-tests for now;
# Delete this part when the privileged tests transition over to tests/wally-riscv-arch-test # Delete this part when the privileged tests transition over to tests/wally-riscv-arch-test
# DH: 2/27/22 temporarily commented out imperas-riscv-tests because license expired # DH: 2/27/22 temporarily commented out imperas-riscv-tests because license expired
@ -54,9 +54,19 @@ riscoftests:
wallyriscoftests: wallyriscoftests:
# Builds riscv-arch-test 64 and 32-bit versions and builds wally-riscv-arch-test 64 and 32-bit versions # Builds riscv-arch-test 64 and 32-bit versions and builds wally-riscv-arch-test 64 and 32-bit versions
make -C ../tests/riscof/ wally-riscv-arch-test make -C ../tests/riscof/ wally-riscv-arch-test
memfiles: memfiles:
make -f makefile-memfile wally-sim-files --jobs make -f makefile-memfile wally-sim-files --jobs
coveragetests: coveragetests:
make -C ../tests/coverage/ --jobs make -C ../tests/coverage/ --jobs
deriv:
derivgen.pl
benchmarks:
$(MAKE) -C ../benchmarks/embench build
$(MAKE) -C ../benchmarks/embench size
$(MAKE) -C ../benchmarks/embench modelsim_build_memfile
$(MAKE) -C ../benchmarks/coremark

View File

@ -1,12 +1,12 @@
../logs/rv32gc_gshare6.log gshare 6 ../logs/bpred_GSHARE_6_16_10_0_rv32gc_embench.log gshare 6
../logs/rv32gc_gshare8.log gshare 8 ../logs/bpred_GSHARE_8_16_10_0_rv32gc_embench.log gshare 8
../logs/rv32gc_gshare10.log gshare 10 ../logs/bpred_GSHARE_10_16_10_0_rv32gc_embench.log gshare 10
../logs/rv32gc_gshare12.log gshare 12 ../logs/bpred_GSHARE_12_16_10_0_rv32gc_embench.log gshare 12
../logs/rv32gc_gshare14.log gshare 14 ../logs/bpred_GSHARE_14_16_10_0_rv32gc_embench.log gshare 14
../logs/rv32gc_gshare16.log gshare 16 ../logs/bpred_GSHARE_16_16_10_0_rv32gc_embench.log gshare 16
../logs/rv32gc_twobit6.log twobit 6 ../logs/bpred_TWOBIT_6_16_10_0_rv32gc_embench.log twobit 6
../logs/rv32gc_twobit8.log twobit 8 ../logs/bpred_TWOBIT_8_16_10_0_rv32gc_embench.log twobit 8
../logs/rv32gc_twobit10.log twobit 10 ../logs/bpred_TWOBIT_10_16_10_0_rv32gc_embench.log twobit 10
../logs/rv32gc_twobit12.log twobit 12 ../logs/bpred_TWOBIT_12_16_10_0_rv32gc_embench.log twobit 12
../logs/rv32gc_twobit14.log twobit 14 ../logs/bpred_TWOBIT_14_16_10_0_rv32gc_embench.log twobit 14
../logs/rv32gc_twobit16.log twobit 16 ../logs/bpred_TWOBIT_16_16_10_0_rv32gc_embench.log twobit 16

View File

@ -1,6 +1,6 @@
../logs/rv32gc_BTB6.log btb 6 ../logs/bpred_GSHARE_16_16_6_0_rv32gc_embench.log btb 6
../logs/rv32gc_BTB8.log btb 8 ../logs/bpred_GSHARE_16_16_8_0_rv32gc_embench.log btb 8
../logs/rv32gc_BTB10.log btb 10 ../logs/bpred_GSHARE_16_16_10_0_rv32gc_embench.log btb 10
../logs/rv32gc_BTB12.log btb 12 ../logs/bpred_GSHARE_16_16_12_0_rv32gc_embench.log btb 12
../logs/rv32gc_BTB14.log btb 14 ../logs/bpred_GSHARE_16_16_14_0_rv32gc_embench.log btb 14
../logs/rv32gc_BTB16.log btb 16 ../logs/bpred_GSHARE_16_16_16_0_rv32gc_embench.log btb 16

View File

@ -1,6 +1,6 @@
../logs/rv32gc_class6.log class 6 ../logs/bpred_GSHARE_16_16_6_1_rv32gc_embench.log btb 6
../logs/rv32gc_class8.log class 8 ../logs/bpred_GSHARE_16_16_8_1_rv32gc_embench.log btb 8
../logs/rv32gc_class10.log class 10 ../logs/bpred_GSHARE_16_16_10_1_rv32gc_embench.log btb 10
../logs/rv32gc_class12.log class 12 ../logs/bpred_GSHARE_16_16_12_1_rv32gc_embench.log btb 12
../logs/rv32gc_class14.log class 14 ../logs/bpred_GSHARE_16_16_14_1_rv32gc_embench.log btb 14
../logs/rv32gc_class16.log class 16 ../logs/bpred_GSHARE_16_16_16_1_rv32gc_embench.log btb 16

View File

@ -1,5 +1,5 @@
../logs/rv32gc_RAS3.log ras 3 ../logs/bpred_GSHARE_10_3_10_0_rv32gc_embench.log ras 3
../logs/rv32gc_RAS4.log ras 4 ../logs/bpred_GSHARE_10_4_10_0_rv32gc_embench.log ras 4
../logs/rv32gc_RAS6.log ras 6 ../logs/bpred_GSHARE_10_6_10_0_rv32gc_embench.log ras 6
../logs/rv32gc_RAS10.log ras 10 ../logs/bpred_GSHARE_10_10_10_0_rv32gc_embench.log ras 10
../logs/rv32gc_RAS16.log ras 16 ../logs/bpred_GSHARE_10_16_10_0_rv32gc_embench.log ras 16

View File

@ -7,6 +7,7 @@
#// For example, signals hardwired to 0 should not be checked for toggle coverage #// For example, signals hardwired to 0 should not be checked for toggle coverage
#// #//
#// A component of the CORE-V-WALLY configurable RISC-V project. #// A component of the CORE-V-WALLY configurable RISC-V project.
#// https://github.com/openhwgroup/cvw
#// #//
#// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University #// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
#// #//
@ -34,21 +35,39 @@ do GetLineNum.do
# DH 4/22/23: Exclude all LZAs # DH 4/22/23: Exclude all LZAs
coverage exclude -srcfile lzc.sv coverage exclude -srcfile lzc.sv
#################
# FPU Exclusions
#################
# DH 4/22/23: FDIVSQRT can't go directly from done to busy again # DH 4/22/23: FDIVSQRT can't go directly from done to busy again
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state DONE->BUSY coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state DONE->BUSY
# DH 4/22/23: The busy->idle transition only occurs if a FlushE occurs while the divider is busy. The flush is caused by a trap or return, # DH 4/22/23: The busy->idle transition only occurs if a FlushE occurs while the divider is busy. The flush is caused by a trap or return,
# which won't happen while the divider is busy. # which won't happen while the divider is busy.
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state BUSY->IDLE coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state BUSY->IDLE
# All Memory-stage stalls have resolved by time fdivsqrt finishes regular operation in this configuration, so can't test StallM
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -linerange [GetLineNum ../src/fpu/fdivsqrt/fdivsqrtfsm.sv "exclusion-tag: fdivsqrtfsm stallm"] -item b 1
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -linerange [GetLineNum ../src/fpu/fdivsqrt/fdivsqrtfsm.sv "exclusion-tag: fdivsqrtfsm stallm"] -item s 1
# Division by zero never sets sticky/guard/overflow/round to cause inexact or underflow result, but check out of paranoia
coverage exclude -scope /dut/core/fpu/fpu/postprocess/flags -linerange [GetLineNum ../src/fpu/postproc/flags.sv "assign FpInexact"] -item e 1 -fecexprrow 15
coverage exclude -scope /dut/core/fpu/fpu/postprocess/flags -linerange [GetLineNum ../src/fpu/postproc/flags.sv "assign Underflow"] -item e 1 -fecexprrow 22
# Convert int to fp will never underflow
coverage exclude -scope /dut/core/fpu/fpu/postprocess/cvtshiftcalc -linerange [GetLineNum ../src/fpu/postproc/cvtshiftcalc.sv "assign CvtResUf"] -item e 1 -fecexprrow 4
##################
# Cache Exclusions
##################
### Exclude D$ states and logic for the I$ instance ### Exclude D$ states and logic for the I$ instance
# This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too) # This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too)
# Also exclude the write line to ready transition for the I$ since we can't get a flush during this operation. # Also exclude the write line to ready transition for the I$ since we can't get a flush during this operation.
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -fstate CurrState STATE_FLUSH STATE_FLUSH_WRITEBACK STATE_FLUSH_WRITEBACK STATE_WRITEBACK coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -fstate CurrState STATE_FLUSH STATE_FLUSH_WRITEBACK STATE_FLUSH_WRITEBACK STATE_WRITEBACK
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -ftrans CurrState STATE_WRITE_LINE->STATE_READY coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -ftrans CurrState STATE_WRITE_LINE->STATE_READY STATE_FETCH->STATE_READY
# exclude unused transitions from case statement. Unfortunately the whole branch needs to be excluded I think. Expression coverage should still work. # exclude unused transitions from case statement. Unfortunately the whole branch needs to be excluded I think. Expression coverage should still work.
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache state-case"] -item b 1 coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache state-case"] -item b 1
# I$ does not flush
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FlushCache"] -item e 1 -fecexprrow 2
# exclude branch/condition coverage: LineDirty if statement # exclude branch/condition coverage: LineDirty if statement
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FETCHStatement"] -item bc 1 coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FETCHStatement"] -item bc 1
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FLUSHStatement"] -item bs 1
# exclude the unreachable logic # exclude the unreachable logic
set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache case"] set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache case"]
set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache case"] set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache case"]
@ -67,7 +86,9 @@ set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache flushdir
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $start-$end coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $start-$end
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusW"] coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusW"]
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrCauses"] -item e 1 -fecexprrow 4 10 coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrCauses"] -item e 1 -fecexprrow 4 10
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrTag"] -item e 1 -fecexprrow 8
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusRCauses"] -item e 1 -fecexprrow 1-2 12 coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusRCauses"] -item e 1 -fecexprrow 1-2 12
# cache.sv AdrSelMuxData and AdrSelMuxTag and CacheBusAdrMux, excluding unhit Flush branch # cache.sv AdrSelMuxData and AdrSelMuxTag and CacheBusAdrMux, excluding unhit Flush branch
coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMuxData -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1 coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMuxData -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMuxTag -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1 coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMuxTag -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
@ -79,7 +100,33 @@ for {set i 0} {$i < $numcacheways} {incr i} {
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: icache SelectedWiteWordEn"] -item e 1 -fecexprrow 4 6 coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: icache SelectedWiteWordEn"] -item e 1 -fecexprrow 4 6
# below: flushD can't go high during an icache write b/c of pipeline stall # below: flushD can't go high during an icache write b/c of pipeline stall
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache SetValidEN"] -item e 1 -fecexprrow 4 coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache SetValidEN"] -item e 1 -fecexprrow 4
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache ClearValidEN"] -item e 1 -fecexprrow 4
# No CMO to clear valid bits of I$
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "// exclusion-tag: icache ClearValidBits"]
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "// exclusion-tag: icache ClearValidWay"] -item e 1
# No dirty ways in read-only I$
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "// exclusion-tag: icache DirtyWay"] -item e 1
} }
# I$ buscachefsm does not perform atomics or write/writeback; HREADY is always 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicReadData"]
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicElse"] -item s 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicPhase"]
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicWait"] -item bs 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"] -item b 2
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"] -item s 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm WritebackWriteback"]
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm WritebackWriteback2"] -item bs 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY4"] -item bs 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY6"] -item bs 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADYread"] -item c 1 -feccondrow 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"] -item c 1 -feccondrow 1,2,3,4,6
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY4"] -item c 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY6"] -item c 1
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign HTRANS"] -item c 1 -feccondrow 5
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign BeatCntEn"] -item e 1 -fecexprrow 4
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign CacheAccess"] -item e 1 -fecexprrow 4
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign BusStall"] -item e 1 -fecexprrow 10,12,18
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign CacheBusAck"] -item e 1 -fecexprrow 3
## D$ Exclusions. ## D$ Exclusions.
# InvalidateCache is I$ only: # InvalidateCache is I$ only:
@ -90,13 +137,17 @@ coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [Get
set numcacheways 4 set numcacheways 4
for {set i 0} {$i < $numcacheways} {incr i} { for {set i 0} {$i < $numcacheways} {incr i} {
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: dcache invalidateway"] -item bes 1 -fecexprrow 4 coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: dcache invalidateway"] -item bes 1 -fecexprrow 4
# InvalidateCacheDelay is always 0 for D$ because it is flushed, not invalidated
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: dcache HitWay"] -item 3 1 -fecexprrow 2
# FlushStage=1 will never happen when SetValidWay=1 since a pipeline stall is asserted by the cache in the fetch stage, which happens before # FlushStage=1 will never happen when SetValidWay=1 since a pipeline stall is asserted by the cache in the fetch stage, which happens before
# going into the WRITE_LINE state (and asserting SetValidWay). No TrapM can fire and since StallW is high, a stallM caused by WFIStallM would not cause a flushW. # going into the WRITE_LINE state (and asserting SetValidWay). No TrapM can fire and since StallW is high, a stallM caused by WFIStallM would not cause a flushW.
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache SetValidEN"] -item e 1 -fecexprrow 4 coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache SetValidEN"] -item e 1 -fecexprrow 4
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache ClearValidEN"] -item e 1 -fecexprrow 4
# Not right; other ways can get flushed and dirtied simultaneously coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache UpdateDirty"] -item c 1 -feccondrow 6
} }
# D$ writeback, flush, write_line, or flush_writeback states can't be cancelled by a flush # D$ writeback, flush, write_line, or flush_writeback states can't be cancelled by a flush
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -ftrans CurrState STATE_WRITEBACK->STATE_READY STATE_FLUSH->STATE_READY STATE_WRITE_LINE->STATE_READY STATE_FLUSH_WRITEBACK->STATE_READY coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -ftrans CurrState STATE_WRITEBACK->STATE_READY STATE_FLUSH->STATE_READY STATE_WRITE_LINE->STATE_READY STATE_FLUSH_WRITEBACK->STATE_READY
#################### ####################
# Unused / illegal peripheral accesses # Unused / illegal peripheral accesses
@ -112,7 +163,13 @@ coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/iromdec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/ddr4dec coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/ddr4dec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/sdcdec coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/sdcdec
# PMA Regions 8, 9, and 10 (dtim, irom, ddr4) are never used in the rv64gc configuration, so exclude coverage # PMA Regions 1, 2, and 3 (dtim, irom, ddr4) are never used in the rv64gc configuration, so exclude coverage
set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-atomic"]
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-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-cachable"]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2 coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2 coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
@ -121,11 +178,17 @@ coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$lin
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4,6,8 coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4,6,8
# Excluding so far un-used instruction sources for the ifu # Excluding so far un-used instruction sources for the ifu
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/bootromdec coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/bootromdec
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/uncoreramdec coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/uncoreramdec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/spidec
#Excluding the bootrom, uncoreran, and clint as sources for the lsu # The following peripherals are always supported
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/bootromdec set line [GetLineNum ../src/mmu/adrdec.sv "exclusion-tag: adrdecSel"]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/bootromdec -linerange $line-$line -item e 1 -fecexprrow 3,7
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/gpiodec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uartdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/plicdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/spidec -linerange $line-$line -item e 1 -fecexprrow 3
#Excluding signals in lsu: clintdec and uncoreram accept all sizes so 'SizeValid' will never be 0 #Excluding signals in lsu: clintdec and uncoreram accept all sizes so 'SizeValid' will never be 0
set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"] set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"]
@ -134,22 +197,15 @@ set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uncoreramdec -linerange $line-$line -item e 1 -fecexprrow 5 coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uncoreramdec -linerange $line-$line -item e 1 -fecexprrow 5
# set line [GetLineNum ../src/mmu/adrdec.sv "& Supported"] # set line [GetLineNum ../src/mmu/adrdec.sv "& Supported"]
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/dtimdec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/iromdec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/ddr4dec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/gpiodec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uartdec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/plicdec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/sdcdec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/dtimdec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/iromdec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/ddr4dec -linerange $line-$line -item e 1 -fecexprrow 3
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/sdcdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/dtimdec coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/dtimdec
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/iromdec coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/iromdec
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/ddr4dec coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/ddr4dec
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/sdcdec coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/sdcdec
# No DTIM or IROM
coverage exclude -scope /dut/core/ifu/bus/icache/UnCachedDataMux -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
coverage exclude -scope /dut/core/lsu/bus/dcache/UnCachedDataMux -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
#################### ####################
# Unused access types due to sharing IFU and LSU logic # Unused access types due to sharing IFU and LSU logic
#################### ####################
@ -192,6 +248,10 @@ set line [GetLineNum ../src/mmu/mmu.sv "ExecuteAccessF \\| ReadAccessM"]
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,3,4 coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,3,4
set line [GetLineNum ../src/mmu/mmu.sv "ReadAccessM & ~WriteAccessM"] set line [GetLineNum ../src/mmu/mmu.sv "ReadAccessM & ~WriteAccessM"]
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 2-4 coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 2-4
set line [GetLineNum ../src/mmu/mmu.sv "assign AmoAccessM"]
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1
set line [GetLineNum ../src/mmu/mmu.sv "assign AmoMisalignedCausesAccessFaultM"]
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1
set line [GetLineNum ../src/mmu/mmu.sv "DataMisalignedM & WriteAccessM"] set line [GetLineNum ../src/mmu/mmu.sv "DataMisalignedM & WriteAccessM"]
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,2,4 coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,2,4
set line [GetLineNum ../src/mmu/mmu.sv "TLBPageFault & ExecuteAccessF"] set line [GetLineNum ../src/mmu/mmu.sv "TLBPageFault & ExecuteAccessF"]
@ -224,6 +284,44 @@ coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line2 -item e
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line2 -item b 1 coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line2 -item b 1
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line2 -item s 1 coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line2 -item s 1
# IMMU never disables translations
coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerange [GetLineNum ../src/mmu/tlb/tlbcontrol.sv "assign Translate"] -item e 1 -fecexprrow 2
coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerange [GetLineNum ../src/mmu/tlb/tlbcontrol.sv "assign UpdateDA"] -item e 1 -fecexprrow 5
# never reaches this when ENVCFG_ADUE_1 because HPTW updates A bit first
coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerange [GetLineNum ../src/mmu/tlb/tlbcontrol.sv "assign PrePageFault"] -item e 1 -fecexprrow 18
###############
# HPTW exclusions
###############
# RV64GC HPTW never starts at L1_ADR
set line [GetLineNum ../src/mmu/hptw.sv "InitialWalkerState == L1_ADR"]
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item c 1 -feccondrow 2
# Never possible to get a page fault when neither reading nor writing
set line [GetLineNum ../src/mmu/hptw.sv "assign HPTWLoadPageFault"]
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item e 1 -fecexprrow 7
# Never possible to get a store page fault from an ITLB walk
set line [GetLineNum ../src/mmu/hptw.sv "assign HPTWStoreAmoPageFault"]
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item e 1 -fecexprrow 3
# Never possible to get Access = 0 on a nonleaf PTE with no OtherPageFault (because InvalidRead/Write will be 1 on the nonleaf)
set line [GetLineNum ../src/mmu/hptw.sv "assign HPTWUpdateDA"]
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item e 1 -fecexprrow 3
###############
# Other exclusions
###############
# IMMU PMP does not support CBO instructions
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcbom"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboz"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboaccess"]
# No irom # No irom
set line [GetLineNum ../src/ifu/ifu.sv "~ITLBMissF & ~CacheableF & ~SelIROM"] set line [GetLineNum ../src/ifu/ifu.sv "~ITLBMissF & ~CacheableF & ~SelIROM"]
coverage exclude -scope /dut/core/ifu -linerange $line-$line -item c 1 -feccondrow 6 coverage exclude -scope /dut/core/ifu -linerange $line-$line -item c 1 -feccondrow 6
@ -246,6 +344,56 @@ coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb -linerange $line-$line -item
set line [GetLineNum ../src/ebu/ebufsmarb.sv "FinalBeatReg\\("] set line [GetLineNum ../src/ebu/ebufsmarb.sv "FinalBeatReg\\("]
coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb -linerange $line-$line -item e 1 -fecexprrow 1 coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb -linerange $line-$line -item e 1 -fecexprrow 1
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicElse"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 1
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicWait"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 1
# The WritebackWriteback and FetchWriteback support back to back pipelined cache writebacks and fetch then
# writebacks. The cache never issues these type of requests.
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm WritebackWriteback"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 2
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 2
# FetchWait never occurs because HREADY is never 0.
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWait"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 1
# all of these HREADY exclusions occur because HREADY is always 1. The ram_ahb module never stalls.
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY0"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
#set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY1"]
#coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
#set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY2"]
#coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY3"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 4
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY4"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 3
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY5"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY6"]
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 5
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign CacheBusAck"] -item e 1 -fecexprrow 5
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicElse"] -item s 1
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicWait"] -item s 1
# these transitions will not happen
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -ftrans CurrState DATA_PHASE->ADR_PHASE ATOMIC_READ_DATA_PHASE->ADR_PHASE ATOMIC_PHASE->ADR_PHASE
# TLB not recently used never has all RU bits = 1 because it will then clear all to 0 # TLB not recently used never has all RU bits = 1 because it will then clear all to 0
# This is a blunt instrument; perhaps there is a more graceful exclusion # This is a blunt instrument; perhaps there is a more graceful exclusion
coverage exclude -srcfile priorityonehot.sv coverage exclude -srcfile priorityonehot.sv
@ -254,9 +402,20 @@ coverage exclude -srcfile priorityonehot.sv
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1 coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1 coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1
####################
# Privileged
####################
# Instruction Misaligned never asserted because compresssed instructions are accepted
coverage exclude -scope /dut/core/priv/priv/trap -linerange [GetLineNum ../src/privileged/trap.sv "assign ExceptionM"] -item e 1 -fecexprrow 2
#################### ####################
# EBU # EBU
#################### ####################
# Exclude EBU Beat Counter because it is only idle when bus has multicycle latency, but rv64gc has single cycle latency # Exclude EBU Beat Counter flop because it is only idle when bus has multicycle latency, but rv64gc has single cycle latency
coverage exclude -scope /core/ebu/ebu/ebufsmarb/BeatCounter coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb/BeatCounter/cntrflop

View File

@ -11,6 +11,7 @@
--override cpu/mvendorid=0x602 --override cpu/mvendorid=0x602
--override cpu/marchid=0x24 --override cpu/marchid=0x24
--override refRoot/cpu/tvec_align=64 --override refRoot/cpu/tvec_align=64
--override refRoot/cpu/envcfg_mask=1 # dh 1/26/24 this should be deleted when ImperasDV is updated to allow envcfg.FIOM to be written
# bit manipulation # bit manipulation
--override cpu/add_Extensions=B --override cpu/add_Extensions=B
@ -21,6 +22,7 @@
--override cpu/Zcb=T --override cpu/Zcb=T
--override cpu/Zicond=T --override cpu/Zicond=T
--override cpu/Zfh=T --override cpu/Zfh=T
--override cpu/Zfa=T
# Cache block operations # Cache block operations
--override cpu/Zicbom=T --override cpu/Zicbom=T
@ -95,6 +97,7 @@
--callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw-aA- 1--- " # UART0 error - 0x10000000 - 0x100000FF --callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw-aA- 1--- " # UART0 error - 0x10000000 - 0x100000FF
--callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw-aA- --4- " # GPIO error - 0x10069000 - 0x100600FF --callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw-aA- --4- " # GPIO error - 0x10069000 - 0x100600FF
--callcommand refRoot/cpu/setPMA -lo 0x0010040000 -hi 0x0010040FFF -attributes " rw-aA- --4- " # SPI error - 0x10040000 - 0x10040FFF --callcommand refRoot/cpu/setPMA -lo 0x0010040000 -hi 0x0010040FFF -attributes " rw-aA- --4- " # SPI error - 0x10040000 - 0x10040FFF
#--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwxaA- 1248 " # UNCORE_RAM
--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM --callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM
# Enable the Imperas instruction coverage # Enable the Imperas instruction coverage

View File

@ -1,19 +1,48 @@
#!/bin/bash #!/bin/bash
# check for warnings in Verilog code # check for warnings in Verilog code
# The verilator lint tool is faster and better than Modelsim so it is best to run this first. # The verilator lint tool is faster and better than Questa so it is best to run this first.
export PATH=$PATH:/usr/local/bin/ export PATH=$PATH:/usr/local/bin/
verilator=`which verilator` verilator=`which verilator`
basepath=$(dirname $0)/.. basepath=$(dirname $0)/..
for config in rv32e rv64gc rv32gc rv32imc rv32i rv64i rv64fpquad; do RED='\033[0;31m'
#for config in rv64gc; do GREEN='\033[0;32m'
echo "$config linting..." NC='\033[0m' # No Color
if !($verilator --no-timing --lint-only "$@" --top-module wallywrapper "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/cvw.sv $basepath/testbench/wallywrapper.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then fails=0
echo "Exiting after $config lint due to errors or warnings"
exit 1 if [ "$1" == "-nightly" ]; then
configs=(rv32e rv64gc rv32gc rv32imc rv32i rv64i) # fdqh_rv64gc
derivconfigs=`ls $WALLY/config/deriv`
for entry in $derivconfigs
do
if [[ $entry != *"syn_sram"* ]]; then # ignore syn_sram* configs that contain undefined module
configs[${#configs[@]}]=$entry
fi
done
else
configs=(rv32e rv64gc rv32gc rv32imc rv32i rv64i div_2_1i_rv64gc ) # add fdqh_rv64gc when working
fi
for config in ${configs[@]}; do
# echo "$config linting..."
if !($verilator --no-timing --lint-only --top-module wallywrapper "-I$basepath/config/shared" "-I$basepath/config/$config" "-I$basepath/config/deriv/$config" $basepath/src/cvw.sv $basepath/testbench/wallywrapper.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then
if [ "$1" == "-nightly" ]; then
echo -e "${RED}$config failed lint${NC}"
fails=$((fails+1))
else
echo -e "${RED}$config fails with lint errors or warnings"
exit 1
fi
else
echo -e "${GREEN}$config passed lint${NC}"
fi fi
done done
echo "All lints run with no errors or warnings" if [ $fails -gt 0 ]; then
echo -e "${RED}Linting failed for $fails of ${#configs[@]} configurations"
exit 1
fi
echo -e "${GREEN}All ${#configs[@]} lints run with no errors or warnings"
# --lint-only just runs lint rather than trying to compile and simulate # --lint-only just runs lint rather than trying to compile and simulate
# -I points to the include directory where files such as `include config.vh are found # -I points to the include directory where files such as `include config.vh are found

View File

@ -11,6 +11,9 @@
# #
################################## ##################################
import sys,os,shutil import sys,os,shutil
import multiprocessing
class bcolors: class bcolors:
HEADER = '\033[95m' HEADER = '\033[95m'
@ -29,6 +32,8 @@ os.chdir(regressionDir)
coverage = '-coverage' in sys.argv coverage = '-coverage' in sys.argv
fp = '-fp' in sys.argv fp = '-fp' in sys.argv
nightly = '-nightly' in sys.argv
softfloat = '-softfloat' in sys.argv
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr']) TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
# name: the name of this test configuration (used in printing human-readable # name: the name of this test configuration (used in printing human-readable
@ -40,14 +45,20 @@ TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
# be any pattern grep accepts, see `man 1 grep` for more info). # be any pattern grep accepts, see `man 1 grep` for more info).
# edit this list to add more test cases # edit this list to add more test cases
configs = [ if (nightly):
TestCase( nightMode = "-nightly";
name="lints", configs = []
variant="all", else:
cmd="./lint-wally | tee {}", nightMode = "";
grepstr="All lints run with no errors or warnings" configs = [
) TestCase(
] name="lints",
variant="all",
cmd="./lint-wally " + nightMode + " | tee {}",
grepstr="lints run with no errors or warnings"
)
]
def getBuildrootTC(boot): def getBuildrootTC(boot):
INSTR_LIMIT = 1000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM INSTR_LIMIT = 1000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM
MAX_EXPECTED = 246000000 # *** TODO: replace this with a search for the login prompt. MAX_EXPECTED = 246000000 # *** TODO: replace this with a search for the login prompt.
@ -62,7 +73,7 @@ def getBuildrootTC(boot):
BRcmd="vsim > {} -c <<!\ndo wally-batch.do buildroot buildroot $RISCV "+str(INSTR_LIMIT)+" 1 0 -coverage\n!" BRcmd="vsim > {} -c <<!\ndo wally-batch.do buildroot buildroot $RISCV "+str(INSTR_LIMIT)+" 1 0 -coverage\n!"
else: else:
print( "buildroot no coverage") print( "buildroot no coverage")
BRcmd="vsim > {} -c <<!\ndo wally-batch.do buildroot buildroot $RISCV "+str(INSTR_LIMIT)+" 1 0\n!" BRcmd="vsim > {} -c <<!\ndo wally-batch.do buildroot buildroot configOptions -GINSTR_LIMIT=" +str(INSTR_LIMIT) + " \n!"
BRgrepstr=str(INSTR_LIMIT)+" instructions" BRgrepstr=str(INSTR_LIMIT)+" instructions"
return TestCase(name,variant="rv64gc",cmd=BRcmd,grepstr=BRgrepstr) return TestCase(name,variant="rv64gc",cmd=BRcmd,grepstr=BRgrepstr)
@ -78,7 +89,7 @@ for test in tests64i:
configs.append(tc) configs.append(tc)
tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused
tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zicond", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "wally32a", "wally32priv", "wally32periph"] tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32f_divsqrt", "arch32d_divsqrt", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zicond", "arch32zba", "arch32zbb", "arch32zbs", "arch32zfh", "arch32zfh_fma", "arch32zfh_divsqrt", "arch32zfaf", "wally32a", "wally32priv", "wally32periph"] # "arch32zbc", "arch32zfad",
#tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zicboz", "arch32zcb", "wally32a", "wally32priv", "wally32periph"] #tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zicboz", "arch32zcb", "wally32a", "wally32priv", "wally32periph"]
for test in tests32gc: for test in tests32gc:
tc = TestCase( tc = TestCase(
@ -117,29 +128,27 @@ for test in tests32e:
grepstr="All tests ran without failures") grepstr="All tests ran without failures")
configs.append(tc) configs.append(tc)
ahbTests = [("0", "0"), ("0", "1"), ("1", "0"), ("1", "1"), ("2", "0"), ("2", "1")] tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64f_divsqrt", "arch64d_divsqrt", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64zfh", "arch64zfh_divsqrt", "arch64zfh_fma", "arch64zfaf", "arch64zfad",
for test in ahbTests: "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "arch64zicond", "wally64a", "wally64periph", "wally64priv"] # add arch64zfh_fma when available; arch64zicobz, arch64zcb when working
tc = TestCase(
name="ram_latency_" + test[0] + "_burst_en_" + test[1],
variant="ahb",
cmd="vsim > {} -c <<!\ndo wally-batch.do rv64gc ahb "+test[0]+" "+test[1]+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
"arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "arch64zicond", "wally64a", "wally64periph", "wally64priv"]
#tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", #tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
# "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv", "arch64zicboz", "arch64zcb"] # "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv", "arch64zicboz", "arch64zcb"]
if (coverage): # delete all but 64gc tests when running coverage if (coverage): # delete all but 64gc tests when running coverage
configs = [] configs = []
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m", tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m",
"arch64zifencei", "arch64zicond", "arch64a", "wally64a", "wally64periph", "wally64priv", "arch64zifencei", "arch64zicond", "arch64a", "wally64a", "wally64periph", "wally64priv",
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] # add when working: "arch64zicboz", "arch64zcb", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] # add when working: "arch64zcb", "arch64zicboz"
if (fp): if (fp):
tests64gc.append("arch64f") tests64gc.append("arch64f")
tests64gc.append("arch64d") tests64gc.append("arch64d")
tests64gc.append("arch64zfh")
tests64gc.append("arch64f_fma") tests64gc.append("arch64f_fma")
tests64gc.append("arch64d_fma") tests64gc.append("arch64d_fma")
tests64gc.append("arch64zfh_fma")
tests64gc.append("arch64f_divsqrt")
tests64gc.append("arch64d_divsqrt")
tests64gc.append("arch64zfh_divsqrt")
tests64gc.append("arch64zfaf")
tests64gc.append("arch64zfad")
coverStr = '-coverage' coverStr = '-coverage'
else: else:
coverStr = '' coverStr = ''
@ -150,7 +159,238 @@ for test in tests64gc:
cmd="vsim > {} -c <<!\ndo wally-batch.do rv64gc "+test+" " + coverStr + "\n!", cmd="vsim > {} -c <<!\ndo wally-batch.do rv64gc "+test+" " + coverStr + "\n!",
grepstr="All tests ran without failures") grepstr="All tests ran without failures")
configs.append(tc) configs.append(tc)
# run derivative configurations if requested
if (nightly):
derivconfigtests = [
["tlb2_rv32gc", ["wally32priv"]],
["tlb16_rv32gc", ["wally32priv"]],
["tlb2_rv64gc", ["wally64priv"]],
["tlb16_rv64gc", ["wally64priv"]],
["way_1_4096_512_rv32gc", ["arch32i"]],
["way_2_4096_512_rv32gc", ["arch32i"]],
["way_8_4096_512_rv32gc", ["arch32i"]],
["way_4_2048_512_rv32gc", ["arch32i"]],
["way_4_4096_256_rv32gc", ["arch32i"]],
["way_1_4096_512_rv64gc", ["arch64i"]],
["way_2_4096_512_rv64gc", ["arch64i"]],
["way_8_4096_512_rv64gc", ["arch64i"]],
["way_4_2048_512_rv64gc", ["arch64i"]],
["way_4_4096_256_rv64gc", ["arch64i"]],
["way_4_4096_1024_rv64gc", ["arch64i"]],
["ram_0_0_rv64gc", ["ahb64"]],
["ram_1_0_rv64gc", ["ahb64"]],
["ram_1_1_rv64gc", ["ahb64"]],
["ram_2_0_rv64gc", ["ahb64"]],
["ram_2_1_rv64gc", ["ahb64"]],
["noicache_rv32gc", ["ahb32"]],
# cacheless designs will not work until DTIM supports FLEN > XLEN
# ["nodcache_rv32gc", ["ahb32"]],
# ["nocache_rv32gc", ["ahb32"]],
["noicache_rv64gc", ["ahb64"]],
["nodcache_rv64gc", ["ahb64"]],
["nocache_rv64gc", ["ahb64"]],
### add misaligned tests
["div_2_1_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_2_1i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_2_2_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_2_2i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_2_4_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_2_4i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_4_1_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_4_1i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_4_2_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_4_2i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_4_4_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_4_4i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
["div_2_1_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_2_1i_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_2_2_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_2_2i_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_2_4_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_2_4i_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_4_1_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_4_1i_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_4_2_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_4_2i_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_4_4_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
["div_4_4i_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
### branch predictor simulation
# ["bpred_TWOBIT_6_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_8_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_10_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_12_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_14_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_16_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_6_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_8_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_10_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_12_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_14_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_TWOBIT_16_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_6_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_6_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_8_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_8_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_12_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_12_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_14_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_14_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_16_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_16_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# # btb
# ["bpred_GSHARE_10_16_6_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_16_6_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_16_8_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_16_8_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_16_12_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_16_12_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# # ras
# ["bpred_GSHARE_10_2_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_2_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_3_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_3_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_4_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_4_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_6_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_6_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_10_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# ["bpred_GSHARE_10_10_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
# enable floating-point tests when lint is fixed
["f_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma"]],
["fh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32zfh", "arch32zfh_divsqrt"]],
["fdh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]],
["fdq_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma"]],
["fdqh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]],
["f_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma"]],
["fh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64zfh", "arch64zfh_divsqrt"]], # hanging 1/31/24 dh; try again when lint is fixed
["fdh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt"]],
["fdq_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma"]],
["fdqh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt", "wally64q"]],
]
for test in derivconfigtests:
config = test[0];
tests = test[1];
if(len(test) >= 4 and test[2] == "configOptions"):
configOptions = test[3]
cmdPrefix = "vsim > {} -c <<!\ndo wally-batch.do "+config
else:
configOptions = ""
cmdPrefix = "vsim > {} -c <<!\ndo wally-batch.do "+config
for t in tests:
tc = TestCase(
name=t,
variant=config,
cmd=cmdPrefix+" "+t+" configOptions "+configOptions+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests32e = ["arch32e"]
for test in tests32e:
tc = TestCase(
name=test,
variant="rv32e",
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32e "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
# softfloat tests
if (softfloat):
configs = []
softfloatconfigs = ['fdh_ieee_rv32gc', 'fdqh_ieee_rv32gc', 'fdq_ieee_rv32gc', \
'fh_ieee_v32gc', 'f_ieee_rv64gc', 'fdqh_ieee_rv64gc', \
'fdq_ieee_rv64gc', 'div_2_1_rv32gc', 'div_2_2_rv32gc', \
'div_2_4_rv32gc', 'div_4_1_rv32gc', 'div_4_2_rv32gc', \
'div_4_4_rv32gc', 'fd_ieee_rv32gc', 'fh_ieee_rv32gc', \
'div_2_1_rv64gc', 'div_2_2_rv64gc', 'div_2_4_rv64gc', \
'div_4_1_rv64gc', 'div_4_2_rv64gc', 'div_4_4_rv64gc', \
'fd_ieee_rv64gc', 'fh_ieee_rv64gc', 'f_ieee_rv32gc']
softfloatconfigs = ['fdh_ieee_div_2_1_rv32gc', 'fdh_ieee_div_2_1_rv64gc', \
'fdh_ieee_div_2_2_rv32gc', 'fdh_ieee_div_2_2_rv64gc', 'fdh_ieee_div_2_4_rv32gc', \
'fdh_ieee_div_2_4_rv64gc', 'fdh_ieee_div_4_1_rv32gc', 'fdh_ieee_div_4_1_rv64gc', \
'fdh_ieee_div_4_2_rv32gc', 'fdh_ieee_div_4_2_rv64gc', 'fdh_ieee_div_4_4_rv64gc', \
'fdh_ieee_rv32gc', 'fd_ieee_div_2_1_rv32gc', 'fd_ieee_div_2_1_rv64gc', \
'fd_ieee_div_2_2_rv32gc', 'fd_ieee_div_2_2_rv64gc', 'fd_ieee_div_2_4_rv32gc', \
'fd_ieee_div_2_4_rv64gc', 'fd_ieee_div_4_1_rv32gc', 'fd_ieee_div_4_1_rv64gc', \
'fd_ieee_div_4_2_rv32gc', 'fd_ieee_div_4_2_rv64gc', 'fd_ieee_div_4_4_rv64gc', \
'fd_ieee_rv32gc', 'fd_ieee_rv64gc', 'fdqh_ieee_div_2_1_rv32gc', \
'fdqh_ieee_div_2_1_rv64gc', 'fdqh_ieee_div_2_2_rv32gc', 'fdqh_ieee_div_2_2_rv64gc', \
'fdqh_ieee_div_2_4_rv32gc', 'fdqh_ieee_div_2_4_rv64gc', 'fdqh_ieee_div_4_1_rv32gc', \
'fdqh_ieee_div_4_1_rv64gc', 'fdqh_ieee_div_4_2_rv32gc', 'fdqh_ieee_div_4_2_rv64gc',\
'fdqh_ieee_div_4_4_rv64gc', 'fdqh_ieee_rv32gc', 'fdqh_ieee_rv64gc', \
'fdq_ieee_div_2_1_rv32gc', 'fdq_ieee_div_2_1_rv64gc', 'fdq_ieee_div_2_2_rv32gc',\
'fdq_ieee_div_2_2_rv64gc', 'fdq_ieee_div_2_4_rv32gc', 'fdq_ieee_div_2_4_rv64gc', \
'fdq_ieee_div_4_1_rv32gc', 'fdq_ieee_div_4_1_rv64gc', 'fdq_ieee_div_4_2_rv32gc', \
'fdq_ieee_div_4_2_rv64gc', 'fdq_ieee_div_4_4_rv64gc', 'fdq_ieee_rv32gc', \
'fdq_ieee_rv64gc', 'fh_ieee_div_2_1_rv32gc', 'fh_ieee_div_2_1_rv64gc', \
'fh_ieee_div_2_2_rv32gc', 'fh_ieee_div_2_2_rv64gc', 'fh_ieee_div_2_4_rv32gc',\
'fh_ieee_div_2_4_rv64gc', 'fh_ieee_div_4_1_rv32gc', 'fh_ieee_div_4_1_rv64gc',\
'fh_ieee_div_4_2_rv32gc', 'fh_ieee_div_4_2_rv64gc', 'fh_ieee_div_4_4_rv64gc', \
'fh_ieee_rv32gc', 'fh_ieee_rv64gc', 'fh_ieee_v32gc', 'f_ieee_div_2_1_rv32gc', \
'f_ieee_div_2_1_rv64gc', 'f_ieee_div_2_2_rv32gc', 'f_ieee_div_2_2_rv64gc', \
'f_ieee_div_2_4_rv32gc', 'f_ieee_div_2_4_rv64gc', 'f_ieee_div_4_1_rv32gc', \
'f_ieee_div_4_1_rv64gc', 'f_ieee_div_4_2_rv32gc', 'f_ieee_div_4_2_rv64gc', \
'f_ieee_div_4_4_rv64gc', 'f_ieee_rv32gc', 'f_ieee_rv64gc']
for config in softfloatconfigs:
# div test case
divtest = TestCase(
name="div",
variant=config,
cmd="vsim > {} -c <<!\ndo testfloat-batch.do " + config + " div \n!",
grepstr="All Tests completed with 0 errors"
)
configs.insert(0,divtest)
# sqrt test case
sqrttest = TestCase(
name="sqrt",
variant=config,
cmd="vsim > {} -c <<!\ndo testfloat-batch.do " + config + " sqrt \n!",
grepstr="All Tests completed with 0 errors"
)
#configs.append(sqrttest)
configs.insert(0,sqrttest)
# skip if divider variant config
if ("ieee" in config):
# cvtint test case
cvtinttest = TestCase(
name="cvtint",
variant=config,
cmd="vsim > {} -c <<!\ndo testfloat-batch.do " + config + " cvtint \n!",
grepstr="All Tests completed with 0 errors"
)
configs.append(cvtinttest)
# cvtfp test case
# WILL fail on F_only (refer to spec)
cvtfptest = TestCase(
name="cvtfp",
variant=config,
cmd="vsim > {} -c <<!\ndo testfloat-batch.do " + config + " cvtfp \n!",
grepstr="All Tests completed with 0 errors"
)
configs.append(cvtfptest)
import os import os
from multiprocessing import Pool, TimeoutError from multiprocessing import Pool, TimeoutError
@ -206,13 +446,18 @@ def main():
# Also it is slow to run. # Also it is slow to run.
# configs.append(getBuildrootTC(boot=False)) # configs.append(getBuildrootTC(boot=False))
os.system('rm -f cov/*.ucdb') os.system('rm -f cov/*.ucdb')
elif '-nightly' in sys.argv:
TIMEOUT_DUR = 60*1440 # 1 day
configs.append(getBuildrootTC(boot=False))
elif '-softfloat' in sys.argv:
TIMEOUT_DUR = 60*60 # seconds
else: else:
TIMEOUT_DUR = 10*60 # seconds TIMEOUT_DUR = 10*60 # seconds
configs.append(getBuildrootTC(boot=False)) configs.append(getBuildrootTC(boot=False))
# Scale the number of concurrent processes to the number of test cases, but # Scale the number of concurrent processes to the number of test cases, but
# max out at a limited number of concurrent processes to not overwhelm the system # max out at a limited number of concurrent processes to not overwhelm the system
with Pool(processes=min(len(configs),40)) as pool: with Pool(processes=min(len(configs),multiprocessing.cpu_count())) as pool:
num_fail = 0 num_fail = 0
results = {} results = {}
for config in configs: for config in configs:

View File

@ -3,8 +3,8 @@
#export RISCV=/scratch/moore/RISCV #export RISCV=/scratch/moore/RISCV
export IMPERAS_TOOLS=$(pwd)/imperas.ic export IMPERAS_TOOLS=$(pwd)/imperas.ic
export OTHERFLAGS="+TRACE2LOG_ENABLE=1" export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=100"
#export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=10500000" #export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=10500000"
export OTHERFLAGS="" #export OTHERFLAGS=""
vsim -c -do "do wally-linux-imperas.do buildroot buildroot-no-trace $::env(RISCV) 0 0 0" vsim -do "do wally-linux-imperas.do buildroot buildroot $::env(RISCV) 0 0 0"

View File

@ -10,6 +10,7 @@
## Purpose: Run the cache simulator on each rv64gc test suite in turn. ## Purpose: Run the cache simulator on each rv64gc test suite in turn.
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -10,6 +10,7 @@
## Purpose: Run wally with imperas ## Purpose: Run wally with imperas
## ##
## A component of the CORE-V-WALLY configurable RISC-V project. ## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
## ##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University ## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
## ##

View File

@ -9,4 +9,4 @@
# sqrt - test square root # sqrt - test square root
# all - test everything # all - test everything
vsim -do "do testfloat.do rv64fpquad $1" vsim -do "do testfloat.do fdqh_ieee_rv64gc $1"

View File

@ -10,4 +10,4 @@
# sqrt - test square root # sqrt - test square root
# all - test everything # all - test everything
vsim -c -do "do testfloat.do rv64fpquad $1" vsim -c -do "do testfloat.do fdqh_ieee_rv64gc $1"

55
sim/testfloat-batch.do Normal file
View File

@ -0,0 +1,55 @@
# testfloat-batch.do
#
# Modification by Oklahoma State University & Harvey Mudd College
# Use with Testbench
# James Stine, 2008; David Harris 2021; Kevin Kim 2024
# Go Cowboys!!!!!!
#
# Takes 1:10 to run RV64IC tests using gui
# run with vsim -do "do wally.do rv64ic riscvarchtest-64m"
onbreak {resume}
# create library
if [file exists wkdir/work_${1}_${2}] {
vdel -lib wkdir/work_${1}_${2} -all
}
vlib wkdir/work_${1}_${2}
# c# compile source files
# suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
# $num = the added words after the call
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-fp.sv ../src/fpu/*.sv ../src/fpu/*/*.sv ../src/generic/*.sv ../src/generic/flop/*.sv -suppress 2583,7063,8607,2697,7033
# Set WAV variable to avoid having any output to wave (to limit disk space)
quietly set WAV 0;
# Determine if nowave argument is provided this removes any output to
# a wlf or wave window to reduce disk space.
if {$WAV eq 0} {
puts "No wave output is selected"
} else {
puts "wave output is selected"
view wave
add log -recursive /*
do wave-fpu.do
}
# Change TEST_SIZE to only test certain FP width
# values are QP, DP, SP, HP or all for all tests
vopt +acc wkdir/work_${1}_${2}.testbenchfp -work wkdir/work_${1}_${2} -G TEST=$2 -G TEST_SIZE="all" -o testbenchopt
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
#-- Run the Simulation
run -all

View File

@ -25,7 +25,7 @@ vlib work
# start and run simulation # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals
# $num = the added words after the call # $num = the added words after the call
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-fp.sv ../src/fpu/*.sv ../src/fpu/*/*.sv ../src/generic/*.sv ../src/generic/flop/*.sv -suppress 2583,7063,8607,2697 vlog +incdir+../config/deriv/$1 +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-fp.sv ../src/fpu/*.sv ../src/fpu/*/*.sv ../src/generic/*.sv ../src/generic/flop/*.sv -suppress 2583,7063,8607,2697
# Change TEST_SIZE to only test certain FP width # Change TEST_SIZE to only test certain FP width
# values are QP, DP, SP, HP or all for all tests # values are QP, DP, SP, HP or all for all tests

View File

@ -21,33 +21,40 @@
onbreak {resume} onbreak {resume}
# create library # create library
if {$2 eq "ahb"} { if [file exists wkdir/work_${1}_${2}] {
if [file exists wkdir/work_${1}_${2}_${3}_${4}] { vdel -lib wkdir/work_${1}_${2} -all
vdel -lib wkdir/work_${1}_${2}_${3}_${4} -all
}
vlib wkdir/work_${1}_${2}_${3}_${4}
} elseif {$2 eq "configOptions"} {
if [file exists wkdir/work_${1}_${3}_${4}] {
vdel -lib wkdir/work_${1}_${3}_${4} -all
}
vlib wkdir/work_${1}_${3}_${4}
} else {
if [file exists wkdir/work_${1}_${2}] {
vdel -lib wkdir/work_${1}_${2} -all
}
vlib wkdir/work_${1}_${2}
} }
vlib wkdir/work_${1}_${2}
# Create directory for coverage data # Create directory for coverage data
mkdir -p cov mkdir -p cov
# Check if measuring coverage set coverage 0
set coverage 0 set CoverageVoptArg ""
set CoverageVsimArg ""
# Need to be able to pass arguments to vopt. Unforunately 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 isd called from questa sim directly. This chunk of code uses the $4 through $n
# variables and compacts into a single list for passing to vopt.
set configOptions ""
set from 4
set step 1
set lst {}
for {set i 0} true {incr i} {
set x [expr {$i*$step + $from}]
if {$x > $argc} break
set arg [expr "$$x"]
lappend lst $arg
}
if {$argc >= 3} { if {$argc >= 3} {
if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} { if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} {
set coverage 1 set coverage 1
set CoverageVoptArg "+cover=sbecf"
set CoverageVsimArg "-coverage"
} elseif {$3 eq "configOptions"} {
set configOptions $lst
puts $configOptions
} }
} }
@ -58,91 +65,20 @@ if {$argc >= 3} {
# default to config/rv64ic, but allow this to be overridden at the command line. For example: # default to config/rv64ic, but allow this to be overridden at the command line. For example:
# do wally-pipelined-batch.do ../config/rv32imc rv32imc # do wally-pipelined-batch.do ../config/rv32imc rv32imc
if {$2 eq "buildroot"} {
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
if { $coverage } {
echo "wally-batch buildroot coverage"
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -o testbenchopt +cover=sbecf
vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 -cover
} else {
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -o testbenchopt
vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7
}
run -all vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
run -all
exec ./slack-notifier/slack-notifier.py
} elseif {$2 eq "buildroot-no-trace"} {
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G NO_SPOOFING=1 -o testbenchopt
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7
#-- Run the Simulation # start and run simulation
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" # remove +acc flag for faster sim during regressions if there is no need to access internal signals
echo "Don't forget to change DEBUG_LEVEL = 0." vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 ${configOptions} -o testbenchopt ${CoverageVoptArg}
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 ${CoverageVsimArg}
run -all
run -all
exec ./slack-notifier/slack-notifier.py
} elseif {$2 eq "ahb"} {
vlog -lint -work wkdir/work_${1}_${2}_${3}_${4} +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 +define+RAM_LATENCY=$3 +define+BURST_EN=$4
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
vopt wkdir/work_${1}_${2}_${3}_${4}.testbench -work wkdir/work_${1}_${2}_${3}_${4} -G TEST=$2 -o testbenchopt
vsim -lib wkdir/work_${1}_${2}_${3}_${4} testbenchopt -fatal 7
# Adding coverage increases runtime from 2:00 to 4:29. Can't run it all the time
#vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf
#vsim -coverage -lib work_$2 workopt_$2
# power add generates the logging necessary for said generation.
# power add -r /dut/core/*
run -all
# power off -r /dut/core/*
} elseif {$2 eq "configOptions"} {
# set arguments " "
# for {set i 5} {$i <= $argc} {incr i} {
# append arguments "\$$i "
# }
# puts $arguments
# set options eval $arguments
# **** fix this so we can pass any number of +defines.
# only allows 3 right now
vlog -lint -work wkdir/work_${1}_${3}_${4} +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 $5 $6 $7
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
vopt wkdir/work_${1}_${3}_${4}.testbench -work wkdir/work_${1}_${3}_${4} -G TEST=$4 -o testbenchopt
vsim -lib wkdir/work_${1}_${3}_${4} testbenchopt -fatal 7 -suppress 3829
# Adding coverage increases runtime from 2:00 to 4:29. Can't run it all the time
#vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf
#vsim -coverage -lib work_$2 workopt_$2
# power add generates the logging necessary for said generation.
# power add -r /dut/core/*
run -all
# power off -r /dut/core/*
} else {
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
if {$coverage} {
# vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbecf
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage
} else {
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
}
# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 # vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
# power add generates the logging necessary for said generation. # power add generates the logging necessary for said generation.
# power add -r /dut/core/* # power add -r /dut/core/*
run -all run -all
# power off -r /dut/core/* # power off -r /dut/core/*
}
if {$coverage} { if {$coverage} {
echo "Saving coverage to ${1}_${2}.ucdb" echo "Saving coverage to ${1}_${2}.ucdb"

View File

@ -32,25 +32,10 @@ vlib work
# start and run simulation # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals
if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { if {$2 eq "buildroot"} {
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
vopt work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -G NO_SPOOFING=0 -o testbenchopt
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7
#-- Run the Simulation
#run -all
run 7000 ms
add log -recursive /*
do linux-wave.do
run -all
exec ./slack-notifier/slack-notifier.py
} elseif {$2 eq "buildroot-no-trace"} {
vlog -lint -work work_${1}_${2} \ vlog -lint -work work_${1}_${2} \
+define+USE_IMPERAS_DV \ +define+USE_IMPERAS_DV \
+incdir+../config/$1 \ +incdir+../config/deriv/$1 \
+incdir+../config/shared \ +incdir+../config/shared \
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \ +incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
+incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \ +incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \
@ -64,7 +49,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \ $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \ $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \
../src/cvw.sv \ ../src/cvw.sv \
../testbench/testbench-linux-imperas.sv \ ../testbench/testbench.sv \
../testbench/common/*.sv ../src/*/*.sv \ ../testbench/common/*.sv ../src/*/*.sv \
../src/*/*/*.sv -suppress 2583 ../src/*/*/*.sv -suppress 2583
@ -76,7 +61,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
# visualizer -fprofile+perf+dir=fprofile # visualizer -fprofile+perf+dir=fprofile
# #
eval vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 \ eval vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 \
-G INSTR_LIMIT=0 -G INSTR_WAVEON=0 -G CHECKPOINT=0 -G NO_SPOOFING=1 -o testbenchopt -G TEST=$2 -o testbenchopt
eval vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 \ eval vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 \
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \ -sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
$env(OTHERFLAGS) $env(OTHERFLAGS)
@ -96,60 +81,4 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
exec ./slack-notifier/slack-notifier.py exec ./slack-notifier/slack-notifier.py
} elseif {$2 eq "fpga"} {
echo "hello"
vlog -work work +incdir+../config/fpga +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/sdc/*.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv ../../fpga/sim/*.sv -suppress 8852,12070,3084,3829,2583,7063,13286
vopt +acc work.testbench -G TEST=$2 -G DEBUG=0 -o workopt
vsim workopt +nowarn3829 -fatal 7
do fpga-wave.do
add log -r /*
run 20 ms
} else {
if {$2 eq "ahb"} {
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 +define+RAM_LATENCY=$3 +define+BURST_EN=$4
} else {
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063
}
vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7
view wave
#-- display input and output signals as hexidecimal values
#do ./wave-dos/peripheral-waves.do
add log -recursive /*
do wave.do
#do wave-bus.do
# power add generates the logging necessary for saif generation.
#power add -r /dut/core/*
#-- Run the Simulation
run -all
#power off -r /dut/core/*
#power report -all -bsaif power.saif
noview ../testbench/testbench.sv
view wave
} }
#elseif {$2 eq "buildroot-no-trace""} {
# vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
# vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=470350800 -G INSTR_WAVEON=470350800 -G CHECKPOINT=470350800 -G DEBUG_TRACE=0 -o testbenchopt
# vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829
#-- Run the Simulation
# run 100 ns
# force -deposit testbench/dut/core/priv/priv/csr/csri/IE_REGW 16'h2aa
# force -deposit testbench/dut/uncore/uncore/clint/clint/MTIMECMP 64'h1000
# add log -recursive /*
# do linux-wave.do
# run -all
# exec ./slack-notifier/slack-notifier.py
#}

View File

@ -77,12 +77,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
run 20 ms run 20 ms
} else { } else {
if {$2 eq "ahb"} { vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 +define+RAM_LATENCY=$3 +define+BURST_EN=$4
} else {
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063
}
vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7 vsim workopt +nowarn3829 -fatal 7

24
src/cache/cache.sv vendored
View File

@ -10,6 +10,7 @@
// Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.9, 7.10, and 7.19) // Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.9, 7.10, and 7.19)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -81,7 +82,7 @@ module cache import cvw::*; #(parameter cvw_t P,
logic ClearDirty, SetDirty, SetValid, ClearValid; logic ClearDirty, SetDirty, SetValid, ClearValid;
logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0]; logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0];
logic [NUMWAYS-1:0] HitWay, ValidWay; logic [NUMWAYS-1:0] HitWay, ValidWay;
logic CacheHit; logic Hit;
logic [NUMWAYS-1:0] VictimWay, DirtyWay, HitDirtyWay; logic [NUMWAYS-1:0] VictimWay, DirtyWay, HitDirtyWay;
logic LineDirty, HitLineDirty; logic LineDirty, HitLineDirty;
logic [TAGLEN-1:0] TagWay [NUMWAYS-1:0]; logic [TAGLEN-1:0] TagWay [NUMWAYS-1:0];
@ -97,7 +98,7 @@ module cache import cvw::*; #(parameter cvw_t P,
logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache; logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache;
logic SelFetchBuffer; logic SelFetchBuffer;
logic CacheEn; logic CacheEn;
logic SelWay; logic SelVictim;
logic [LINELEN/8-1:0] LineByteMask; logic [LINELEN/8-1:0] LineByteMask;
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
genvar index; genvar index;
@ -119,7 +120,7 @@ module cache import cvw::*; #(parameter cvw_t P,
// Array of cache ways, along with victim, hit, dirty, and read merging logic // Array of cache ways, along with victim, hit, dirty, and read merging logic
cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0]( cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0](
.clk, .reset, .CacheEn, .CacheSetData, .CacheSetTag, .PAdr, .LineWriteData, .LineByteMask, .SelWay, .clk, .reset, .CacheEn, .CacheSetData, .CacheSetTag, .PAdr, .LineWriteData, .LineByteMask, .SelVictim,
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .VictimWay, .SetValid, .ClearValid, .SetDirty, .ClearDirty, .VictimWay,
.FlushWay, .FlushCache, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .HitDirtyWay, .TagWay, .FlushStage, .InvalidateCache); .FlushWay, .FlushCache, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .HitDirtyWay, .TagWay, .FlushStage, .InvalidateCache);
@ -131,7 +132,7 @@ module cache import cvw::*; #(parameter cvw_t P,
end else end else
assign VictimWay = 1'b1; // one hot. assign VictimWay = 1'b1; // one hot.
assign CacheHit = |HitWay; assign Hit = |HitWay;
assign LineDirty = |DirtyWay; assign LineDirty = |DirtyWay;
assign HitLineDirty = |HitDirtyWay; assign HitLineDirty = |HitDirtyWay;
@ -175,18 +176,18 @@ module cache import cvw::*; #(parameter cvw_t P,
logic [LINELEN/8-1:0] BlankByteMask; logic [LINELEN/8-1:0] BlankByteMask;
assign BlankByteMask[WORDLEN/8-1:0] = ByteMask; assign BlankByteMask[WORDLEN/8-1:0] = ByteMask;
assign BlankByteMask[LINELEN/8-1:WORDLEN/8] = '0; assign BlankByteMask[LINELEN/8-1:WORDLEN/8] = 0;
assign DemuxedByteMask = BlankByteMask << ((MUXINTERVAL/8) * WordOffsetAddr); assign DemuxedByteMask = BlankByteMask << ((MUXINTERVAL/8) * WordOffsetAddr);
assign FetchBufferByteSel = SetValid & ~SetDirty ? '1 : ~DemuxedByteMask; // If load miss set all muxes to 1. assign FetchBufferByteSel = SetDirty ? ~DemuxedByteMask : '1; // If load miss set all muxes to 1.
// Merge write data into fetched cache line for store miss // Merge write data into fetched cache line for store miss
for(index = 0; index < LINELEN/8; index++) begin for(index = 0; index < LINELEN/8; index++) begin
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]),
.d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index] & ~CMOpM[3]), .y(LineWriteData[8*index+7:8*index])); .d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index] & ~CMOpM[3]), .y(LineWriteData[8*index+7:8*index]));
end end
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0; assign LineByteMask = SetDirty ? DemuxedByteMask : '1;
end end
else else
begin:WriteSelLogic begin:WriteSelLogic
@ -199,7 +200,7 @@ module cache import cvw::*; #(parameter cvw_t P,
// Flush logic // Flush logic
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
if (!READ_ONLY_CACHE) begin:flushlogic if (!READ_ONLY_CACHE) begin:flushlogic // D$ can be flushed
// Flush address (line number) // Flush address (line number)
assign ResetOrFlushCntRst = reset | FlushCntRst; assign ResetOrFlushCntRst = reset | FlushCntRst;
flopenr #(SETLEN) FlushAdrReg(clk, ResetOrFlushCntRst, FlushAdrCntEn, FlushAdrP1, NextFlushAdr); flopenr #(SETLEN) FlushAdrReg(clk, ResetOrFlushCntRst, FlushAdrCntEn, FlushAdrP1, NextFlushAdr);
@ -213,7 +214,8 @@ module cache import cvw::*; #(parameter cvw_t P,
else assign NextFlushWay = FlushWay[NUMWAYS-1]; else assign NextFlushWay = FlushWay[NUMWAYS-1];
assign FlushWayFlag = FlushWay[NUMWAYS-1]; assign FlushWayFlag = FlushWay[NUMWAYS-1];
end // block: flushlogic end // block: flushlogic
else begin:flushlogic else begin:flushlogic // I$ is never flushed because it is never dirty
assign FlushWay = 0;
assign FlushWayFlag = 0; assign FlushWayFlag = 0;
assign FlushAdrFlag = 0; assign FlushAdrFlag = 0;
end end
@ -224,8 +226,8 @@ module cache import cvw::*; #(parameter cvw_t P,
cachefsm #(P, READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck, cachefsm #(P, READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck,
.FlushStage, .CacheRW, .Stall, .FlushStage, .CacheRW, .Stall,
.CacheHit, .LineDirty, .HitLineDirty, .CacheStall, .CacheCommitted, .Hit, .LineDirty, .HitLineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelWay, .CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelVictim,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,

58
src/cache/cacheLRU.sv vendored
View File

@ -1,7 +1,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// cacheLRU.sv // cacheLRU.sv
// //
// Written: Ross Thompson ross1728@gmail.com // Written: Rose Thompson ross1728@gmail.com
// Created: 20 July 2021 // Created: 20 July 2021
// Modified: 20 January 2023 // Modified: 20 January 2023
// //
@ -10,6 +10,7 @@
// Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.8 and 7.15 to 7.18) // Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.8 and 7.15 to 7.18)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -35,8 +36,8 @@ module cacheLRU
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
input logic [NUMWAYS-1:0] HitWay, // Which way is valid and matches PAdr's tag input logic [NUMWAYS-1:0] HitWay, // Which way is valid and matches PAdr's tag
input logic [NUMWAYS-1:0] ValidWay, // Which ways for a particular set are valid, ignores tag input logic [NUMWAYS-1:0] ValidWay, // Which ways for a particular set are valid, ignores tag
input logic [SETLEN-1:0] CacheSetData, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr input logic [SETLEN-1:0] CacheSetData, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
input logic [SETLEN-1:0] CacheSetTag, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr input logic [SETLEN-1:0] CacheSetTag, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
input logic [SETLEN-1:0] PAdr, // Physical address input logic [SETLEN-1:0] PAdr, // Physical address
input logic LRUWriteEn, // Update the LRU state input logic LRUWriteEn, // Update the LRU state
input logic SetValid, // Set the dirty bit in the selected way and set input logic SetValid, // Set the dirty bit in the selected way and set
@ -50,23 +51,27 @@ module cacheLRU
logic [NUMWAYS-2:0] LRUMemory [NUMLINES-1:0]; logic [NUMWAYS-2:0] LRUMemory [NUMLINES-1:0];
logic [NUMWAYS-2:0] CurrLRU; logic [NUMWAYS-2:0] CurrLRU;
logic [NUMWAYS-2:0] NextLRU; logic [NUMWAYS-2:0] NextLRU;
logic [NUMWAYS-1:0] Way; logic [LOGNUMWAYS-1:0] HitWayEncoded, Way;
logic [LOGNUMWAYS-1:0] WayEncoded;
logic [NUMWAYS-2:0] WayExpanded; logic [NUMWAYS-2:0] WayExpanded;
logic AllValid; logic AllValid;
genvar row; genvar row;
/* verilator lint_off UNOPTFLAT */ /* verilator lint_off UNOPTFLAT */
// Ross: For some reason verilator does not like this. I checked and it is not a circular path. // Rose: For some reason verilator does not like this. I checked and it is not a circular path.
logic [NUMWAYS-2:0] LRUUpdate; logic [NUMWAYS-2:0] LRUUpdate;
logic [LOGNUMWAYS-1:0] Intermediate [NUMWAYS-2:0]; logic [LOGNUMWAYS-1:0] Intermediate [NUMWAYS-2:0];
/* verilator lint_on UNOPTFLAT */ /* verilator lint_on UNOPTFLAT */
logic [NUMWAYS-1:0] FirstZero;
logic [LOGNUMWAYS-1:0] FirstZeroWay;
logic [LOGNUMWAYS-1:0] VictimWayEnc;
binencoder #(NUMWAYS) hitwayencoder(HitWay, HitWayEncoded);
assign AllValid = &ValidWay; assign AllValid = &ValidWay;
///// Update replacement bits. ///// Update replacement bits.
// coverage off // coverage off
// Excluded from coverage b/c it is untestable without varying NUMWAYS. // Excluded from coverage b/c it is untestable without varying NUMWAYS.
function integer log2 (integer value); function integer log2 (integer value);
@ -79,8 +84,7 @@ module cacheLRU
// coverage on // coverage on
// On a miss we need to ignore HitWay and derive the new replacement bits with the VictimWay. // On a miss we need to ignore HitWay and derive the new replacement bits with the VictimWay.
mux2 #(NUMWAYS) WayMux(HitWay, VictimWay, SetValid, Way); mux2 #(LOGNUMWAYS) WayMuxEnc(HitWayEncoded, VictimWayEnc, SetValid, Way);
binencoder #(NUMWAYS) encoder(Way, WayEncoded);
// bit duplication // bit duplication
// expand HitWay as HitWay[3], {{2}{HitWay[2]}}, {{4}{HitWay[1]}, {{8{HitWay[0]}}, ... // expand HitWay as HitWay[3], {{2}{HitWay[2]}}, {{4}{HitWay[1]}, {{8{HitWay[0]}}, ...
@ -88,7 +92,7 @@ module cacheLRU
localparam integer DuplicationFactor = 2**(LOGNUMWAYS-row-1); localparam integer DuplicationFactor = 2**(LOGNUMWAYS-row-1);
localparam StartIndex = NUMWAYS-2 - DuplicationFactor + 1; localparam StartIndex = NUMWAYS-2 - DuplicationFactor + 1;
localparam EndIndex = NUMWAYS-2 - 2 * DuplicationFactor + 2; localparam EndIndex = NUMWAYS-2 - 2 * DuplicationFactor + 2;
assign WayExpanded[StartIndex : EndIndex] = {{DuplicationFactor}{WayEncoded[row]}}; assign WayExpanded[StartIndex : EndIndex] = {{DuplicationFactor}{Way[row]}};
end end
genvar node; genvar node;
@ -101,14 +105,14 @@ module cacheLRU
localparam r = LOGNUMWAYS - ctr_depth; localparam r = LOGNUMWAYS - ctr_depth;
// the child node will be updated if its parent was updated and // the child node will be updated if its parent was updated and
// the WayEncoded bit was the correct value. // the Way bit was the correct value.
// The if statement is only there for coverage since LRUUpdate[root] is always 1. // The if statement is only there for coverage since LRUUpdate[root] is always 1.
if (node == NUMWAYS-2) begin if (node == NUMWAYS-2) begin
assign LRUUpdate[lchild] = ~WayEncoded[r]; assign LRUUpdate[lchild] = ~Way[r];
assign LRUUpdate[rchild] = WayEncoded[r]; assign LRUUpdate[rchild] = Way[r];
end else begin end else begin
assign LRUUpdate[lchild] = LRUUpdate[node] & ~WayEncoded[r]; assign LRUUpdate[lchild] = LRUUpdate[node] & ~Way[r];
assign LRUUpdate[rchild] = LRUUpdate[node] & WayEncoded[r]; assign LRUUpdate[rchild] = LRUUpdate[node] & Way[r];
end end
end end
@ -128,30 +132,26 @@ module cacheLRU
assign Intermediate[node] = CurrLRU[node] ? int1[LOGNUMWAYS-1:0] : int0[LOGNUMWAYS-1:0]; assign Intermediate[node] = CurrLRU[node] ? int1[LOGNUMWAYS-1:0] : int0[LOGNUMWAYS-1:0];
end end
logic [NUMWAYS-1:0] FirstZero;
logic [LOGNUMWAYS-1:0] FirstZeroWay;
logic [LOGNUMWAYS-1:0] VictimWayEnc;
priorityonehot #(NUMWAYS) FirstZeroEncoder(~ValidWay, FirstZero); priorityonehot #(NUMWAYS) FirstZeroEncoder(~ValidWay, FirstZero);
binencoder #(NUMWAYS) FirstZeroWayEncoder(FirstZero, FirstZeroWay); binencoder #(NUMWAYS) FirstZeroWayEncoder(FirstZero, FirstZeroWay);
mux2 #(LOGNUMWAYS) VictimMux(FirstZeroWay, Intermediate[NUMWAYS-2], AllValid, VictimWayEnc); mux2 #(LOGNUMWAYS) VictimMux(FirstZeroWay, Intermediate[NUMWAYS-2], AllValid, VictimWayEnc);
//decoder #(LOGNUMWAYS) decoder (Intermediate[NUMWAYS-2], VictimWay);
decoder #(LOGNUMWAYS) decoder (VictimWayEnc, VictimWay); decoder #(LOGNUMWAYS) decoder (VictimWayEnc, VictimWay);
// LRU storage must be reset for modelsim to run. However the reset value does not actually matter in practice. // LRU storage must be reset for modelsim to run. However the reset value does not actually matter in practice.
// This is a two port memory. // This is a two port memory.
// Every cycle must read from CacheSetData and each load/store must write the new LRU. // Every cycle must read from CacheSetData and each load/store must write the new LRU.
// note: Verilator lint doesn't like <= for array initialization (https://verilator.org/warn/BLKLOOPINIT?v=5.021)
// Move to = to keep Verilator happy and simulator running fast
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (reset | (InvalidateCache & ~FlushStage)) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; if (reset | (InvalidateCache & ~FlushStage))
if(CacheEn) begin for (int set = 0; set < NUMLINES; set++) LRUMemory[set] = 0; // exclusion-tag: initialize
if(ClearValid & ~FlushStage) else if(CacheEn) begin
LRUMemory[PAdr] <= '0; // Because we are using blocking assignments, change to LRUMemory must occur after LRUMemory is used so we get the proper value
else if(LRUWriteEn) if(LRUWriteEn & (PAdr == CacheSetTag)) CurrLRU = #1 NextLRU;
LRUMemory[PAdr] <= NextLRU; else CurrLRU = #1 LRUMemory[CacheSetTag];
if(LRUWriteEn & (PAdr == CacheSetTag)) if(LRUWriteEn) LRUMemory[PAdr] = NextLRU;
CurrLRU <= #1 NextLRU;
else
CurrLRU <= #1 LRUMemory[CacheSetTag];
end end
end end

87
src/cache/cachefsm.sv vendored
View File

@ -10,6 +10,7 @@
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.14 and Table 7.1) // Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.14 and Table 7.1)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -49,7 +50,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
output logic CacheAccess, // Cache access output logic CacheAccess, // Cache access
// cache internals // cache internals
input logic CacheHit, // Exactly 1 way hits input logic Hit, // Exactly 1 way hits
input logic LineDirty, // The selected line and way is dirty input logic LineDirty, // The selected line and way is dirty
input logic HitLineDirty, // The cache hit way is dirty input logic HitLineDirty, // The cache hit way is dirty
input logic FlushAdrFlag, // On last set of a cache flush input logic FlushAdrFlag, // On last set of a cache flush
@ -62,7 +63,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
output logic ClearDirty, // Clear the dirty bit in the selected way and set output logic ClearDirty, // Clear the dirty bit in the selected way and set
output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
output logic LRUWriteEn, // Update the LRU state output logic LRUWriteEn, // Update the LRU state
output logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway output logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
output logic FlushAdrCntEn, // Enable the counter for Flush Adr output logic FlushAdrCntEn, // Enable the counter for Flush Adr
output logic FlushWayCntEn, // Enable the way counter during a flush output logic FlushWayCntEn, // Enable the way counter during a flush
output logic FlushCntRst, // Reset both flush counters output logic FlushCntRst, // Reset both flush counters
@ -78,12 +79,12 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
logic CMOZeroNoEviction; logic CMOZeroNoEviction;
logic StallConditions; logic StallConditions;
typedef enum logic [3:0]{STATE_READY, // hit states typedef enum logic [3:0]{STATE_ACCESS, // hit states
// miss states // miss states
STATE_FETCH, STATE_FETCH,
STATE_WRITEBACK, STATE_WRITEBACK,
STATE_WRITE_LINE, STATE_WRITE_LINE,
STATE_READ_HOLD, // required for back to back reads. structural hazard on writting SRAM STATE_ADDRESS_SETUP, // required for back to back reads. structural hazard on writting SRAM
// flush cache // flush cache
STATE_FLUSH, STATE_FLUSH,
STATE_FLUSH_WRITEBACK STATE_FLUSH_WRITEBACK
@ -91,61 +92,60 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
statetype CurrState, NextState; statetype CurrState, NextState;
assign AnyMiss = (CacheRW[0] | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss assign AnyMiss = (CacheRW[0] | CacheRW[1]) & ~Hit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
assign AnyUpdateHit = (CacheRW[0]) & CacheHit; // exclusion-tag: icache storeAMO1 assign AnyUpdateHit = (CacheRW[0]) & Hit; // exclusion-tag: icache storeAMO1
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit assign AnyHit = AnyUpdateHit | (CacheRW[1] & Hit); // exclusion-tag: icache AnyUpdateHit
assign CMOZeroNoEviction = CMOpM[3] & ~LineDirty; // (hit or miss) with no writeback store zeros now assign CMOZeroNoEviction = CMOpM[3] & ~LineDirty; // (hit or miss) with no writeback store zeros now
assign CMOWriteback = ((CMOpM[1] | CMOpM[2]) & CacheHit & HitLineDirty) | CMOpM[3] & LineDirty; assign CMOWriteback = ((CMOpM[1] | CMOpM[2]) & Hit & HitLineDirty) | CMOpM[3] & LineDirty;
assign FlushFlag = FlushAdrFlag & FlushWayFlag; assign FlushFlag = FlushAdrFlag & FlushWayFlag;
// outputs for the performance counters. // outputs for the performance counters.
assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW assign CacheAccess = (|CacheRW) & ((CurrState == STATE_ACCESS & ~Stall & ~FlushStage) | (CurrState == STATE_ADDRESS_SETUP & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW
assign CacheMiss = CacheAccess & ~CacheHit; assign CacheMiss = CacheAccess & ~Hit;
// special case on reset. When the fsm first exists reset the // special case on reset. When the fsm first exists reset twayhe
// PCNextF will no longer be pointing to the correct address. // PCNextF will no longer be pointing to the correct address.
// But PCF will be the reset vector. // But PCF will be the reset vector.
flop #(1) resetDelayReg(.clk, .d(reset), .q(resetDelay)); flop #(1) resetDelayReg(.clk, .d(reset), .q(resetDelay));
always_ff @(posedge clk) always_ff @(posedge clk)
if (reset | FlushStage) CurrState <= #1 STATE_READY; if (reset | FlushStage) CurrState <= #1 STATE_ACCESS;
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
always_comb begin always_comb begin
NextState = STATE_READY; NextState = STATE_ACCESS;
case (CurrState) // exclusion-tag: icache state-case case (CurrState) // exclusion-tag: icache state-case
STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck STATE_ACCESS: if(InvalidateCache) NextState = STATE_ACCESS; // exclusion-tag: dcache InvalidateCheck
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; // exclusion-tag: icache FLUSHStatement
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
else if(AnyMiss | CMOWriteback) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement else if((AnyMiss | CMOWriteback) & ~READ_ONLY_CACHE) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
else NextState = STATE_READY; else NextState = STATE_ACCESS;
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE; STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
else if(CacheBusAck) NextState = STATE_READY;
else NextState = STATE_FETCH; else NextState = STATE_FETCH;
STATE_WRITE_LINE: NextState = STATE_READ_HOLD; STATE_WRITE_LINE: NextState = STATE_ADDRESS_SETUP;
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD; STATE_ADDRESS_SETUP: if(Stall) NextState = STATE_ADDRESS_SETUP;
else NextState = STATE_READY; else NextState = STATE_ACCESS;
// exclusion-tag-start: icache case // exclusion-tag-start: icache case
STATE_WRITEBACK: if(CacheBusAck & ~(|CMOpM[3:1])) NextState = STATE_FETCH; STATE_WRITEBACK: if(CacheBusAck & ~(|CMOpM[3:1])) NextState = STATE_FETCH;
else if(CacheBusAck) NextState = STATE_READ_HOLD; // Read_hold lowers CacheStall else if(CacheBusAck) NextState = STATE_ADDRESS_SETUP; // Read_hold lowers CacheStall
else NextState = STATE_WRITEBACK; else NextState = STATE_WRITEBACK;
// eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack. // eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack.
STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK; STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK;
else if (FlushFlag) NextState = STATE_READ_HOLD; else if (FlushFlag) NextState = STATE_ADDRESS_SETUP;
else NextState = STATE_FLUSH; else NextState = STATE_FLUSH;
STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH; STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH;
else if(CacheBusAck) NextState = STATE_READ_HOLD; else if(CacheBusAck) NextState = STATE_ADDRESS_SETUP;
else NextState = STATE_FLUSH_WRITEBACK; else NextState = STATE_FLUSH_WRITEBACK;
// exclusion-tag-end: icache case // exclusion-tag-end: icache case
default: NextState = STATE_READY; default: NextState = STATE_ACCESS;
endcase endcase
end end
// com back to CPU // com back to CPU
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD)); assign CacheCommitted = (CurrState != STATE_ACCESS) & ~(READ_ONLY_CACHE & (CurrState == STATE_ADDRESS_SETUP));
assign StallConditions = FlushCache | AnyMiss | CMOWriteback; assign StallConditions = FlushCache | AnyMiss | CMOWriteback; // exclusion-tag: icache FlushCache
assign CacheStall = (CurrState == STATE_READY & StallConditions) | // exclusion-tag: icache StallStates assign CacheStall = (CurrState == STATE_ACCESS & StallConditions) | // exclusion-tag: icache StallStates
(CurrState == STATE_FETCH) | (CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) | // this cycle writes the sram, must keep stalling so the next cycle can read the next hit/miss unless its a write. (CurrState == STATE_WRITE_LINE) | // this cycle writes the sram, must keep stalling so the next cycle can read the next hit/miss unless its a write.
@ -153,27 +153,26 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
(CurrState == STATE_FLUSH_WRITEBACK); (CurrState == STATE_FLUSH_WRITEBACK);
// write enables internal to cache // write enables internal to cache
assign SetValid = CurrState == STATE_WRITE_LINE | assign SetValid = CurrState == STATE_WRITE_LINE |
(CurrState == STATE_READY & CMOZeroNoEviction) | (CurrState == STATE_ACCESS & CMOZeroNoEviction) |
(CurrState == STATE_WRITEBACK & CacheBusAck & CMOpM[3]); (CurrState == STATE_WRITEBACK & CacheBusAck & CMOpM[3]);
assign ClearValid = (CurrState == STATE_READY & CMOpM[0]) | assign ClearValid = (CurrState == STATE_ACCESS & CMOpM[0]) |
(CurrState == STATE_WRITEBACK & CMOpM[2] & CacheBusAck); (CurrState == STATE_WRITEBACK & CMOpM[2] & CacheBusAck);
// coverage off -item e 1 -fecexprrow 8 assign LRUWriteEn = (((CurrState == STATE_ACCESS & (AnyHit | CMOZeroNoEviction)) |
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) | (CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
(CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck); (CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck);
// exclusion-tag-start: icache flushdirtycontrols // exclusion-tag-start: icache flushdirtycontrols
assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty assign SetDirty = (CurrState == STATE_ACCESS & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty
(CurrState == STATE_WRITE_LINE & (CacheRW[0])) | (CurrState == STATE_WRITE_LINE & (CacheRW[0])) |
(CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck)); (CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck));
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty
(CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set. (CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
// Flush and eviction controls // Flush and eviction controls
CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck; CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck;
assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) | assign SelVictim = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
(CurrState == STATE_READY & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) | (CurrState == STATE_ACCESS & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~Hit))) |
(CurrState == STATE_WRITE_LINE); (CurrState == STATE_WRITE_LINE);
assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2] | ~CacheBusAck)) | assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2] | ~CacheBusAck)) |
(CurrState == STATE_READY & AnyMiss & LineDirty); (CurrState == STATE_ACCESS & AnyMiss & LineDirty);
// coverage off -item e 1 -fecexprrow 1 // coverage off -item e 1 -fecexprrow 1
// (state is always FLUSH_WRITEBACK when FlushWayFlag & CacheBusAck) // (state is always FLUSH_WRITEBACK when FlushWayFlag & CacheBusAck)
assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) | assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) |
@ -184,31 +183,29 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
(CurrState == STATE_FLUSH_WRITEBACK & FlushFlag & CacheBusAck); (CurrState == STATE_FLUSH_WRITEBACK & FlushFlag & CacheBusAck);
// exclusion-tag-end: icache flushdirtycontrols // exclusion-tag-end: icache flushdirtycontrols
// Bus interface controls // Bus interface controls
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses assign CacheBusRW[1] = (CurrState == STATE_ACCESS & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses
(CurrState == STATE_FETCH & ~CacheBusAck) | (CurrState == STATE_FETCH & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOpM)); (CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOpM));
logic LoadMiss; logic LoadMiss;
assign LoadMiss = (CacheRW[1]) & ~Hit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
//assign StoreMiss = (CacheRW[0]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
assign LoadMiss = (CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
assign CacheBusRW[0] = (CurrState == STATE_READY & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW assign CacheBusRW[0] = (CurrState == STATE_ACCESS & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW
(CurrState == STATE_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & ~CacheBusAck); (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & ~CacheBusAck);
assign SelAdrData = (CurrState == STATE_READY & (CacheRW[0] | AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed assign SelAdrData = (CurrState == STATE_ACCESS & (CacheRW[0] | AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
(CurrState == STATE_FETCH) | (CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) | (CurrState == STATE_WRITE_LINE) |
resetDelay; resetDelay;
assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed assign SelAdrTag = (CurrState == STATE_ACCESS & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrTag // changes if store delay hazard removed
(CurrState == STATE_FETCH) | (CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) | (CurrState == STATE_WRITE_LINE) |
resetDelay; resetDelay;
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD; assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_ADDRESS_SETUP;
assign CacheEn = (~Stall | StallConditions) | (CurrState != STATE_READY) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn assign CacheEn = (~Stall | StallConditions) | (CurrState != STATE_ACCESS) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
endmodule // cachefsm endmodule // cachefsm

48
src/cache/cacheway.sv vendored
View File

@ -10,6 +10,7 @@
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.11) // Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.11)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -41,7 +42,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
input logic SetValid, // Set the valid bit in the selected way and set input logic SetValid, // Set the valid bit in the selected way and set
input logic ClearValid, // Clear the valid bit in the selected way and set input logic ClearValid, // Clear the valid bit in the selected way and set
input logic SetDirty, // Set the dirty bit in the selected way and set input logic SetDirty, // Set the dirty bit in the selected way and set
input logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway input logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
input logic ClearDirty, // Clear the dirty bit in the selected way and set input logic ClearDirty, // Clear the dirty bit in the selected way and set
input logic FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr input logic FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
input logic VictimWay, // LRU selected this way as victim to evict input logic VictimWay, // LRU selected this way as victim to evict
@ -52,7 +53,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
output logic [LINELEN-1:0] ReadDataLineWay,// This way's read data if valid output logic [LINELEN-1:0] ReadDataLineWay,// This way's read data if valid
output logic HitWay, // This way hits output logic HitWay, // This way hits
output logic ValidWay, // This way is valid output logic ValidWay, // This way is valid
output logic HitDirtyWay, // The hit way is dirty output logic HitDirtyWay, // The hit way is dirty
output logic DirtyWay , // The selected way is dirty output logic DirtyWay , // The selected way is dirty
output logic [TAGLEN-1:0] TagWay); // This way's tag if valid output logic [TAGLEN-1:0] TagWay); // This way's tag if valid
@ -67,7 +68,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
logic [LINELEN-1:0] ReadDataLine; logic [LINELEN-1:0] ReadDataLine;
logic [TAGLEN-1:0] ReadTag; logic [TAGLEN-1:0] ReadTag;
logic Dirty; logic Dirty;
logic SelDirty; logic SelecteDirty;
logic SelectedWriteWordEn; logic SelectedWriteWordEn;
logic [LINELEN/8-1:0] FinalByteMask; logic [LINELEN/8-1:0] FinalByteMask;
logic SetValidEN, ClearValidEN; logic SetValidEN, ClearValidEN;
@ -76,36 +77,33 @@ module cacheway import cvw::*; #(parameter cvw_t P,
logic SetDirtyWay; logic SetDirtyWay;
logic ClearDirtyWay; logic ClearDirtyWay;
logic SelNonHit; logic SelNonHit;
logic SelData; logic SelectedWay;
logic InvalidateCacheDelay; logic InvalidateCacheDelay;
if (!READ_ONLY_CACHE) begin:flushlogic if (!READ_ONLY_CACHE) begin:flushlogic
logic FlushWayEn; mux2 #(1) seltagmux(VictimWay, FlushWay, FlushCache, SelecteDirty);
mux2 #(1) seltagmux(VictimWay, FlushWay, FlushCache, SelDirty); mux3 #(1) selectedmux(HitWay, FlushWay, VictimWay, {SelVictim, FlushCache}, SelectedWay);
// FlushWay is part of a one hot way selection. Must clear it if FlushWay not selected. // FlushWay is part of a one hot way selection. Must clear it if FlushWay not selected.
// coverage off -item e 1 -fecexprrow 3 // coverage off -item e 1 -fecexprrow 3
// nonzero ways will never see FlushCache=0 while FlushWay=1 since FlushWay only advances on a subset of FlushCache assertion cases. // nonzero ways will never see FlushCache=0 while FlushWay=1 since FlushWay only advances on a subset of FlushCache assertion cases.
assign FlushWayEn = FlushWay & FlushCache;
assign SelNonHit = FlushWayEn | SelWay;
end else begin:flushlogic // no flush operation for read-only caches. end else begin:flushlogic // no flush operation for read-only caches.
assign SelDirty = VictimWay; assign SelecteDirty = VictimWay;
assign SelNonHit = SelWay; mux2 #(1) selectedwaymux(HitWay, SelecteDirty, SelVictim , SelectedWay);
end end
mux2 #(1) selectedwaymux(HitWay, SelDirty, SelNonHit , SelData);
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Enable demux // Write Enable demux
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
assign SetValidWay = SetValid & SelData; assign SetValidWay = SetValid & SelectedWay;
assign ClearValidWay = ClearValid & SelData; assign ClearValidWay = ClearValid & SelectedWay; // exclusion-tag: icache ClearValidWay
assign SetDirtyWay = SetDirty & SelData; // exclusion-tag: icache SetDirtyWay assign SetDirtyWay = SetDirty & SelectedWay; // exclusion-tag: icache SetDirtyWay
assign ClearDirtyWay = ClearDirty & SelData; assign ClearDirtyWay = ClearDirty & SelectedWay;
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn
assign SetValidEN = SetValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN assign SetValidEN = SetValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN
assign ClearValidEN = ClearValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN assign ClearValidEN = ClearValidWay & ~FlushStage; // exclusion-tag: cache ClearValidEN
// If writing the whole line set all write enables to 1, else only set the correct word. // If writing the whole line set all write enables to 1, else only set the correct word.
assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR
@ -119,10 +117,10 @@ module cacheway import cvw::*; #(parameter cvw_t P,
.din(PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN)); .din(PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
// AND portion of distributed tag multiplexer // AND portion of distributed tag multiplexer
assign TagWay = SelData ? ReadTag : '0; // AND part of AOMux assign TagWay = SelectedWay ? ReadTag : 0; // AND part of AOMux
assign HitDirtyWay = Dirty & ValidWay; assign HitDirtyWay = Dirty & ValidWay;
assign DirtyWay = SelDirty & HitDirtyWay; assign DirtyWay = SelecteDirty & HitDirtyWay; // exclusion-tag: icache DirtyWay
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay; assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay; // exclusion-tag: dcache HitWay
flop #(1) InvalidateCacheReg(clk, InvalidateCache, InvalidateCacheDelay); flop #(1) InvalidateCacheReg(clk, InvalidateCache, InvalidateCacheDelay);
@ -151,19 +149,19 @@ module cacheway import cvw::*; #(parameter cvw_t P,
end end
// AND portion of distributed read multiplexers // AND portion of distributed read multiplexers
assign ReadDataLineWay = SelData ? ReadDataLine : '0; // AND part of AO mux. assign ReadDataLineWay = SelectedWay ? ReadDataLine : 0; // AND part of AO mux.
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Valid Bits // Valid Bits
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
always_ff @(posedge clk) begin // Valid bit array, always_ff @(posedge clk) begin // Valid bit array,
if (reset) ValidBits <= #1 '0; if (reset) ValidBits <= #1 0;
if(CacheEn) begin if(CacheEn) begin
ValidWay <= #1 ValidBits[CacheSetTag]; ValidWay <= #1 ValidBits[CacheSetTag];
if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway if(InvalidateCache) ValidBits <= #1 0; // exclusion-tag: dcache invalidateway
else if (SetValidEN) ValidBits[CacheSetData] <= #1 SetValidWay; else if (SetValidEN) ValidBits[CacheSetData] <= #1 SetValidWay;
else if (ClearValidEN) ValidBits[CacheSetData] <= #1 '0; else if (ClearValidEN) ValidBits[CacheSetData] <= #1 0; // exclusion-tag: icache ClearValidBits
end end
end end
@ -178,7 +176,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
//if (reset) DirtyBits <= #1 {NUMLINES{1'b0}}; //if (reset) DirtyBits <= #1 {NUMLINES{1'b0}};
if(CacheEn) begin if(CacheEn) begin
Dirty <= #1 DirtyBits[CacheSetTag]; Dirty <= #1 DirtyBits[CacheSetTag];
if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CacheSetData] <= #1 SetDirtyWay; if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CacheSetData] <= #1 SetDirtyWay; // exclusion-tag: cache UpdateDirty
end end
end end
end else assign Dirty = 1'b0; end else assign Dirty = 1'b0;

View File

@ -10,6 +10,7 @@
// Documentation: RISC-V System on Chip Design Chapter 7 // Documentation: RISC-V System on Chip Design Chapter 7
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

View File

@ -41,6 +41,8 @@ typedef struct packed {
logic IEEE754; // IEEE754 NaN handling (0 = use RISC-V NaN propagation instead) logic IEEE754; // IEEE754 NaN handling (0 = use RISC-V NaN propagation instead)
int MISA; // Machine Instruction Set Architecture int MISA; // Machine Instruction Set Architecture
int AHBW; // AHB bus width (usually = XLEN) int AHBW; // AHB bus width (usually = XLEN)
int RAM_LATENCY; // Latency to stress AHB
logic BURST_EN; // Support AHB Burst Mode
// RISC-V Features // RISC-V Features
logic ZICSR_SUPPORTED; logic ZICSR_SUPPORTED;
@ -160,6 +162,7 @@ typedef struct packed {
int BPRED_SIZE; int BPRED_SIZE;
int BTB_SIZE; int BTB_SIZE;
int RAS_SIZE; int RAS_SIZE;
logic INSTR_CLASS_PRED; // is class predictor enabled
// FPU division architecture // FPU division architecture
int RADIX; int RADIX;

View File

@ -10,6 +10,7 @@
// Documentation: RISC-V System on Chip Design Chapter 9 (Figure 9.8) // Documentation: RISC-V System on Chip Design Chapter 9 (Figure 9.8)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -27,10 +28,8 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module ahbcacheinterface #( module ahbcacheinterface import cvw::*; #(
parameter AHBW, parameter cvw_t P,
parameter LLEN,
parameter PA_BITS,
parameter BEATSPERLINE, // Number of AHBW words (beats) in cacheline parameter BEATSPERLINE, // Number of AHBW words (beats) in cacheline
parameter AHBWLOGBWPL, // Log2 of ^ parameter AHBWLOGBWPL, // Log2 of ^
parameter LINELEN, // Number of bits in cacheline parameter LINELEN, // Number of bits in cacheline
@ -45,14 +44,14 @@ module ahbcacheinterface #(
output logic [2:0] HSIZE, // AHB transaction width output logic [2:0] HSIZE, // AHB transaction width
output logic [2:0] HBURST, // AHB burst length output logic [2:0] HBURST, // AHB burst length
// bus interface buses // bus interface buses
input logic [AHBW-1:0] HRDATA, // AHB read data input logic [P.AHBW-1:0] HRDATA, // AHB read data
output logic [PA_BITS-1:0] HADDR, // AHB address output logic [P.PA_BITS-1:0] HADDR, // AHB address
output logic [AHBW-1:0] HWDATA, // AHB write data output logic [P.AHBW-1:0] HWDATA, // AHB write data
output logic [AHBW/8-1:0] HWSTRB, // AHB byte mask output logic [P.AHBW/8-1:0] HWSTRB, // AHB byte mask
// cache interface // cache interface
input logic [PA_BITS-1:0] CacheBusAdr, // Address of cache line input logic [P.PA_BITS-1:0] CacheBusAdr, // Address of cache line
input logic [LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback input logic [P.LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$ input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$
input logic Cacheable, // Memory operation is cachable input logic Cacheable, // Memory operation is cachable
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
@ -62,8 +61,8 @@ module ahbcacheinterface #(
output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr
// uncached interface // uncached interface
input logic [PA_BITS-1:0] PAdr, // Physical address of uncached memory operation input logic [P.PA_BITS-1:0] PAdr, // Physical address of uncached memory operation
input logic [LLEN-1:0] WriteDataM, // IEU write data for uncached store input logic [P.LLEN-1:0] WriteDataM, // IEU write data for uncached store
input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write
input logic BusAtomic, // Uncache atomic memory operation input logic BusAtomic, // Uncache atomic memory operation
input logic [2:0] Funct3, // Size of uncached memory operation input logic [2:0] Funct3, // Size of uncached memory operation
@ -77,12 +76,12 @@ module ahbcacheinterface #(
localparam BeatCountThreshold = BEATSPERLINE - 1; // Largest beat index localparam BeatCountThreshold = BEATSPERLINE - 1; // Largest beat index
logic [PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation logic [P.PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation
logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage
logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA
logic [AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s logic [P.AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s
logic [AHBW-1:0] PreHWDATA; // AHB Address phase write data logic [P.AHBW-1:0] PreHWDATA; // AHB Address phase write data
logic [PA_BITS-1:0] PAdrZero; logic [P.PA_BITS-1:0] PAdrZero;
genvar index; genvar index;
@ -90,38 +89,38 @@ module ahbcacheinterface #(
for (index = 0; index < BEATSPERLINE; index++) begin:fetchbuffer for (index = 0; index < BEATSPERLINE; index++) begin:fetchbuffer
logic [BEATSPERLINE-1:0] CaptureBeat; logic [BEATSPERLINE-1:0] CaptureBeat;
assign CaptureBeat[index] = CaptureEn & (index == BeatCountDelayed); assign CaptureBeat[index] = CaptureEn & (index == BeatCountDelayed);
flopen #(AHBW) fb(.clk(HCLK), .en(CaptureBeat[index]), .d(HRDATA), flopen #(P.AHBW) fb(.clk(HCLK), .en(CaptureBeat[index]), .d(HRDATA),
.q(FetchBuffer[(index+1)*AHBW-1:index*AHBW])); .q(FetchBuffer[(index+1)*P.AHBW-1:index*P.AHBW]));
end end
assign PAdrZero = BusCMOZero ? {PAdr[PA_BITS-1:$clog2(LINELEN/8)], {$clog2(LINELEN/8){1'b0}}} : PAdr; assign PAdrZero = BusCMOZero ? {PAdr[P.PA_BITS-1:$clog2(LINELEN/8)], {$clog2(LINELEN/8){1'b0}}} : PAdr;
mux2 #(PA_BITS) localadrmux(PAdrZero, CacheBusAdr, Cacheable, LocalHADDR); mux2 #(P.PA_BITS) localadrmux(PAdrZero, CacheBusAdr, Cacheable, LocalHADDR);
assign HADDR = ({{PA_BITS-AHBWLOGBWPL{1'b0}}, BeatCount} << $clog2(AHBW/8)) + LocalHADDR; assign HADDR = ({{P.PA_BITS-AHBWLOGBWPL{1'b0}}, BeatCount} << $clog2(P.AHBW/8)) + LocalHADDR;
mux2 #(3) sizemux(.d0(Funct3), .d1(AHBW == 32 ? 3'b010 : 3'b011), .s(Cacheable | BusCMOZero), .y(HSIZE)); mux2 #(3) sizemux(.d0(Funct3), .d1(P.AHBW == 32 ? 3'b010 : 3'b011), .s(Cacheable | BusCMOZero), .y(HSIZE));
// When AHBW is less than LLEN need extra muxes to select the subword from cache's read data. // When AHBW is less than LLEN need extra muxes to select the subword from cache's read data.
logic [AHBW-1:0] CacheReadDataWordAHB; logic [P.AHBW-1:0] CacheReadDataWordAHB;
if(LLENPOVERAHBW > 1) begin if(LLENPOVERAHBW > 1) begin
logic [AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0]; logic [P.AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0];
genvar index; genvar index;
for (index = 0; index < LLENPOVERAHBW; index++) begin:readdatalinesetsmux for (index = 0; index < LLENPOVERAHBW; index++) begin:readdatalinesetsmux
assign AHBWordSets[index] = CacheReadDataWordM[(index*AHBW)+AHBW-1: (index*AHBW)]; assign AHBWordSets[index] = CacheReadDataWordM[(index*P.AHBW)+P.AHBW-1: (index*P.AHBW)];
end end
assign CacheReadDataWordAHB = AHBWordSets[BeatCount[$clog2(LLENPOVERAHBW)-1:0]]; assign CacheReadDataWordAHB = AHBWordSets[BeatCount[$clog2(LLENPOVERAHBW)-1:0]];
end else assign CacheReadDataWordAHB = CacheReadDataWordM[AHBW-1:0]; end else assign CacheReadDataWordAHB = CacheReadDataWordM[P.AHBW-1:0];
mux2 #(AHBW) HWDATAMux(.d0(CacheReadDataWordAHB), .d1(WriteDataM[AHBW-1:0]), mux2 #(P.AHBW) HWDATAMux(.d0(CacheReadDataWordAHB), .d1(WriteDataM[P.AHBW-1:0]),
.s(~(CacheableOrFlushCacheM)), .y(PreHWDATA)); .s(~(CacheableOrFlushCacheM)), .y(PreHWDATA));
flopen #(AHBW) wdreg(HCLK, HREADY, PreHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec flopen #(P.AHBW) wdreg(HCLK, HREADY, PreHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec
// *** bummer need a second byte mask for bus as it is AHBW rather than LLEN. // *** bummer need a second byte mask for bus as it is AHBW rather than LLEN.
// probably can merge by muxing PAdrM's LLEN/8-1 index bit based on HTRANS being != 0. // probably can merge by muxing PAdrM's LLEN/8-1 index bit based on HTRANS being != 0.
swbytemask #(AHBW) busswbytemask(.Size(HSIZE), .Adr(HADDR[$clog2(AHBW/8)-1:0]), .ByteMask(BusByteMaskM), .ByteMaskExtended()); swbytemask #(P.AHBW) busswbytemask(.Size(HSIZE), .Adr(HADDR[$clog2(P.AHBW/8)-1:0]), .ByteMask(BusByteMaskM), .ByteMaskExtended());
flopen #(AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[AHBW/8-1:0], HWSTRB); flopen #(P.AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[P.AHBW/8-1:0], HWSTRB);
buscachefsm #(BeatCountThreshold, AHBWLOGBWPL, READ_ONLY_CACHE) AHBBuscachefsm( buscachefsm #(BeatCountThreshold, AHBWLOGBWPL, READ_ONLY_CACHE, P.BURST_EN) AHBBuscachefsm(
.HCLK, .HRESETn, .Flush, .BusRW, .BusAtomic, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat, .HCLK, .HRESETn, .Flush, .BusRW, .BusAtomic, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat,
.CacheBusRW, .BusCMOZero, .CacheBusAck, .BeatCount, .BeatCountDelayed, .CacheBusRW, .BusCMOZero, .CacheBusAck, .BeatCount, .BeatCountDelayed,
.HREADY, .HTRANS, .HWRITE, .HBURST); .HREADY, .HTRANS, .HWRITE, .HBURST);

View File

@ -10,6 +10,7 @@
// Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.21) // Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.21)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -61,8 +62,8 @@ module ahbinterface #(
flop #(XLEN) wdreg(HCLK, WriteData, HWDATA); flop #(XLEN) wdreg(HCLK, WriteData, HWDATA);
flop #(XLEN/8) HWSTRBReg(HCLK, ByteMask, HWSTRB); flop #(XLEN/8) HWSTRBReg(HCLK, ByteMask, HWSTRB);
end else begin end else begin
assign HWDATA = '0; assign HWDATA = 0;
assign HWSTRB = '0; assign HWSTRB = 0;
end end
busfsm #(~LSU) busfsm(.HCLK, .HRESETn, .Flush, .BusRW, .BusAtomic, busfsm #(~LSU) busfsm(.HCLK, .HRESETn, .Flush, .BusRW, .BusAtomic,

View File

@ -10,6 +10,7 @@
// Documentation: RISC-V System on Chip Design Chapter 9 (Figure 9.9) // Documentation: RISC-V System on Chip Design Chapter 9 (Figure 9.9)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -27,13 +28,12 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`define BURST_EN 1 // Enables burst mode. Disable to show the lost performance.
// HCLK and clk must be the same clock! // HCLK and clk must be the same clock!
module buscachefsm #( module buscachefsm #(
parameter BeatCountThreshold, // Largest beat index parameter BeatCountThreshold, // Largest beat index
parameter AHBWLOGBWPL, // Log2 of BEATSPERLINE parameter AHBWLOGBWPL, // Log2 of BEATSPERLINE
parameter READ_ONLY_CACHE parameter READ_ONLY_CACHE, // 1 for read-only instruction cache
parameter BURST_EN // burst mode supported
)( )(
input logic HCLK, input logic HCLK,
input logic HRESETn, input logic HRESETn,
@ -79,7 +79,7 @@ module buscachefsm #(
logic CacheAccess; logic CacheAccess;
logic BusWrite; logic BusWrite;
assign BusWrite = CacheBusRW[0] | BusCMOZero; assign BusWrite = (CacheBusRW[0] | BusCMOZero) & ~READ_ONLY_CACHE;
always_ff @(posedge HCLK) always_ff @(posedge HCLK)
if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE; if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE;
@ -87,28 +87,28 @@ module buscachefsm #(
always_comb begin always_comb begin
case(CurrState) case(CurrState)
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; // exclusion-tag: buscachefsm HREADY0
else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK; else if (HREADY & BusWrite & ~READ_ONLY_CACHE) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm HREADY1
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm HREADYread
else NextState = ADR_PHASE; else NextState = ADR_PHASE;
DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_READ_DATA_PHASE; DATA_PHASE: if(HREADY & BusAtomic & ~READ_ONLY_CACHE) NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm HREADY2
else if(HREADY & ~BusAtomic) NextState = MEM3; else if(HREADY & ~BusAtomic) NextState = MEM3; // exclusion-tag: buscachefsm HREADY3
else NextState = DATA_PHASE; else NextState = DATA_PHASE;
ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE; ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicReadData
else NextState = ATOMIC_READ_DATA_PHASE; else NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm AtomicElse
ATOMIC_PHASE: if(HREADY) NextState = MEM3; ATOMIC_PHASE: if(HREADY) NextState = MEM3; // exclusion-tag: buscachefsm AtomicPhase
else NextState = ATOMIC_PHASE; else NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicWait
MEM3: if(Stall) NextState = MEM3; MEM3: if(Stall) NextState = MEM3;
else NextState = ADR_PHASE; else NextState = ADR_PHASE;
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm FetchWriteback
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm FetchWait
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
else NextState = CACHE_FETCH; else NextState = CACHE_FETCH;
CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm WritebackWriteback
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm HREADY4
else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3; else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3; // exclusion-tag: buscachefsm HREADY5
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; // exclusion-tag: buscachefsm HREADY6
else NextState = CACHE_WRITEBACK; else NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm WritebackWriteback2
default: NextState = ADR_PHASE; default: NextState = ADR_PHASE;
endcase endcase
end end
@ -139,13 +139,13 @@ module buscachefsm #(
// AHB bus interface // AHB bus interface
assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW) | BusCMOZero) & ~Flush) | assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW) | BusCMOZero) & ~Flush) |
(CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) | (CurrState == ATOMIC_READ_DATA_PHASE) |
(CacheAccess & FinalBeatCount & |CacheBusRW & HREADY & ~Flush) ? AHB_NONSEQ : // if we have a pipelined request (CacheAccess & FinalBeatCount & |CacheBusRW & HREADY & ~Flush) ? AHB_NONSEQ : // if we have a pipelined request
(CacheAccess & |BeatCount) ? (`BURST_EN ? AHB_SEQ : AHB_NONSEQ) : AHB_IDLE; (CacheAccess & |BeatCount) ? (BURST_EN ? AHB_SEQ : AHB_NONSEQ) : AHB_IDLE;
assign HWRITE = ((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) | assign HWRITE = (((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) |
(CurrState == CACHE_WRITEBACK & |BeatCount); (CurrState == CACHE_WRITEBACK & |BeatCount)) & ~READ_ONLY_CACHE;
assign HBURST = `BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0; assign HBURST = BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0;
always_comb begin always_comb begin
case(BeatCountThreshold) case(BeatCountThreshold)

View File

@ -10,6 +10,7 @@
// Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.23) // Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.23)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

View File

@ -14,6 +14,7 @@
// Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.25) // Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.25)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

View File

@ -14,6 +14,7 @@
// Documentation: RISC-V System on Chip Design Chapter 6 (Figures 6.25 and 6.26) // Documentation: RISC-V System on Chip Design Chapter 6 (Figures 6.25 and 6.26)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -31,31 +32,31 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module ebu #(parameter XLEN, PA_BITS, AHBW)( module ebu import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
// Signals from IFU // Signals from IFU
input logic [1:0] IFUHTRANS, // IFU AHB transaction request input logic [1:0] IFUHTRANS, // IFU AHB transaction request
input logic [2:0] IFUHSIZE, // IFU AHB transaction size input logic [2:0] IFUHSIZE, // IFU AHB transaction size
input logic [2:0] IFUHBURST, // IFU AHB burst length input logic [2:0] IFUHBURST, // IFU AHB burst length
input logic [PA_BITS-1:0] IFUHADDR, // IFU AHB address input logic [P.PA_BITS-1:0] IFUHADDR, // IFU AHB address
output logic IFUHREADY, // AHB peripheral ready gated by possible non-grant output logic IFUHREADY, // AHB peripheral ready gated by possible non-grant
// Signals from LSU // Signals from LSU
input logic [1:0] LSUHTRANS, // LSU AHB transaction request input logic [1:0] LSUHTRANS, // LSU AHB transaction request
input logic LSUHWRITE, // LSU AHB transaction direction. 1: write, 0: read input logic LSUHWRITE, // LSU AHB transaction direction. 1: write, 0: read
input logic [2:0] LSUHSIZE, // LSU AHB size input logic [2:0] LSUHSIZE, // LSU AHB size
input logic [2:0] LSUHBURST, // LSU AHB burst length input logic [2:0] LSUHBURST, // LSU AHB burst length
input logic [PA_BITS-1:0] LSUHADDR, // LSU AHB address input logic [P.PA_BITS-1:0] LSUHADDR, // LSU AHB address
input logic [XLEN-1:0] LSUHWDATA, // initially support AHBW = XLEN input logic [P.XLEN-1:0] LSUHWDATA, // initially support AHBW = XLEN
input logic [XLEN/8-1:0] LSUHWSTRB, // AHB byte mask input logic [P.XLEN/8-1:0] LSUHWSTRB, // AHB byte mask
output logic LSUHREADY, // AHB peripheral. Never gated as LSU always has priority output logic LSUHREADY, // AHB peripheral. Never gated as LSU always has priority
// AHB-Lite external signals // AHB-Lite external signals
output logic HCLK, HRESETn, output logic HCLK, HRESETn,
input logic HREADY, // AHB peripheral ready input logic HREADY, // AHB peripheral ready
input logic HRESP, // AHB peripheral response. 0: OK 1: Error. Presently ignored. input logic HRESP, // AHB peripheral response. 0: OK 1: Error. Presently ignored.
output logic [PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration output logic [P.PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration
output logic [AHBW-1:0] HWDATA, // AHB Write data after arbitration output logic [P.AHBW-1:0] HWDATA, // AHB Write data after arbitration
output logic [XLEN/8-1:0] HWSTRB, // AHB byte write enables after arbitration output logic [P.XLEN/8-1:0] HWSTRB, // AHB byte write enables after arbitration
output logic HWRITE, // AHB transaction direction after arbitration output logic HWRITE, // AHB transaction direction after arbitration
output logic [2:0] HSIZE, // AHB transaction size after arbitration output logic [2:0] HSIZE, // AHB transaction size after arbitration
output logic [2:0] HBURST, // AHB burst length after arbitration output logic [2:0] HBURST, // AHB burst length after arbitration
@ -71,13 +72,13 @@ module ebu #(parameter XLEN, PA_BITS, AHBW)(
logic IFUDisable; logic IFUDisable;
logic IFUSelect; logic IFUSelect;
logic [PA_BITS-1:0] IFUHADDROut; logic [P.PA_BITS-1:0] IFUHADDROut;
logic [1:0] IFUHTRANSOut; logic [1:0] IFUHTRANSOut;
logic [2:0] IFUHBURSTOut; logic [2:0] IFUHBURSTOut;
logic [2:0] IFUHSIZEOut; logic [2:0] IFUHSIZEOut;
logic IFUHWRITEOut; logic IFUHWRITEOut;
logic [PA_BITS-1:0] LSUHADDROut; logic [P.PA_BITS-1:0] LSUHADDROut;
logic [1:0] LSUHTRANSOut; logic [1:0] LSUHTRANSOut;
logic [2:0] LSUHBURSTOut; logic [2:0] LSUHBURSTOut;
logic [2:0] LSUHSIZEOut; logic [2:0] LSUHSIZEOut;
@ -96,25 +97,25 @@ module ebu #(parameter XLEN, PA_BITS, AHBW)(
// input stages and muxing for IFU and LSU // input stages and muxing for IFU and LSU
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
controllerinput #(PA_BITS) IFUInput(.HCLK, .HRESETn, .Save(IFUSave), .Restore(IFURestore), .Disable(IFUDisable), controllerinput #(P.PA_BITS) IFUInput(.HCLK, .HRESETn, .Save(IFUSave), .Restore(IFURestore), .Disable(IFUDisable),
.Request(IFUReq), .Request(IFUReq),
.HWRITEIn(1'b0), .HSIZEIn(IFUHSIZE), .HBURSTIn(IFUHBURST), .HTRANSIn(IFUHTRANS), .HADDRIn(IFUHADDR), .HWRITEIn(1'b0), .HSIZEIn(IFUHSIZE), .HBURSTIn(IFUHBURST), .HTRANSIn(IFUHTRANS), .HADDRIn(IFUHADDR),
.HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY), .HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY),
.HTRANSOut(IFUHTRANSOut), .HADDROut(IFUHADDROut), .HREADYIn(HREADY)); .HTRANSOut(IFUHTRANSOut), .HADDROut(IFUHADDROut), .HREADYIn(HREADY));
// LSU always has priority so there should never be a need to save and restore the address phase inputs. // LSU always has priority so there should never be a need to save and restore the address phase inputs.
controllerinput #(PA_BITS, 0) LSUInput(.HCLK, .HRESETn, .Save(1'b0), .Restore(1'b0), .Disable(LSUDisable), controllerinput #(P.PA_BITS, 0) LSUInput(.HCLK, .HRESETn, .Save(1'b0), .Restore(1'b0), .Disable(LSUDisable),
.Request(LSUReq), .Request(LSUReq),
.HWRITEIn(LSUHWRITE), .HSIZEIn(LSUHSIZE), .HBURSTIn(LSUHBURST), .HTRANSIn(LSUHTRANS), .HADDRIn(LSUHADDR), .HREADYOut(LSUHREADY), .HWRITEIn(LSUHWRITE), .HSIZEIn(LSUHSIZE), .HBURSTIn(LSUHBURST), .HTRANSIn(LSUHTRANS), .HADDRIn(LSUHADDR), .HREADYOut(LSUHREADY),
.HWRITEOut(LSUHWRITEOut), .HSIZEOut(LSUHSIZEOut), .HBURSTOut(LSUHBURSTOut), .HWRITEOut(LSUHWRITEOut), .HSIZEOut(LSUHSIZEOut), .HBURSTOut(LSUHBURSTOut),
.HTRANSOut(LSUHTRANSOut), .HADDROut(LSUHADDROut), .HREADYIn(HREADY)); .HTRANSOut(LSUHTRANSOut), .HADDROut(LSUHADDROut), .HREADYIn(HREADY));
// output mux //*** switch to structural implementation // output mux //*** switch to structural implementation
assign HADDR = LSUSelect ? LSUHADDROut : IFUSelect ? IFUHADDROut : '0; assign HADDR = LSUSelect ? LSUHADDROut : IFUSelect ? IFUHADDROut : 0;
assign HSIZE = LSUSelect ? LSUHSIZEOut : IFUSelect ? IFUHSIZEOut: '0; assign HSIZE = LSUSelect ? LSUHSIZEOut : IFUSelect ? IFUHSIZEOut: 0;
assign HBURST = LSUSelect ? LSUHBURSTOut : IFUSelect ? IFUHBURSTOut : '0; // If doing memory accesses, use LSUburst, else use Instruction burst. assign HBURST = LSUSelect ? LSUHBURSTOut : IFUSelect ? IFUHBURSTOut : 0; // If doing memory accesses, use LSUburst, else use Instruction burst.
assign HTRANS = LSUSelect ? LSUHTRANSOut : IFUSelect ? IFUHTRANSOut: '0; // SEQ if not first read or write, NONSEQ if first read or write, IDLE otherwise assign HTRANS = LSUSelect ? LSUHTRANSOut : IFUSelect ? IFUHTRANSOut: 0; // SEQ if not first read or write, NONSEQ if first read or write, IDLE otherwise
assign HWRITE = LSUSelect ? LSUHWRITEOut : IFUSelect ? 1'b0 : '0; assign HWRITE = LSUSelect ? LSUHWRITEOut : 0;
assign HPROT = 4'b0011; // not used; see Section 3.7 assign HPROT = 4'b0011; // not used; see Section 3.7
assign HMASTLOCK = 0; // no locking supported assign HMASTLOCK = 0; // no locking supported

View File

@ -11,6 +11,7 @@
// Documentation: RISC-V System on Chip Design Chapter 6 (Figures 6.25 and 6.26) // Documentation: RISC-V System on Chip Design Chapter 6 (Figures 6.25 and 6.26)
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -67,12 +68,13 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
// LT/LE - signaling - sets invalid if NaN input // LT/LE - signaling - sets invalid if NaN input
// EQ - quiet - sets invalid if signaling NaN input // EQ - quiet - sets invalid if signaling NaN input
always_comb begin always_comb begin
case (OpCtrl[2:0]) casez (OpCtrl[2:0])
3'b110: CmpNV = EitherSNaN; //min 3'b110: CmpNV = EitherSNaN; //min
3'b101: CmpNV = EitherSNaN; //max 3'b101: CmpNV = EitherSNaN; //max
3'b010: CmpNV = EitherSNaN; //equal 3'b010: CmpNV = EitherSNaN; //equal
3'b001: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fltq / flt perform CompareQuietLess / CompareSignalingLess differing on when to set invalid 3'b0?1: if (P.ZFA_SUPPORTED)
3'b011: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fleq / fle differ on when to set invalid CmpNV = Zfa ? EitherSNaN : EitherNaN; // fltq,fleq / flt,fle perform CompareQuietLess / CompareSignalingLess differing on when to set invalid
else CmpNV = EitherNaN; // flt, fle
default: CmpNV = 1'bx; default: CmpNV = 1'bx;
endcase endcase
end end

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -45,11 +46,11 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
// input mux selections // input mux selections
output logic XEnD, YEnD, ZEnD, // enable inputs output logic XEnD, YEnD, ZEnD, // enable inputs
output logic XEnE, YEnE, ZEnE, // enable inputs output logic XEnE, YEnE, ZEnE, // enable inputs
// opperation mux selections // operation mux selections
output logic FCvtIntE, FCvtIntW, // convert to integer opperation output logic FCvtIntE, FCvtIntW, // convert to integer operation
output logic [2:0] FrmM, // FP rounding mode output logic [2:0] FrmM, // FP rounding mode
output logic [P.FMTBITS-1:0] FmtE, FmtM, // FP format output logic [P.FMTBITS-1:0] FmtE, FmtM, // FP format
output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component output logic [2:0] OpCtrlE, OpCtrlM, // Select which operation to do in each component
output logic FpLoadStoreM, // FP load or store instruction output logic FpLoadStoreM, // FP load or store instruction
output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit
output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage
@ -71,7 +72,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
logic FRegWriteD; // FP register write enable logic FRegWriteD; // FP register write enable
logic FDivStartD; // start division/sqrt logic FDivStartD; // start division/sqrt
logic FWriteIntD; // integer register write enable logic FWriteIntD; // integer register write enable
logic [2:0] OpCtrlD; // Select which opperation to do in each component logic [2:0] OpCtrlD; // Select which operation to do in each component
logic [1:0] PostProcSelD; // select result in the post processing unit logic [1:0] PostProcSelD; // select result in the post processing unit
logic [1:0] FResSelD; // Select one of the results that finish in the memory stage logic [1:0] FResSelD; // Select one of the results that finish in the memory stage
logic [2:0] FrmD, FrmE; // FP rounding mode logic [2:0] FrmD, FrmE; // FP rounding mode
@ -79,16 +80,15 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
logic [1:0] Fmt, Fmt2; // format - before possible reduction logic [1:0] Fmt, Fmt2; // format - before possible reduction
logic SupportedFmt; // is the format supported logic SupportedFmt; // is the format supported
logic SupportedFmt2; // is the source format supported for fp -> fp logic SupportedFmt2; // is the source format supported for fp -> fp
logic FCvtIntD, FCvtIntM; // convert to integer opperation logic FCvtIntD, FCvtIntM; // convert to integer operation
logic ZfaD; // Zfa variants of instructions logic ZfaD; // Zfa variants of instructions
// FPU Instruction Decoder // FPU Instruction Decoder
assign Fmt = Funct7D[1:0]; assign Fmt = Funct7D[1:0];
assign Fmt2 = Rs2D[1:0]; // source format for fcvt fp->fp assign Fmt2 = Rs2D[1:0]; // source format for fcvt fp->fp
assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & P.D_SUPPORTED) | assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & P.D_SUPPORTED) |
(Fmt == 2'b10 & P.ZFH_SUPPORTED & {OpD[6:4], OpD[1:0]} != 5'b10011) | // fma not supported for Zfh (Fmt == 2'b10 & P.ZFH_SUPPORTED) | (Fmt == 2'b11 & P.Q_SUPPORTED));
(Fmt == 2'b11 & P.Q_SUPPORTED));
assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & P.D_SUPPORTED) | assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & P.D_SUPPORTED) |
(Fmt2 == 2'b10 & P.ZFH_SUPPORTED) | (Fmt2 == 2'b11 & P.Q_SUPPORTED)); (Fmt2 == 2'b10 & P.ZFH_SUPPORTED) | (Fmt2 == 2'b11 & P.Q_SUPPORTED));
@ -237,11 +237,10 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0; // fcvt.l.q q->l 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0; // fcvt.l.q q->l
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0; // fcvt.lu.q q->lu 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0; // fcvt.lu.q q->lu
endcase endcase
// coverage on // coverage off
// Not covered in testing because rv64gc is not RV64Q or RV32D
7'b1011001: if (P.ZFA_SUPPORTED & P.XLEN == 32 & P.D_SUPPORTED & Funct3D == 3'b000) 7'b1011001: if (P.ZFA_SUPPORTED & P.XLEN == 32 & P.D_SUPPORTED & Funct3D == 3'b000)
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.d.x (Zfa) *** untested, controls could be wrong ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.d.x (Zfa) *** untested, controls could be wrong
// Not covered in testing because rv64gc does not support quad precision
// coverage off
7'b1011011: if (P.ZFA_SUPPORTED & P.XLEN == 64 & P.Q_SUPPORTED & Funct3D == 3'b000) 7'b1011011: if (P.ZFA_SUPPORTED & P.XLEN == 64 & P.Q_SUPPORTED & Funct3D == 3'b000)
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.q.x (Zfa) ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.q.x (Zfa)
// coverage on // coverage on

View File

@ -31,7 +31,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
input logic [P.NE-1:0] Xe, // input's exponent input logic [P.NE-1:0] Xe, // input's exponent
input logic [P.NF:0] Xm, // input's fraction input logic [P.NF:0] Xm, // input's fraction
input logic [P.XLEN-1:0] Int, // integer input - from IEU input logic [P.XLEN-1:0] Int, // integer input - from IEU
input logic [2:0] OpCtrl, // choose which opperation (look below for values) input logic [2:0] OpCtrl, // choose which operation (look below for values)
input logic ToInt, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic XZero, // is the input zero input logic XZero, // is the input zero
input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half) input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
@ -58,9 +58,9 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] TrimInt; // integer trimmed to the correct size logic [P.XLEN-1:0] TrimInt; // integer trimmed to the correct size
logic [P.NE-2:0] NewBias; // the bias of the final result logic [P.NE-2:0] NewBias; // the bias of the final result
logic [P.NE-1:0] OldExp; // the old exponent logic [P.NE-1:0] OldExp; // the old exponent
logic Signed; // is the opperation with a signed integer? logic Signed; // is the operation with a signed integer?
logic Int64; // is the integer 64 bits? logic Int64; // is the integer 64 bits?
logic IntToFp; // is the opperation an int->fp conversion? logic IntToFp; // is the operation an int->fp conversion?
logic [P.CVTLEN:0] LzcInFull; // input to the Leading Zero Counter (priority encoder) logic [P.CVTLEN:0] LzcInFull; // input to the Leading Zero Counter (priority encoder)
logic [P.LOGCVTLEN-1:0] LeadingZeros; // output from the LZC logic [P.LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
@ -69,7 +69,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
assign Int64 = OpCtrl[1]; assign Int64 = OpCtrl[1];
assign IntToFp = OpCtrl[2]; assign IntToFp = OpCtrl[2];
// choose the output format depending on the opperation // choose the output format depending on the operation
// - fp -> fp: OpCtrl contains the precision of the output // - fp -> fp: OpCtrl contains the precision of the output
// - int -> fp: Fmt contains the precision of the output // - int -> fp: Fmt contains the precision of the output
if (P.FPSIZES == 2) if (P.FPSIZES == 2)

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -70,8 +71,7 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
// The datapath produces rk bits per cycle, so Cycles = ceil (ResultBitsE / rk) // The datapath produces rk bits per cycle, so Cycles = ceil (ResultBitsE / rk)
always_comb begin always_comb begin
if (SqrtE) FPResultBitsE = Nf + 2 + 0; // Nf + two fractional bits for round/guard; integer bit implicit because starting at n=1 FPResultBitsE = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard; integer bit implicit because starting at n=1
else FPResultBitsE = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard + integer bits
if (P.IDIV_ON_FPU) ResultBitsE = IntDivE ? IntResultBitsE : FPResultBitsE; if (P.IDIV_ON_FPU) ResultBitsE = IntDivE ? IntResultBitsE : FPResultBitsE;
else ResultBitsE = FPResultBitsE; else ResultBitsE = FPResultBitsE;

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -36,7 +37,7 @@ module fdivsqrtfgen2 import cvw::*; #(parameter cvw_t P) (
// Generate for both positive and negative quotient digits // Generate for both positive and negative quotient digits
assign FP = ~(U << 1) & C; assign FP = ~(U << 1) & C;
assign FN = (UM << 1) | (C & ~(C << 2)); assign FN = (UM << 1) | (C & ~(C << 2));
assign FZ = '0; assign FZ = 0;
always_comb // Choose which adder input will be used always_comb // Choose which adder input will be used
if (up) F = FP; if (up) F = FP;

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -36,7 +37,7 @@ module fdivsqrtfgen4 import cvw::*; #(parameter cvw_t P) (
// Generate for both positive and negative digits // Generate for both positive and negative digits
assign F2 = (~U << 2) & (C << 2); // assign F2 = (~U << 2) & (C << 2); //
assign F1 = ~(U << 1) & C; assign F1 = ~(U << 1) & C;
assign F0 = '0; assign F0 = 0;
assign FN1 = (UM << 1) | (C & ~(C << 3)); assign FN1 = (UM << 1) | (C & ~(C << 3));
assign FN2 = (UM << 2) | ((C << 2) & ~(C << 4)); assign FN2 = (UM << 2) | ((C << 2) & ~(C << 4));

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -70,8 +71,8 @@ module fdivsqrtfsm import cvw::*; #(parameter cvw_t P) (
end else if (state == BUSY) begin end else if (state == BUSY) begin
if (step == 1 | WZeroE) state <= #1 DONE; // finished steps or terminate early on zero residual if (step == 1 | WZeroE) state <= #1 DONE; // finished steps or terminate early on zero residual
step <= step - 1; step <= step - 1;
end else if (state == DONE) begin end else if (state == DONE) begin // Can't still be stalled in configs tested, but keep this check for paranoia
if (StallM) state <= #1 DONE; if (StallM) state <= #1 DONE; // exclusion-tag: fdivsqrtfsm stallm
else state <= #1 IDLE; else state <= #1 IDLE;
end end
end end

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -43,7 +44,7 @@ module fdivsqrtiter import cvw::*; #(parameter cvw_t P) (
logic [P.DIVb+3:0] WCNext[P.DIVCOPIES-1:0]; // Q4.DIVb logic [P.DIVb+3:0] WCNext[P.DIVCOPIES-1:0]; // Q4.DIVb
logic [P.DIVb+3:0] WS[P.DIVCOPIES:0]; // Q4.DIVb logic [P.DIVb+3:0] WS[P.DIVCOPIES:0]; // Q4.DIVb
logic [P.DIVb+3:0] WC[P.DIVCOPIES:0]; // Q4.DIVb logic [P.DIVb+3:0] WC[P.DIVCOPIES:0]; // Q4.DIVb
logic [P.DIVb:0] U[P.DIVCOPIES:0]; // U1.DIVb logic [P.DIVb:0] U[P.DIVCOPIES:0]; // U1.DIVb // *** probably Q not U. See Table 16.26 notes
logic [P.DIVb:0] UM[P.DIVCOPIES:0]; // U1.DIVb logic [P.DIVb:0] UM[P.DIVCOPIES:0]; // U1.DIVb
logic [P.DIVb:0] UNext[P.DIVCOPIES-1:0]; // U1.DIVb logic [P.DIVb:0] UNext[P.DIVCOPIES-1:0]; // U1.DIVb
logic [P.DIVb:0] UMNext[P.DIVCOPIES-1:0]; // U1.DIVb logic [P.DIVb:0] UMNext[P.DIVCOPIES-1:0]; // U1.DIVb
@ -70,24 +71,18 @@ module fdivsqrtiter import cvw::*; #(parameter cvw_t P) (
flopen #(P.DIVb+4) wcreg(clk, FDivBusyE, WCN, WC[0]); flopen #(P.DIVb+4) wcreg(clk, FDivBusyE, WCN, WC[0]);
// UOTFC Result U and UM registers/initialization mux // UOTFC Result U and UM registers/initialization mux
// Initialize U to 1.0 and UM to 0 for square root; U to 0 and UM to -1 otherwise // Initialize U to 0 = 0.0000... and UM to -1 = 1.00000... (in Q1.Divb)
assign initU = {SqrtE, {(P.DIVb){1'b0}}}; assign initU ={(P.DIVb+1){1'b0}};
assign initUM = {~SqrtE, {(P.DIVb){1'b0}}}; assign initUM = {{1'b1}, {(P.DIVb){1'b0}}};
mux2 #(P.DIVb+1) Umux(UNext[P.DIVCOPIES-1], initU, IFDivStartE, UMux); mux2 #(P.DIVb+1) Umux(UNext[P.DIVCOPIES-1], initU, IFDivStartE, UMux);
mux2 #(P.DIVb+1) UMmux(UMNext[P.DIVCOPIES-1], initUM, IFDivStartE, UMMux); mux2 #(P.DIVb+1) UMmux(UMNext[P.DIVCOPIES-1], initUM, IFDivStartE, UMMux);
flopen #(P.DIVb+1) UReg(clk, FDivBusyE, UMux, U[0]); flopen #(P.DIVb+1) UReg(clk, FDivBusyE, UMux, U[0]);
flopen #(P.DIVb+1) UMReg(clk, FDivBusyE, UMMux, UM[0]); flopen #(P.DIVb+1) UMReg(clk, FDivBusyE, UMMux, UM[0]);
// C register/initialization mux // C register/initialization mux: C = -R:
// Initialize C to -1 for sqrt and -R for division // C = -4 = 00.000000... (in Q2.DIVb) for radix 4, C = -2 = 10.000000... for radix2
logic [1:0] initCUpper; if(P.RADIX == 4) assign initC = 0;
if(P.RADIX == 4) begin else assign initC = {2'b10, {{P.DIVb{1'b0}}}};
mux2 #(2) cuppermux4(2'b00, 2'b11, SqrtE, initCUpper);
end else begin
mux2 #(2) cuppermux2(2'b10, 2'b11, SqrtE, initCUpper);
end
assign initC = {initCUpper, {P.DIVb{1'b0}}};
mux2 #(P.DIVb+2) cmux(C[P.DIVCOPIES], initC, IFDivStartE, NextC); mux2 #(P.DIVb+2) cmux(C[P.DIVCOPIES], initC, IFDivStartE, NextC);
flopen #(P.DIVb+2) creg(clk, FDivBusyE, NextC, C[0]); flopen #(P.DIVb+2) creg(clk, FDivBusyE, NextC, C[0]);
@ -107,9 +102,7 @@ module fdivsqrtiter import cvw::*; #(parameter cvw_t P) (
.WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]), .WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]),
.C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i])); .C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i]));
end else begin: stage end else begin: stage
logic j1; fdivsqrtstage4 #(P) fdivsqrtstage(.D, .DBar, .D2, .DBar2, .SqrtE,
assign j1 = (i == 0 & ~C[0][P.DIVb-1]);
fdivsqrtstage4 #(P) fdivsqrtstage(.D, .DBar, .D2, .DBar2, .SqrtE, .j1,
.WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]), .WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]),
.C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i])); .C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i]));
end end

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -120,7 +121,7 @@ module fdivsqrtpostproc import cvw::*; #(parameter cvw_t P) (
else IntDivResultM = {(P.XLEN){1'b1}}; else IntDivResultM = {(P.XLEN){1'b1}};
end else if (ALTBM) begin // Numerator is small end else if (ALTBM) begin // Numerator is small
if (RemOpM) IntDivResultM = AM; if (RemOpM) IntDivResultM = AM;
else IntDivResultM = '0; else IntDivResultM = 0;
end else IntDivResultM = PreIntResultM[P.XLEN-1:0]; end else IntDivResultM = PreIntResultM[P.XLEN-1:0];
// sign extend result for W64 // sign extend result for W64

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -173,9 +174,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
logic [P.DIVb:0] PreSqrtX; logic [P.DIVb:0] PreSqrtX;
assign EvenExp = Xe[0] ^ ell[0]; // effective unbiased exponent after normalization is even assign EvenExp = Xe[0] ^ ell[0]; // effective unbiased exponent after normalization is even
mux2 #(P.DIVb+1) sqrtxmux(Xnorm, {1'b0, Xnorm[P.DIVb:1]}, EvenExp, PreSqrtX); // X if exponent odd, X/2 if exponent even mux2 #(P.DIVb+4) sqrtxmux({4'b0,Xnorm[P.DIVb:1]}, {5'b00, Xnorm[P.DIVb:2]}, EvenExp, SqrtX); // X/2 if exponent odd, X/4 if exponent even
if (P.RADIX == 2) assign SqrtX = {3'b111, PreSqrtX}; // PreSqrtX - 2 = 2(PreSqrtX/2 - 1)
else assign SqrtX = {2'b11, PreSqrtX, 1'b0}; // 2PreSqrtX - 4 = 4(PreSqrtX/2 - 1)
/* /*
// Attempt to optimize radix 4 to use a left shift by 1 or zero initially, followed by no more left shift // Attempt to optimize radix 4 to use a left shift by 1 or zero initially, followed by no more left shift

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -57,7 +58,7 @@ module fdivsqrtstage2 import cvw::*; #(parameter cvw_t P) (
// Divisor multiple // Divisor multiple
always_comb always_comb
if (up) Dsel = DBar; if (up) Dsel = DBar;
else if (uz) Dsel = '0; else if (uz) Dsel = 0;
else Dsel = D; // un else Dsel = D; // un
// Residual Update // Residual Update

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
@ -31,7 +32,7 @@ module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) (
input logic [P.DIVb:0] U,UM, // U1.DIVb input logic [P.DIVb:0] U,UM, // U1.DIVb
input logic [P.DIVb+3:0] WS, WC, // Q4.DIVb input logic [P.DIVb+3:0] WS, WC, // Q4.DIVb
input logic [P.DIVb+1:0] C, // Q2.DIVb input logic [P.DIVb+1:0] C, // Q2.DIVb
input logic SqrtE, j1, input logic SqrtE,
output logic [P.DIVb+1:0] CNext, // Q2.DIVb output logic [P.DIVb+1:0] CNext, // Q2.DIVb
output logic un, output logic un,
output logic [P.DIVb:0] UNext, UMNext, // U1.DIVb output logic [P.DIVb:0] UNext, UMNext, // U1.DIVb
@ -47,13 +48,16 @@ module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) (
logic [7:0] WCmsbs, WSmsbs; // U4.4 logic [7:0] WCmsbs, WSmsbs; // U4.4
logic CarryIn; logic CarryIn;
logic [P.DIVb+3:0] WSA, WCA; // Q4.DIVb logic [P.DIVb+3:0] WSA, WCA; // Q4.DIVb
logic j0, j1; // step j = 0 or step j = 1
// Digit Selection logic // Digit Selection logic
assign j0 = ~C[P.DIVb+1]; // first step of R digit selection: C = 00...0
assign j1 = C[P.DIVb] & ~C[P.DIVb-1]; // second step of R digit selection: C = 1100...0; *** could simplify to ~C[P.DIVb-1] because j=0 case takes priority
assign Smsbs = U[P.DIVb:P.DIVb-4]; // U1.4 most significant bits of square root assign Smsbs = U[P.DIVb:P.DIVb-4]; // U1.4 most significant bits of square root
assign Dmsbs = D[P.DIVb-1:P.DIVb-3]; // U0.3 most significant fractional bits of divisor after leading 1 assign Dmsbs = D[P.DIVb-1:P.DIVb-3]; // U0.3 most significant fractional bits of divisor after leading 1
assign WCmsbs = WC[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual assign WCmsbs = WC[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual
assign WSmsbs = WS[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual assign WSmsbs = WS[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual
fdivsqrtuslc4cmp uslc4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j1, .udigit); fdivsqrtuslc4cmp uslc4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j0, .j1, .udigit);
assign un = 1'b0; // unused for radix 4 assign un = 1'b0; // unused for radix 4
// F generation logic // F generation logic
@ -64,7 +68,7 @@ module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) (
case (udigit) case (udigit)
4'b1000: Dsel = DBar2; 4'b1000: Dsel = DBar2;
4'b0100: Dsel = DBar; 4'b0100: Dsel = DBar;
4'b0000: Dsel = '0; 4'b0000: Dsel = 0;
4'b0010: Dsel = D; 4'b0010: Dsel = D;
4'b0001: Dsel = D2; 4'b0001: Dsel = D2;
default: Dsel = 'x; default: Dsel = 'x;

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

View File

@ -9,6 +9,7 @@
// Documentation: RISC-V System on Chip Design Chapter 13 // Documentation: RISC-V System on Chip Design Chapter 13
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //

Some files were not shown because too many files have changed in this diff Show More