mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' into rvvi
This commit is contained in:
commit
140e64772e
1
.gitignore
vendored
1
.gitignore
vendored
@ -184,3 +184,4 @@ sim/cfi/*
|
||||
sim/branch/*
|
||||
sim/obj_dir
|
||||
examples/verilog/fulladder/obj_dir
|
||||
config/deriv
|
||||
|
@ -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
|
||||
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
|
||||
In a web browser, visit https://github.com/openhwgroup/cvw
|
||||
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
|
||||
|
||||
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
|
||||
$ cd cvw
|
||||
$ git remote add upstream https://github.com/openhwgroup/cvw
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c955abf757df98cf38809e40a62d2a6b448ea507
|
||||
Subproject commit 8a52b016dbe1e2733cc168b9d6e5c93e39059d4d
|
@ -9,6 +9,7 @@
|
||||
## Computes the geometric mean for btb accuracy
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -9,6 +9,7 @@
|
||||
## Computes the geometric mean.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -10,6 +10,7 @@
|
||||
## Purpose: Simulate a L1 D$ or I$ for comparison with Wally
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -12,6 +12,7 @@
|
||||
## separated by benchmark application. Example names are aha-mot64bd_sizeopt_speed_branch.log
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
133
bin/derivgen.pl
Executable file
133
bin/derivgen.pl
Executable 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");
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
## Imperas and riscv-arch-test benchmarks
|
||||
##
|
||||
## A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
## https://github.com/openhwgroup/cvw
|
||||
##
|
||||
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
##
|
||||
|
@ -11,6 +11,7 @@
|
||||
## to read into a Verilog simulation with $readmemh
|
||||
##
|
||||
## A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
## https://github.com/openhwgroup/cvw
|
||||
##
|
||||
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
##
|
||||
|
21
bin/fparchtest.sh
Executable file
21
bin/fparchtest.sh
Executable 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
|
@ -9,6 +9,7 @@
|
||||
## Purpose: One time setup script for running imperas.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -13,6 +13,7 @@
|
||||
## and for TSMC change the $cellname to the actual name of the inverter.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
693
bin/nightly_build.py
Executable file
693
bin/nightly_build.py
Executable 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)
|
@ -8,6 +8,7 @@
|
||||
## Purpose: Parses the performance counters from a modelsim trace.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -12,6 +12,7 @@
|
||||
## and count how many tests are in each
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -11,6 +11,7 @@
|
||||
## and generate a list of tests and signature addresses for tests.vh
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -11,6 +11,7 @@
|
||||
## verilator should do this, but it also reports partially used signals
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -10,6 +10,7 @@
|
||||
## Purpose: Open source tool chain installation script
|
||||
##
|
||||
## 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
|
||||
##
|
||||
@ -68,9 +69,6 @@ fi
|
||||
cd $RISCV
|
||||
git clone https://github.com/riscv/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--;"
|
||||
make -j ${NUM_THREADS}
|
||||
|
||||
@ -110,14 +108,15 @@ cd riscv-isa-sim/build
|
||||
make -j ${NUM_THREADS}
|
||||
make install
|
||||
cd ../arch_test_target/spike/device
|
||||
sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include
|
||||
sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include
|
||||
# dh 2/5/24: these should be obsolete
|
||||
#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.
|
||||
# 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
|
||||
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
|
||||
git clone https://github.com/verilator/verilator # Only first time
|
||||
# unsetenv VERILATOR_ROOT # For csh; ignore error if on bash
|
||||
@ -172,6 +171,8 @@ sudo make install
|
||||
|
||||
cd $RISCV
|
||||
opam init -y --disable-sandboxing
|
||||
opam update
|
||||
opam upgrade
|
||||
opam switch create 5.1.0
|
||||
opam install sail -y
|
||||
|
||||
|
28
bin/wrapper_nightly_runs.sh
Executable file
28
bin/wrapper_nightly_runs.sh
Executable 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
|
@ -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
1077
config/derivlist.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -132,6 +132,10 @@ localparam AHBW = 32'd32;
|
||||
|
||||
// Test modes
|
||||
|
||||
// AHB
|
||||
localparam RAM_LATENCY = 32'b0;
|
||||
localparam BURST_EN = 1;
|
||||
|
||||
// Tie GPIO outputs back to inputs
|
||||
localparam GPIO_LOOPBACK_TEST = 1;
|
||||
localparam SPI_LOOPBACK_TEST = 0;
|
||||
@ -154,6 +158,7 @@ localparam BPRED_SIZE = 32'd10;
|
||||
localparam BPRED_NUM_LHR = 32'd6;
|
||||
localparam BTB_SIZE = 32'd10;
|
||||
localparam RAS_SIZE = 32'd16;
|
||||
localparam INSTR_CLASS_PRED = 0;
|
||||
|
||||
localparam SVADU_SUPPORTED = 0;
|
||||
localparam ZMMUL_SUPPORTED = 0;
|
||||
|
@ -133,6 +133,10 @@ localparam AHBW = 32'd32;
|
||||
|
||||
// Test modes
|
||||
|
||||
// AHB
|
||||
localparam RAM_LATENCY = 32'b0;
|
||||
localparam BURST_EN = 1;
|
||||
|
||||
// Tie GPIO outputs back to inputs
|
||||
localparam GPIO_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 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_SIZE = 32'd10;
|
||||
`endif
|
||||
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 RAS_SIZE = 32'd16;
|
||||
`endif
|
||||
localparam INSTR_CLASS_PRED = 1;
|
||||
|
||||
localparam SVADU_SUPPORTED = 1;
|
||||
localparam ZMMUL_SUPPORTED = 0;
|
||||
|
@ -132,6 +132,10 @@ localparam AHBW = 32'd32;
|
||||
|
||||
// Test modes
|
||||
|
||||
// AHB
|
||||
localparam RAM_LATENCY = 32'b0;
|
||||
localparam BURST_EN = 1;
|
||||
|
||||
// Tie GPIO outputs back to inputs
|
||||
localparam GPIO_LOOPBACK_TEST = 1;
|
||||
localparam SPI_LOOPBACK_TEST = 1;
|
||||
@ -155,6 +159,7 @@ localparam BPRED_SIZE = 32'd10;
|
||||
localparam BPRED_NUM_LHR = 32'd6;
|
||||
localparam BTB_SIZE = 32'd10;
|
||||
localparam RAS_SIZE = 32'd16;
|
||||
localparam INSTR_CLASS_PRED = 0;
|
||||
|
||||
localparam SVADU_SUPPORTED = 0;
|
||||
localparam ZMMUL_SUPPORTED = 0;
|
||||
|
@ -131,6 +131,10 @@ localparam AHBW = 32'd32;
|
||||
|
||||
// Test modes
|
||||
|
||||
// AHB
|
||||
localparam RAM_LATENCY = 32'b0;
|
||||
localparam BURST_EN = 1;
|
||||
|
||||
// Tie GPIO outputs back to inputs
|
||||
localparam GPIO_LOOPBACK_TEST = 1;
|
||||
localparam SPI_LOOPBACK_TEST = 1;
|
||||
@ -153,6 +157,7 @@ localparam BPRED_SIZE = 32'd10;
|
||||
localparam BPRED_NUM_LHR = 32'd6;
|
||||
localparam BTB_SIZE = 32'd10;
|
||||
localparam RAS_SIZE = 32'd16;
|
||||
localparam INSTR_CLASS_PRED = 0;
|
||||
|
||||
localparam SVADU_SUPPORTED = 0;
|
||||
localparam ZMMUL_SUPPORTED = 0;
|
||||
|
@ -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"
|
@ -41,7 +41,7 @@ localparam COUNTERS = 12'd32;
|
||||
localparam ZICNTR_SUPPORTED = 1;
|
||||
localparam ZIHPM_SUPPORTED = 1;
|
||||
localparam ZFH_SUPPORTED = 1;
|
||||
localparam ZFA_SUPPORTED = 0;
|
||||
localparam ZFA_SUPPORTED = 1;
|
||||
localparam SSTC_SUPPORTED = 1;
|
||||
localparam ZICBOM_SUPPORTED = 1;
|
||||
localparam ZICBOZ_SUPPORTED = 1;
|
||||
@ -134,6 +134,10 @@ localparam logic [63:0] SPI_RANGE = 64'h00000FFF;
|
||||
|
||||
// Test modes
|
||||
|
||||
// AHB
|
||||
localparam RAM_LATENCY = 32'b0;
|
||||
localparam BURST_EN = 1;
|
||||
|
||||
// Tie GPIO outputs back to inputs
|
||||
localparam GPIO_LOOPBACK_TEST = 1;
|
||||
localparam SPI_LOOPBACK_TEST = 1;
|
||||
@ -156,6 +160,7 @@ localparam BPRED_NUM_LHR = 32'd6;
|
||||
localparam BPRED_SIZE = 32'd10;
|
||||
localparam BTB_SIZE = 32'd10;
|
||||
localparam RAS_SIZE = 32'd16;
|
||||
localparam INSTR_CLASS_PRED = 1;
|
||||
|
||||
localparam SVADU_SUPPORTED = 1;
|
||||
localparam ZMMUL_SUPPORTED = 0;
|
||||
@ -180,3 +185,4 @@ localparam ZCD_SUPPORTED = 0;
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "config-shared.vh"
|
||||
|
||||
|
@ -134,6 +134,10 @@ localparam logic [63:0] SPI_RANGE = 64'h00000FFF;
|
||||
|
||||
// Test modes
|
||||
|
||||
// AHB
|
||||
localparam RAM_LATENCY = 32'b0;
|
||||
localparam BURST_EN = 1;
|
||||
|
||||
// Tie GPIO outputs back to inputs
|
||||
localparam GPIO_LOOPBACK_TEST = 1;
|
||||
localparam SPI_LOOPBACK_TEST = 1;
|
||||
@ -156,6 +160,7 @@ localparam BPRED_SIZE = 32'd10;
|
||||
localparam BPRED_NUM_LHR = 32'd6;
|
||||
localparam BTB_SIZE = 32'd10;
|
||||
localparam RAS_SIZE = 32'd16;
|
||||
localparam INSTR_CLASS_PRED = 0;
|
||||
|
||||
localparam SVADU_SUPPORTED = 0;
|
||||
localparam ZMMUL_SUPPORTED = 0;
|
||||
|
@ -94,7 +94,7 @@ localparam LOGR = $clog2(RADIX); // r = log(R
|
||||
localparam RK = LOGR*DIVCOPIES; // r*k bits per cycle generated
|
||||
|
||||
// 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 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
|
||||
@ -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 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 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
|
||||
localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); // max(XLEN, NF)
|
||||
localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($unsigned(FLEN)));
|
||||
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 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
|
||||
|
@ -8,6 +8,8 @@ localparam cvw_t P = '{
|
||||
IEEE754 : IEEE754,
|
||||
MISA : MISA,
|
||||
AHBW : AHBW,
|
||||
RAM_LATENCY : RAM_LATENCY,
|
||||
BURST_EN : BURST_EN,
|
||||
ZICSR_SUPPORTED : ZICSR_SUPPORTED,
|
||||
ZIFENCEI_SUPPORTED : ZIFENCEI_SUPPORTED,
|
||||
COUNTERS : COUNTERS,
|
||||
@ -100,6 +102,7 @@ localparam cvw_t P = '{
|
||||
BPRED_NUM_LHR : BPRED_NUM_LHR,
|
||||
BTB_SIZE : BTB_SIZE,
|
||||
RAS_SIZE : RAS_SIZE,
|
||||
INSTR_CLASS_PRED : INSTR_CLASS_PRED,
|
||||
RADIX : RADIX,
|
||||
DIVCOPIES : DIVCOPIES,
|
||||
ZBA_SUPPORTED : ZBA_SUPPORTED,
|
||||
|
@ -7,6 +7,7 @@
|
||||
## Purpose: Dockerfile for Wally docker container creation
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -48,29 +48,14 @@ IP_Arty: $(dst)/xlnx_proc_sys_reset.log \
|
||||
|
||||
|
||||
PreProcessFiles:
|
||||
$(MAKE) -C ../../sim deriv
|
||||
rm -rf ../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/
|
||||
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
|
||||
# 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/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
|
||||
#sed -i "s/EXT_MEM_RANGE.*/EXT_MEM_RANGE = 64'h0FFFFFFF;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
# 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
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
## Modified: 20 January 2023
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -7,6 +7,7 @@
|
||||
## Modified: 16 August 2023
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -7,6 +7,7 @@
|
||||
## Modified: 16 August 2023
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -7,6 +7,7 @@
|
||||
## Modified: 16 August 2023
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -21,7 +21,7 @@ ROOT := ..
|
||||
LIBRARY_DIRS :=
|
||||
LIBRARY_FILES :=
|
||||
|
||||
MARCH :=-march=rv64imfdc
|
||||
MARCH :=-march=rv64imfdc_zifencei
|
||||
MABI :=-mabi=lp64d
|
||||
LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles
|
||||
LINKER :=linker.x
|
@ -94,5 +94,5 @@ end_of_bios:
|
||||
.globl _dtb
|
||||
.align 4, 0
|
||||
_dtb:
|
||||
.incbin "wally-vcu118.dtb"
|
||||
#.incbin "wally-vcu118.dtb"
|
||||
|
@ -1,7 +1,7 @@
|
||||
///////////////////////////////////////////
|
||||
// SDC.sv
|
||||
//
|
||||
// Written: Ross Thompson September 25, 2021
|
||||
// Written: Rose Thompson September 25, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: driver for sdc reader.
|
@ -1,5 +1,6 @@
|
||||
###########################################
|
||||
## 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
|
||||
##
|
||||
|
@ -72,6 +72,13 @@ if [ ! -e "$SDCARD" ] ; then
|
||||
exit 1
|
||||
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 [ ! -d $IMAGES ] ; then
|
||||
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"
|
||||
|
||||
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"
|
||||
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"
|
||||
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 mount -v "$SDCARD"4 /mnt/$MNT_DIR
|
||||
sudo mount -v "$SDCARD""$PART_PREFIX"4 /mnt/$MNT_DIR
|
||||
|
||||
sudo umount -v /mnt/$MNT_DIR
|
||||
|
||||
|
12
sim/Makefile
12
sim/Makefile
@ -1,5 +1,5 @@
|
||||
|
||||
all: riscoftests memfiles coveragetests
|
||||
all: riscoftests memfiles coveragetests deriv benchmarks
|
||||
# *** Build old tests/imperas-riscv-tests for now;
|
||||
# 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
|
||||
@ -60,3 +60,13 @@ memfiles:
|
||||
|
||||
coveragetests:
|
||||
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
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
../logs/rv32gc_gshare6.log gshare 6
|
||||
../logs/rv32gc_gshare8.log gshare 8
|
||||
../logs/rv32gc_gshare10.log gshare 10
|
||||
../logs/rv32gc_gshare12.log gshare 12
|
||||
../logs/rv32gc_gshare14.log gshare 14
|
||||
../logs/rv32gc_gshare16.log gshare 16
|
||||
../logs/rv32gc_twobit6.log twobit 6
|
||||
../logs/rv32gc_twobit8.log twobit 8
|
||||
../logs/rv32gc_twobit10.log twobit 10
|
||||
../logs/rv32gc_twobit12.log twobit 12
|
||||
../logs/rv32gc_twobit14.log twobit 14
|
||||
../logs/rv32gc_twobit16.log twobit 16
|
||||
../logs/bpred_GSHARE_6_16_10_0_rv32gc_embench.log gshare 6
|
||||
../logs/bpred_GSHARE_8_16_10_0_rv32gc_embench.log gshare 8
|
||||
../logs/bpred_GSHARE_10_16_10_0_rv32gc_embench.log gshare 10
|
||||
../logs/bpred_GSHARE_12_16_10_0_rv32gc_embench.log gshare 12
|
||||
../logs/bpred_GSHARE_14_16_10_0_rv32gc_embench.log gshare 14
|
||||
../logs/bpred_GSHARE_16_16_10_0_rv32gc_embench.log gshare 16
|
||||
../logs/bpred_TWOBIT_6_16_10_0_rv32gc_embench.log twobit 6
|
||||
../logs/bpred_TWOBIT_8_16_10_0_rv32gc_embench.log twobit 8
|
||||
../logs/bpred_TWOBIT_10_16_10_0_rv32gc_embench.log twobit 10
|
||||
../logs/bpred_TWOBIT_12_16_10_0_rv32gc_embench.log twobit 12
|
||||
../logs/bpred_TWOBIT_14_16_10_0_rv32gc_embench.log twobit 14
|
||||
../logs/bpred_TWOBIT_16_16_10_0_rv32gc_embench.log twobit 16
|
||||
|
@ -1,6 +1,6 @@
|
||||
../logs/rv32gc_BTB6.log btb 6
|
||||
../logs/rv32gc_BTB8.log btb 8
|
||||
../logs/rv32gc_BTB10.log btb 10
|
||||
../logs/rv32gc_BTB12.log btb 12
|
||||
../logs/rv32gc_BTB14.log btb 14
|
||||
../logs/rv32gc_BTB16.log btb 16
|
||||
../logs/bpred_GSHARE_16_16_6_0_rv32gc_embench.log btb 6
|
||||
../logs/bpred_GSHARE_16_16_8_0_rv32gc_embench.log btb 8
|
||||
../logs/bpred_GSHARE_16_16_10_0_rv32gc_embench.log btb 10
|
||||
../logs/bpred_GSHARE_16_16_12_0_rv32gc_embench.log btb 12
|
||||
../logs/bpred_GSHARE_16_16_14_0_rv32gc_embench.log btb 14
|
||||
../logs/bpred_GSHARE_16_16_16_0_rv32gc_embench.log btb 16
|
||||
|
@ -1,6 +1,6 @@
|
||||
../logs/rv32gc_class6.log class 6
|
||||
../logs/rv32gc_class8.log class 8
|
||||
../logs/rv32gc_class10.log class 10
|
||||
../logs/rv32gc_class12.log class 12
|
||||
../logs/rv32gc_class14.log class 14
|
||||
../logs/rv32gc_class16.log class 16
|
||||
../logs/bpred_GSHARE_16_16_6_1_rv32gc_embench.log btb 6
|
||||
../logs/bpred_GSHARE_16_16_8_1_rv32gc_embench.log btb 8
|
||||
../logs/bpred_GSHARE_16_16_10_1_rv32gc_embench.log btb 10
|
||||
../logs/bpred_GSHARE_16_16_12_1_rv32gc_embench.log btb 12
|
||||
../logs/bpred_GSHARE_16_16_14_1_rv32gc_embench.log btb 14
|
||||
../logs/bpred_GSHARE_16_16_16_1_rv32gc_embench.log btb 16
|
||||
|
@ -1,5 +1,5 @@
|
||||
../logs/rv32gc_RAS3.log ras 3
|
||||
../logs/rv32gc_RAS4.log ras 4
|
||||
../logs/rv32gc_RAS6.log ras 6
|
||||
../logs/rv32gc_RAS10.log ras 10
|
||||
../logs/rv32gc_RAS16.log ras 16
|
||||
../logs/bpred_GSHARE_10_3_10_0_rv32gc_embench.log ras 3
|
||||
../logs/bpred_GSHARE_10_4_10_0_rv32gc_embench.log ras 4
|
||||
../logs/bpred_GSHARE_10_6_10_0_rv32gc_embench.log ras 6
|
||||
../logs/bpred_GSHARE_10_10_10_0_rv32gc_embench.log ras 10
|
||||
../logs/bpred_GSHARE_10_16_10_0_rv32gc_embench.log ras 16
|
||||
|
@ -7,6 +7,7 @@
|
||||
#// For example, signals hardwired to 0 should not be checked for toggle coverage
|
||||
#//
|
||||
#// 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
|
||||
#//
|
||||
@ -34,21 +35,39 @@ do GetLineNum.do
|
||||
# DH 4/22/23: Exclude all LZAs
|
||||
coverage exclude -srcfile lzc.sv
|
||||
|
||||
#################
|
||||
# FPU Exclusions
|
||||
#################
|
||||
# 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
|
||||
# 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.
|
||||
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
|
||||
# This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too)
|
||||
# Also exclude the write line to ready transition for the I$ since we can't get a flush during this operation.
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -fstate CurrState STATE_FLUSH STATE_FLUSH_WRITEBACK STATE_FLUSH_WRITEBACK STATE_WRITEBACK
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -ftrans CurrState STATE_WRITE_LINE->STATE_READY
|
||||
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.
|
||||
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
|
||||
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
|
||||
set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: 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 [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 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
|
||||
|
||||
# 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/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
|
||||
# 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 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.
|
||||
# InvalidateCache is I$ only:
|
||||
@ -90,10 +137,14 @@ coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [Get
|
||||
set numcacheways 4
|
||||
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
|
||||
# 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
|
||||
# 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 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
|
||||
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
|
||||
@ -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/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"]
|
||||
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
|
||||
@ -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
|
||||
|
||||
# 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/uncoreramdec
|
||||
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/spidec
|
||||
|
||||
#Excluding the bootrom, uncoreran, and clint as sources for the lsu
|
||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/bootromdec
|
||||
# The following peripherals are always supported
|
||||
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
|
||||
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
|
||||
|
||||
# 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/iromdec
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/ddr4dec
|
||||
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
|
||||
####################
|
||||
@ -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
|
||||
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
|
||||
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"]
|
||||
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"]
|
||||
@ -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 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
|
||||
set line [GetLineNum ../src/ifu/ifu.sv "~ITLBMissF & ~CacheableF & ~SelIROM"]
|
||||
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\\("]
|
||||
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
|
||||
# This is a blunt instrument; perhaps there is a more graceful exclusion
|
||||
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/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
|
||||
####################
|
||||
|
||||
# Exclude EBU Beat Counter because it is only idle when bus has multicycle latency, but rv64gc has single cycle latency
|
||||
coverage exclude -scope /core/ebu/ebu/ebufsmarb/BeatCounter
|
||||
# Exclude EBU Beat Counter flop because it is only idle when bus has multicycle latency, but rv64gc has single cycle latency
|
||||
coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb/BeatCounter/cntrflop
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
--override cpu/mvendorid=0x602
|
||||
--override cpu/marchid=0x24
|
||||
--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
|
||||
--override cpu/add_Extensions=B
|
||||
@ -21,6 +22,7 @@
|
||||
--override cpu/Zcb=T
|
||||
--override cpu/Zicond=T
|
||||
--override cpu/Zfh=T
|
||||
--override cpu/Zfa=T
|
||||
|
||||
# Cache block operations
|
||||
--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 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 0x0080000000 -hi 0x008FFFFFFF -attributes " rwxaA- 1248 " # UNCORE_RAM
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM
|
||||
|
||||
# Enable the Imperas instruction coverage
|
||||
|
@ -1,19 +1,48 @@
|
||||
#!/bin/bash
|
||||
# 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/
|
||||
verilator=`which verilator`
|
||||
|
||||
basepath=$(dirname $0)/..
|
||||
for config in rv32e rv64gc rv32gc rv32imc rv32i rv64i rv64fpquad; do
|
||||
#for config in rv64gc; do
|
||||
echo "$config linting..."
|
||||
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
|
||||
echo "Exiting after $config lint due to errors or warnings"
|
||||
exit 1
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
fails=0
|
||||
|
||||
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
|
||||
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
|
||||
# -I points to the include directory where files such as `include config.vh are found
|
||||
|
@ -11,6 +11,9 @@
|
||||
#
|
||||
##################################
|
||||
import sys,os,shutil
|
||||
import multiprocessing
|
||||
|
||||
|
||||
|
||||
class bcolors:
|
||||
HEADER = '\033[95m'
|
||||
@ -29,6 +32,8 @@ os.chdir(regressionDir)
|
||||
|
||||
coverage = '-coverage' 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'])
|
||||
# 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).
|
||||
|
||||
# edit this list to add more test cases
|
||||
configs = [
|
||||
TestCase(
|
||||
name="lints",
|
||||
variant="all",
|
||||
cmd="./lint-wally | tee {}",
|
||||
grepstr="All lints run with no errors or warnings"
|
||||
)
|
||||
]
|
||||
if (nightly):
|
||||
nightMode = "-nightly";
|
||||
configs = []
|
||||
else:
|
||||
nightMode = "";
|
||||
configs = [
|
||||
TestCase(
|
||||
name="lints",
|
||||
variant="all",
|
||||
cmd="./lint-wally " + nightMode + " | tee {}",
|
||||
grepstr="lints run with no errors or warnings"
|
||||
)
|
||||
]
|
||||
|
||||
def getBuildrootTC(boot):
|
||||
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.
|
||||
@ -62,7 +73,7 @@ def getBuildrootTC(boot):
|
||||
BRcmd="vsim > {} -c <<!\ndo wally-batch.do buildroot buildroot $RISCV "+str(INSTR_LIMIT)+" 1 0 -coverage\n!"
|
||||
else:
|
||||
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"
|
||||
return TestCase(name,variant="rv64gc",cmd=BRcmd,grepstr=BRgrepstr)
|
||||
|
||||
@ -78,7 +89,7 @@ for test in tests64i:
|
||||
configs.append(tc)
|
||||
|
||||
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"]
|
||||
for test in tests32gc:
|
||||
tc = TestCase(
|
||||
@ -117,29 +128,27 @@ for test in tests32e:
|
||||
grepstr="All tests ran without failures")
|
||||
configs.append(tc)
|
||||
|
||||
ahbTests = [("0", "0"), ("0", "1"), ("1", "0"), ("1", "1"), ("2", "0"), ("2", "1")]
|
||||
for test in ahbTests:
|
||||
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", "arch64f_divsqrt", "arch64d_divsqrt", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64zfh", "arch64zfh_divsqrt", "arch64zfh_fma", "arch64zfaf", "arch64zfad",
|
||||
"arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "arch64zicond", "wally64a", "wally64periph", "wally64priv"] # add arch64zfh_fma when available; arch64zicobz, arch64zcb when working
|
||||
#tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
|
||||
# "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv", "arch64zicboz", "arch64zcb"]
|
||||
if (coverage): # delete all but 64gc tests when running coverage
|
||||
configs = []
|
||||
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m",
|
||||
"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):
|
||||
tests64gc.append("arch64f")
|
||||
tests64gc.append("arch64d")
|
||||
tests64gc.append("arch64zfh")
|
||||
tests64gc.append("arch64f_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'
|
||||
else:
|
||||
coverStr = ''
|
||||
@ -151,6 +160,237 @@ for test in tests64gc:
|
||||
grepstr="All tests ran without failures")
|
||||
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
|
||||
from multiprocessing import Pool, TimeoutError
|
||||
@ -206,13 +446,18 @@ def main():
|
||||
# Also it is slow to run.
|
||||
# configs.append(getBuildrootTC(boot=False))
|
||||
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:
|
||||
TIMEOUT_DUR = 10*60 # seconds
|
||||
configs.append(getBuildrootTC(boot=False))
|
||||
|
||||
# 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
|
||||
with Pool(processes=min(len(configs),40)) as pool:
|
||||
with Pool(processes=min(len(configs),multiprocessing.cpu_count())) as pool:
|
||||
num_fail = 0
|
||||
results = {}
|
||||
for config in configs:
|
||||
|
@ -3,8 +3,8 @@
|
||||
#export RISCV=/scratch/moore/RISCV
|
||||
|
||||
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=""
|
||||
#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"
|
||||
|
@ -10,6 +10,7 @@
|
||||
## Purpose: Run the cache simulator on each rv64gc test suite in turn.
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -10,6 +10,7 @@
|
||||
## Purpose: Run wally with imperas
|
||||
##
|
||||
## 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
|
||||
##
|
||||
|
@ -9,4 +9,4 @@
|
||||
# sqrt - test square root
|
||||
# all - test everything
|
||||
|
||||
vsim -do "do testfloat.do rv64fpquad $1"
|
||||
vsim -do "do testfloat.do fdqh_ieee_rv64gc $1"
|
||||
|
@ -10,4 +10,4 @@
|
||||
# sqrt - test square root
|
||||
# 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
55
sim/testfloat-batch.do
Normal 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
|
@ -25,7 +25,7 @@ vlib work
|
||||
# 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 +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
|
||||
# values are QP, DP, SP, HP or all for all tests
|
||||
|
@ -21,33 +21,40 @@
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if {$2 eq "ahb"} {
|
||||
if [file exists wkdir/work_${1}_${2}_${3}_${4}] {
|
||||
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}
|
||||
if [file exists wkdir/work_${1}_${2}] {
|
||||
vdel -lib wkdir/work_${1}_${2} -all
|
||||
}
|
||||
vlib wkdir/work_${1}_${2}
|
||||
# Create directory for coverage data
|
||||
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 {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} {
|
||||
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:
|
||||
# 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
|
||||
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
|
||||
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 the Simulation
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
echo "Don't forget to change DEBUG_LEVEL = 0."
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
run -all
|
||||
run -all
|
||||
exec ./slack-notifier/slack-notifier.py
|
||||
# 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}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 ${configOptions} -o testbenchopt ${CoverageVoptArg}
|
||||
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 ${CoverageVsimArg}
|
||||
|
||||
} 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
|
||||
# power add generates the logging necessary for said generation.
|
||||
# power add -r /dut/core/*
|
||||
run -all
|
||||
# power off -r /dut/core/*
|
||||
}
|
||||
# power add generates the logging necessary for said generation.
|
||||
# power add -r /dut/core/*
|
||||
run -all
|
||||
# power off -r /dut/core/*
|
||||
|
||||
|
||||
if {$coverage} {
|
||||
echo "Saving coverage to ${1}_${2}.ucdb"
|
||||
|
@ -32,25 +32,10 @@ vlib work
|
||||
|
||||
# start and run simulation
|
||||
# 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"} {
|
||||
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"} {
|
||||
if {$2 eq "buildroot"} {
|
||||
vlog -lint -work work_${1}_${2} \
|
||||
+define+USE_IMPERAS_DV \
|
||||
+incdir+../config/$1 \
|
||||
+incdir+../config/deriv/$1 \
|
||||
+incdir+../config/shared \
|
||||
+incdir+$env(IMPERAS_HOME)/ImpPublic/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/trace2bin.sv \
|
||||
../src/cvw.sv \
|
||||
../testbench/testbench-linux-imperas.sv \
|
||||
../testbench/testbench.sv \
|
||||
../testbench/common/*.sv ../src/*/*.sv \
|
||||
../src/*/*/*.sv -suppress 2583
|
||||
|
||||
@ -76,7 +61,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
||||
# visualizer -fprofile+perf+dir=fprofile
|
||||
#
|
||||
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 \
|
||||
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
|
||||
$env(OTHERFLAGS)
|
||||
@ -96,60 +81,4 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
||||
|
||||
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
|
||||
#}
|
||||
|
@ -77,12 +77,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
||||
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
|
||||
}
|
||||
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
|
||||
|
24
src/cache/cache.sv
vendored
24
src/cache/cache.sv
vendored
@ -10,6 +10,7 @@
|
||||
// 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.
|
||||
// https://github.com/openhwgroup/cvw
|
||||
//
|
||||
// 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 [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0];
|
||||
logic [NUMWAYS-1:0] HitWay, ValidWay;
|
||||
logic CacheHit;
|
||||
logic Hit;
|
||||
logic [NUMWAYS-1:0] VictimWay, DirtyWay, HitDirtyWay;
|
||||
logic LineDirty, HitLineDirty;
|
||||
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 SelFetchBuffer;
|
||||
logic CacheEn;
|
||||
logic SelWay;
|
||||
logic SelVictim;
|
||||
logic [LINELEN/8-1:0] LineByteMask;
|
||||
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
|
||||
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
|
||||
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,
|
||||
.FlushWay, .FlushCache, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .HitDirtyWay, .TagWay, .FlushStage, .InvalidateCache);
|
||||
|
||||
@ -131,7 +132,7 @@ module cache import cvw::*; #(parameter cvw_t P,
|
||||
end else
|
||||
assign VictimWay = 1'b1; // one hot.
|
||||
|
||||
assign CacheHit = |HitWay;
|
||||
assign Hit = |HitWay;
|
||||
assign LineDirty = |DirtyWay;
|
||||
assign HitLineDirty = |HitDirtyWay;
|
||||
|
||||
@ -175,18 +176,18 @@ module cache import cvw::*; #(parameter cvw_t P,
|
||||
|
||||
logic [LINELEN/8-1:0] BlankByteMask;
|
||||
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 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
|
||||
for(index = 0; index < LINELEN/8; index++) begin
|
||||
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]));
|
||||
end
|
||||
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0;
|
||||
assign LineByteMask = SetDirty ? DemuxedByteMask : '1;
|
||||
end
|
||||
else
|
||||
begin:WriteSelLogic
|
||||
@ -199,7 +200,7 @@ module cache import cvw::*; #(parameter cvw_t P,
|
||||
// Flush logic
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (!READ_ONLY_CACHE) begin:flushlogic
|
||||
if (!READ_ONLY_CACHE) begin:flushlogic // D$ can be flushed
|
||||
// Flush address (line number)
|
||||
assign ResetOrFlushCntRst = reset | FlushCntRst;
|
||||
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];
|
||||
assign FlushWayFlag = FlushWay[NUMWAYS-1];
|
||||
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 FlushAdrFlag = 0;
|
||||
end
|
||||
@ -224,8 +226,8 @@ module cache import cvw::*; #(parameter cvw_t P,
|
||||
|
||||
cachefsm #(P, READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck,
|
||||
.FlushStage, .CacheRW, .Stall,
|
||||
.CacheHit, .LineDirty, .HitLineDirty, .CacheStall, .CacheCommitted,
|
||||
.CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelWay,
|
||||
.Hit, .LineDirty, .HitLineDirty, .CacheStall, .CacheCommitted,
|
||||
.CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelVictim,
|
||||
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback,
|
||||
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
|
||||
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
|
||||
|
58
src/cache/cacheLRU.sv
vendored
58
src/cache/cacheLRU.sv
vendored
@ -1,7 +1,7 @@
|
||||
///////////////////////////////////////////
|
||||
// cacheLRU.sv
|
||||
//
|
||||
// Written: Ross Thompson ross1728@gmail.com
|
||||
// Written: Rose Thompson ross1728@gmail.com
|
||||
// Created: 20 July 2021
|
||||
// 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)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -35,8 +36,8 @@ module cacheLRU
|
||||
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
|
||||
input logic [NUMWAYS-1:0] HitWay, // Which way is valid and matches PAdr's tag
|
||||
input logic [NUMWAYS-1:0] ValidWay, // Which ways for a particular set are valid, ignores tag
|
||||
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] 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] PAdr, // Physical address
|
||||
input logic LRUWriteEn, // Update the LRU state
|
||||
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] CurrLRU;
|
||||
logic [NUMWAYS-2:0] NextLRU;
|
||||
logic [NUMWAYS-1:0] Way;
|
||||
logic [LOGNUMWAYS-1:0] WayEncoded;
|
||||
logic [LOGNUMWAYS-1:0] HitWayEncoded, Way;
|
||||
logic [NUMWAYS-2:0] WayExpanded;
|
||||
logic AllValid;
|
||||
|
||||
genvar row;
|
||||
|
||||
/* 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 [LOGNUMWAYS-1:0] Intermediate [NUMWAYS-2:0];
|
||||
/* 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;
|
||||
|
||||
///// Update replacement bits.
|
||||
|
||||
// coverage off
|
||||
// Excluded from coverage b/c it is untestable without varying NUMWAYS.
|
||||
function integer log2 (integer value);
|
||||
@ -79,8 +84,7 @@ module cacheLRU
|
||||
// coverage on
|
||||
|
||||
// On a miss we need to ignore HitWay and derive the new replacement bits with the VictimWay.
|
||||
mux2 #(NUMWAYS) WayMux(HitWay, VictimWay, SetValid, Way);
|
||||
binencoder #(NUMWAYS) encoder(Way, WayEncoded);
|
||||
mux2 #(LOGNUMWAYS) WayMuxEnc(HitWayEncoded, VictimWayEnc, SetValid, Way);
|
||||
|
||||
// bit duplication
|
||||
// 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 StartIndex = NUMWAYS-2 - DuplicationFactor + 1;
|
||||
localparam EndIndex = NUMWAYS-2 - 2 * DuplicationFactor + 2;
|
||||
assign WayExpanded[StartIndex : EndIndex] = {{DuplicationFactor}{WayEncoded[row]}};
|
||||
assign WayExpanded[StartIndex : EndIndex] = {{DuplicationFactor}{Way[row]}};
|
||||
end
|
||||
|
||||
genvar node;
|
||||
@ -101,14 +105,14 @@ module cacheLRU
|
||||
localparam r = LOGNUMWAYS - ctr_depth;
|
||||
|
||||
// the child node will be updated if its parent was updated and
|
||||
// the WayEncoded bit was the correct value.
|
||||
// the Way bit was the correct value.
|
||||
// The if statement is only there for coverage since LRUUpdate[root] is always 1.
|
||||
if (node == NUMWAYS-2) begin
|
||||
assign LRUUpdate[lchild] = ~WayEncoded[r];
|
||||
assign LRUUpdate[rchild] = WayEncoded[r];
|
||||
assign LRUUpdate[lchild] = ~Way[r];
|
||||
assign LRUUpdate[rchild] = Way[r];
|
||||
end else begin
|
||||
assign LRUUpdate[lchild] = LRUUpdate[node] & ~WayEncoded[r];
|
||||
assign LRUUpdate[rchild] = LRUUpdate[node] & WayEncoded[r];
|
||||
assign LRUUpdate[lchild] = LRUUpdate[node] & ~Way[r];
|
||||
assign LRUUpdate[rchild] = LRUUpdate[node] & Way[r];
|
||||
end
|
||||
end
|
||||
|
||||
@ -128,30 +132,26 @@ module cacheLRU
|
||||
assign Intermediate[node] = CurrLRU[node] ? int1[LOGNUMWAYS-1:0] : int0[LOGNUMWAYS-1:0];
|
||||
end
|
||||
|
||||
logic [NUMWAYS-1:0] FirstZero;
|
||||
logic [LOGNUMWAYS-1:0] FirstZeroWay;
|
||||
logic [LOGNUMWAYS-1:0] VictimWayEnc;
|
||||
|
||||
priorityonehot #(NUMWAYS) FirstZeroEncoder(~ValidWay, FirstZero);
|
||||
binencoder #(NUMWAYS) FirstZeroWayEncoder(FirstZero, FirstZeroWay);
|
||||
mux2 #(LOGNUMWAYS) VictimMux(FirstZeroWay, Intermediate[NUMWAYS-2], AllValid, VictimWayEnc);
|
||||
//decoder #(LOGNUMWAYS) decoder (Intermediate[NUMWAYS-2], 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.
|
||||
// This is a two port memory.
|
||||
// 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
|
||||
if (reset | (InvalidateCache & ~FlushStage)) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
|
||||
if(CacheEn) begin
|
||||
if(ClearValid & ~FlushStage)
|
||||
LRUMemory[PAdr] <= '0;
|
||||
else if(LRUWriteEn)
|
||||
LRUMemory[PAdr] <= NextLRU;
|
||||
if(LRUWriteEn & (PAdr == CacheSetTag))
|
||||
CurrLRU <= #1 NextLRU;
|
||||
else
|
||||
CurrLRU <= #1 LRUMemory[CacheSetTag];
|
||||
if (reset | (InvalidateCache & ~FlushStage))
|
||||
for (int set = 0; set < NUMLINES; set++) LRUMemory[set] = 0; // exclusion-tag: initialize
|
||||
else if(CacheEn) begin
|
||||
// Because we are using blocking assignments, change to LRUMemory must occur after LRUMemory is used so we get the proper value
|
||||
if(LRUWriteEn & (PAdr == CacheSetTag)) CurrLRU = #1 NextLRU;
|
||||
else CurrLRU = #1 LRUMemory[CacheSetTag];
|
||||
if(LRUWriteEn) LRUMemory[PAdr] = NextLRU;
|
||||
end
|
||||
end
|
||||
|
||||
|
87
src/cache/cachefsm.sv
vendored
87
src/cache/cachefsm.sv
vendored
@ -10,6 +10,7 @@
|
||||
// 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.
|
||||
// https://github.com/openhwgroup/cvw
|
||||
//
|
||||
// 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
|
||||
|
||||
// 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 HitLineDirty, // The cache hit way is dirty
|
||||
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 SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
|
||||
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 FlushWayCntEn, // Enable the way counter during a flush
|
||||
output logic FlushCntRst, // Reset both flush counters
|
||||
@ -78,12 +79,12 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
logic CMOZeroNoEviction;
|
||||
logic StallConditions;
|
||||
|
||||
typedef enum logic [3:0]{STATE_READY, // hit states
|
||||
typedef enum logic [3:0]{STATE_ACCESS, // hit states
|
||||
// miss states
|
||||
STATE_FETCH,
|
||||
STATE_WRITEBACK,
|
||||
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
|
||||
STATE_FLUSH,
|
||||
STATE_FLUSH_WRITEBACK
|
||||
@ -91,61 +92,60 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
|
||||
statetype CurrState, NextState;
|
||||
|
||||
assign AnyMiss = (CacheRW[0] | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
|
||||
assign AnyUpdateHit = (CacheRW[0]) & CacheHit; // exclusion-tag: icache storeAMO1
|
||||
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit
|
||||
assign AnyMiss = (CacheRW[0] | CacheRW[1]) & ~Hit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
|
||||
assign AnyUpdateHit = (CacheRW[0]) & Hit; // exclusion-tag: icache storeAMO1
|
||||
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 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;
|
||||
|
||||
// outputs for the performance counters.
|
||||
assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW
|
||||
assign CacheMiss = CacheAccess & ~CacheHit;
|
||||
assign CacheAccess = (|CacheRW) & ((CurrState == STATE_ACCESS & ~Stall & ~FlushStage) | (CurrState == STATE_ADDRESS_SETUP & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW
|
||||
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.
|
||||
// But PCF will be the reset vector.
|
||||
flop #(1) resetDelayReg(.clk, .d(reset), .q(resetDelay));
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset | FlushStage) CurrState <= #1 STATE_READY;
|
||||
if (reset | FlushStage) CurrState <= #1 STATE_ACCESS;
|
||||
else CurrState <= #1 NextState;
|
||||
|
||||
always_comb begin
|
||||
NextState = STATE_READY;
|
||||
NextState = STATE_ACCESS;
|
||||
case (CurrState) // exclusion-tag: icache state-case
|
||||
STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck
|
||||
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
|
||||
STATE_ACCESS: if(InvalidateCache) NextState = STATE_ACCESS; // exclusion-tag: dcache InvalidateCheck
|
||||
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 | CMOWriteback) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
||||
else NextState = STATE_READY;
|
||||
else if((AnyMiss | CMOWriteback) & ~READ_ONLY_CACHE) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
||||
else NextState = STATE_ACCESS;
|
||||
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
|
||||
else if(CacheBusAck) NextState = STATE_READY;
|
||||
else NextState = STATE_FETCH;
|
||||
STATE_WRITE_LINE: NextState = STATE_READ_HOLD;
|
||||
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
|
||||
else NextState = STATE_READY;
|
||||
STATE_WRITE_LINE: NextState = STATE_ADDRESS_SETUP;
|
||||
STATE_ADDRESS_SETUP: if(Stall) NextState = STATE_ADDRESS_SETUP;
|
||||
else NextState = STATE_ACCESS;
|
||||
// exclusion-tag-start: icache case
|
||||
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;
|
||||
// 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;
|
||||
else if (FlushFlag) NextState = STATE_READ_HOLD;
|
||||
else if (FlushFlag) NextState = STATE_ADDRESS_SETUP;
|
||||
else 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;
|
||||
// exclusion-tag-end: icache case
|
||||
default: NextState = STATE_READY;
|
||||
default: NextState = STATE_ACCESS;
|
||||
endcase
|
||||
end
|
||||
|
||||
// com back to CPU
|
||||
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD));
|
||||
assign StallConditions = FlushCache | AnyMiss | CMOWriteback;
|
||||
assign CacheStall = (CurrState == STATE_READY & StallConditions) | // exclusion-tag: icache StallStates
|
||||
assign CacheCommitted = (CurrState != STATE_ACCESS) & ~(READ_ONLY_CACHE & (CurrState == STATE_ADDRESS_SETUP));
|
||||
assign StallConditions = FlushCache | AnyMiss | CMOWriteback; // exclusion-tag: icache FlushCache
|
||||
assign CacheStall = (CurrState == STATE_ACCESS & StallConditions) | // exclusion-tag: icache StallStates
|
||||
(CurrState == STATE_FETCH) |
|
||||
(CurrState == STATE_WRITEBACK) |
|
||||
(CurrState == STATE_WRITE_LINE) | // this cycle writes the sram, must keep stalling so the next cycle can read the next hit/miss unless its a write.
|
||||
@ -153,27 +153,26 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
(CurrState == STATE_FLUSH_WRITEBACK);
|
||||
// write enables internal to cache
|
||||
assign SetValid = CurrState == STATE_WRITE_LINE |
|
||||
(CurrState == STATE_READY & CMOZeroNoEviction) |
|
||||
(CurrState == STATE_ACCESS & CMOZeroNoEviction) |
|
||||
(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);
|
||||
// coverage off -item e 1 -fecexprrow 8
|
||||
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
|
||||
assign LRUWriteEn = (((CurrState == STATE_ACCESS & (AnyHit | CMOZeroNoEviction)) |
|
||||
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
|
||||
(CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck);
|
||||
// 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_WRITEBACK & (CMOpM[3] & CacheBusAck));
|
||||
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty
|
||||
(CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
|
||||
// Flush and eviction controls
|
||||
CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck;
|
||||
assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
|
||||
(CurrState == STATE_READY & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) |
|
||||
assign SelVictim = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
|
||||
(CurrState == STATE_ACCESS & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~Hit))) |
|
||||
(CurrState == STATE_WRITE_LINE);
|
||||
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
|
||||
// (state is always FLUSH_WRITEBACK when 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);
|
||||
// exclusion-tag-end: icache flushdirtycontrols
|
||||
// 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_WRITEBACK & CacheBusAck & ~(|CMOpM));
|
||||
|
||||
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_FLUSH_WRITEBACK & ~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_WRITEBACK) |
|
||||
(CurrState == STATE_WRITE_LINE) |
|
||||
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_WRITEBACK) |
|
||||
(CurrState == STATE_WRITE_LINE) |
|
||||
resetDelay;
|
||||
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD;
|
||||
assign CacheEn = (~Stall | StallConditions) | (CurrState != STATE_READY) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
|
||||
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_ADDRESS_SETUP;
|
||||
assign CacheEn = (~Stall | StallConditions) | (CurrState != STATE_ACCESS) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
|
||||
|
||||
endmodule // cachefsm
|
||||
|
48
src/cache/cacheway.sv
vendored
48
src/cache/cacheway.sv
vendored
@ -10,6 +10,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.11)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -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 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 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 FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
|
||||
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 HitWay, // This way hits
|
||||
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 [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 [TAGLEN-1:0] ReadTag;
|
||||
logic Dirty;
|
||||
logic SelDirty;
|
||||
logic SelecteDirty;
|
||||
logic SelectedWriteWordEn;
|
||||
logic [LINELEN/8-1:0] FinalByteMask;
|
||||
logic SetValidEN, ClearValidEN;
|
||||
@ -76,36 +77,33 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
logic SetDirtyWay;
|
||||
logic ClearDirtyWay;
|
||||
logic SelNonHit;
|
||||
logic SelData;
|
||||
logic SelectedWay;
|
||||
logic InvalidateCacheDelay;
|
||||
|
||||
if (!READ_ONLY_CACHE) begin:flushlogic
|
||||
logic FlushWayEn;
|
||||
mux2 #(1) seltagmux(VictimWay, FlushWay, FlushCache, SelDirty);
|
||||
|
||||
mux2 #(1) seltagmux(VictimWay, FlushWay, FlushCache, SelecteDirty);
|
||||
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.
|
||||
// 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.
|
||||
assign FlushWayEn = FlushWay & FlushCache;
|
||||
assign SelNonHit = FlushWayEn | SelWay;
|
||||
end else begin:flushlogic // no flush operation for read-only caches.
|
||||
assign SelDirty = VictimWay;
|
||||
assign SelNonHit = SelWay;
|
||||
assign SelecteDirty = VictimWay;
|
||||
mux2 #(1) selectedwaymux(HitWay, SelecteDirty, SelVictim , SelectedWay);
|
||||
end
|
||||
|
||||
mux2 #(1) selectedwaymux(HitWay, SelDirty, SelNonHit , SelData);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Write Enable demux
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign SetValidWay = SetValid & SelData;
|
||||
assign ClearValidWay = ClearValid & SelData;
|
||||
assign SetDirtyWay = SetDirty & SelData; // exclusion-tag: icache SetDirtyWay
|
||||
assign ClearDirtyWay = ClearDirty & SelData;
|
||||
assign SetValidWay = SetValid & SelectedWay;
|
||||
assign ClearValidWay = ClearValid & SelectedWay; // exclusion-tag: icache ClearValidWay
|
||||
assign SetDirtyWay = SetDirty & SelectedWay; // exclusion-tag: icache SetDirtyWay
|
||||
assign ClearDirtyWay = ClearDirty & SelectedWay;
|
||||
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn
|
||||
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.
|
||||
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));
|
||||
|
||||
// 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 DirtyWay = SelDirty & HitDirtyWay;
|
||||
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay;
|
||||
assign DirtyWay = SelecteDirty & HitDirtyWay; // exclusion-tag: icache DirtyWay
|
||||
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay; // exclusion-tag: dcache HitWay
|
||||
|
||||
flop #(1) InvalidateCacheReg(clk, InvalidateCache, InvalidateCacheDelay);
|
||||
|
||||
@ -151,19 +149,19 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
end
|
||||
|
||||
// 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
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge clk) begin // Valid bit array,
|
||||
if (reset) ValidBits <= #1 '0;
|
||||
if (reset) ValidBits <= #1 0;
|
||||
if(CacheEn) begin
|
||||
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 (ClearValidEN) ValidBits[CacheSetData] <= #1 '0;
|
||||
else if (ClearValidEN) ValidBits[CacheSetData] <= #1 0; // exclusion-tag: icache ClearValidBits
|
||||
end
|
||||
end
|
||||
|
||||
@ -178,7 +176,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
//if (reset) DirtyBits <= #1 {NUMLINES{1'b0}};
|
||||
if(CacheEn) begin
|
||||
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 else assign Dirty = 1'b0;
|
||||
|
1
src/cache/subcachelineread.sv
vendored
1
src/cache/subcachelineread.sv
vendored
@ -10,6 +10,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 7
|
||||
|
||||
// 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
|
||||
//
|
||||
|
@ -41,6 +41,8 @@ typedef struct packed {
|
||||
logic IEEE754; // IEEE754 NaN handling (0 = use RISC-V NaN propagation instead)
|
||||
int MISA; // Machine Instruction Set Architecture
|
||||
int AHBW; // AHB bus width (usually = XLEN)
|
||||
int RAM_LATENCY; // Latency to stress AHB
|
||||
logic BURST_EN; // Support AHB Burst Mode
|
||||
|
||||
// RISC-V Features
|
||||
logic ZICSR_SUPPORTED;
|
||||
@ -160,6 +162,7 @@ typedef struct packed {
|
||||
int BPRED_SIZE;
|
||||
int BTB_SIZE;
|
||||
int RAS_SIZE;
|
||||
logic INSTR_CLASS_PRED; // is class predictor enabled
|
||||
|
||||
// FPU division architecture
|
||||
int RADIX;
|
||||
|
@ -10,6 +10,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 9 (Figure 9.8)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -27,10 +28,8 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module ahbcacheinterface #(
|
||||
parameter AHBW,
|
||||
parameter LLEN,
|
||||
parameter PA_BITS,
|
||||
module ahbcacheinterface import cvw::*; #(
|
||||
parameter cvw_t P,
|
||||
parameter BEATSPERLINE, // Number of AHBW words (beats) in cacheline
|
||||
parameter AHBWLOGBWPL, // Log2 of ^
|
||||
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] HBURST, // AHB burst length
|
||||
// bus interface buses
|
||||
input logic [AHBW-1:0] HRDATA, // AHB read data
|
||||
output logic [PA_BITS-1:0] HADDR, // AHB address
|
||||
output logic [AHBW-1:0] HWDATA, // AHB write data
|
||||
output logic [AHBW/8-1:0] HWSTRB, // AHB byte mask
|
||||
input logic [P.AHBW-1:0] HRDATA, // AHB read data
|
||||
output logic [P.PA_BITS-1:0] HADDR, // AHB address
|
||||
output logic [P.AHBW-1:0] HWDATA, // AHB write data
|
||||
output logic [P.AHBW/8-1:0] HWSTRB, // AHB byte mask
|
||||
|
||||
// cache interface
|
||||
input logic [PA_BITS-1:0] CacheBusAdr, // Address of cache line
|
||||
input logic [LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
|
||||
input logic [P.PA_BITS-1:0] CacheBusAdr, // Address of cache line
|
||||
input logic [P.LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
|
||||
input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$
|
||||
input logic Cacheable, // Memory operation is cachable
|
||||
input logic [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
|
||||
|
||||
// uncached interface
|
||||
input logic [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.PA_BITS-1:0] PAdr, // Physical address of uncached memory operation
|
||||
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 BusAtomic, // Uncache atomic 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
|
||||
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 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 [AHBW-1:0] PreHWDATA; // AHB Address phase write data
|
||||
logic [PA_BITS-1:0] PAdrZero;
|
||||
logic [P.AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s
|
||||
logic [P.AHBW-1:0] PreHWDATA; // AHB Address phase write data
|
||||
logic [P.PA_BITS-1:0] PAdrZero;
|
||||
|
||||
genvar index;
|
||||
|
||||
@ -90,38 +89,38 @@ module ahbcacheinterface #(
|
||||
for (index = 0; index < BEATSPERLINE; index++) begin:fetchbuffer
|
||||
logic [BEATSPERLINE-1:0] CaptureBeat;
|
||||
assign CaptureBeat[index] = CaptureEn & (index == BeatCountDelayed);
|
||||
flopen #(AHBW) fb(.clk(HCLK), .en(CaptureBeat[index]), .d(HRDATA),
|
||||
.q(FetchBuffer[(index+1)*AHBW-1:index*AHBW]));
|
||||
flopen #(P.AHBW) fb(.clk(HCLK), .en(CaptureBeat[index]), .d(HRDATA),
|
||||
.q(FetchBuffer[(index+1)*P.AHBW-1:index*P.AHBW]));
|
||||
end
|
||||
|
||||
assign PAdrZero = BusCMOZero ? {PAdr[PA_BITS-1:$clog2(LINELEN/8)], {$clog2(LINELEN/8){1'b0}}} : PAdr;
|
||||
mux2 #(PA_BITS) localadrmux(PAdrZero, CacheBusAdr, Cacheable, LocalHADDR);
|
||||
assign HADDR = ({{PA_BITS-AHBWLOGBWPL{1'b0}}, BeatCount} << $clog2(AHBW/8)) + LocalHADDR;
|
||||
assign PAdrZero = BusCMOZero ? {PAdr[P.PA_BITS-1:$clog2(LINELEN/8)], {$clog2(LINELEN/8){1'b0}}} : PAdr;
|
||||
mux2 #(P.PA_BITS) localadrmux(PAdrZero, CacheBusAdr, Cacheable, 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.
|
||||
logic [AHBW-1:0] CacheReadDataWordAHB;
|
||||
logic [P.AHBW-1:0] CacheReadDataWordAHB;
|
||||
if(LLENPOVERAHBW > 1) begin
|
||||
logic [AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0];
|
||||
logic [P.AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0];
|
||||
genvar index;
|
||||
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
|
||||
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));
|
||||
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.
|
||||
// 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,
|
||||
.CacheBusRW, .BusCMOZero, .CacheBusAck, .BeatCount, .BeatCountDelayed,
|
||||
.HREADY, .HTRANS, .HWRITE, .HBURST);
|
||||
|
@ -10,6 +10,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.21)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -61,8 +62,8 @@ module ahbinterface #(
|
||||
flop #(XLEN) wdreg(HCLK, WriteData, HWDATA);
|
||||
flop #(XLEN/8) HWSTRBReg(HCLK, ByteMask, HWSTRB);
|
||||
end else begin
|
||||
assign HWDATA = '0;
|
||||
assign HWSTRB = '0;
|
||||
assign HWDATA = 0;
|
||||
assign HWSTRB = 0;
|
||||
end
|
||||
|
||||
busfsm #(~LSU) busfsm(.HCLK, .HRESETn, .Flush, .BusRW, .BusAtomic,
|
||||
|
@ -10,6 +10,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 9 (Figure 9.9)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -27,13 +28,12 @@
|
||||
// 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!
|
||||
module buscachefsm #(
|
||||
parameter BeatCountThreshold, // Largest beat index
|
||||
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 HRESETn,
|
||||
@ -79,7 +79,7 @@ module buscachefsm #(
|
||||
logic CacheAccess;
|
||||
logic BusWrite;
|
||||
|
||||
assign BusWrite = CacheBusRW[0] | BusCMOZero;
|
||||
assign BusWrite = (CacheBusRW[0] | BusCMOZero) & ~READ_ONLY_CACHE;
|
||||
|
||||
always_ff @(posedge HCLK)
|
||||
if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE;
|
||||
@ -87,28 +87,28 @@ module buscachefsm #(
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE;
|
||||
else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK;
|
||||
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; // exclusion-tag: buscachefsm HREADY0
|
||||
else if (HREADY & BusWrite & ~READ_ONLY_CACHE) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm HREADY1
|
||||
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm HREADYread
|
||||
else NextState = ADR_PHASE;
|
||||
DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_READ_DATA_PHASE;
|
||||
else if(HREADY & ~BusAtomic) NextState = MEM3;
|
||||
DATA_PHASE: if(HREADY & BusAtomic & ~READ_ONLY_CACHE) NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm HREADY2
|
||||
else if(HREADY & ~BusAtomic) NextState = MEM3; // exclusion-tag: buscachefsm HREADY3
|
||||
else NextState = DATA_PHASE;
|
||||
ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE;
|
||||
else NextState = ATOMIC_READ_DATA_PHASE;
|
||||
ATOMIC_PHASE: if(HREADY) NextState = MEM3;
|
||||
else NextState = ATOMIC_PHASE;
|
||||
ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicReadData
|
||||
else NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm AtomicElse
|
||||
ATOMIC_PHASE: if(HREADY) NextState = MEM3; // exclusion-tag: buscachefsm AtomicPhase
|
||||
else NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicWait
|
||||
MEM3: if(Stall) NextState = MEM3;
|
||||
else NextState = ADR_PHASE;
|
||||
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm FetchWriteback
|
||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm FetchWait
|
||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
||||
else NextState = CACHE_FETCH;
|
||||
CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||
else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3;
|
||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
||||
else 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; // exclusion-tag: buscachefsm HREADY4
|
||||
else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3; // exclusion-tag: buscachefsm HREADY5
|
||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; // exclusion-tag: buscachefsm HREADY6
|
||||
else NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm WritebackWriteback2
|
||||
default: NextState = ADR_PHASE;
|
||||
endcase
|
||||
end
|
||||
@ -139,13 +139,13 @@ module buscachefsm #(
|
||||
|
||||
// AHB bus interface
|
||||
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 & |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) |
|
||||
(CurrState == CACHE_WRITEBACK & |BeatCount);
|
||||
assign HBURST = `BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0;
|
||||
assign HWRITE = (((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) |
|
||||
(CurrState == CACHE_WRITEBACK & |BeatCount)) & ~READ_ONLY_CACHE;
|
||||
assign HBURST = BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0;
|
||||
|
||||
always_comb begin
|
||||
case(BeatCountThreshold)
|
||||
|
@ -10,6 +10,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.23)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
@ -14,6 +14,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 6 (Figure 6.25)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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.
|
||||
// https://github.com/openhwgroup/cvw
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
@ -31,31 +32,31 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module ebu #(parameter XLEN, PA_BITS, AHBW)(
|
||||
module ebu import cvw::*; #(parameter cvw_t P) (
|
||||
input logic clk, reset,
|
||||
// Signals from IFU
|
||||
input logic [1:0] IFUHTRANS, // IFU AHB transaction request
|
||||
input logic [2:0] IFUHSIZE, // IFU AHB transaction size
|
||||
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
|
||||
// Signals from LSU
|
||||
input logic [1:0] LSUHTRANS, // LSU AHB transaction request
|
||||
input logic LSUHWRITE, // LSU AHB transaction direction. 1: write, 0: read
|
||||
input logic [2:0] LSUHSIZE, // LSU AHB size
|
||||
input logic [2:0] LSUHBURST, // LSU AHB burst length
|
||||
input logic [PA_BITS-1:0] LSUHADDR, // LSU AHB address
|
||||
input logic [XLEN-1:0] LSUHWDATA, // initially support AHBW = XLEN
|
||||
input logic [XLEN/8-1:0] LSUHWSTRB, // AHB byte mask
|
||||
input logic [P.PA_BITS-1:0] LSUHADDR, // LSU AHB address
|
||||
input logic [P.XLEN-1:0] LSUHWDATA, // initially support AHBW = XLEN
|
||||
input logic [P.XLEN/8-1:0] LSUHWSTRB, // AHB byte mask
|
||||
output logic LSUHREADY, // AHB peripheral. Never gated as LSU always has priority
|
||||
|
||||
// AHB-Lite external signals
|
||||
output logic HCLK, HRESETn,
|
||||
input logic HREADY, // AHB peripheral ready
|
||||
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 [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.PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration
|
||||
output logic [P.AHBW-1:0] HWDATA, // AHB Write data 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 [2:0] HSIZE, // AHB transaction size 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 IFUSelect;
|
||||
|
||||
logic [PA_BITS-1:0] IFUHADDROut;
|
||||
logic [P.PA_BITS-1:0] IFUHADDROut;
|
||||
logic [1:0] IFUHTRANSOut;
|
||||
logic [2:0] IFUHBURSTOut;
|
||||
logic [2:0] IFUHSIZEOut;
|
||||
logic IFUHWRITEOut;
|
||||
|
||||
logic [PA_BITS-1:0] LSUHADDROut;
|
||||
logic [P.PA_BITS-1:0] LSUHADDROut;
|
||||
logic [1:0] LSUHTRANSOut;
|
||||
logic [2:0] LSUHBURSTOut;
|
||||
logic [2:0] LSUHSIZEOut;
|
||||
@ -96,25 +97,25 @@ module ebu #(parameter XLEN, PA_BITS, AHBW)(
|
||||
// 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),
|
||||
.HWRITEIn(1'b0), .HSIZEIn(IFUHSIZE), .HBURSTIn(IFUHBURST), .HTRANSIn(IFUHTRANS), .HADDRIn(IFUHADDR),
|
||||
.HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY),
|
||||
.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.
|
||||
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),
|
||||
.HWRITEIn(LSUHWRITE), .HSIZEIn(LSUHSIZE), .HBURSTIn(LSUHBURST), .HTRANSIn(LSUHTRANS), .HADDRIn(LSUHADDR), .HREADYOut(LSUHREADY),
|
||||
.HWRITEOut(LSUHWRITEOut), .HSIZEOut(LSUHSIZEOut), .HBURSTOut(LSUHBURSTOut),
|
||||
.HTRANSOut(LSUHTRANSOut), .HADDROut(LSUHADDROut), .HREADYIn(HREADY));
|
||||
|
||||
// output mux //*** switch to structural implementation
|
||||
assign HADDR = LSUSelect ? LSUHADDROut : IFUSelect ? IFUHADDROut : '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 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 HADDR = LSUSelect ? LSUHADDROut : IFUSelect ? IFUHADDROut : 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 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 : 0;
|
||||
assign HPROT = 4'b0011; // not used; see Section 3.7
|
||||
assign HMASTLOCK = 0; // no locking supported
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
// 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.
|
||||
// https://github.com/openhwgroup/cvw
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -67,12 +68,13 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
|
||||
// LT/LE - signaling - sets invalid if NaN input
|
||||
// EQ - quiet - sets invalid if signaling NaN input
|
||||
always_comb begin
|
||||
case (OpCtrl[2:0])
|
||||
casez (OpCtrl[2:0])
|
||||
3'b110: CmpNV = EitherSNaN; //min
|
||||
3'b101: CmpNV = EitherSNaN; //max
|
||||
3'b010: CmpNV = EitherSNaN; //equal
|
||||
3'b001: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fltq / flt perform CompareQuietLess / CompareSignalingLess differing on when to set invalid
|
||||
3'b011: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fleq / fle differ on when to set invalid
|
||||
3'b0?1: if (P.ZFA_SUPPORTED)
|
||||
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;
|
||||
endcase
|
||||
end
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -45,11 +46,11 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
// input mux selections
|
||||
output logic XEnD, YEnD, ZEnD, // enable inputs
|
||||
output logic XEnE, YEnE, ZEnE, // enable inputs
|
||||
// opperation mux selections
|
||||
output logic FCvtIntE, FCvtIntW, // convert to integer opperation
|
||||
// operation mux selections
|
||||
output logic FCvtIntE, FCvtIntW, // convert to integer operation
|
||||
output logic [2:0] FrmM, // FP rounding mode
|
||||
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 [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
|
||||
@ -71,7 +72,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
logic FRegWriteD; // FP register write enable
|
||||
logic FDivStartD; // start division/sqrt
|
||||
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] FResSelD; // Select one of the results that finish in the memory stage
|
||||
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 SupportedFmt; // is the format supported
|
||||
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
|
||||
|
||||
// FPU Instruction Decoder
|
||||
assign Fmt = Funct7D[1:0];
|
||||
assign Fmt2 = Rs2D[1:0]; // source format for fcvt fp->fp
|
||||
|
||||
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'b11 & P.Q_SUPPORTED));
|
||||
assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & P.D_SUPPORTED) |
|
||||
(Fmt == 2'b10 & P.ZFH_SUPPORTED) | (Fmt == 2'b11 & P.Q_SUPPORTED));
|
||||
assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & P.D_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'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0; // fcvt.lu.q q->lu
|
||||
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)
|
||||
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)
|
||||
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.q.x (Zfa)
|
||||
// coverage on
|
||||
|
@ -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.NF:0] Xm, // input's fraction
|
||||
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 XZero, // is the input zero
|
||||
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.NE-2:0] NewBias; // the bias of the final result
|
||||
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 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.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 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
|
||||
// - int -> fp: Fmt contains the precision of the output
|
||||
if (P.FPSIZES == 2)
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -70,8 +71,7 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
|
||||
// The datapath produces rk bits per cycle, so Cycles = ceil (ResultBitsE / rk)
|
||||
|
||||
always_comb begin
|
||||
if (SqrtE) FPResultBitsE = Nf + 2 + 0; // 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
|
||||
FPResultBitsE = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard; integer bit implicit because starting at n=1
|
||||
|
||||
if (P.IDIV_ON_FPU) ResultBitsE = IntDivE ? IntResultBitsE : FPResultBitsE;
|
||||
else ResultBitsE = FPResultBitsE;
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -36,7 +37,7 @@ module fdivsqrtfgen2 import cvw::*; #(parameter cvw_t P) (
|
||||
// Generate for both positive and negative quotient digits
|
||||
assign FP = ~(U << 1) & C;
|
||||
assign FN = (UM << 1) | (C & ~(C << 2));
|
||||
assign FZ = '0;
|
||||
assign FZ = 0;
|
||||
|
||||
always_comb // Choose which adder input will be used
|
||||
if (up) F = FP;
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -36,7 +37,7 @@ module fdivsqrtfgen4 import cvw::*; #(parameter cvw_t P) (
|
||||
// Generate for both positive and negative digits
|
||||
assign F2 = (~U << 2) & (C << 2); //
|
||||
assign F1 = ~(U << 1) & C;
|
||||
assign F0 = '0;
|
||||
assign F0 = 0;
|
||||
assign FN1 = (UM << 1) | (C & ~(C << 3));
|
||||
assign FN2 = (UM << 2) | ((C << 2) & ~(C << 4));
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -70,8 +71,8 @@ module fdivsqrtfsm import cvw::*; #(parameter cvw_t P) (
|
||||
end else if (state == BUSY) begin
|
||||
if (step == 1 | WZeroE) state <= #1 DONE; // finished steps or terminate early on zero residual
|
||||
step <= step - 1;
|
||||
end else if (state == DONE) begin
|
||||
if (StallM) state <= #1 DONE;
|
||||
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; // exclusion-tag: fdivsqrtfsm stallm
|
||||
else state <= #1 IDLE;
|
||||
end
|
||||
end
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -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] WS[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] UNext[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]);
|
||||
|
||||
// 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
|
||||
assign initU = {SqrtE, {(P.DIVb){1'b0}}};
|
||||
assign initUM = {~SqrtE, {(P.DIVb){1'b0}}};
|
||||
// Initialize U to 0 = 0.0000... and UM to -1 = 1.00000... (in Q1.Divb)
|
||||
assign initU ={(P.DIVb+1){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) UMmux(UMNext[P.DIVCOPIES-1], initUM, IFDivStartE, UMMux);
|
||||
flopen #(P.DIVb+1) UReg(clk, FDivBusyE, UMux, U[0]);
|
||||
flopen #(P.DIVb+1) UMReg(clk, FDivBusyE, UMMux, UM[0]);
|
||||
|
||||
// C register/initialization mux
|
||||
// Initialize C to -1 for sqrt and -R for division
|
||||
logic [1:0] initCUpper;
|
||||
if(P.RADIX == 4) begin
|
||||
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}}};
|
||||
// C register/initialization mux: C = -R:
|
||||
// C = -4 = 00.000000... (in Q2.DIVb) for radix 4, C = -2 = 10.000000... for radix2
|
||||
if(P.RADIX == 4) assign initC = 0;
|
||||
else assign initC = {2'b10, {{P.DIVb{1'b0}}}};
|
||||
mux2 #(P.DIVb+2) cmux(C[P.DIVCOPIES], initC, IFDivStartE, NextC);
|
||||
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]),
|
||||
.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
|
||||
logic j1;
|
||||
assign j1 = (i == 0 & ~C[0][P.DIVb-1]);
|
||||
fdivsqrtstage4 #(P) fdivsqrtstage(.D, .DBar, .D2, .DBar2, .SqrtE, .j1,
|
||||
fdivsqrtstage4 #(P) fdivsqrtstage(.D, .DBar, .D2, .DBar2, .SqrtE,
|
||||
.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]));
|
||||
end
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -120,7 +121,7 @@ module fdivsqrtpostproc import cvw::*; #(parameter cvw_t P) (
|
||||
else IntDivResultM = {(P.XLEN){1'b1}};
|
||||
end else if (ALTBM) begin // Numerator is small
|
||||
if (RemOpM) IntDivResultM = AM;
|
||||
else IntDivResultM = '0;
|
||||
else IntDivResultM = 0;
|
||||
end else IntDivResultM = PreIntResultM[P.XLEN-1:0];
|
||||
|
||||
// sign extend result for W64
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -173,9 +174,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
logic [P.DIVb:0] PreSqrtX;
|
||||
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
|
||||
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)
|
||||
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
|
||||
|
||||
/*
|
||||
// Attempt to optimize radix 4 to use a left shift by 1 or zero initially, followed by no more left shift
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -57,7 +58,7 @@ module fdivsqrtstage2 import cvw::*; #(parameter cvw_t P) (
|
||||
// Divisor multiple
|
||||
always_comb
|
||||
if (up) Dsel = DBar;
|
||||
else if (uz) Dsel = '0;
|
||||
else if (uz) Dsel = 0;
|
||||
else Dsel = D; // un
|
||||
|
||||
// Residual Update
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -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+3:0] WS, WC, // Q4.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 un,
|
||||
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 CarryIn;
|
||||
logic [P.DIVb+3:0] WSA, WCA; // Q4.DIVb
|
||||
logic j0, j1; // step j = 0 or step j = 1
|
||||
|
||||
// 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 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 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
|
||||
|
||||
// F generation logic
|
||||
@ -64,7 +68,7 @@ module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) (
|
||||
case (udigit)
|
||||
4'b1000: Dsel = DBar2;
|
||||
4'b0100: Dsel = DBar;
|
||||
4'b0000: Dsel = '0;
|
||||
4'b0000: Dsel = 0;
|
||||
4'b0010: Dsel = D;
|
||||
4'b0001: Dsel = D2;
|
||||
default: Dsel = 'x;
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
@ -9,6 +9,7 @@
|
||||
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user