mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-06-27 08:50:26 -04:00
Merge branch 'main' of github.com:rosethompson/cvw
This commit is contained in:
commit
b311717385
180 changed files with 443 additions and 443 deletions
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
|
@ -21,7 +21,7 @@ jobs:
|
|||
name: Lint (Python ${{matrix.version}})
|
||||
strategy:
|
||||
matrix:
|
||||
version: [39, 312] # Test on oldest and newest verions used in wally-package-install.sh
|
||||
version: [39, 312] # Test on oldest and newest versions used in wally-package-install.sh
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
|
|
@ -194,7 +194,7 @@ void stop_time(void) {
|
|||
|
||||
Actual value returned may be cpu cycles, milliseconds or any other value,
|
||||
as long as it can be converted to seconds by <time_in_secs>.
|
||||
This methodology is taken to accomodate any hardware or simulated platform.
|
||||
This methodology is taken to accommodate any hardware or simulated platform.
|
||||
The sample implementation returns millisecs by default,
|
||||
and the resolution is controlled by <TIMER_RES_DIVIDER>
|
||||
*/
|
||||
|
@ -213,7 +213,7 @@ CORE_TICKS get_time(void) {
|
|||
/* Function: time_in_secs
|
||||
Convert the value returned by get_time to seconds.
|
||||
|
||||
The <secs_ret> type is used to accomodate systems with no support for floating point.
|
||||
The <secs_ret> type is used to accommodate systems with no support for floating point.
|
||||
Default implementation implemented by the EE_TICKS_PER_SEC macro above.
|
||||
*/
|
||||
secs_ret time_in_secs(CORE_TICKS ticks) {
|
||||
|
|
|
@ -99,7 +99,7 @@ typedef clock_t CORE_TICKS;
|
|||
#endif
|
||||
|
||||
/* Data Types:
|
||||
To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in <core_portme.h>.
|
||||
To avoid compiler issues, define the data types that need to be used for 8b, 16b and 32b in <core_portme.h>.
|
||||
|
||||
*Imprtant*:
|
||||
ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!!
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/* The OUTPUT_ARCH command specifies the machine architecture where the
|
||||
argument is one of the names used in the BFD library. More
|
||||
specifically one of the entires in bfd/cpu-mips.c */
|
||||
specifically one of the entries in bfd/cpu-mips.c */
|
||||
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
ENTRY(_start)
|
||||
|
@ -60,7 +60,7 @@ SECTIONS
|
|||
*(.tbss.end)
|
||||
}
|
||||
|
||||
/* End of uninitalized data segement */
|
||||
/* End of uninitialized data segment */
|
||||
_end = .;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ for(my $i=0; $i<=$#ARGV; $i++) {
|
|||
# if (/^\s*(\S\S\S\S\S\S\S\S):\s+(.*)/) { # changed to \t 30 Oct 2021 dmh to fix parsing issue in d_fmadd_b17
|
||||
if (/^\s*(\S\S\S\S\S\S\S\S):\s+(.*)/) {
|
||||
$address = &fixadr($1);
|
||||
# print "addresss $address maxaddress $maxaddress\n";
|
||||
# print "address $address maxaddress $maxaddress\n";
|
||||
if ($address > $maxaddress) { $maxaddress = $address; }
|
||||
#print "test $address $1 $2\n";
|
||||
my $lineorig = $2;
|
||||
|
@ -157,7 +157,7 @@ for(my $i=0; $i<=$#ARGV; $i++) {
|
|||
print("\n");
|
||||
|
||||
sub emitData {
|
||||
# print the data portion of the ELF into a memroy file, including 0s for empty stuff
|
||||
# print the data portion of the ELF into a memory file, including 0s for empty stuff
|
||||
# deal with endianness
|
||||
my $address = shift;
|
||||
my $payload = shift;
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
## Created: March 1, 2021
|
||||
## Modified: March 10, 2021
|
||||
##
|
||||
## Purpose: Processes all compiled object files into 2 types of files which assist in debuging applications.
|
||||
## Purpose: Processes all compiled object files into 2 types of files which assist in debugging applications.
|
||||
## File 1: .addr: A sorted list of function starting addresses.
|
||||
## When a the PCE is greater than or equal to the function's starting address, the label will be associated with this address.
|
||||
## File 2: .lab: A sorted list of funciton labels. The names of functions. Modelsim will display these names rather than the function address.
|
||||
## File 2: .lab: A sorted list of function labels. The names of functions. Modelsim will display these names rather than the function address.
|
||||
##
|
||||
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
##
|
||||
|
|
|
@ -35,7 +35,7 @@ def search_log_for_mismatches(logfile):
|
|||
return os.system(grepcmd) == 0
|
||||
|
||||
def run_test_case(elf):
|
||||
"""Run the given test case, and return 0 if the test suceeds and 1 if it fails"""
|
||||
"""Run the given test case, and return 0 if the test succeeds and 1 if it fails"""
|
||||
WALLY = os.environ.get("WALLY")
|
||||
fields = elf.rsplit("/", 3)
|
||||
if fields[2] == "ref":
|
||||
|
@ -70,7 +70,7 @@ parser.add_argument("--config", help="Configuration", default="rv64gc")
|
|||
parser.add_argument("--sim", "-s", help="Simulator", choices=["questa", "vcs"], default="questa")
|
||||
parser.add_argument("--coverage", "-c", help="Code & Functional Coverage", action="store_true")
|
||||
parser.add_argument("--fcov", "-f", help="Code & Functional Coverage", action="store_true")
|
||||
parser.add_argument("--exclude", help="Exclude files with this sufix", default="my.elf")
|
||||
parser.add_argument("--exclude", help="Exclude files with this suffix", default="my.elf")
|
||||
args = parser.parse_args()
|
||||
|
||||
# find all ELF files in directory
|
||||
|
|
|
@ -167,7 +167,7 @@ class FolderManager:
|
|||
None
|
||||
"""
|
||||
cvw = folder.joinpath("cvw")
|
||||
tmp_folder = os.path.join(cvw, "tmp") # temprorary files will be stored in here
|
||||
tmp_folder = os.path.join(cvw, "tmp") # temporary files will be stored in here
|
||||
if not cvw.exists():
|
||||
os.system(f"git clone --recurse-submodules {repo_url} {cvw}")
|
||||
os.makedirs(tmp_folder)
|
||||
|
@ -196,7 +196,7 @@ class TestRunner:
|
|||
folder: the "nightly-runs/repos/"
|
||||
|
||||
Returns:
|
||||
bool: True if the script is copied successfuly, False otherwise.
|
||||
bool: True if the script is copied successfully, False otherwise.
|
||||
"""
|
||||
# Get today's date in YYYY-MM-DD format
|
||||
self.todays_date = datetime.now().strftime("%Y-%m-%d")
|
||||
|
@ -346,9 +346,9 @@ class TestRunner:
|
|||
result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True, shell=True, executable="/bin/bash")
|
||||
except Exception as e:
|
||||
self.logger.error(f"There was an error in running the tests in the run_tests function: {e}")
|
||||
# Check if the command executed successfuly
|
||||
# Check if the command executed successfully
|
||||
if result.returncode or result.returncode == 0:
|
||||
self.logger.info(f"Test ran successfuly. Test name: {test_name}, test extension: {' '.join(test_extensions)}")
|
||||
self.logger.info(f"Test ran successfully. Test name: {test_name}, test extension: {' '.join(test_extensions)}")
|
||||
return True, output_file
|
||||
else:
|
||||
self.logger.error(f"Error making test. Test name: {test_name}, test extension: {' '.join(test_extensions)}")
|
||||
|
@ -763,7 +763,7 @@ def main():
|
|||
|
||||
output_log_list = [] # a list where the output markdown file locations will be saved to
|
||||
total_number_failures = 0 # an integer where the total number failures from all of the tests will be collected
|
||||
total_number_success = 0 # an integer where the total number of sucess will be collected
|
||||
total_number_success = 0 # an integer where the total number of successes will be collected
|
||||
|
||||
total_failures = []
|
||||
total_success = []
|
||||
|
@ -772,21 +772,21 @@ def main():
|
|||
|
||||
check, output_location = test_runner.run_tests(test_type=test_type, test_name=test_name, test_extensions=test_extensions)
|
||||
try:
|
||||
if check: # this checks if the test actually ran successfuly
|
||||
if check: # this checks if the test actually ran successfully
|
||||
output_log_list.append(output_location)
|
||||
logger.info(f"{test_name} ran successfuly. Output location: {output_location}")
|
||||
logger.info(f"{test_name} ran successfully. Output location: {output_location}")
|
||||
# format tests to markdown
|
||||
try:
|
||||
passed, failed = test_runner.clean_format_output(input_file = output_location)
|
||||
logger.info(f"{test_name} has been formatted to markdown")
|
||||
except:
|
||||
logger.error(f"Error occured with formatting {test_name}")
|
||||
logger.error(f"Error occurred with formatting {test_name}")
|
||||
|
||||
logger.info(f"The # of failures are for {test_name}: {len(failed)}")
|
||||
total_number_failures+= len(failed)
|
||||
total_failures.append(failed)
|
||||
|
||||
logger.info(f"The # of sucesses are for {test_name}: {len(passed)}")
|
||||
logger.info(f"The # of successes are for {test_name}: {len(passed)}")
|
||||
total_number_success += len(passed)
|
||||
total_success.append(passed)
|
||||
test_runner.rewrite_to_markdown(test_name, passed, failed)
|
||||
|
@ -797,7 +797,7 @@ def main():
|
|||
except Exception as e:
|
||||
logger.error(f"There was an error in running the tests: {e}")
|
||||
|
||||
logger.info(f"The total sucesses for all tests ran are: {total_number_success}")
|
||||
logger.info(f"The total successes for all tests ran are: {total_number_success}")
|
||||
logger.info(f"The total failures for all tests ran are: {total_number_failures}")
|
||||
|
||||
# Copy actual test logs from sim/questa, sim/verilator, sim/vcs
|
||||
|
|
|
@ -45,7 +45,7 @@ RefDataBTB = [('BTBCModel6', 'BTBCModel', 64, 128, 1.51480272475844), ('BTBCMode
|
|||
|
||||
def ParseBranchListFile(path):
|
||||
'''Take the path to the list of Questa Sim log files containing the performance counters outputs. File
|
||||
is formated in row columns. Each row is a trace with the file, branch predictor type, and the parameters.
|
||||
is formatted in row columns. Each row is a trace with the file, branch predictor type, and the parameters.
|
||||
parameters can be any number and depend on the predictor type. Returns a list of lists.'''
|
||||
lst = []
|
||||
with open(path) as BranchList:
|
||||
|
@ -59,7 +59,7 @@ def ParseBranchListFile(path):
|
|||
return lst
|
||||
|
||||
def ProcessFile(fileName):
|
||||
'''Extract preformance counters from a modelsim log. Outputs a list of tuples for each test/benchmark.
|
||||
'''Extract performance counters from a modelsim log. Outputs a list of tuples for each test/benchmark.
|
||||
The tuple contains the test name, optimization characteristics, and dictionary of performance counters.'''
|
||||
# 1 find lines with Read memfile and extract test name
|
||||
# 2 parse counters into a list of (name, value) tuples (dictionary maybe?)
|
||||
|
@ -328,23 +328,23 @@ def ReportAsGraph(benchmarkDict, bar, FileName):
|
|||
markers = ['x', '.', '+', '*', '^', 'o', ',', 's']
|
||||
colors = ['blue', 'black', 'gray', 'dodgerblue', 'lightsteelblue', 'turquoise', 'black', 'blue']
|
||||
|
||||
# the benchmarkDict['Mean'] contains sequencies of results for multiple
|
||||
# the benchmarkDict['Mean'] contains sequences of results for multiple
|
||||
# branch predictors with various parameterizations
|
||||
# group the parameterizations by the common typ.
|
||||
sequencies = {}
|
||||
sequences = {}
|
||||
for (name, typ, entries, size, value) in benchmarkDict['Mean']:
|
||||
if typ not in sequencies:
|
||||
sequencies[typ] = [(entries if not args.size else int(size/8), value)]
|
||||
if typ not in sequences:
|
||||
sequences[typ] = [(entries if not args.size else int(size/8), value)]
|
||||
else:
|
||||
sequencies[typ].append((entries if not args.size else int(size/8) ,value))
|
||||
sequences[typ].append((entries if not args.size else int(size/8) ,value))
|
||||
# then graph the common typ as a single line+scatter plot
|
||||
# finally repeat for all typs of branch predictors and overlay
|
||||
fig, axes = plt.subplots()
|
||||
index = 0
|
||||
if(args.invert): plt.title(titlesInvert[ReportPredictorType])
|
||||
else: plt.title(titles[ReportPredictorType])
|
||||
for branchPredName in sequencies:
|
||||
data = sequencies[branchPredName]
|
||||
for branchPredName in sequences:
|
||||
data = sequences[branchPredName]
|
||||
(xdata, ydata) = zip(*data)
|
||||
if args.invert: ydata = [100 - x for x in ydata]
|
||||
axes.plot(xdata, ydata, color=colors[index])
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
## Created: 30 June 2024
|
||||
## Modified:
|
||||
##
|
||||
## Purpose: Check for compatible Linux distibution and set variables accordingly
|
||||
## Purpose: Check for compatible Linux distribution and set variables accordingly
|
||||
##
|
||||
## A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
## https://github.com/openhwgroup/cvw
|
||||
|
|
|
@ -62,7 +62,7 @@ case "$FAMILY" in
|
|||
SPIKE_PACKAGES+=(dtc boost-regex boost-system)
|
||||
VERILATOR_PACKAGES+=(gperftools mold)
|
||||
BUILDROOT_PACKAGES+=(ncurses ncurses-base ncurses-libs ncurses-devel gcc-gfortran) # gcc-gfortran is only needed for compiling spec benchmarks on buildroot linux
|
||||
# Extra packages not availale in rhel8, nice for Verilator
|
||||
# Extra packages not available in rhel8, nice for Verilator
|
||||
if (( RHEL_VERSION >= 9 )); then
|
||||
VERILATOR_PACKAGES+=(perl-doc)
|
||||
fi
|
||||
|
|
|
@ -236,9 +236,9 @@ pip install --upgrade pip && pip install --upgrade -r "$dir"/requirements.txt
|
|||
source "$RISCV"/riscv-python/bin/activate # reload python virtual environment
|
||||
echo -e "${SUCCESS_COLOR}Python environment successfully configured!${ENDC}"
|
||||
|
||||
# Extra dependecies needed for older distros that don't have new enough versions available from package manager
|
||||
# Extra dependencies needed for older distros that don't have new enough versions available from package manager
|
||||
if (( RHEL_VERSION == 8 )) || (( UBUNTU_VERSION == 20 )); then
|
||||
# Newer versin of glib required for QEMU.
|
||||
# Newer version of glib required for QEMU.
|
||||
# Anything newer than this won't build on red hat 8
|
||||
STATUS="glib"
|
||||
if [ ! -e "$RISCV"/include/glib-2.0 ]; then
|
||||
|
@ -480,7 +480,7 @@ fi
|
|||
|
||||
|
||||
# Buildroot and Linux testvectors
|
||||
# Buildroot is used to boot a minimal versio of Linux on Wally.
|
||||
# Buildroot is used to boot a minimal version of Linux on Wally.
|
||||
# Testvectors are generated using QEMU.
|
||||
if [ ! "$no_buidroot" ]; then
|
||||
section_header "Installing Buildroot and Creating Linux testvectors"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
QUESTA_HOME?=/cad/mentor/questa_sim-2023.4
|
||||
CVW_GIT?=""
|
||||
|
||||
commanline:
|
||||
commandline:
|
||||
podman run -it --rm \
|
||||
-v cvw_temp:/home/cad/cvw \
|
||||
-v $(QUESTA_HOME):/cad/mentor/questa_sim-xxxx.x_x \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Consistant Build of Toolchain for Wally
|
||||
# Consistent Build of Toolchain for Wally
|
||||
|
||||
`Dockerfile.*` contains a ~~multi-stage~~ build for all the toolchains that are required for Wally's open-source features.
|
||||
|
||||
|
@ -69,7 +69,7 @@ Files at this folder can help you to build/fetch environment you need to run wal
|
|||
Here are some common use cases, it will **provides you an environment with RISC-V toolchains** that required by this project:
|
||||
|
||||
```shell
|
||||
# By default, we assume that you have cloned the cvw respository and running the script at relative path `docs/docker`
|
||||
# By default, we assume that you have cloned the cvw repository and running the script at relative path `docs/docker`
|
||||
|
||||
# For HMC students, /opt/riscv is available and nothing needs to be built
|
||||
TOOLCHAINS_MOUNT=/opt/riscv QUESTA=/cad/mentor/questa_sim-2023.4 ./start.sh
|
||||
|
@ -265,7 +265,7 @@ There are at least two ways to solve this problem:
|
|||
|
||||
There are stages in the old Dockerfile:
|
||||
|
||||
- debian-based package installtion
|
||||
- debian-based package installation
|
||||
- apt package
|
||||
- python3 package
|
||||
- user and its group configuration
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/* The OUTPUT_ARCH command specifies the machine architecture where the
|
||||
argument is one of the names used in the BFD library. More
|
||||
specifically one of the entires in bfd/cpu-mips.c */
|
||||
specifically one of the entries in bfd/cpu-mips.c */
|
||||
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
ENTRY(_start)
|
||||
|
@ -60,7 +60,7 @@ SECTIONS
|
|||
_tbss_end = .;
|
||||
}
|
||||
|
||||
/* End of uninitalized data segement */
|
||||
/* End of uninitialized data segment */
|
||||
_end = .;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ int main(void) {
|
|||
int tmp = Y[i];
|
||||
printf("Y[%d] = %d\n", i, tmp);
|
||||
}
|
||||
// verifyDouble doesn't work exaclty because of rounding, so check for almost equal
|
||||
// verifyDouble doesn't work exactly because of rounding, so check for almost equal
|
||||
for (int i=0; i<15; i++) {
|
||||
if (fabs(Y[i] - Yexpected[i]) > 1e-10) {
|
||||
return 1;
|
||||
|
|
|
@ -273,7 +273,7 @@ void mixColumn(unsigned char *column) {
|
|||
column[3] = b[3] ^ a[2] ^ a[1] ^ gfmul(a[0], 3);
|
||||
}
|
||||
|
||||
// The rounds in the specifcation of CIPHER() are composed of the following 4 byte-oriented
|
||||
// The rounds in the specification of CIPHER() are composed of the following 4 byte-oriented
|
||||
// transformations on the state (Section 5.1 of FIPS 197) - outputs hex after each step
|
||||
void aes_cipher(unsigned char *state, unsigned char *roundKey) {
|
||||
subBytes(state);
|
||||
|
|
|
@ -230,11 +230,11 @@ set verilogout_no_tri true
|
|||
set verilogout_equation false
|
||||
|
||||
# setting to generate output files
|
||||
set write_v 1 ;# generates structual netlist
|
||||
set write_v 1 ;# generates structural netlist
|
||||
set write_sdc 1 ;# generates synopsys design constraint file for p&r
|
||||
set write_ddc 1 ;# compiler file in ddc format
|
||||
set write_sdf 1 ;# sdf file for backannotated timing sim
|
||||
set write_pow 1 ;# genrates estimated power report
|
||||
set write_pow 1 ;# generates estimated power report
|
||||
set write_rep 1 ;# generates estimated area and timing report
|
||||
set write_cst 1 ;# generate report of constraints
|
||||
set write_hier 1 ;# generate hierarchy report
|
||||
|
|
|
@ -169,7 +169,7 @@ int main(int argc, char **argv){
|
|||
if (ioctl(sockfd, SIOCGIFINDEX, &ifopts) < 0)
|
||||
perror("SIOCGIFINDEX");
|
||||
|
||||
/* Allow the socket to be reused - incase connection is closed prematurely */
|
||||
/* Allow the socket to be reused - in case connection is closed prematurely */
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
|
||||
perror("setsockopt");
|
||||
close(sockfd);
|
||||
|
|
|
@ -223,7 +223,7 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 0)
|
|||
// the ddr3 mig7 requires 2 input clocks
|
||||
// 1. sys clock which is 167 MHz = ddr3 clock / 4
|
||||
// 2. a second clock which is 200 MHz
|
||||
// Wally requires a slower clock. At this point I don't know what speed the atrix 7 will run so I'm initially targetting 25Mhz.
|
||||
// Wally requires a slower clock. At this point I don't know what speed the atrix 7 will run so I'm initially targeting 25Mhz.
|
||||
// the mig will output a clock at 1/4 the sys clock or 41Mhz which might work with wally so we may be able to simplify the logic a lot.
|
||||
mmcm mmcm(.clk_out1(clk167),
|
||||
.clk_out2(clk200),
|
||||
|
@ -486,7 +486,7 @@ module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 0)
|
|||
localparam [31:0] RVVI_INIT_TIME_OUT = 32'd100000000;
|
||||
localparam [31:0] RVVI_PACKET_DELAY = 32'd400;
|
||||
|
||||
// pipeline controlls
|
||||
// pipeline controls
|
||||
logic StallE, StallM, StallW, FlushE, FlushM, FlushW;
|
||||
// required
|
||||
logic [P.XLEN-1:0] PCM;
|
||||
|
|
|
@ -51,7 +51,7 @@ int gpt_load_partitions() {
|
|||
BYTE lba2_buf[512];
|
||||
ret = disk_read(lba2_buf, (LBA_t)lba1->partition_entries_lba, 1);
|
||||
|
||||
// Load parition entries for the relevant boot partitions.
|
||||
// Load partition entries for the relevant boot partitions.
|
||||
partition_entries_t *fdt = (partition_entries_t *)(lba2_buf);
|
||||
partition_entries_t *opensbi = (partition_entries_t *)(lba2_buf + 128);
|
||||
partition_entries_t *kernel = (partition_entries_t *)(lba2_buf + 256);
|
||||
|
|
|
@ -93,7 +93,7 @@ uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc) {
|
|||
}
|
||||
|
||||
// Make interrupt pending after response fifo receives the correct
|
||||
// response length. Probably unecessary so let's wait and see what
|
||||
// response length. Probably unnecessary so let's wait and see what
|
||||
// happens.
|
||||
// write_reg(SPI_RXMARK, response_len);
|
||||
|
||||
|
|
|
@ -38,5 +38,5 @@ qemu-system-riscv64 \
|
|||
-kernel "$IMAGES"/Image \
|
||||
-initrd "$IMAGES"/rootfs.cpio \
|
||||
-dtb "$IMAGES"/wally-virt.dtb \
|
||||
-cpu rva22s64,zicond=true,zfa=true,zfh=true,zcb=true,zbc=true,zkn=true,sstc=true,svadu=true,svnapot=true \
|
||||
-cpu rva22s64,zicond=true,zfa=true,zfh=true,zcb=true,zbc=true,zkn=true,sstc=true,svadu=true,svnapot=true,pmp=on,debug=off \
|
||||
$GDB_FLAG
|
||||
|
|
|
@ -197,7 +197,7 @@ coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$lin
|
|||
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-tim"]
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
||||
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-cachable"]
|
||||
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-cacheable"]
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
|
||||
set line [GetLineNum ${SRC}/mmu/pmachecker.sv "exclusion-tag: unused-idempotent"]
|
||||
|
@ -440,7 +440,7 @@ coverage exclude -scope /dut/core/hzu -linerange [GetLineNum ${SRC}/hazard/hazar
|
|||
# Privileged
|
||||
####################
|
||||
|
||||
# Instruction Misaligned never asserted because compresssed instructions are accepted
|
||||
# Instruction Misaligned never asserted because compressed instructions are accepted
|
||||
coverage exclude -scope /dut/core/priv/priv/trap -linerange [GetLineNum ${SRC}/privileged/trap.sv "assign ExceptionM"] -item e 1 -fecexprrow 2
|
||||
|
||||
# Attempting to access fflags, frm, fcsr with mstatus.FS = 0 traps, so checking for (STATUS_FS != 2'b00)
|
||||
|
|
|
@ -75,7 +75,7 @@ set SVLib ""
|
|||
set GUI 0
|
||||
set accFlag ""
|
||||
|
||||
# Need to be able to pass arguments to vopt. Unforunately argv does not work because
|
||||
# Need to be able to pass arguments to vopt. Unfortunately argv does not work because
|
||||
# it takes on different values if vsim and the do file are called from the command line or
|
||||
# if the do file is called from questa sim directly. This chunk of code uses the $n variables
|
||||
# and compacts them into a single list for passing to vopt. Shift is used to move the arguments
|
||||
|
|
|
@ -22,7 +22,7 @@ TESTBENCH?=testbench
|
|||
|
||||
# constants
|
||||
# assume WALLY variable is correctly configured in the shell environment
|
||||
# INCLUDE_PATH are pathes that Verilator should search for files it needs
|
||||
# INCLUDE_PATH are paths that Verilator should search for files it needs
|
||||
INCLUDE_PATH="-I${WALLY}/config/shared" "-I${WALLY}/config/$(WALLYCONF)" "-I${WALLY}/config/deriv/$(WALLYCONF)"
|
||||
# SOURCES are source files
|
||||
SOURCES=${WALLY}/src/cvw.sv ${WALLY}/testbench/${TESTBENCH}.sv ${WALLY}/testbench/common/*.sv ${WALLY}/src/*/*.sv ${WALLY}/src/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv
|
||||
|
|
6
src/cache/cachefsm.sv
vendored
6
src/cache/cachefsm.sv
vendored
|
@ -62,7 +62,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||
output logic ClearDirty, // Clear the dirty bit in the selected way and set
|
||||
output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
|
||||
output logic LRUWriteEn, // Update the LRU state
|
||||
output logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
|
||||
output logic SelVictim, // Overrides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
|
||||
output logic FlushAdrCntEn, // Enable the counter for Flush Adr
|
||||
output logic FlushWayCntEn, // Enable the way counter during a flush
|
||||
output logic FlushCntRst, // Reset both flush counters
|
||||
|
@ -83,7 +83,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||
STATE_FETCH,
|
||||
STATE_WRITEBACK,
|
||||
STATE_WRITE_LINE,
|
||||
STATE_ADDRESS_SETUP, // required for back to back reads. structural hazard on writting SRAM
|
||||
STATE_ADDRESS_SETUP, // required for back to back reads. structural hazard on writing SRAM
|
||||
// flush cache
|
||||
STATE_FLUSH,
|
||||
STATE_FLUSH_WRITEBACK
|
||||
|
@ -165,7 +165,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||
(CurrState == STATE_WRITE_LINE & (CacheRW[0])) |
|
||||
(CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck));
|
||||
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty
|
||||
(CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
|
||||
(CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocol. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
|
||||
// Flush and eviction controls
|
||||
CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck;
|
||||
assign SelVictim = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
|
||||
|
|
2
src/cache/cacheway.sv
vendored
2
src/cache/cacheway.sv
vendored
|
@ -42,7 +42,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
|||
input logic SetValid, // Set the valid bit in the selected way and set
|
||||
input logic ClearValid, // Clear the valid bit in the selected way and set
|
||||
input logic SetDirty, // Set the dirty bit in the selected way and set
|
||||
input logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
|
||||
input logic SelVictim, // Overrides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
|
||||
input logic ClearDirty, // Clear the dirty bit in the selected way and set
|
||||
input logic FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
|
||||
input logic VictimWay, // LRU selected this way as victim to evict
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Usiing global `define statements isn't ideal in a large SystemVerilog system because
|
||||
// Using global `define statements isn't ideal in a large SystemVerilog system because
|
||||
// of the risk of `define name conflicts across different subsystems.
|
||||
// Instead, CORE-V-Wally loads the appropriate configuration one time and places it in a package
|
||||
// that is referenced by all Wally modules but not by other subsystems.
|
||||
|
|
|
@ -53,7 +53,7 @@ module ahbcacheinterface import cvw::*; #(
|
|||
input logic [P.PA_BITS-1:0] CacheBusAdr, // Address of cache line
|
||||
input logic [P.LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
|
||||
input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$
|
||||
input logic Cacheable, // Memory operation is cachable
|
||||
input logic Cacheable, // Memory operation is cacheable
|
||||
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
|
||||
output logic CacheBusAck, // Handshake to $ indicating bus transaction completed
|
||||
output logic [LINELEN-1:0] FetchBuffer, // Register to hold beats of cache line as the arrive from bus
|
||||
|
|
|
@ -91,7 +91,7 @@ module ebu import cvw::*; #(parameter cvw_t P) (
|
|||
assign HRESETn = ~reset;
|
||||
|
||||
// if two requests come in at once pick one to select and save the others Address phase
|
||||
// inputs. Abritration scheme is LSU always goes first.
|
||||
// inputs. Arbitration scheme is LSU always goes first.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// input stages and muxing for IFU and LSU
|
||||
|
|
|
@ -59,7 +59,7 @@ module ebufsmarb (
|
|||
logic [3:0] Threshold; // Number of beats derived from HBURST
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Aribtration scheme
|
||||
// Arbitration scheme
|
||||
// FSM decides if arbitration needed. Arbitration is held until the last beat of
|
||||
// a burst is completed.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -87,7 +87,7 @@ module ebufsmarb (
|
|||
// Once the LSU request is done the fsm returns to IDLE. To prevent the LSU from regaining
|
||||
// priority and re-issuing the same memory operation, the delayed IFUReqDelay squashes the LSU request.
|
||||
// This is necessary because the pipeline is stalled for the entire duration of both transactions,
|
||||
// and the LSU memory request will stil be active.
|
||||
// and the LSU memory request will still be active.
|
||||
flopr #(1) ifureqreg(HCLK, ~HRESETn, IFUReq, IFUReqDelay);
|
||||
//assign LSUDisable = (CurrState != ARBITRATE) & (IFUReqDelay & ~(HREADY & FinalBeatD));
|
||||
assign LSUDisable = (CurrState != ARBITRATE) & IFUReqDelay;
|
||||
|
|
|
@ -60,8 +60,8 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
|||
// register control signals
|
||||
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
|
||||
output logic FWriteIntE, FWriteIntM, // Write to integer register
|
||||
output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input
|
||||
output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input
|
||||
output logic [4:0] Adr1D, Adr2D, Adr3D, // addresses of each input
|
||||
output logic [4:0] Adr1E, Adr2E, Adr3E, // addresses of each input
|
||||
// other control signals
|
||||
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
|
||||
output logic FDivStartE, IDivStartE // Start division or squareroot
|
||||
|
@ -355,12 +355,12 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
|||
// 01 - negate sign
|
||||
// 10 - xor sign
|
||||
|
||||
// rename input adresses for readability
|
||||
// rename input addresses for readability
|
||||
assign Adr1D = InstrD[19:15];
|
||||
assign Adr2D = InstrD[24:20];
|
||||
assign Adr3D = InstrD[31:27];
|
||||
|
||||
// D/E pipleine register
|
||||
// D/E pipeline register
|
||||
flopenrc #(`FCTRLW+2+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
|
||||
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD, ZfaD, ZfaFRoundNXD, ~IllegalFPUInstrD},
|
||||
{FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE, ZfaFRoundNXE, FPUActiveE});
|
||||
|
@ -372,7 +372,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.M_SUPPORTED & P.IDIV_ON_FPU) assign IDivStartE = IntDivE;
|
||||
else assign IDivStartE = 1'b0;
|
||||
|
||||
// E/M pipleine register
|
||||
// E/M pipeline register
|
||||
flopenrc #(14+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
|
||||
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE},
|
||||
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, FCvtIntM, ZfaM});
|
||||
|
@ -380,7 +380,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
|||
// renameing for readability
|
||||
assign FpLoadStoreM = FResSelM[1];
|
||||
|
||||
// M/W pipleine register
|
||||
// M/W pipeline register
|
||||
flopenrc #(4) MWCtrlReg(clk, reset, FlushW, ~StallW,
|
||||
{FRegWriteM, FResSelM, FCvtIntM},
|
||||
{FRegWriteW, FResSelW, FCvtIntW});
|
||||
|
|
|
@ -32,10 +32,10 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
|||
input logic [P.NF:0] Xm, // input's fraction
|
||||
input logic [P.XLEN-1:0] Int, // integer input - from IEU
|
||||
input logic [2:0] OpCtrl, // choose which operation (look below for values)
|
||||
input logic ToInt, // is fp->int (since it's writting to the integer register)
|
||||
input logic ToInt, // is fp->int (since it's writing to the integer register)
|
||||
input logic XZero, // is the input zero
|
||||
input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
|
||||
output logic [P.NE:0] Ce, // the calculated expoent
|
||||
output logic [P.NE:0] Ce, // the calculated exponent
|
||||
output logic [P.LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
|
||||
output logic ResSubnormUf, // does the result underflow or is subnormal
|
||||
output logic Cs, // the result's sign
|
||||
|
@ -64,7 +64,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
|||
logic [P.CVTLEN:0] LzcInFull; // input to the Leading Zero Counter (priority encoder)
|
||||
logic [P.LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
|
||||
|
||||
// seperate OpCtrl for code readability
|
||||
// separate OpCtrl for code readability
|
||||
assign Signed = OpCtrl[0];
|
||||
assign Int64 = OpCtrl[1];
|
||||
assign IntToFp = OpCtrl[2];
|
||||
|
@ -80,7 +80,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// negation
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 1) negate the input if the input is a negative singed integer
|
||||
// 1) negate the input if the input is a negative signed integer
|
||||
// 2) trim the input to the proper size (kill the 32 most significant zeroes if needed)
|
||||
|
||||
assign PosInt = Cs ? -Int : Int;
|
||||
|
@ -150,20 +150,20 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
|||
// - XExp - Largest bias + new bias - (LeadingZeros+1)
|
||||
// only do ^ if the input was subnormal
|
||||
// - convert the expoenent to the final preciaion (Exp - oldBias + newBias)
|
||||
// - correct the expoent when there is a normalization shift ( + LeadingZeros+1)
|
||||
// - correct the exponent when there is a normalization shift ( + LeadingZeros+1)
|
||||
// - the plus 1 is built into the leading zeros by counting the leading zeroes in the mantissa rather than the fraction
|
||||
// fp -> int : XExp - Largest Bias + 1 - (LeadingZeros+1)
|
||||
// | P.XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
|
||||
// | P.XLEN zeros | Mantissa | 0's if necessary | << CalcExp
|
||||
// process:
|
||||
// - start
|
||||
// | P.XLEN zeros | Mantissa | 0's if nessisary |
|
||||
// | P.XLEN zeros | Mantissa | 0's if necessary |
|
||||
//
|
||||
// - shift left 1 (1)
|
||||
// | P.XLEN-1 zeros |bit| frac | 0's if nessisary |
|
||||
// | P.XLEN-1 zeros |bit| frac | 0's if necessary |
|
||||
// . <- binary point
|
||||
//
|
||||
// - shift left till unbiased exponent is 0 (XExp - Largest Bias)
|
||||
// | 0's | Mantissa | 0's if nessisary |
|
||||
// | 0's | Mantissa | 0's if necessary |
|
||||
// | keep |
|
||||
//
|
||||
// - if the input is subnormal then we dont shift... so the "- LeadingZeros" is just leftovers from other options
|
||||
|
@ -199,7 +199,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
|||
// - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0
|
||||
// ??? -> fp:
|
||||
// - shift left by LeadingZeros - to shift till the result is normalized
|
||||
// - only shift fp -> fp if the intital value is subnormal
|
||||
// - only shift fp -> fp if the initial value is subnormal
|
||||
// - this is a problem because the input to the lzc was the fraction rather than the mantissa
|
||||
// - rather have a few and-gates than an extra bit in the priority encoder???
|
||||
always_comb
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu
|
||||
// Modified:13 January 2022
|
||||
//
|
||||
// Purpose: Exponent caclulation for divide and square root
|
||||
// Purpose: Exponent calculation for divide and square root
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design
|
||||
//
|
||||
|
|
|
@ -88,7 +88,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
assign AsE = AE[P.XLEN-1] & SignedDivE;
|
||||
assign BsE = BE[P.XLEN-1] & SignedDivE;
|
||||
|
||||
// Force integer inputs to be postiive
|
||||
// Force integer inputs to be positive
|
||||
mux2 #(P.XLEN) posamux(AE, -AE, AsE, PosA);
|
||||
mux2 #(P.XLEN) posbmux(BE, -BE, BsE, PosB);
|
||||
|
||||
|
@ -165,7 +165,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
// Then multiply by R is left shift by r (1 or 2 for radix 2 or 4)
|
||||
// This is optimized in hardware by first right shifting by 0 or 1 bit (instead of 1 or 2), then left shifting by (r-1), then subtracting 2 or 4
|
||||
// Subtracting 2 is equivalent to adding 1110. Subtracting 4 is equivalent to adding 1100. Prepend leading 1s to do a free subtraction.
|
||||
// This also means only one extra fractional bit is needed becaue we never shift right by more than 1.
|
||||
// This also means only one extra fractional bit is needed because we never shift right by more than 1.
|
||||
// Radix Exponent odd Exponent Even
|
||||
// 2 x-2 = 2(x/2 - 1) x/2 - 2 = 2(x/4 - 1)
|
||||
// 4 2(x)-4 = 4(x/2 - 1)) 2(x/2)-4 = 4(x/4 - 1)
|
||||
|
@ -194,7 +194,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
mux2 #(P.DIVb+4) prexmux(DivX, SqrtX, SqrtE, PreShiftX);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Selet integer or floating-point operands
|
||||
// Select integer or floating-point operands
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
if (P.IDIV_ON_FPU) begin
|
||||
|
@ -203,7 +203,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
assign X = PreShiftX;
|
||||
end
|
||||
|
||||
// Divisior register
|
||||
// Divisor register
|
||||
flopen #(P.DIVb+4) dreg(clk, IFDivStartE, {3'b000, Dnorm}, D);
|
||||
|
||||
// Floating-point exponent
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fhazard(
|
||||
input logic [4:0] Adr1D, Adr2D, Adr3D, // read data adresses
|
||||
input logic [4:0] Adr1E, Adr2E, Adr3E, // read data adresses
|
||||
input logic [4:0] Adr1D, Adr2D, Adr3D, // read data addresses
|
||||
input logic [4:0] Adr1E, Adr2E, Adr3E, // read data addresses
|
||||
input logic FRegWriteE, FRegWriteM, FRegWriteW, // is the fp register being written to
|
||||
input logic [4:0] RdE, RdM, RdW, // the adress being written to
|
||||
input logic [4:0] RdE, RdM, RdW, // the address being written to
|
||||
input logic [1:0] FResSelM, // the result being selected
|
||||
input logic XEnD, YEnD, ZEnD, // are the inputs needed
|
||||
output logic FPUStallD, // stall the decode stage
|
||||
|
|
|
@ -31,11 +31,11 @@ module fmaadd import cvw::*; #(parameter cvw_t P) (
|
|||
input logic [3*P.NF+5:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1)
|
||||
input logic [P.NE-1:0] Ze, // exponent of Z
|
||||
input logic Ps, // the product sign and the alligend addeded's sign (Modified Z sign for other operations)
|
||||
input logic [P.NE+1:0] Pe, // product's exponet
|
||||
input logic [P.NE+1:0] Pe, // product's exponent
|
||||
input logic [2*P.NF+1:0] Pm, // the product's mantissa
|
||||
input logic InvA, // invert the aligned addend
|
||||
input logic KillProd, // should the product be set to 0
|
||||
input logic ASticky, // Alighed addend's sticky bit
|
||||
input logic ASticky, // Aligned addend's sticky bit
|
||||
output logic [3*P.NF+5:0] AmInv, // aligned addend possibly inverted
|
||||
output logic [2*P.NF+1:0] PmKilled, // the product's mantissa possibly killed
|
||||
output logic Ss, // sum's sign
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: FMA alginment shift
|
||||
// Purpose: FMA alignment shift
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design
|
||||
//
|
||||
|
@ -32,7 +32,7 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
|
|||
input logic [P.NF:0] Zm, // significand in U(0.NF) format]
|
||||
input logic XZero, YZero, ZZero, // is the input zero
|
||||
output logic [P.FMALEN-1:0] Am, // addend aligned for addition in U(NF+5.2NF+1)
|
||||
output logic ASticky, // Sticky bit calculated from the aliged addend
|
||||
output logic ASticky, // Sticky bit calculated from the aligned addend
|
||||
output logic KillProd // should the product be set to zero
|
||||
);
|
||||
|
||||
|
@ -51,7 +51,7 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
|
|||
// This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed
|
||||
assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)} + (P.NE+2)'(P.NF+3) - {2'b0, Ze};
|
||||
|
||||
// Default Addition with only inital left shift
|
||||
// Default Addition with only initial left shift
|
||||
// extra bit at end and beginning so the correct guard bit is calculated when subtracting
|
||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
||||
// | addnend |
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fmasign(
|
||||
input logic [2:0] OpCtrl, // operation contol
|
||||
input logic [2:0] OpCtrl, // operation control
|
||||
input logic Xs, Ys, Zs, // sign of the inputs
|
||||
output logic Ps, // the product's sign - takes operation into account
|
||||
output logic As, // aligned addend sign used in fma - takes operation into account
|
||||
|
|
|
@ -78,8 +78,8 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
|||
logic [2:0] OpCtrlE, OpCtrlM; // Select which operation to do in each component
|
||||
logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage
|
||||
logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
|
||||
logic [4:0] Adr1D, Adr2D, Adr3D; // register adresses of each input
|
||||
logic [4:0] Adr1E, Adr2E, Adr3E; // register adresses of each input
|
||||
logic [4:0] Adr1D, Adr2D, Adr3D; // register addresses of each input
|
||||
logic [4:0] Adr1E, Adr2E, Adr3E; // register addresses of each input
|
||||
logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation
|
||||
logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation
|
||||
logic FRegWriteE; // Write floating-point register
|
||||
|
@ -129,7 +129,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
|||
logic [$clog2(P.FMALEN+1)-1:0] SCntE, SCntM; // LZA sum leading zero count
|
||||
|
||||
// Cvt Signals
|
||||
logic [P.NE:0] CeE, CeM; // convert intermediate expoent
|
||||
logic [P.NE:0] CeE, CeM; // convert intermediate exponent
|
||||
logic [P.LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by
|
||||
logic CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal
|
||||
logic CsE, CsM; // convert result sign
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
module fregfile #(parameter FLEN) (
|
||||
input logic clk, reset,
|
||||
input logic we4, // write enable
|
||||
input logic [4:0] a1, a2, a3, a4, // adresses
|
||||
input logic [4:0] a1, a2, a3, a4, // addresses
|
||||
input logic [FLEN-1:0] wd4, // write data
|
||||
output logic [FLEN-1:0] rd1, rd2, rd3 // read data
|
||||
);
|
||||
|
|
|
@ -30,12 +30,12 @@
|
|||
module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic XZero, // is the input zero?
|
||||
input logic ToInt, // to integer conversion?
|
||||
input logic IntToFp, // interger to floating point conversion?
|
||||
input logic IntToFp, // integer to floating point conversion?
|
||||
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent
|
||||
input logic [P.NE:0] CvtCe, // the calculated exponent
|
||||
input logic [P.NF:0] Xm, // input mantissas
|
||||
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||
input logic CvtResSubnormUf, // is the conversion result subnormal or underlows
|
||||
input logic CvtResSubnormUf, // is the conversion result subnormal or underflows
|
||||
output logic CvtResUf, // does the cvt result unerflow
|
||||
output logic [P.CVTLEN+P.NF:0] CvtShiftIn // number to be shifted
|
||||
);
|
||||
|
@ -51,12 +51,12 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
// | P.XLEN zeros | mantissa | 0's if necessary |
|
||||
// .
|
||||
// Other problems:
|
||||
// - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later durring rounding)
|
||||
// - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later during rounding)
|
||||
// - we do however want to keep the one in the sticky bit so set one of bits in the sticky bit area to 1
|
||||
// - ex: for the case 0010000.... (double)
|
||||
// ??? -> fp:
|
||||
// - if result is subnormal or underflowed then we want to shift right i.e. shift right then shift left:
|
||||
// | P.NF-1 zeros | mantissa | 0's if nessisary |
|
||||
// | P.NF-1 zeros | mantissa | 0's if necessary |
|
||||
// .
|
||||
// - otherwise:
|
||||
// | LzcInM | 0's if necessary |
|
||||
|
|
|
@ -57,8 +57,8 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
// 00000000.xxxxxxx... << NF Exp = DivUe+1
|
||||
// 00000000x.xxxxxx... << NF Exp = DivUe (extra shift done afterwards)
|
||||
// 00000000xx.xxxxx... << 1? Exp = DivUe-1 (determined after)
|
||||
// inital Left shift amount = NF
|
||||
// shift one more if the it's a minimally redundent radix 4 - one entire cycle needed for integer bit
|
||||
// initial Left shift amount = NF
|
||||
// shift one more if the it's a minimally redundant radix 4 - one entire cycle needed for integer bit
|
||||
assign NormShift = (P.LOGNORMSHIFTSZ)'(P.NF);
|
||||
|
||||
// if the shift amount is negative then don't shift (keep sticky bit)
|
||||
|
|
|
@ -47,7 +47,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
input logic IntToFp, // convert integer to floating point
|
||||
input logic Int64, // convert to 64 bit integer
|
||||
input logic Signed, // convert to a signed integer
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent - Cvt
|
||||
input logic [P.NE:0] CvtCe, // the calculated exponent - Cvt
|
||||
input logic [1:0] CvtNegResMsbs, // the negative integer result's most significant bits
|
||||
// divsqrt
|
||||
input logic DivOp, // conversion operation?
|
||||
|
@ -70,7 +70,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
logic FmaInvalid; // integer invalid flag
|
||||
logic DivInvalid; // integer invalid flag
|
||||
logic Underflow; // Underflow flag
|
||||
logic ResExpGteMax; // is the result greater than or equal to the maximum floating point expoent
|
||||
logic ResExpGteMax; // is the result greater than or equal to the maximum floating point exponent
|
||||
logic ShiftGtIntSz; // is the shift greater than the the integer size (use Re to account for possible rounding "shift")
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -81,7 +81,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
// the shift amount is greater than the integers size (for cvt to int)
|
||||
// ShiftGtIntSz calculation:
|
||||
// a left shift of intlen+1 is still in range but any more than that is an overflow
|
||||
// inital: | 64 0's | XLEN |
|
||||
// initial: | 64 0's | XLEN |
|
||||
// | 64 0's | XLEN | << 64
|
||||
// | XLEN | 00000... |
|
||||
// 65 = ...0 0 0 0 0 1 0 0 0 0 0 1
|
||||
|
@ -89,8 +89,8 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
// 33 = ...0 0 0 0 0 0 1 0 0 0 0 1
|
||||
// | or | | or |
|
||||
// larger or equal if:
|
||||
// - any of the bits after the most significan 1 is one
|
||||
// - the most signifcant in 65 or 33 is still a one in the number and
|
||||
// - any of the bits after the most significant 1 is one
|
||||
// - the most significant in 65 or 33 is still a one in the number and
|
||||
// one of the later bits is one
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign ResExpGteMax = &FullRe[P.NE-1:0] | FullRe[P.NE];
|
||||
|
@ -121,7 +121,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
assign ShiftGtIntSz = (|FullRe[P.Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
|
||||
end
|
||||
|
||||
// calulate overflow flag:
|
||||
// calculate overflow flag:
|
||||
// if the result is greater than or equal to the max exponent(not taking into account sign)
|
||||
// | and the exponent isn't negative
|
||||
// | | if the input isnt infinity or NaN
|
||||
|
@ -146,8 +146,8 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
// Inexact
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Set Inexact flag if the result is diffrent from what would be outputed given infinite precision
|
||||
// - Don't set the underflow flag if an underflowed res isn't outputed
|
||||
// Set Inexact flag if the result is different from what would be outputted given infinite precision
|
||||
// - Don't set the underflow flag if an underflowed res isn't outputted
|
||||
assign FpInexact = (Sticky|Guard|Overflow|Round)&~(InfIn|NaNIn|DivByZero|Invalid);
|
||||
|
||||
// if the res is too small to be represented and not 0
|
||||
|
|
|
@ -34,7 +34,7 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
input logic [$clog2(P.FMALEN+1)-1:0] FmaSCnt, // normalization shift count
|
||||
output logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||
output logic FmaSZero, // is the sum zero
|
||||
output logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
||||
output logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA correction
|
||||
output logic [$clog2(P.FMALEN+1)-1:0] FmaShiftAmt // normalization shift count
|
||||
);
|
||||
logic [P.NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the P.FLEN bias
|
||||
|
|
|
@ -56,7 +56,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
|||
input logic [P.NE:0] CvtCe, // the calculated exponent
|
||||
input logic CvtResSubnormUf, // the convert result is subnormal or underflows
|
||||
input logic [P.LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by
|
||||
input logic ToInt, // is fp->int (since it's writting to the integer register)
|
||||
input logic ToInt, // is fp->int (since it's writing to the integer register)
|
||||
input logic Zfa, // Zfa operation (fcvtmod.w.d)
|
||||
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||
input logic IntZero, // is the integer input zero
|
||||
|
@ -77,7 +77,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
|||
logic UfPlus1; // do you add one (for determining underflow flag)
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount
|
||||
logic [P.NORMSHIFTSZ-1:0] ShiftIn; // input to normalization shift
|
||||
logic [P.NORMSHIFTSZ-1:0] Shifted; // the ouput of the normalized shifter (before shift correction)
|
||||
logic [P.NORMSHIFTSZ-1:0] Shifted; // the output of the normalized shifter (before shift correction)
|
||||
logic Plus1; // add one to the final result?
|
||||
logic Overflow; // overflow flag used to select results
|
||||
logic Invalid; // invalid flag used to select results
|
||||
|
@ -87,14 +87,14 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
|||
logic [P.NE+1:0] FmaMe; // exponent of the normalized sum
|
||||
logic FmaSZero; // is the sum zero
|
||||
logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||
logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection
|
||||
logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA correction
|
||||
logic [$clog2(P.FMALEN+1)-1:0] FmaShiftAmt; // normalization shift amount for fma
|
||||
// division signals
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
|
||||
logic [P.NE+1:0] Ue; // divsqrt corrected exponent after corretion shift
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shift amount
|
||||
logic [P.NE+1:0] Ue; // divsqrt corrected exponent after correction shift
|
||||
logic DivByZero; // divide by zero flag
|
||||
logic DivResSubnorm; // is the divsqrt result subnormal
|
||||
logic DivSubnormShiftPos; // is the divsqrt subnorm shift amout positive (not underflowed)
|
||||
logic DivSubnormShiftPos; // is the divsqrt subnorm shift amount positive (not underflowed)
|
||||
// conversion signals
|
||||
logic [P.CVTLEN+P.NF:0] CvtShiftIn; // number to be shifted for converter
|
||||
logic [1:0] CvtNegResMsbs; // most significant bits of possibly negated int result
|
||||
|
@ -107,7 +107,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
|||
logic Int64; // is the integer 64 bits?
|
||||
logic Signed; // is the operation with a signed integer?
|
||||
logic IntToFp; // is the operation an int->fp conversion?
|
||||
logic CvtOp; // convertion operation
|
||||
logic CvtOp; // conversion operation
|
||||
logic FmaOp; // fma operation
|
||||
logic DivOp; // divider operation
|
||||
logic InfIn; // are any of the inputs infinity
|
||||
|
@ -187,7 +187,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
|||
// round to infinity
|
||||
// round to nearest max magnitude
|
||||
|
||||
// calulate result sign used in rounding unit
|
||||
// calculate result sign used in rounding unit
|
||||
roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
|
||||
|
||||
round #(P) round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Ue,
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
module resultsign(
|
||||
input logic [2:0] Frm, // rounding mode
|
||||
input logic FmaOp, // is the operation an Fma
|
||||
input logic Mult, // is the fma operation multipy
|
||||
input logic Mult, // is the fma operation multiply
|
||||
input logic ZInf, // is Z infinity
|
||||
input logic InfIn, // are any of the inputs infinity
|
||||
input logic FmaSZero, // is the fma sum zero
|
||||
|
@ -48,12 +48,12 @@ module resultsign(
|
|||
|
||||
// determine the sign for a result of 0
|
||||
// The IEEE754-2019 standard specifies:
|
||||
// - the sign of an exact zero sum (with operands of diffrent signs) should be positive unless rounding toward negative infinity
|
||||
// - the sign of an exact zero sum (with operands of different signs) should be positive unless rounding toward negative infinity
|
||||
// - when the exact result of an FMA operation is non-zero, but is zero due to rounding, use the sign of the exact result
|
||||
// - if x = +0 or -0 then x+x=x and x-(-x)=x
|
||||
// - the sign of a product is the exclisive or or the opperand's signs
|
||||
// Zero sign will only be selected if:
|
||||
// - P=Z and a cancelation occurs - exact zero
|
||||
// - P=Z and a cancellation occurs - exact zero
|
||||
// - Z is zero and P is zero - exact zero
|
||||
// - P is killed and Z is zero - Psgn
|
||||
// - Z is killed and P is zero - impossible
|
||||
|
|
|
@ -40,13 +40,13 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
// divsqrt
|
||||
input logic DivOp, // is a division operation being done
|
||||
input logic DivSticky, // divsqrt sticky bit
|
||||
input logic [P.NE+1:0] Ue, // the divsqrt calculated expoent
|
||||
input logic [P.NE+1:0] Ue, // the divsqrt calculated exponent
|
||||
// cvt
|
||||
input logic CvtOp, // is a convert operation being done
|
||||
input logic ToInt, // is the cvt op a cvt to integer
|
||||
input logic CvtResSubnormUf, // is the cvt result subnormal or underflow
|
||||
input logic CvtResUf, // does the cvt result underflow
|
||||
input logic [P.NE:0] CvtCe, // the cvt calculated expoent
|
||||
input logic [P.NE:0] CvtCe, // the cvt calculated exponent
|
||||
// outputs
|
||||
output logic [P.NE+1:0] Me, // normalied fraction
|
||||
output logic UfPlus1, // do you add one to the result if given an unbounded exponent
|
||||
|
@ -172,7 +172,7 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
(|Mf[P.NORMSHIFTSZ-P.XLEN-2:P.NORMSHIFTSZ-P.Q_NF-1]&(~(OutFmt==P.Q_FMT)|IntRes)) |
|
||||
(|Mf[P.NORMSHIFTSZ-P.Q_NF-2:0]);
|
||||
// 3: NF > NF1 > XLEN
|
||||
// The extra XLEN bit will be ored later when caculating the final sticky bit - the ufplus1 not needed for integer
|
||||
// The extra XLEN bit will be ored later when calculating the final sticky bit - the ufplus1 not needed for integer
|
||||
if (XLENPOS == 3) assign NormSticky = (|Mf[P.NORMSHIFTSZ-P.H_NF-2:P.NORMSHIFTSZ-P.S_NF-1]&FpRes&(OutFmt==P.H_FMT)) |
|
||||
(|Mf[P.NORMSHIFTSZ-P.S_NF-2:P.NORMSHIFTSZ-P.XLEN-1]&FpRes&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT))) |
|
||||
(|Mf[P.NORMSHIFTSZ-P.XLEN-2:P.NORMSHIFTSZ-P.D_NF-1]&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT)|IntRes)) |
|
||||
|
|
|
@ -44,7 +44,7 @@ module roundsign(
|
|||
// calculate divsqrt sign
|
||||
assign Qs = Xs^(Ys&~Sqrt);
|
||||
|
||||
// Select sign for rounding calulation
|
||||
// Select sign for rounding calculation
|
||||
assign Ms = (FmaSs&FmaOp) | (CvtCs&CvtOp) | (Qs&DivOp);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -37,7 +37,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
|||
//fma
|
||||
input logic FmaOp, // is it an fma operation
|
||||
input logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||
input logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
||||
input logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA correction
|
||||
input logic FmaSZero,
|
||||
// output
|
||||
output logic [P.NE+1:0] FmaMe, // exponent of the normalized sum
|
||||
|
@ -61,10 +61,10 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
|||
assign LZAPlus1 = Shifted[P.NORMSHIFTSZ-1];
|
||||
|
||||
// correct the shifting of the divsqrt caused by producing a result in (0.5, 2) range
|
||||
// condition: if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm)
|
||||
// condition: if the msb is 1 or the exponent was one, but the shifted quotient was < 1 (Subnorm)
|
||||
assign LeftShiftQm = (LZAPlus1|(DivUe==1&~LZAPlus1));
|
||||
|
||||
// Determine the shif for either FMA or divsqrt
|
||||
// Determine the shift for either FMA or divsqrt
|
||||
assign RightShift = FmaOp ? LZAPlus1 : LeftShiftQm;
|
||||
|
||||
// possible one bit right shift for FMA or division
|
||||
|
@ -79,8 +79,8 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
|||
// main exponent issues:
|
||||
// - LZA was one too large
|
||||
// - LZA was two too large
|
||||
// - if the result was calulated to be subnorm but it's norm and the LZA was off by 1
|
||||
// - if the result was calulated to be subnorm but it's norm and the LZA was off by 2
|
||||
// - if the result was calculated to be subnorm but it's norm and the LZA was off by 1
|
||||
// - if the result was calculated to be subnorm but it's norm and the LZA was off by 2
|
||||
// if plus1 If plus2 kill if the result Zero or actually subnormal
|
||||
// | | |
|
||||
assign FmaMe = (NormSumExp+{{P.NE+1{1'b0}}, LZAPlus1} +{{P.NE+1{1'b0}}, FmaPreResultSubnorm}) & {P.NE+2{~(FmaSZero|ResSubnorm)}};
|
||||
|
@ -88,8 +88,8 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
|||
// recalculate if the result is subnormal after LZA correction
|
||||
assign ResSubnorm = FmaPreResultSubnorm&~Shifted[P.NORMSHIFTSZ-2]&~Shifted[P.NORMSHIFTSZ-1];
|
||||
|
||||
// the quotent is in the range (.5,2) if there is no early termination
|
||||
// if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift
|
||||
// the quotient is in the range (.5,2) if there is no early termination
|
||||
// if the quotient < 1 and not Subnormal then subtract 1 to account for the normalization shift
|
||||
assign Ue = (DivResSubnorm & DivSubnormShiftPos) ? 0 : DivUe - {(P.NE+1)'(0), ~LZAPlus1};
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
input logic Int64, // is the integer 64 bits
|
||||
input logic Signed, // is the integer signed
|
||||
input logic Zfa, // Zfa conversion operation: fcvtmod.w.d
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent for cvt
|
||||
input logic [P.NE:0] CvtCe, // the calculated exponent for cvt
|
||||
input logic IntInvalid, // integer invalid flag to choose the result
|
||||
input logic CvtResUf, // does the convert result underflow
|
||||
input logic [P.XLEN+1:0] CvtNegRes, // the possibly negated of the integer result
|
||||
|
@ -240,7 +240,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
endcase
|
||||
end
|
||||
|
||||
// determine if you shoould kill the res - Cvt
|
||||
// determine if you should kill the res - Cvt
|
||||
// - do so if the res underflows, is zero (the exp doesnt calculate correctly). or the integer input is 0
|
||||
// - dont set to zero if fp input is zero but not using the fp input
|
||||
// - dont set to zero if int input is zero but not using the int input
|
||||
|
@ -334,7 +334,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
end
|
||||
|
||||
// fcvtmod.w.d logic
|
||||
// fcvtmod.w.d is like fcvt.w.d excep thtat it takes bits [31:0] and sign extends the rest,
|
||||
// fcvtmod.w.d is like fcvt.w.d excep that it takes bits [31:0] and sign extends the rest,
|
||||
// and converts +/-inf and NaN to zero.
|
||||
|
||||
if (P.ZFA_SUPPORTED & P.D_SUPPORTED) // fcvtmod.w.d support
|
||||
|
@ -358,7 +358,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
// - if the input underflows
|
||||
// - if rounding and signed operation and negative input, output -1
|
||||
// - otherwise output a rounded 0
|
||||
// - otherwise output the normal res (trmined and sign extended if nessisary)
|
||||
// - otherwise output the normal res (trmined and sign extended if necessary)
|
||||
always_comb
|
||||
if(SelCvtOfRes) FCvtIntRes = OfIntRes2;
|
||||
else if(CvtCe[P.NE])
|
||||
|
|
|
@ -88,10 +88,10 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
end else
|
||||
PostBox = In;
|
||||
|
||||
// choose sign bit depending on format - 1=larger precsion 0=smaller precision
|
||||
// choose sign bit depending on format - 1=larger precision 0=smaller precision
|
||||
assign Sgn = Fmt ? In[P.FLEN-1] : (BadNaNBox ? 0 : In[P.LEN1-1]); // improperly boxed NaNs are treated as positive
|
||||
|
||||
// extract the fraction, add trailing zeroes to the mantissa if nessisary
|
||||
// extract the fraction, add trailing zeroes to the mantissa if necessary
|
||||
assign Frac = Fmt ? In[P.NF-1:0] : {In[P.NF1-1:0], (P.NF-P.NF1)'(0)};
|
||||
|
||||
// is the exponent non-zero
|
||||
|
@ -105,14 +105,14 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/Subnorm/inf/NaN values
|
||||
|
||||
// extract the exponent, converting the smaller exponent into the larger precision if nessisary
|
||||
// extract the exponent, converting the smaller exponent into the larger precision if necessary
|
||||
// - if the original precision had a Subnormal number convert the exponent value 1
|
||||
assign Exp = Fmt ? {In[P.FLEN-2:P.NF+1], In[P.NF]|~ExpNonZero} : {In[P.LEN1-2], {P.NE-P.NE1{~In[P.LEN1-2]}}, In[P.LEN1-3:P.NF1+1], In[P.NF1]|~ExpNonZero};
|
||||
|
||||
// is the exponent all 1's
|
||||
assign ExpMax = Fmt ? &In[P.FLEN-2:P.NF] : &In[P.LEN1-2:P.NF1];
|
||||
|
||||
end else if (P.FPSIZES == 3) begin // three floating point precsions supported
|
||||
end else if (P.FPSIZES == 3) begin // three floating point precisions supported
|
||||
|
||||
// largest format | larger format | smallest format
|
||||
//---------------------------------------------------
|
||||
|
@ -171,8 +171,8 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
always_comb
|
||||
case (Fmt)
|
||||
P.FMT: ExpNonZero = |In[P.FLEN-2:P.NF]; // if input is largest precision (P.FLEN - ie quad or double)
|
||||
P.FMT1: ExpNonZero = |In[P.LEN1-2:P.NF1]; // if input is larger precsion (P.LEN1 - double or single)
|
||||
P.FMT2: ExpNonZero = |In[P.LEN2-2:P.NF2]; // if input is smallest precsion (P.LEN2 - single or half)
|
||||
P.FMT1: ExpNonZero = |In[P.LEN1-2:P.NF1]; // if input is larger precision (P.LEN1 - double or single)
|
||||
P.FMT2: ExpNonZero = |In[P.LEN2-2:P.NF2]; // if input is smallest precision (P.LEN2 - single or half)
|
||||
default: ExpNonZero = 1'bx;
|
||||
endcase
|
||||
|
||||
|
@ -269,7 +269,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
// dexp = 0bdd dbbb bbbb
|
||||
// also need to take into account possible zero/Subnorm/inf/NaN values
|
||||
|
||||
// convert the double precsion exponent into quad precsion
|
||||
// convert the double precision exponent into quad precision
|
||||
// 1 is added to the exponent if the input is zero or subnormal
|
||||
always_comb
|
||||
case (Fmt)
|
||||
|
@ -294,7 +294,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||
assign FracZero = ~|Frac & ~BadNaNBox; // is the fraction zero?
|
||||
assign Man = {ExpNonZero, Frac}; // add the assumed one (or zero if Subnormal or zero) to create the significand
|
||||
assign NaN = ((ExpMax & ~FracZero)|BadNaNBox)&En; // is the input a NaN?
|
||||
assign SNaN = NaN&~Frac[P.NF-1]&~BadNaNBox; // is the input a singnaling NaN?
|
||||
assign SNaN = NaN&~Frac[P.NF-1]&~BadNaNBox; // is the input a signaling NaN?
|
||||
assign Inf = ExpMax & FracZero & En; // is the input infinity?
|
||||
assign Zero = ~ExpNonZero & FracZero; // is the input zero?
|
||||
assign Subnorm = ~ExpNonZero & ~FracZero & ~BadNaNBox; // is the input subnormal
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
///////////////////////////////////////////
|
||||
// ram1p1rwbe_64x22.sv
|
||||
//
|
||||
// Written: james.stine@okstate.edu 2 Feburary 2023
|
||||
// Written: james.stine@okstate.edu 2 February 2023
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: RAM wrapper for instantiating RAM IP
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// Written: tfleming@hmc.edu & jtorrey@hmc.edu 7 April 2021
|
||||
// Modified: Teo Ene 15 Apr 2021:
|
||||
// Temporarily removed paramterized priority encoder for non-parameterized one
|
||||
// Temporarily removed parameterized priority encoder for non-parameterized one
|
||||
// To get synthesis working quickly
|
||||
// Kmacsaigoren@hmc.edu 28 May 2021:
|
||||
// Added working version of parameterized priority encoder.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// David_Harris@Hmc.edu switched to one-hot output
|
||||
//
|
||||
// Purpose: Priority circuit producing a thermometer code output.
|
||||
// with 1's in all the least signficant bits of the output
|
||||
// with 1's in all the least significant bits of the output
|
||||
// until the column where the least significant 1 occurs in the input.
|
||||
//
|
||||
// Example: msb lsb
|
||||
|
|
|
@ -67,7 +67,7 @@ module hazard (
|
|||
// Trap returns (RetM) also flush the entire pipeline after the RetM (all stages except W) because all the subsequent instructions must be discarded.
|
||||
// Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents
|
||||
// Branch misprediction is found in the Execute stage and must flush the next two instructions.
|
||||
// However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divde must still complete
|
||||
// However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divide must still complete
|
||||
// When a WFI is interrupted and causes a trap, it flushes the rest of the pipeline but not the W stage, because the WFI needs to commit
|
||||
assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE;
|
||||
assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE));
|
||||
|
@ -75,7 +75,7 @@ module hazard (
|
|||
assign FlushWCause = TrapM & ~WFIInterruptedM;
|
||||
|
||||
// Stall causes
|
||||
// Most data depenency stalls are identified in the decode stage
|
||||
// Most data dependency stalls are identified in the decode stage
|
||||
// Division stalls in the execute stage
|
||||
// Flushing any stage has priority over the corresponding stage stall.
|
||||
// Even if the register gave clear priority over enable, various FSMs still need to disable the stall, so it's best to gate the stall here with flush
|
||||
|
|
|
@ -37,7 +37,7 @@ module aes64ks1i(
|
|||
logic [31:0] rcon, rs1Rotate;
|
||||
|
||||
rconlut32 rc(round, rcon); // Get rcon value from lookup table
|
||||
assign rs1Rotate = {rs1[39:32], rs1[63:40]}; // Get rotated value fo ruse in tmp2
|
||||
assign rs1Rotate = {rs1[39:32], rs1[63:40]}; // Get rotated value for use in tmp2
|
||||
assign finalround = (round == 4'b1010); // round 10 is the last one
|
||||
assign SboxKIn = finalround ? rs1[63:32] : rs1Rotate; // Don't rotate on the last round
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P) (
|
|||
logic [P.XLEN-1:0] MaskB; // BitMask of B
|
||||
logic [P.XLEN-1:0] RevA; // Bit-reversed A
|
||||
logic Mask; // Indicates if it is ZBS instruction
|
||||
logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction
|
||||
logic PreShift; // Indicates if it is sh1add, sh2add, sh3add instruction
|
||||
logic [1:0] PreShiftAmt; // Amount to Pre-Shift A
|
||||
logic [P.XLEN-1:0] CondZextA; // A Conditional Extend Intermediary Signal
|
||||
logic [P.XLEN-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity
|
||||
|
|
|
@ -35,8 +35,8 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
|
|||
input logic ALUOpD, // Regular ALU Operation
|
||||
output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage
|
||||
output logic BALUSrcBD, // Indicates if it is an I/IW (non auipc) type B instruction in Decode Stage
|
||||
output logic BW64D, // Indiciates if it is a W type B instruction in Decode Stage
|
||||
output logic BUW64D, // Indiciates if it is a .uw type B instruction in Decode Stage
|
||||
output logic BW64D, // Indicates if it is a W type B instruction in Decode Stage
|
||||
output logic BUW64D, // Indicates if it is a .uw type B instruction in Decode Stage
|
||||
output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage
|
||||
output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage
|
||||
// Execute stage control signals
|
||||
|
|
|
@ -158,7 +158,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
|||
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
|
||||
logic FCvtIntStallD, MDUStallD, CSRRdStallD; // Stall due to conversion, load, multiply/divide, CSR read
|
||||
logic FunctCZeroD; // Funct7 and Funct3 indicate czero.* (not including Op check)
|
||||
logic BUW64D; // Indiciates if it is a .uw type B instruction in Decode Stage
|
||||
logic BUW64D; // Indicates if it is a .uw type B instruction in Decode Stage
|
||||
|
||||
// Extract fields
|
||||
assign OpD = InstrD[6:0];
|
||||
|
@ -401,7 +401,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
|||
IFUPrefetchD = 1'b0;
|
||||
LSUPrefetchD = 1'b0;
|
||||
ImmSrcD = PreImmSrcD;
|
||||
if (P.ZICBOP_SUPPORTED & (InstrD[14:0] == 15'b110_00000_0010011)) begin // ori with destiation x0 is hint for Prefetch
|
||||
if (P.ZICBOP_SUPPORTED & (InstrD[14:0] == 15'b110_00000_0010011)) begin // ori with destination x0 is hint for Prefetch
|
||||
/* verilator lint_off CASEINCOMPLETE */
|
||||
case (Rs2D) // which type of prefectch? Note: prefetch.r and .w are handled the same in Wally
|
||||
5'b00000: IFUPrefetchD = 1'b1; // prefetch.i
|
||||
|
|
|
@ -60,7 +60,7 @@ module shifter import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.ZBB_SUPPORTED | P.ZBKB_SUPPORTED) begin: rotfunnel64 // rv64 shifter with rotates
|
||||
// shifter rotate source select mux
|
||||
logic [P.XLEN-1:0] RotA; // rotate source
|
||||
mux2 #(P.XLEN) rotmux(A, {A[31:0], A[31:0]}, W64, RotA); // W64 rotatons
|
||||
mux2 #(P.XLEN) rotmux(A, {A[31:0], A[31:0]}, W64, RotA); // W64 rotations
|
||||
always_comb // funnel mux
|
||||
case ({Right, Rotate})
|
||||
2'b00: Z = {A64[63:0],{63'b0}};
|
||||
|
|
|
@ -55,7 +55,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
|||
input logic InstrValidD, InstrValidE,
|
||||
input logic BranchD, BranchE,
|
||||
input logic JumpD, JumpE,
|
||||
input logic PCSrcE, // Executation stage branch is taken
|
||||
input logic PCSrcE, // Execution stage branch is taken
|
||||
input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address
|
||||
input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address
|
||||
input logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
||||
|
@ -188,7 +188,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
|||
mux2 #(P.XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
|
||||
|
||||
// If the fence/csrw was predicted as a taken branch then we select PCF, rather than PCE.
|
||||
// Effectively this is PCM+4 or the non-existant PCLinkM
|
||||
// Effectively this is PCM+4 or the non-existent PCLinkM
|
||||
if(`INSTR_CLASS_PRED) mux2 #(P.XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
|
||||
else assign NextValidPCE = PCE;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// Modified: 24 January 2023
|
||||
//
|
||||
// Purpose: Branch Target Buffer (BTB). The BTB predicts the target address of all control flow instructions.
|
||||
// It also guesses the type of instrution; jalr(r), return, jump (jr), or branch.
|
||||
// It also guesses the type of instruction; jalr(r), return, jump (jr), or branch.
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design
|
||||
//
|
||||
|
|
|
@ -49,7 +49,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||
output logic [P.XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW
|
||||
// Execute
|
||||
output logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
||||
input logic PCSrcE, // Executation stage branch is taken
|
||||
input logic PCSrcE, // Execution stage branch is taken
|
||||
input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address
|
||||
input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address
|
||||
output logic [P.XLEN-1:0] PCE, // Execution stage instruction address
|
||||
|
@ -79,7 +79,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||
output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP
|
||||
output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
||||
// mmu management
|
||||
input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage
|
||||
input logic [1:0] PrivilegeModeW, // Privilege mode in Writeback stage
|
||||
input logic [P.XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
|
||||
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
|
||||
input logic ITLBWriteF, // Writes PTE and PageType to ITLB
|
||||
|
@ -219,7 +219,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CommittedM tells the CPU's privileged unit the current instruction
|
||||
// in the memory stage is a memory operaton and that memory operation is either completed
|
||||
// in the memory stage is a memory operation and that memory operation is either completed
|
||||
// or is partially executed. Partially completed memory operations need to prevent an interrupts.
|
||||
// There is not a clean way to restore back to a partial executed instruction. CommiteedM will
|
||||
// delay the interrupt until the LSU is in a clean state.
|
||||
|
|
|
@ -40,7 +40,7 @@ module irom import cvw::*; #(parameter cvw_t P) (
|
|||
logic [31:0] RawIROMInstrF;
|
||||
logic [2:1] AdrD;
|
||||
|
||||
// preload IROM with the FPGA bootloader by default so that it syntehsizes to something, avoiding having the IEU optimized away because instructions are all 0
|
||||
// preload IROM with the FPGA bootloader by default so that it synthesizes to something, avoiding having the IEU optimized away because instructions are all 0
|
||||
// the testbench replaces these dummy contents with the actual program of interest during simulation
|
||||
rom1p1r #(ADDR_WDITH, P.XLEN, 1) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull));
|
||||
if (P.XLEN == 32) assign RawIROMInstrF = IROMInstrFFull;
|
||||
|
@ -50,7 +50,7 @@ module irom import cvw::*; #(parameter cvw_t P) (
|
|||
flopen #(1) AdrReg2(clk, ce, Adr[2], AdrD[2]);
|
||||
assign RawIROMInstrF = AdrD[2] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0];
|
||||
end
|
||||
// If the memory addres is aligned to 2 bytes return the upper 2 bytes in the lower 2 bytes.
|
||||
// If the memory address is aligned to 2 bytes return the upper 2 bytes in the lower 2 bytes.
|
||||
// The spill logic will handle merging the two together.
|
||||
if (P.ZCA_SUPPORTED) begin
|
||||
flopen #(1) AdrReg1(clk, ce, Adr[1], AdrD[1]);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// Modified: 26 October 2023
|
||||
//
|
||||
// Purpose: This module implements native alignment support for the Zicclsm extension
|
||||
// It is simlar to the IFU's spill module and probably could be merged together with
|
||||
// It is similar to the IFU's spill module and probably could be merged together with
|
||||
// some effort.
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design
|
||||
|
@ -98,7 +98,7 @@ module align import cvw::*; #(parameter cvw_t P) (
|
|||
// 2) offset
|
||||
// 3) access location within the cacheline
|
||||
|
||||
// compute misalignement
|
||||
// compute misalignment
|
||||
always_comb begin
|
||||
case (Funct3M & {FpLoadStoreM, 2'b11})
|
||||
3'b000: AccessByteOffsetM = '0; // byte access
|
||||
|
|
|
@ -36,7 +36,7 @@ module lrsc import cvw::*; #(parameter cvw_t P) (
|
|||
input logic MemReadM, // Memory read
|
||||
input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write
|
||||
output logic [1:0] LSURWM, // Memory operation after potential squash of SC
|
||||
input logic [1:0] LSUAtomicM, // Atomic memory operaiton
|
||||
input logic [1:0] LSUAtomicM, // Atomic memory operation
|
||||
input logic [P.PA_BITS-1:0] PAdrM, // Physical memory address
|
||||
output logic SquashSCW // Squash the store conditional by not allowing rf write
|
||||
);
|
||||
|
|
|
@ -142,7 +142,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
logic DTLBMissM; // DTLB miss causes HPTW walk
|
||||
logic DTLBWriteM; // Writes PTE and PageType to DTLB
|
||||
logic LSULoadAccessFaultM; // Load acces fault
|
||||
logic LSULoadAccessFaultM; // Load access fault
|
||||
logic LSUStoreAmoAccessFaultM; // Store access fault
|
||||
logic HPTWFlushW; // HPTW needs to flush operation
|
||||
logic LSUFlushW; // HPTW or hazard unit flushes operation
|
||||
|
@ -303,7 +303,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||
logic [P.PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback.
|
||||
logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache
|
||||
logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback
|
||||
logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount
|
||||
logic SelBusBeat; // ahbcacheinterface selects position in cacheline with BeatCount
|
||||
logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface
|
||||
logic [1:0] BusRW; // Uncached bus memory access
|
||||
logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush
|
||||
|
@ -353,7 +353,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||
mux3 #(P.LLEN) UnCachedDataMux(.d0(DCacheReadDataWordSpillM), .d1({LLENPOVERAHBW{FetchBuffer[P.XLEN-1:0]}}),
|
||||
.d2({{P.LLEN-P.XLEN{1'b0}}, DTIMReadDataWordM[P.XLEN-1:0]}),
|
||||
.s({SelDTIM, ~(CacheableOrFlushCacheM)}), .y(ReadDataWordMuxM));
|
||||
end else begin : passthrough // No Cache, use simple ahbinterface instad of ahbcacheinterface
|
||||
end else begin : passthrough // No Cache, use simple ahbinterface instead of ahbcacheinterface
|
||||
logic [1:0] BusRW; // Non-DTIM memory access, ignore cacheableM
|
||||
logic [P.XLEN-1:0] FetchBuffer;
|
||||
assign BusRW = ~SelDTIM ? LSURWM : 0;
|
||||
|
|
|
@ -78,7 +78,7 @@ module div import cvw::*; #(parameter cvw_t P) (
|
|||
assign DinE = ForwardedSrcBE;
|
||||
end
|
||||
|
||||
// Extract sign bits and check fo division by zero
|
||||
// Extract sign bits and check for division by zero
|
||||
assign SignDE = DivSignedE & DinE[P.XLEN-1];
|
||||
assign SignXE = DivSignedE & XinE[P.XLEN-1];
|
||||
assign NegQE = SignDE ^ SignXE;
|
||||
|
|
|
@ -33,7 +33,7 @@ module mdu import cvw::*; #(parameter cvw_t P) (
|
|||
input logic FlushE, FlushM, FlushW,
|
||||
input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output
|
||||
input logic [2:0] Funct3E, Funct3M, // type of MDU operation
|
||||
input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions
|
||||
input logic IntDivE, W64E, // Integer division/remainder, and W-type instructions
|
||||
input logic MDUActiveE, // Mul/Div instruction being executed
|
||||
output logic [P.XLEN-1:0] MDUResultW, // multiply/divide result
|
||||
output logic DivBusyE // busy signal to stall pipeline in Execute stage
|
||||
|
|
|
@ -200,8 +200,8 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
|||
assign InvalidOp = DTLBWalk ? (InvalidRead | InvalidWrite) : ~Executable;
|
||||
assign OtherPageFault = ImproperPrivilege | InvalidOp | UpperBitsUnequalD | Misaligned | ~Valid;
|
||||
|
||||
// hptw needs to know if there is a Dirty or Access fault occuring on this
|
||||
// memory access. If there is the PTE needs to be updated seting Access
|
||||
// hptw needs to know if there is a Dirty or Access fault occurring on this
|
||||
// memory access. If there is the PTE needs to be updated setting Access
|
||||
// and possibly also Dirty. Dirty is set if the operation is a store/amo.
|
||||
// However any other fault should not cause the update, and updates are in software when ENVCFG_ADUE = 0
|
||||
assign HPTWUpdateDA = ValidLeafPTE & (~Accessed | SetDirty) & ENVCFG_ADUE & ~OtherPageFault;
|
||||
|
@ -316,7 +316,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
|||
// HTPW address/data/control muxing
|
||||
|
||||
// Once the walk is done and it is time to update the TLB we need to switch back
|
||||
// to the orignal data virtual address.
|
||||
// to the original data virtual address.
|
||||
assign SelHPTWAdr = SelHPTW & ~(DTLBWriteM | ITLBWriteF);
|
||||
|
||||
// multiplex the outputs to LSU
|
||||
|
|
|
@ -47,7 +47,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||
input logic TLBFlush, // Invalidate all TLB entries
|
||||
output logic [P.PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation
|
||||
output logic TLBMiss, // Miss TLB
|
||||
output logic Cacheable, // PMA indicates memory address is cachable
|
||||
output logic Cacheable, // PMA indicates memory address is cacheable
|
||||
output logic Idempotent, // PMA indicates memory address is idempotent
|
||||
output logic SelTIM, // Select a tightly integrated memory
|
||||
// Faults
|
||||
|
@ -105,8 +105,8 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||
assign TLBPAdr = '0;
|
||||
end
|
||||
|
||||
// If translation is occuring, select translated physical address from TLB
|
||||
// the lower 12 bits are the page offset. These are never changed from the orginal
|
||||
// If translation is occurring, select translated physical address from TLB
|
||||
// the lower 12 bits are the page offset. These are never changed from the original
|
||||
// non translated address.
|
||||
mux2 #(P.PA_BITS-12) addressmux(VAdr[P.PA_BITS-1:12], TLBPAdr[P.PA_BITS-1:12], Translate, PhysicalAddress[P.PA_BITS-1:12]);
|
||||
assign PhysicalAddress[11:0] = VAdr[11:0];
|
||||
|
@ -141,7 +141,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||
2'b10: DataMisalignedM = VAdr[1] | VAdr[0]; // lw, sw, flw, fsw, lwu
|
||||
2'b11: DataMisalignedM = |VAdr[2:0]; // ld, sd, fld, fsd
|
||||
endcase
|
||||
// When ZiCCLSM_SUPPORTED, misalgined cachable loads and stores are handled in hardware so they do not throw a misaligned fault
|
||||
// When ZiCCLSM_SUPPORTED, misalgined cacheable loads and stores are handled in hardware so they do not throw a misaligned fault
|
||||
assign LoadMisalignedFaultM = DataMisalignedM & ReadNoAmoAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable) & ~TLBMiss;
|
||||
assign StoreAmoMisalignedFaultM = DataMisalignedM & WriteAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable) & ~TLBMiss; // Store and AMO both assert WriteAccess
|
||||
|
||||
|
|
|
@ -58,8 +58,8 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||
// Determine which region of physical memory (if any) is being accessed
|
||||
adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWXC, Size, SelRegions);
|
||||
|
||||
// Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable
|
||||
assign CacheableRegion = SelRegions[3] | SelRegions[4] | SelRegions[5]; // exclusion-tag: unused-cachable
|
||||
// Only non-core RAM/ROM memory regions are cacheable. PBMT can override cacheable; NC and IO are uncachable
|
||||
assign CacheableRegion = SelRegions[3] | SelRegions[4] | SelRegions[5]; // exclusion-tag: unused-cacheable
|
||||
assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 1'b0;
|
||||
|
||||
// Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly
|
||||
|
|
|
@ -76,7 +76,7 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
|
|||
// form a mask where the bottom k bits are 1, corresponding to a size of 2^k bytes for this memory region.
|
||||
// This assumes we're using at least an NA4 region, but works for any size NAPOT region.
|
||||
assign NABase = {(PMPAdr & ~NAMask[P.PA_BITS-1:2]), 2'b00}; // base physical address of the pmp region
|
||||
assign NAMatch = &((NABase ~^ PhysicalAddress) | NAMask); // check if upper bits of base address match, ignore lower bits correspoonding to inside the memory range
|
||||
assign NAMatch = &((NABase ~^ PhysicalAddress) | NAMask); // check if upper bits of base address match, ignore lower bits corresponding to inside the memory range
|
||||
|
||||
// finally pick the appropriate match for the access type
|
||||
assign Match = (AdrMode == TOR) ? TORMatch :
|
||||
|
|
|
@ -75,7 +75,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
|
|||
.Match, .PMPTop, .L, .X, .W, .R);
|
||||
end
|
||||
|
||||
priorityonehot #(P.PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
|
||||
priorityonehot #(P.PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the address decoders to find the first one that matches.
|
||||
|
||||
// Distributed AND-OR mux to select the first matching results
|
||||
// If the access does not match all bytes of the PMP region, it is too big and the matches are disabled
|
||||
|
|
|
@ -71,7 +71,7 @@ module tlbcamline import cvw::*; #(parameter cvw_t P,
|
|||
// Calculate the actual match value based on the input vpn and the page type.
|
||||
// For example, a megapage in SV32 only cares about VPN[1], so VPN[0]
|
||||
// should automatically match.
|
||||
assign Match0 = (Query0 == Key0) | (PageType[0]); // least signifcant section
|
||||
assign Match0 = (Query0 == Key0) | (PageType[0]); // least significant section
|
||||
assign Match1 = (Query1 == Key1);
|
||||
|
||||
assign Match = Match0 & Match1 & MatchASID & Valid;
|
||||
|
|
|
@ -115,7 +115,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
|
|||
assign PreUpdateDA = ~PTE_A | WriteAccess & ~PTE_D;
|
||||
end
|
||||
|
||||
// Determine wheter to update DA bits. With SVADU, it is done in hardware
|
||||
// Determine whether to update DA bits. With SVADU, it is done in hardware
|
||||
assign UpdateDA = P.SVADU_SUPPORTED & PreUpdateDA & Translate & TLBHit & ~TLBPageFault & ENVCFG_ADUE;
|
||||
|
||||
// Determine whether page fault occurs
|
||||
|
|
|
@ -63,7 +63,7 @@ module tlbmixer import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// In Svnapot, when N=1, use bottom bits of VPN for contiugous translations
|
||||
if (P.SVNAPOT_SUPPORTED) begin
|
||||
// 64 KiB contiguous NAPOT translations suported
|
||||
// 64 KiB contiguous NAPOT translations supported
|
||||
logic [3:0] PPNMixedBot;
|
||||
mux2 #(4) napotmux(PPNMixed[3:0], VPN[3:0], PTE_N, PPNMixedBot);
|
||||
assign PPNMixed2 = {PPNMixed[P.PPN_BITS-1:4], PPNMixedBot};
|
||||
|
|
|
@ -90,14 +90,14 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
|||
end
|
||||
|
||||
// hardwired STATUS bits
|
||||
assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported
|
||||
assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override register with 0 if supervisor mode not supported
|
||||
assign STATUS_TW = P.U_SUPPORTED & STATUS_TW_INT; // override register with 0 if only machine mode supported
|
||||
assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported
|
||||
assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported
|
||||
assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override register with 0 if supervisor mode not supported
|
||||
assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override register with 0 if supervisor mode not supported
|
||||
// SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not
|
||||
assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported
|
||||
assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
|
||||
assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported
|
||||
assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override register with 0 if supervisor mode not supported
|
||||
assign STATUS_MPRV = P.U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported
|
||||
assign STATUS_FS = P.F_SUPPORTED ? STATUS_FS_INT : 2'b00; // off if no FP
|
||||
assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic
|
||||
|
|
|
@ -83,7 +83,7 @@ module privdec import cvw::*; #(parameter cvw_t P) (
|
|||
assign WFICountPlus1 = wfiM ? WFICount + 1 : '0; // restart counting on WFI
|
||||
flopr #(P.WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, WFICountPlus1, WFICount); // count while in WFI
|
||||
// coverage off -item e 1 -fecexprrow 1
|
||||
// WFI Timout trap will not occur when STATUS_TW is low while in supervisor mode, so the system gets stuck waiting for an interrupt and triggers a watchdog timeout.
|
||||
// WFI Timeout trap will not occur when STATUS_TW is low while in supervisor mode, so the system gets stuck waiting for an interrupt and triggers a watchdog timeout.
|
||||
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != P.M_MODE) | (P.S_SUPPORTED & PrivilegeModeW == P.U_MODE)) & WFICount[P.WFI_TIMEOUT_BIT];
|
||||
// coverage on
|
||||
end else assign WFITimeoutM = 1'b0;
|
||||
|
|
|
@ -52,7 +52,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
|||
input logic DCacheStallM, // D cache stalled
|
||||
input logic BPDirWrongM, // branch predictor guessed wrong direction
|
||||
input logic BTAWrongM, // branch predictor guessed wrong target
|
||||
input logic RASPredPCWrongM, // return adddress stack guessed wrong target
|
||||
input logic RASPredPCWrongM, // return address stack guessed wrong target
|
||||
input logic IClassWrongM, // branch predictor guessed wrong instruction class
|
||||
input logic BPWrongM, // branch predictor is wrong
|
||||
input logic [3:0] IClassM, // actual instruction class
|
||||
|
@ -114,7 +114,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
|||
logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits
|
||||
logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return
|
||||
logic DelegateM; // trap should be delegated
|
||||
logic InterruptM; // interrupt occuring
|
||||
logic InterruptM; // interrupt occurring
|
||||
logic ExceptionM; // Memory stage instruction caused a fault
|
||||
logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE
|
||||
logic HPTWInstrPageFaultM; // Hardware page table page fault while fetching instruction PTE
|
||||
|
|
|
@ -48,7 +48,7 @@ module trap import cvw::*; #(parameter cvw_t P) (
|
|||
output logic [3:0] CauseM // trap cause
|
||||
);
|
||||
|
||||
logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables
|
||||
logic MIntGlobalEnM, SIntGlobalEnM; // Global interrupt enables
|
||||
logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted
|
||||
logic BothInstrAccessFaultM, BothInstrPageFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
|
||||
logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
|
||||
|
|
|
@ -48,7 +48,7 @@ module rvvisynth import cvw::*; #(parameter cvw_t P,
|
|||
output logic [72+(5*P.XLEN) + MAX_CSRS*(P.XLEN+16)-1:0] rvvi
|
||||
);
|
||||
|
||||
// pipeline controlls
|
||||
// pipeline controls
|
||||
|
||||
// required
|
||||
logic [P.XLEN-1:0] PCW;
|
||||
|
|
|
@ -215,7 +215,7 @@ module timereg import cvw::*; #(parameter cvw_t P) (
|
|||
done <= ack_stored & ~ack;
|
||||
end
|
||||
|
||||
// synchronize the reset and reqest into the TIMECLK domain
|
||||
// synchronize the reset and request into the TIMECLK domain
|
||||
sync resetsync(TIMECLK, PRESETn, resetn_sync);
|
||||
sync rsync(TIMECLK, req, req_sync);
|
||||
// synchronize the acknowledge back to the PCLK domain to indicate the request was handled and can be lowered
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
// up to 63 sources supported; in the future, allow up to 1023 sources
|
||||
|
||||
`define C 2
|
||||
// number of conexts
|
||||
// number of contexts
|
||||
// hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts
|
||||
|
||||
module plic_apb import cvw::*; #(parameter cvw_t P) (
|
||||
|
@ -195,7 +195,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
|||
end
|
||||
end
|
||||
|
||||
// which prority levels have one or more active requests?
|
||||
// which priority levels have one or more active requests?
|
||||
assign priorities_with_irqs[ctx][7:1] = {
|
||||
|irqMatrix[ctx][7],
|
||||
|irqMatrix[ctx][6],
|
||||
|
|
|
@ -60,7 +60,7 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
|
|||
flopenr #(1) memwritereg(HCLK, ~HRESETn, HREADY, memwrite, memwriteD);
|
||||
flopenr #(P.PA_BITS) haddrreg(HCLK, ~HRESETn, HREADY, HADDR, HADDRD);
|
||||
|
||||
// Stall on a read after a write because the RAM can't take both adddresses on the same cycle
|
||||
// Stall on a read after a write because the RAM can't take both addresses on the same cycle
|
||||
assign nextHREADYRam = (~(memwriteD & memread)) & ~DelayReady;
|
||||
flopr #(1) readyreg(HCLK, ~HRESETn, nextHREADYRam, HREADYRam);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
// Purpose: SPI peripheral
|
||||
//
|
||||
// SPI module is written to the specifications described in FU540-C000-v1.0. At the top level, it is consists of synchronous 8 byte transmit and recieve FIFOs connected to shift registers.
|
||||
// SPI module is written to the specifications described in FU540-C000-v1.0. At the top level, it is consists of synchronous 8 byte transmit and receive FIFOs connected to shift registers.
|
||||
// The FIFOs are connected to WALLY by an apb control register interface, which includes various control registers for modifying the SPI transmission along with registers for writing
|
||||
// to the transmit FIFO and reading from the receive FIFO. The transmissions themselves are then controlled by a finite state machine. The SPI module uses 4 tristate pins for SPI input/output,
|
||||
// along with a 4 bit Chip Select signal, a clock signal, and an interrupt signal to WALLY.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
// Written: David_Harris@hmc.edu 21 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Universial Asynchronous Receiver/ Transmitter with FIFOs
|
||||
// Purpose: Universal Asynchronous Receiver/ Transmitter with FIFOs
|
||||
// Emulates interface of Texas Instruments PC16550D
|
||||
// https://media.digikey.com/pdf/Data%20Sheets/Texas%20Instruments%20PDFs/PC16550D.pdf
|
||||
// Compatible with UART in Imperas Virtio model
|
||||
//
|
||||
// Compatible with most of PC16550D with the following known exceptions:
|
||||
// Generates 2 rather than 1.5 stop bits when 5-bit word length is slected and LCR[2] = 1
|
||||
// Generates 2 rather than 1.5 stop bits when 5-bit word length is selected and LCR[2] = 1
|
||||
// Timeout not yet implemented
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design
|
||||
|
@ -71,7 +71,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
|||
logic [3:0] IER, MSR;
|
||||
logic [4:0] MCR;
|
||||
|
||||
// Syncrhonized and delayed UART signals
|
||||
// Synchronized and delayed UART signals
|
||||
logic SINd, DSRbd, DCDbd, CTSbd, RIbd;
|
||||
logic SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync;
|
||||
logic DSRb2, DCDb2, CTSb2, RIb2;
|
||||
|
@ -88,7 +88,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
|||
logic [3:0] rxbitsreceived, txbitssent;
|
||||
statetype rxstate, txstate;
|
||||
|
||||
// shift registrs and FIFOs
|
||||
// shift registers and FIFOs
|
||||
logic [9:0] rxshiftreg;
|
||||
logic [10:0] rxfifo[15:0];
|
||||
logic [7:0] txfifo[15:0];
|
||||
|
@ -137,7 +137,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
|||
always_ff @(posedge PCLK) begin
|
||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd} <= {SIN, DSRb, DCDb, CTSb, RIb};
|
||||
{SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} :
|
||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd}; // syncrhonized signals, handle loopback testing
|
||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd}; // synchronized signals, handle loopback testing
|
||||
{DSRb2, DCDb2, CTSb2, RIb2} <= {DSRbsync, DCDbsync, CTSbsync, RIbsync}; // for detecting state changes
|
||||
end
|
||||
|
||||
|
@ -171,7 +171,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
|||
end
|
||||
|
||||
// Line Status Register (8.6.3)
|
||||
// Ben 6/9/21 I don't like how this is a register. A lot of the individual bits have clocked components, so this just adds unecessary delay.
|
||||
// Ben 6/9/21 I don't like how this is a register. A lot of the individual bits have clocked components, so this just adds unnecessary delay.
|
||||
if (~MEMWb & (A == UART_LSR))
|
||||
LSR[6:1] <= Din[6:1]; // recommended only for test, see 8.6.3
|
||||
else begin
|
||||
|
@ -203,7 +203,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
|||
case (A)
|
||||
UART_DLL_RBR: if (DLAB) Dout = DLL; else Dout = RBR[7:0];
|
||||
UART_DLM_IER: if (DLAB) Dout = DLM; else Dout = {4'b0, IER[3:0]};
|
||||
UART_IIR: Dout = {{2{fifoenabled}}, 2'b00, intrID[2:0], ~intrpending}; // Read only Interupt Ident Register
|
||||
UART_IIR: Dout = {{2{fifoenabled}}, 2'b00, intrID[2:0], ~intrpending}; // Read only Interrupt Ident Register
|
||||
UART_LCR: Dout = LCR;
|
||||
UART_MCR: Dout = {3'b000, MCR};
|
||||
UART_LSR: Dout = LSR;
|
||||
|
@ -472,7 +472,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
|||
// pointer indicates where the next write goes and not the location of the
|
||||
// current head, the head and tail pointer being equal imply two different
|
||||
// things. First it could mean the fifo is empty and second it could mean
|
||||
// the fifo is full. To differenciate we need to know which pointer moved
|
||||
// the fifo is full. To differentiate we need to know which pointer moved
|
||||
// to cause them to be equal. If the head pointer moved then it is full.
|
||||
// If the tail pointer moved then it is empty. it resets to empty so
|
||||
// if reset with the tail pointer indicating the last update.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Written: David_Harris@hmc.edu 21 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: APB Interface to Universial Asynchronous Receiver/ Transmitter with FIFOs
|
||||
// Purpose: APB Interface to Universal Asynchronous Receiver/ Transmitter with FIFOs
|
||||
// Emulates interface of Texas Instruments PC165550D
|
||||
// Compatible with UART in Imperas Virtio model
|
||||
//
|
||||
|
|
|
@ -195,9 +195,9 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
|
||||
// Address Decoder Delay (figure 4-2 in spec)
|
||||
// The select for HREADY needs to be based on the address phase address. If the device
|
||||
// takes more than 1 cycle to repsond it needs to hold on to the old select until the
|
||||
// device is ready. Hense this register must be selectively enabled by HREADY.
|
||||
// However on reset None must be seleted.
|
||||
// takes more than 1 cycle to respond it needs to hold on to the old select until the
|
||||
// device is ready. Hence this register must be selectively enabled by HREADY.
|
||||
// However on reset None must be selected.
|
||||
flopenl #(12) hseldelayreg(HCLK, ~HRESETn, HREADY, HSELRegions, 12'b1,
|
||||
{HSELSPID, HSELSDCD, HSELPLICD, HSELUARTD, HSELGPIOD, HSELCLINTD,
|
||||
HSELRamD, HSELBootRomD, HSELEXTD, HSELIROMD, HSELDTIMD, HSELNoneD});
|
||||
|
|
|
@ -16,7 +16,7 @@ import matplotlib.lines as lines
|
|||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import scipy.optimize as opt
|
||||
import sklearn.metrics as skm # depricated, will need to replace with scikit-learn
|
||||
import sklearn.metrics as skm # deprecated, will need to replace with scikit-learn
|
||||
from matplotlib.cbook import flatten
|
||||
|
||||
|
||||
|
|
|
@ -250,11 +250,11 @@ set verilogout_no_tri true
|
|||
set verilogout_equation false
|
||||
|
||||
# setting to generate output files
|
||||
set write_v 1 ;# generates structual netlist
|
||||
set write_v 1 ;# generates structural netlist
|
||||
set write_sdc 1 ;# generates synopsys design constraint file for p&r
|
||||
set write_ddc 1 ;# compiler file in ddc format
|
||||
set write_sdf 1 ;# sdf file for backannotated timing sim
|
||||
set write_pow 1 ;# genrates estimated power report
|
||||
set write_pow 1 ;# generates estimated power report
|
||||
set write_rep 1 ;# generates estimated area and timing report
|
||||
set write_cst 1 ;# generate report of constraints
|
||||
set write_hier 1 ;# generate hierarchy report
|
||||
|
|
|
@ -33,7 +33,7 @@ if __name__ == '__main__':
|
|||
parser.add_argument("-f", "--featuresweep", action='store_true', help = "Synthesize wally with features turned off progressively to visualize critical path")
|
||||
|
||||
parser.add_argument("-v", "--version", choices=allConfigs, help = "Configuration of wally")
|
||||
parser.add_argument("-t", "--targetfreq", type=int, help = "Target frequncy")
|
||||
parser.add_argument("-t", "--targetfreq", type=int, help = "Target frequency")
|
||||
parser.add_argument("-e", "--tech", choices=techs, help = "Technology")
|
||||
parser.add_argument("-o", "--maxopt", action='store_true', help = "Turn on MAXOPT")
|
||||
parser.add_argument("-r", "--usesram", action='store_true', help = "Use SRAM modules")
|
||||
|
|
|
@ -93,9 +93,9 @@ module functionName import cvw::*; #(parameter cvw_t P) (
|
|||
end
|
||||
end // while (left <= right)
|
||||
// if the element pc is now found, right and left will be equal at this point.
|
||||
// we need to check if pc is less than the array at left or greather.
|
||||
// we need to check if pc is less than the array at left or greater.
|
||||
// if it is less than pc, then we select left as the index.
|
||||
// if it is greather we want 1 less than left.
|
||||
// if it is greater we want 1 less than left.
|
||||
if (array[left] < pc) begin
|
||||
minval = array[left];
|
||||
mid = left;
|
||||
|
@ -120,7 +120,7 @@ module functionName import cvw::*; #(parameter cvw_t P) (
|
|||
// initial begin
|
||||
always @ (negedge reset) begin
|
||||
|
||||
// cannot readmemh directoy to a dynmaic array. Sad times :(
|
||||
// cannot readmemh directly to a dynamic array. Sad times :(
|
||||
// Let's initialize a static array with FFFF_FFFF for all addresses.
|
||||
// Then we can readmemh and finally copy to the dynamic array.
|
||||
|
||||
|
|
|
@ -126,8 +126,8 @@ module loggers import cvw::*; #(parameter cvw_t P,
|
|||
assign EndSample = EndSampleFirst & ~ EndSampleDelayed;
|
||||
|
||||
end else begin
|
||||
// default start condiction is reset
|
||||
// default end condiction is end of test (DCacheFlushDone)
|
||||
// default start condition is reset
|
||||
// default end condition is end of test (DCacheFlushDone)
|
||||
//assign StartSampleFirst = reset;
|
||||
//flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed);
|
||||
//assign StartSample = StartSampleFirst & ~ StartSampleDelayed;
|
||||
|
@ -221,7 +221,7 @@ module loggers import cvw::*; #(parameter cvw_t P,
|
|||
dut.core.lsu.bus.dcache.dcache.CMOpM == 4'b1000 ? "Z" : // cbo.zero
|
||||
dut.core.lsu.bus.dcache.dcache.CMOpM == 4'b0001 ? "V" : // cbo.inval should just clear the valid and dirty bits
|
||||
dut.core.lsu.bus.dcache.dcache.CMOpM == 4'b0010 ? "C" : // cbo.clean should act like a read in terms of the lru, but clears the dirty bit
|
||||
dut.core.lsu.bus.dcache.dcache.CMOpM == 4'b0100 ? "L" : // cbo.flush should just clear and the valid and drity bits
|
||||
dut.core.lsu.bus.dcache.dcache.CMOpM == 4'b0100 ? "L" : // cbo.flush should just clear and the valid and dirty bits
|
||||
"NULL";
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Written: David_Harris@hmc.edu
|
||||
// Modified: 2 July 2023
|
||||
//
|
||||
// Purpose: Detects if the processor is attempting to read unitialized RAM
|
||||
// Purpose: Detects if the processor is attempting to read uninitialized RAM
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
|
@ -39,7 +39,7 @@ module ramxdetector #(parameter XLEN, LLEN) (
|
|||
/* verilator lint_off WIDTHXZEXPAND */
|
||||
if (MemReadM & ~LSULoadAccessFaultM & (ReadDataM === 'bx)) begin
|
||||
/* verilator lint_on WIDTHXZEXPAND */
|
||||
$display("WARNING: Attempting to read from unitialized RAM. Processor may go haywire if it uses x value. But this is normal in WALLY-mmu and ExceptionInstr tests.");
|
||||
$display("WARNING: Attempting to read from uninitialized RAM. Processor may go haywire if it uses x value. But this is normal in WALLY-mmu and ExceptionInstr tests.");
|
||||
$display(" PCM = %x InstrM = %x (%s), IEUAdrM = %x", PCM, InstrM, InstrMName, IEUAdrM);
|
||||
//$stop;
|
||||
end
|
||||
|
|
|
@ -29,10 +29,10 @@ module riscvassertions import cvw::*; #(parameter cvw_t P);
|
|||
assert (P.F_SUPPORTED | ~P.ZFH_SUPPORTED) else $fatal(1, "Can't support half-precision fp (ZFH) without supporting float (F)");
|
||||
assert (P.DCACHE_SUPPORTED | ~P.F_SUPPORTED | P.FLEN <= P.XLEN) else $fatal(1, "Data cache required to support FLEN > XLEN because AHB/DTIM bus width is XLEN");
|
||||
assert (P.I_SUPPORTED ^ P.E_SUPPORTED) else $fatal(1, "Exactly one of I and E must be supported");
|
||||
assert (P.DCACHE_WAYSIZEINBYTES <= 4096 | (!P.DCACHE_SUPPORTED) | P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (P.DCACHE_WAYSIZEINBYTES <= 4096 | (!P.DCACHE_SUPPORTED) | P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and virtual memory is enabled (to prevent aliasing)");
|
||||
assert (P.DCACHE_LINELENINBITS >= 128 | (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
|
||||
assert (P.DCACHE_LINELENINBITS < P.DCACHE_WAYSIZEINBYTES*8) else $fatal(1, "DCACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (P.ICACHE_WAYSIZEINBYTES <= 4096 | (!P.ICACHE_SUPPORTED) | P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (P.ICACHE_WAYSIZEINBYTES <= 4096 | (!P.ICACHE_SUPPORTED) | P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and virtual memory is enabled (to prevent aliasing)");
|
||||
assert (P.ICACHE_LINELENINBITS >= 32 | (!P.ICACHE_SUPPORTED)) else $fatal(1, "ICACHE_LINELENINBITS must be at least 32 when caches are enabled");
|
||||
assert (P.ICACHE_LINELENINBITS < P.ICACHE_WAYSIZEINBYTES*8) else $fatal(1, "ICACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (2**$clog2(P.DCACHE_LINELENINBITS) == P.DCACHE_LINELENINBITS | (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_LINELENINBITS must be a power of 2");
|
||||
|
|
|
@ -45,7 +45,7 @@ module rvvitbwrapper import cvw::*; #(parameter cvw_t P,
|
|||
|
||||
localparam TOTAL_CSRS = 36;
|
||||
|
||||
// pipeline controlls
|
||||
// pipeline controls
|
||||
logic StallE, StallM, StallW, FlushE, FlushM, FlushW;
|
||||
// required
|
||||
logic [P.XLEN-1:0] PCM;
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
`endif
|
||||
|
||||
//SD-Clock Defines ---------
|
||||
//Use bus clock or a seperate clock
|
||||
//Use bus clock or a separate clock
|
||||
`define SDC_CLK_BUS_CLK
|
||||
//`define SDC_CLK_SEP
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue