Merge branch 'fetch_buffer' of https://github.com/openhwgroup/cvw into configurable_fetch_buffer

This commit is contained in:
Jordan Carlin 2024-11-10 16:21:02 -08:00
commit ad4bc8f450
No known key found for this signature in database
36 changed files with 417 additions and 1676 deletions

View File

@ -88,6 +88,18 @@ foreach my $key (@derivnames) {
open(my $unmod, $configunmod) or die "Could not open file '$configunmod' $!";
open(my $fh, '>>', $config) or die "Could not open file '$config' $!";
# Create symlink to imperas.ic for deriv buildroot
if ($key eq "buildroot") {
my $baseimperas_ic = "$ENV{WALLY}/config/$basederiv{$key}/imperas.ic";
if (! -e $baseimperas_ic) {
my $baseimperas_ic = "$ENV{WALLY}/config/deriv/$basederiv{$key}/config.vh";
}
if (-e $baseimperas_ic) { # If imperas.ic exists for base derivative, create hardlink to it
my $imperas_ic = "$dir/imperas.ic";
system("ln -T $baseimperas_ic $imperas_ic");
}
}
my $datestring = localtime();
my %hit = ();
print $fh "// Config $key automatically derived from $basederiv{$key} on $datestring using derivgen.pl\n";

View File

@ -261,9 +261,6 @@ class TestRunner:
cvw = folder.joinpath("cvw")
self.logger.info(f"cvw is: {cvw}")
# set the WALLY environmental variable to the new repository
os.environ["WALLY"] = str(cvw)
self.cvw = cvw
self.sim_dir = cvw.joinpath("bin")
self.base_parent_dir = folder
@ -292,11 +289,11 @@ class TestRunner:
output_file = self.log_dir.joinpath(f"make-{target}-output.log")
else: output_file = self.log_dir.joinpath(f"make-output.log")
# Execute make with target and cores/2
# Source setup script and execute make with target and cores/2
if target:
command = ["make", target, "--jobs=$(($(nproc)/2))"]
command = [f"source {os.path.join(self.cvw, 'setup.sh')} > /dev/null && make {target} --jobs=$(($(nproc)/2))"]
else:
command = ["make", "--jobs=$(($(nproc)/2))"]
command = [f"source {os.path.join(self.cvw, 'setup.sh')} > /dev/null && make --jobs=$(($(nproc)/2))"]
self.logger.info(f"Command used in directory {makefile_location}: {' '.join(command)}")
@ -305,7 +302,7 @@ class TestRunner:
formatted_datetime = self.current_datetime.strftime("%Y-%m-%d %H:%M:%S")
f.write(formatted_datetime)
f.write("\n\n")
result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True, shell=True)
result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True, shell=True, executable="/bin/bash")
# Execute the command using a subprocess and not save the output
#result = subprocess.run(command, text=True)
@ -334,12 +331,16 @@ class TestRunner:
output_file = self.log_dir.joinpath(f"{test_name}-output.log")
os.chdir(self.sim_dir)
# Source setup script and delete output from log on whatever test command gets run
command = f"source {os.path.join(self.cvw, 'setup.sh')} > /dev/null && "
if test_extensions:
command = [test_type, test_name] + test_extensions
commandext = [test_type, test_name] + test_extensions
self.logger.info(f"Command used to run tests in directory {self.sim_dir}: {test_type} {test_name} {' '.join(test_extensions)}")
else:
command = [test_type, test_name]
commandext = [test_type, test_name]
self.logger.info(f"Command used to run tests in directory {self.sim_dir}: {test_type} {test_name}")
command += " ".join(commandext)
# Execute the command using subprocess and save the output into a file
@ -348,15 +349,15 @@ class TestRunner:
formatted_datetime = self.current_datetime.strftime("%Y-%m-%d %H:%M:%S")
f.write(formatted_datetime)
f.write("\n\n")
result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True)
result = subprocess.run(command, stdout=f, stderr=subprocess.STDOUT, text=True, shell=True, executable="/bin/bash")
except Exception as e:
self.logger.error("There was an error in running the tests in the run_tests function: {e}")
self.logger.error(f"There was an error in running the tests in the run_tests function: {e}")
# Check if the command executed successfuly
if result.returncode or result.returncode == 0:
self.logger.info(f"Test ran successfuly. Test type: {test_type}, test name: {test_name}, test extension: {' '.join(test_extensions)}")
self.logger.info(f"Test ran successfuly. Test name: {test_name}, test extension: {' '.join(test_extensions)}")
return True, output_file
else:
self.logger.error(f"Error making test. Test type: {test_type}, test name: {test_name}, test extension: {' '.join(test_extensions)}")
self.logger.error(f"Error making test. Test name: {test_name}, test extension: {' '.join(test_extensions)}")
return False, output_file

View File

@ -539,7 +539,7 @@ def main():
num_fail = 0
results = {}
for config in configs:
results[config] = pool.apply_async(run_test_case,(config,))
results[config] = pool.apply_async(run_test_case,(config, args.dryrun))
for (config,result) in results.items():
try:
num_fail+=result.get(timeout=TIMEOUT_DUR)

View File

@ -65,7 +65,7 @@ if(args.testsuite.endswith('.elf') and args.elf == ""): # No --elf argument; che
print("ELF file not found: " + args.testsuite)
exit(1)
if(args.lockstep and not args.testsuite.endswith('.elf')):
if(args.lockstep and not args.testsuite.endswith('.elf') and not args.testsuite == "buildroot"):
print(f"Invalid Options. Cannot run a testsuite, {args.testsuite} with lockstep. Must run a single elf.")
exit(1)
@ -90,7 +90,10 @@ else: EnableLog = 0
prefix = ""
if (args.lockstep or args.lockstepverbose or args.fcov or args.fcovimp):
if (args.sim == "questa" or args.sim == "vcs"):
prefix = "IMPERAS_TOOLS=" + WALLY + "/config/"+args.config+"/imperas.ic"
imperasicPath = os.path.join(WALLY, "config", args.config, "imperas.ic")
if not os.path.isfile(imperasicPath): # If config is a derivative, look for imperas.ic in derivative configs
imperasicPath = os.path.join(WALLY, "config", "deriv", args.config, "imperas.ic")
prefix = "IMPERAS_TOOLS=" + imperasicPath
# Force Questa to use 64-bit mode, sometimes it defaults to 32-bit even on 64-bit machines
if (args.sim == "questa"):
prefix = "MTI_VCO_MODE=64 " + prefix

View File

@ -10,6 +10,13 @@
`include "RV32M_coverage.svh"
`include "RV32F_coverage.svh"
`include "RV32D_coverage.svh"
`include "RV32Zba_coverage.svh"
`include "RV32Zbb_coverage.svh"
`include "RV32Zbc_coverage.svh"
`include "RV32Zbs_coverage.svh"
`include "RV32Zbkb_coverage.svh"
`include "RV32Zbkc_coverage.svh"
`include "RV32Zbkx_coverage.svh"
`include "RV32ZfaF_coverage.svh"
`include "RV32ZfaD_coverage.svh"
`include "RV32ZfaZfh_coverage.svh"
@ -22,6 +29,11 @@
`include "RV32ZcbZbb_coverage.svh"
`include "RV32Zcf_coverage.svh"
`include "RV32Zcd_coverage.svh"
`include "RV32Zaamo_coverage.svh"
`include "RV32Zalrsc_coverage.svh"
`include "RV32Zknd_coverage.svh"
`include "RV32Zkne_coverage.svh"
`include "RV32Zknh_coverage.svh"
// Privileged extensions
`include "ZicsrM_coverage.svh"

View File

@ -10,6 +10,13 @@
`include "RV64M_coverage.svh"
`include "RV64F_coverage.svh"
`include "RV64D_coverage.svh"
`include "RV64Zba_coverage.svh"
`include "RV64Zbb_coverage.svh"
`include "RV64Zbc_coverage.svh"
`include "RV64Zbs_coverage.svh"
`include "RV64Zbkb_coverage.svh"
`include "RV64Zbkc_coverage.svh"
`include "RV64Zbkx_coverage.svh"
`include "RV64ZfaF_coverage.svh"
`include "RV32ZfaD_coverage.svh"
`include "RV32ZfaZfh_coverage.svh"
@ -22,6 +29,18 @@
`include "RV64ZcbZbb_coverage.svh"
`include "RV64ZcbZba_coverage.svh"
`include "RV64Zcd_coverage.svh"
`include "RV64Zaamo_coverage.svh"
`include "RV64Zalrsc_coverage.svh"
`include "RV64Zknd_coverage.svh"
`include "RV64Zkne_coverage.svh"
`include "RV64Zknh_coverage.svh"
// Privileged extensions
`include "RV64VM_coverage.svh"

View File

@ -1,47 +0,0 @@
#!/bin/bash
usage() { echo "Usage: $0 [-h] [-b <path/to/buildroot>] [-d <path/to/device tree>]" 1>&2; exit 1; }
help() {
echo "Usage: $0 [OPTIONS] <device>"
echo " -b <path/to/buildroot> get images from given buildroot"
echo " -d <device tree name> specify device tree to use"
exit 0;
}
# defaults
imageDir=$RISCV/buildroot/output/images
DEVICE_TREE=${imageDir}/wally-virt.dtb
# Process options and arguments. The following code grabs the single
# sdcard device argument no matter where it is in the positional
# parameters list.
ARGS=()
while [ $OPTIND -le "$#" ] ; do
if getopts "hb:d:" arg ; then
case "${arg}" in
h) help
;;
b) BUILDROOT=${OPTARG}
;;
d) DEVICE_TREE=${OPTARG}
;;
esac
else
ARGS+=("${!OPTIND}")
((OPTIND++))
fi
done
# File location variables
imageDir=$BUILDROOT/output/images
tvDir=$RISCV/linux-testvectors
tcpPort=1239
# QEMU Simulation
qemu-system-riscv64 \
-M virt -m 256M -dtb $DEVICE_TREE \
-nographic \
-bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro"
-singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on

View File

@ -1,6 +0,0 @@
#!/bin/bash
for index in {450..500};
do
instrs=$(($index*1000000))
echo "y" | nice -n 5 ./genCheckpoint.sh $instrs
done

View File

@ -1,21 +0,0 @@
#!/bin/bash
imageDir=$RISCV/buildroot/output/images
tvDir=$RISCV/linux-testvectors
tcpPort=1239
# QEMU Simulation
qemu-system-riscv64 \
-M virt -dtb $imageDir/wally-virt.dtb \
-nographic \
-bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \
-singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on
# > ./qemu-serial \
# -gdb tcp::$tcpPort -S) \
# & riscv64-unknown-elf-gdb -quiet \
# -ex "set pagination off" \
# -ex "set logging overwrite on" \
# -ex "set logging redirect on" \
# -ex "set confirm off" \
# -ex "target extended-remote :$tcpPort" \
# -ex "maintenance packet Qqemu.PhyMemMode:1" \
# -ex "file $imageDir/vmlinux"

View File

@ -1,74 +0,0 @@
#!/usr/bin/env python3
#
# disassembleBootTrace.py
# David_Harris@hmc.edu 22 November 2023
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
#
# Reads boottrace.log and disassembles the machine code
#
import csv
import os
import re
# read a file from sim/logs/boottrace.log and extract the second comma-separated field containing the instruction
print("Reading boottrace.log")
trace = []
count = 0
with open('../../sim/logs/boottrace.log') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
trace.append(row)
count = count + 1
if count > 50000000:
break
f.close()
print("Disassembling boottrace.log instructions")
# Write an assembly language file with the machine code
with (open('boottrace.S', 'w')) as f:
f.write('main:\n')
for row in trace:
instr = row[1]
# scrape off leading white space from instr
instr = instr.lstrip()
# check if last character indicates an compressed or uncompressed instruction
lastNibble = instr[-1]
if (lastNibble == '3' or lastNibble == '7' or lastNibble == 'b' or lastNibble == 'f'):
# uncompressed
f.write('.word 0x' + instr + '\n')
else:
# compressed
instr = instr[-4:]
f.write('.hword 0x' + instr + '\n')
f.close()
# Then assemble and disassemble the file
os.system('riscv64-unknown-elf-gcc -march=rv64gqc_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64d -c boottrace.S')
os.system('riscv64-unknown-elf-objdump -D boottrace.o > boottrace.objdump')
# Patch disassembly back into boottrace
print("Inserting disassembly into trace")
dumpedLines = []
with (open('boottrace.objdump', 'r')) as f:
lines = f.readlines()
f.close()
lines = lines[7:] # skip header
p = r'[^:]*:\s*(\S*)\s*(.*)'
for line in lines:
match = re.search(p, line)
if (match):
dump = [match.group(1), match.group(2)]
dumpedLines.append(dump)
linenum = 0
for i in range(len(trace)):
row = trace[i]
row.insert(2, dumpedLines[i][1])
# write trace back to csv file
print("Writing trace back to boottrace_disasm.log")
with (open('boottrace_disasm.log', 'w')) as f:
writer = csv.writer(f)
writer.writerows(trace)
f.close()

View File

@ -1,68 +0,0 @@
#!/usr/bin/env python3
import sys, os
from functools import reduce
################
# Helper Funcs #
################
def tokenize(string):
tokens = []
token = ''
whitespace = 0
prevWhitespace = 0
for char in string:
prevWhitespace = whitespace
whitespace = char in ' \t\n'
if (whitespace):
if ((not prevWhitespace) and (token != '')):
tokens.append(token)
token = ''
else:
token = token + char
return tokens
def strip0x(num):
return num[2:]
def stripZeroes(num):
num = num.strip('0')
if num=='':
return '0'
else:
return num
#############
# Main Code #
#############
print("Begin filtering traps down to just external interrupts.")
# Parse Args
if len(sys.argv) != 2:
sys.exit('Error filterTrapsToInterrupts.py expects 1 arg: <path_to_testvector_dir>')
tvDir = sys.argv[1]+'/'
trapsFilePath = tvDir+'traps.txt'
if not os.path.exists(trapsFilePath):
sys.exit('Error input file '+trapsFilePath+'not found')
with open(tvDir+'interrupts.txt', 'w') as interruptsFile:
with open(trapsFilePath, 'r') as trapsFile:
while True:
trap = trapsFile.readline()
if trap == '':
break
trapType = trap.split(' ')[-1]
if ('interrupt' in trap) and (('external' in trapType) or ('m_timer' in trapType)): # no s_timer because that is not controlled by CLINT
interruptsFile.write(trap) # overall line
interruptsFile.write(trapsFile.readline()) # attempted instr count
interruptsFile.write(trapsFile.readline()) # hart #
interruptsFile.write(trapsFile.readline()) # asynchronous
interruptsFile.write(trapsFile.readline()) # cause
interruptsFile.write(trapsFile.readline()) # epc
interruptsFile.write(trapsFile.readline()) # tval
interruptsFile.write(trapsFile.readline()) # description
else:
for i in range(7):
trapsFile.readline()
print("Finished filtering traps down to just external interrupts.")

View File

@ -1,146 +0,0 @@
#!/bin/bash
tcpPort=1238
imageDir=$RISCV/buildroot/output/images
tvDir=$RISCV/linux-testvectors
recordFile="$tvDir/all.qemu"
traceFile="$tvDir/all.txt"
# Parse Commandline Arg
if [ "$#" -ne 1 ]; then
echo "genCheckpoint requires 1 argument: <num instrs>" >&2
exit 1
fi
instrs=$1
if ! [ "$instrs" -eq "$instrs" ] 2> /dev/null
then
echo "Error expected integer number of instructions, got $instrs" >&2
exit 1
fi
checkPtDir="$tvDir/checkpoint$instrs"
outTraceFile="$checkPtDir/all.txt"
rawStateFile="$checkPtDir/stateGDB.txt"
rawUartStateFile="$checkPtDir/uartStateGDB.txt"
uartStateFile="$checkPtDir/checkpoint-UART"
rawPlicStateFile="$checkPtDir/plicStateGDB.txt"
plicStateFile="$checkPtDir/checkpoint-PLIC"
rawRamFile="$checkPtDir/ramGDB.bin"
ramFile="$checkPtDir/ram.bin"
read -p "This scripts is going to create a checkpoint at $instrs instrs.
Is that what you wanted? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo "Creating checkpoint at $instrs instructions!"
if [ ! -d "$tvDir" ]; then
echo "Error: linux testvector directory $tvDir not found!">&2
echo "Please create it. For example:">&2
echo " sudo mkdir -p $tvDir">&2
exit 1
fi
test -w $tvDir
if [ ! $? -eq 0 ]; then
echo "Error: insuffcient write privileges for linux testvector directory $tvDir !">&2
echo "Please chmod it. For example:">&2
echo " sudo chmod -R a+rw $tvDir">&2
exit 1
fi
mkdir -p $checkPtDir
# Identify instruction in trace
instr=$(sed "${instrs}q;d" "$traceFile")
echo "Found ${instrs}th instr: ${instr}"
pc=$(echo $instr | cut -d " " -f1)
asm=$(echo $instr | cut -d " " -f2)
occurences=$(($(head -$instrs "$traceFile" | grep -c "${pc} ${asm}")-1))
echo "It occurs ${occurences} times before the ${instrs}th instr."
# Create GDB script because GDB is terrible at handling arguments / variables
cat > genCheckpoint.gdb <<- end_of_script
set pagination off
set logging overwrite on
set logging redirect on
set confirm off
target extended-remote :$tcpPort
maintenance packet Qqemu.PhyMemMode:1
file $imageDir/vmlinux
# Step over reset vector into actual code
stepi 100
shell echo \"GDB proceeding to checkpoint at $instrs instrs, pc $pc\"
b *0x$pc
ignore 1 $occurences
c
shell echo \"Reached checkpoint at $instrs instrs\"
shell echo \"GDB storing CPU state to $rawStateFile\"
set logging file $rawStateFile
set logging on
info all-registers
set logging off
shell echo \"GDB storing UART state to $rawUartStateFile\"
# Save value of LCR
set \$LCR=*0x10000003 & 0xff
set logging file $rawUartStateFile
set logging on
# Change LCR to set DLAB=0 to be able to read RBR and IER
set {char}0x10000003 &= ~0x80
x/1xb 0x10000000
x/1xb 0x10000001
x/1xb 0x10000002
# But log original value of LCR
printf "0x10000003:\t0x%02x\n", \$LCR
x/1xb 0x10000004
x/1xb 0x10000005
x/1xb 0x10000006
x/1xb 0x10000007
set logging off
shell echo \"GDB storing PLIC state to $rawPlicStateFile\"
shell echo \"Note: this dumping assumes a maximum of 63 PLIC sources\"
set logging file $rawPlicStateFile
set logging on
# Priority Levels for sources 1 thru 63
x/63xw 0x0C000004
# Interrupt Enables for sources 1 thru 63 for contexts 0 and 1
x/2xw 0x0C002000
x/2xw 0x0C002080
# Global Priority Threshold for contexts 0 and 1
x/1xw 0x0C200000
x/1xw 0x0C201000
set logging off
shell echo \"GDB storing RAM to $rawRamFile\"
dump binary memory $rawRamFile 0x80000000 0x87ffffff
kill
q
end_of_script
# GDB+QEMU
echo "Starting QEMU in replay mode with attached GDB script at $(date +%H:%M:%S)"
(qemu-system-riscv64 \
-M virt -dtb $imageDir/wally-virt.dtb \
-nographic \
-bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \
-singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on,rr=replay,rrfile=$recordFile \
-gdb tcp::$tcpPort -S \
1>./qemu-serial) \
& riscv64-unknown-elf-gdb --quiet -x genCheckpoint.gdb
echo "Completed GDB script at $(date +%H:%M:%S)"
# Post-Process GDB outputs
./parseState.py "$checkPtDir"
./parseUartState.py "$checkPtDir"
./parsePlicState.py "$checkPtDir"
echo "Changing Endianness at $(date +%H:%M:%S)"
make fixBinMem
./fixBinMem "$rawRamFile" "$ramFile"
echo "Copying over a truncated trace"
tail -n+$instrs $traceFile > $outTraceFile
echo "Checkpoint completed at $(date +%H:%M:%S)"
echo "You may want to restrict write access to $tvDir now and give cad ownership of it."
echo "Run the following:"
echo " sudo chown -R cad:cad $tvDir"
echo " sudo chmod -R go-w $tvDir"
fi

View File

@ -1,38 +0,0 @@
#!/bin/bash
imageDir=$RISCV/buildroot/output/images
tvDir=$RISCV/linux-testvectors
recordFile="$tvDir/all.qemu"
DEVICE_TREE=${imageDir}/wally-virt.dtb
read -p "Warning: running this script will overwrite $recordFile
Would you like to proceed? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]
then
if [ ! -d "$tvDir" ]; then
echo "Error: linux testvector directory $tvDir not found!">&2
echo "Please create it. For example:">&2
echo " sudo mkdir -p $tvDir">&2
exit 1
fi
test -w $tvDir
if [ ! $? -eq 0 ]; then
echo "Error: insuffcient write privileges for linux testvector directory $tvDir !">&2
echo "Please chmod it. For example:">&2
echo " sudo chmod -R a+rw $tvDir">&2
exit 1
fi
echo "Launching QEMU in record mode!"
qemu-system-riscv64 \
-M virt -m 256M -dtb $DEVICE_TREE \
-nographic \
-bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \
-singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on,rr=record,rrfile=$recordFile
echo "genRecording.sh completed!"
echo "You may want to restrict write access to $tvDir now and give cad ownership of it."
echo "Run the following:"
echo " sudo chown -R cad:cad $tvDir"
echo " sudo chmod -R go-w $tvDir"
fi

View File

@ -1,54 +0,0 @@
#!/bin/bash
tcpPort=1234
imageDir=$RISCV/buildroot/output/images
tvDir=$RISCV/linux-testvectors
recordFile="$tvDir/all.qemu"
traceFile="$tvDir/all.txt"
trapsFile="$tvDir/traps.txt"
interruptsFile="$tvDir/interrupts.txt"
DEVICE_TREE=${imageDir}/wally-virt.dtb
read -p "Warning: running this script will overwrite the contents of:
* $traceFile
* $trapsFile
* $interruptsFile
Would you like to proceed? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]
then
if [ ! -d "$tvDir" ]; then
echo "Error: linux testvector directory $tvDir not found!">&2
echo "Please create it. For example:">&2
echo " sudo mkdir -p $tvDir">&2
exit 1
fi
test -w $tvDir
if [ ! $? -eq 0 ]; then
echo "Error: insuffcient write privileges for linux testvector directory $tvDir !">&2
echo "Please chmod it. For example:">&2
echo " sudo chmod -R a+rw $tvDir">&2
exit 1
fi
touch $traceFile
touch $trapsFile
touch $interruptsFile
# QEMU Simulation
echo "Launching QEMU in replay mode!"
(qemu-system-riscv64 \
-M virt -m 256M -dtb $DEVICE_TREE \
-nographic \
-bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \
-singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on,rr=replay,rrfile=$recordFile \
-d nochain,cpu,in_asm,int \
2>&1 >./qemu-serial | ./parseQEMUtoGDB.py | ./parseGDBtoTrace.py $trapsFile > $traceFile)
./filterTrapsToInterrupts.py $tvDir
echo "genTrace.sh completed!"
echo "You may want to restrict write access to $tvDir now and give cad ownership of it."
echo "Run the following:"
echo " sudo chown -R cad:cad $tvDir"
echo " sudo chmod -R go-w $tvDir"
fi

View File

@ -1,243 +0,0 @@
#!/usr/bin/env python3
import sys, fileinput, re
# Rose Thompson
# July 27, 2021
# Rewrite of the linux trace parser.
InstrStartDelim = '=>'
InstrEndDelim = '-----'
#InputFile = 'noparse.txt'
#InputFile = sys.stdin
#InputFile = 'temp.txt'
#OutputFile = 'parsedAll.txt'
HUMAN_READABLE = False
def toDict(lst):
'Converts the list of register values to a dictionary'
dct= {}
for item in lst:
regTup = item.split()
dct[regTup[0]] = int(regTup[2], 10)
del dct['pc']
return dct
def whichClass(text, Regs):
'Which instruction class?'
#print(text, Regs)
if text[0:2] == 'ld' or text[0:2] == 'lw' or text[0:2] == 'lh' or text[0:2] == 'lb':
return ('load', WhatAddr(text, Regs), None, WhatMemDestSource(text))
elif text[0:2] == 'sd' or text[0:2] == 'sw' or text[0:2] == 'sh' or text[0:2] == 'sb':
return ('store', WhatAddr(text, Regs), WhatMemDestSource(text), None)
elif text[0:3] == 'amo':
return ('amo', WhatAddrAMO(text, Regs), WhatMemDestSource(text), WhatMemDestSource(text))
elif text[0:2] == 'lr':
return ('lr', WhatAddrLR(text, Regs), None, WhatMemDestSource(text))
elif text[0:2] == 'sc':
return ('sc', WhatAddrSC(text, Regs), WhatMemDestSource(text), None)
else:
return ('other', None, None, None)
def whatChanged(dct0, dct1):
'Compares two dictionaries of instrution registers and indicates which registers changed'
dct = {}
for key in dct0:
if (dct1[key] != dct0[key]):
dct[key] = dct1[key]
return dct
def WhatMemDestSource(text):
''''What is the destination register. Used to compute where the read data is
on a load or the write data on a store.'''
return text.split()[1].split(',')[0]
def WhatAddr(text, Regs):
'What is the data memory address?'
Imm = text.split(',')[1]
(Imm, Src) = Imm.split('(')
Imm = int(Imm.strip(), 10)
Src = Src.strip(')').strip()
RegVal = Regs[Src]
return Imm + RegVal
def WhatAddrAMO(text, Regs):
'What is the data memory address?'
Src = text.split('(')[1]
Src = Src.strip(')').strip()
return Regs[Src]
def WhatAddrLR(text, Regs):
'What is the data memory address?'
Src = text.split('(')[1]
Src = Src.strip(')').strip()
return Regs[Src]
def WhatAddrSC(text, Regs):
'What is the data memory address?'
Src = text.split('(')[1]
Src = Src.strip(')').strip()
return Regs[Src]
def PrintInstr(instr):
if instr[2] == None:
return
ChangedRegisters = instr[4]
GPR = ''
CSR = []
for key in ChangedRegisters:
# filter out csr which are not checked.
if(key in RegNumber):
if(RegNumber[key] < 32):
# GPR
if(HUMAN_READABLE):
GPR = '{:-2d} {:016x}'.format(RegNumber[key], ChangedRegisters[key])
else:
GPR = '{:d} {:x}'.format(RegNumber[key], ChangedRegisters[key])
else:
if(HUMAN_READABLE):
CSR.extend([key, '{:016x}'.format(ChangedRegisters[key])])
else:
CSR.extend([key, '{:x}'.format(ChangedRegisters[key])])
CSRStr = ' '.join(CSR)
#print(instr)
if (HUMAN_READABLE == True):
outString='{:016x} {:08x} {:25s}'.format(instr[0], instr[1], instr[2])
if(len(GPR) != 0):
outString+=' GPR {}'.format(GPR)
if(instr[3] == 'load' or instr[3] == 'lr'):
outString+=' MemR {:016x} {:016x} {:016x}'.format(instr[5], 0, instr[7])
if(instr[3] == 'store'):
outString+='\t\t\t MemW {:016x} {:016x} {:016x}'.format(instr[5], instr[6], 0)
if(len(CSR) != 0):
outString+=' CSR {}'.format(CSRStr)
else:
outString='{:x} {:x} {:s}'.format(instr[0], instr[1], instr[2].replace(' ', '_'))
if(len(GPR) != 0):
outString+=' GPR {}'.format(GPR)
if(instr[3] == 'load' or instr[3] == 'lr'):
outString+=' MemR {:x} {:x} {:x}'.format(instr[5], 0, instr[7])
if(instr[3] == 'store'):
outString+=' MemW {:x} {:x} {:x}'.format(instr[5], instr[6], 0)
if(len(CSR) != 0):
outString+=' CSR {}'.format(CSRStr)
outString+='\n'
return outString
# =========
# Main Code
# =========
# Parse argument for interrupt file
if len(sys.argv) != 2:
sys.exit('Error parseGDBtoTrace.py expects 1 arg:\n <interrupt filename>>')
interruptFname = sys.argv[1]
# reg number
RegNumber = {'zero': 0, 'ra': 1, 'sp': 2, 'gp': 3, 'tp': 4, 't0': 5, 't1': 6, 't2': 7, 's0': 8, 's1': 9, 'a0': 10, 'a1': 11, 'a2': 12, 'a3': 13, 'a4': 14, 'a5': 15, 'a6': 16, 'a7': 17, 's2': 18, 's3': 19, 's4': 20, 's5': 21, 's6': 22, 's7': 23, 's8': 24, 's9': 25, 's10': 26, 's11': 27, 't3': 28, 't4': 29, 't5': 30, 't6': 31, 'mhartid': 32, 'mstatus': 33, 'mip': 34, 'mie': 35, 'mideleg': 36, 'medeleg': 37, 'mtvec': 38, 'stvec': 39, 'mepc': 40, 'sepc': 41, 'mcause': 42, 'scause': 43, 'mtval': 44, 'stval': 45, 'mscratch': 46, 'sscratch': 47, 'satp': 48}
# initial state
CurrentInstr = ['0', '0', None, 'other', {'zero': 0, 'ra': 0, 'sp': 0, 'gp': 0, 'tp': 0, 't0': 0, 't1': 0, 't2': 0, 's0': 0, 's1': 0, 'a0': 0, 'a1': 0, 'a2': 0, 'a3': 0, 'a4': 0, 'a5': 0, 'a6': 0, 'a7': 0, 's2': 0, 's3': 0, 's4': 0, 's5': 0, 's6': 0, 's7': 0, 's8': 0, 's9': 0, 's10': 0, 's11': 0, 't3': 0, 't4': 0, 't5': 0, 't6': 0, 'mhartid': 0, 'mstatus': 0, 'mip': 0, 'mie': 0, 'mideleg': 0, 'medeleg': 0, 'mtvec': 0, 'stvec': 0, 'mepc': 0, 'sepc': 0, 'mcause': 0, 'scause': 0, 'mtval': 0, 'stval': 0, 'mscratch': 0, 'sscratch': 0, 'satp': 0}, {}, None, None, None]
#with open (InputFile, 'r') as InputFileFP:
#lines = InputFileFP.readlines()
lineNum = 0
StartLine = 0
EndLine = 0
numInstrs = 0
#instructions = []
MemAdr = 0
lines = []
interrupts=open(interruptFname,'w')
interrupts.close()
prevInstrOutString=''
currInstrOutString=''
for line in fileinput.input('-'):
if line.startswith('riscv_cpu_do_interrupt'):
with open(interruptFname,'a') as interrupts:
# Write line
# Example line: hart:0, async:0, cause:0000000000000002, epc:0x0000000080008548, tval:0x0000000000000000, desc=illegal_instruction
interrupts.write(line)
# Write instruction count
interrupts.write(str(numInstrs)+'\n')
# Convert line to rows of info for easier Verilog parsing
vals=line.strip('riscv_cpu_do_interrupt: ').strip('\n').split(',')
vals=[val.split(':')[-1].strip(' ') for val in vals]
vals=[val.split('=')[-1].strip(' ') for val in vals]
for val in vals:
interrupts.write(val+'\n')
continue
lines.insert(lineNum, line)
if InstrStartDelim in line:
lineNum = 0
StartLine = lineNum
elif InstrEndDelim in line:
EndLine = lineNum
(InstrBits, text) = lines[StartLine].split(':')
InstrBits = int(InstrBits.strip('=> '), 16)
text = text.strip()
PC = int(lines[StartLine+1].split(':')[0][2:], 16)
Regs = toDict(lines[StartLine+2:EndLine])
(Class, Addr, WriteReg, ReadReg) = whichClass(text, Regs)
#print("CWR", Class, WriteReg, ReadReg)
PreviousInstr = CurrentInstr
Changed = whatChanged(PreviousInstr[4], Regs)
if (ReadReg !=None): ReadData = ReadReg
else: ReadData = None
if (WriteReg !=None): WriteData = WriteReg
else: WriteData = None
CurrentInstr = [PC, InstrBits, text, Class, Regs, Changed, Addr, WriteData, ReadData]
#print(CurrentInstr[0:4], PreviousInstr[5], CurrentInstr[6:7], PreviousInstr[8])
# pc, instrbits, text and class come from the last line.
MoveInstrToRegWriteLst = PreviousInstr[0:4]
# updated registers come from the current line.
MoveInstrToRegWriteLst.append(CurrentInstr[5]) # destination regs
# memory address if present comes from the last line.
MoveInstrToRegWriteLst.append(PreviousInstr[6]) # MemAdrM
# write data from the previous line
#MoveInstrToRegWriteLst.append(PreviousInstr[7]) # WriteDataM
if (PreviousInstr[7] != None):
MoveInstrToRegWriteLst.append(Regs[PreviousInstr[7]]) # WriteDataM
else:
MoveInstrToRegWriteLst.append(None)
# read data from the current line
#MoveInstrToRegWriteLst.append(PreviousInstr[8]) # ReadDataM
if (PreviousInstr[8] != None):
MoveInstrToRegWriteLst.append(Regs[PreviousInstr[8]]) # ReadDataM
else:
MoveInstrToRegWriteLst.append(None)
lines.clear()
#instructions.append(MoveInstrToRegWriteLst)
prevInstrOutString = currInstrOutString
currInstrOutString = PrintInstr(MoveInstrToRegWriteLst)
# Remove duplicates
if (PreviousInstr[0] != CurrentInstr[0]) and (currInstrOutString != None):
sys.stdout.write(currInstrOutString)
numInstrs += 1
if (numInstrs % 1e5 == 0):
sys.stderr.write('GDB trace parser reached '+str(numInstrs/1.0e6)+' million instrs.\n')
sys.stderr.flush()
lineNum += 1
#for instruction in instructions[1::]:
#with open(OutputFile, 'w') as OutputFileFP:
# print('opened file')

View File

@ -1,106 +0,0 @@
#!/usr/bin/env python3
import sys, os
from functools import reduce
################
# Helper Funcs #
################
def tokenize(string):
tokens = []
token = ''
whitespace = 0
prevWhitespace = 0
for char in string:
prevWhitespace = whitespace
whitespace = char in ' \t\n'
if (whitespace):
if ((not prevWhitespace) and (token != '')):
tokens.append(token)
token = ''
else:
token = token + char
return tokens
def strip0x(num):
return num[2:]
def stripZeroes(num):
num = int(num,16)
return hex(num)[2:]
#############
# Main Code #
#############
print("Begin parsing PLIC state.")
# Parse Args
if len(sys.argv) != 2:
sys.exit('Error parsePlicState.py expects 1 arg: <path_to_checkpoint_dir>')
outDir = sys.argv[1]+'/'
rawPlicStateFile = outDir+'plicStateGDB.txt'
if not os.path.exists(rawPlicStateFile):
sys.exit('Error input file '+rawPlicStateFile+'not found')
with open(rawPlicStateFile, 'r') as rawPlicStateFile:
plicIntPriorityArray = [] # iterates over number of different sources
# 0x0C000004 thru 0x0C000010
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000014 thru 0x0C000020
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000024 thru 0x0C000030
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000034 thru 0x0C000040
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000044 thru 0x0C000050
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000054 thru 0x0C000060
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000064 thru 0x0C000070
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000074 thru 0x0C000080
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000084 thru 0x0C000090
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000094 thru 0x0C0000a0
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C0000a4 thru 0x0C0000b0
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C0000b4 thru 0x0C0000c0
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C0000c4 thru 0x0C0000d0
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C0000d4 thru 0x0C0000e0
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C0000e4 thru 0x0C0000f0
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C0000f4 thru 0x0C0000fc
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
plicIntEnableArray = [] # iterates over number of different contexts
# 0x0C020000 thru 0x0C020004
plicIntEnable = tokenize(rawPlicStateFile.readline())[1:]
plicIntEnable = map(strip0x,plicIntEnable)
plicIntEnableArray.append(reduce(lambda x,y: y+x,plicIntEnable))
# 0x0C020080 thru 0x0C020084
plicIntEnable = tokenize(rawPlicStateFile.readline())[1:]
plicIntEnable = map(strip0x,plicIntEnable)
plicIntEnableArray.append(reduce(lambda x,y: y+x,plicIntEnable))
plicIntPriorityThresholdArray = [] # iterates over number of different contexts
# 0x0C200000
plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C201000
plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:]
with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile:
for word in plicIntPriorityArray:
outFile.write(stripZeroes(word[2:])+'\n')
with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile:
for word in plicIntEnableArray:
outFile.write(stripZeroes(word[2:])+'\n')
with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile:
for word in plicIntPriorityThresholdArray:
outFile.write(stripZeroes(word[2:])+'\n')
print("Finished parsing PLIC state!")

View File

@ -1,145 +0,0 @@
#!/usr/bin/env python3
import fileinput, sys
parseState = "idle"
beginPageFault = 0
inPageFault = 0
endPageFault = 0
CSRs = {}
pageFaultCSRs = {}
regs = {}
pageFaultRegs = {}
instrs = {}
instrCount = 0
returnAdr = 0
sys.stderr.write("reminder: parse_qemu.py takes input from stdin\n")
def printPC(l):
global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs, instrCount
if not inPageFault:
inst = l.split()
if len(inst) > 3:
print(f'=> {inst[1]}:\t{inst[2]} {inst[3]}')
else:
print(f'=> {inst[1]}:\t{inst[2]}')
print(f'{inst[0]} 0x{inst[1]}')
instrCount += 1
if ((instrCount % 100000) == 0):
sys.stderr.write("QEMU parser reached "+str(instrCount)+" instrs\n")
def printCSRs():
global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs
global interrupt_line
if not inPageFault:
for (csr,val) in CSRs.items():
print('{}{}{:#x} {}'.format(csr, ' '*(15-len(csr)), val, val))
print('-----') # end of current instruction
if len(interrupt_line)>0: # squish interrupts in between instructions
print(interrupt_line)
interrupt_line=""
def parseCSRs(l):
global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs
if l.strip() and (not l.startswith("Disassembler")) and (not l.startswith("Please")):
# If we've hit the register file
if l.startswith(' x0/zero'):
parseState = "regFile"
if not inPageFault:
instr = instrs[CSRs["pc"]]
printPC(instr)
parseRegs(l)
# If we've hit a CSR
else:
csr = l.split()[0]
val = int(l.split()[1],16)
# Commented out this conditional because the pageFault instrs don't corrupt CSRs
#if inPageFault:
# Not sure if these CSRs should be updated or not during page fault.
#if l.startswith("mstatus") or l.startswith("mepc") or l.startswith("mcause") or l.startswith("mtval") or l.startswith("sepc") or l.startswith("scause") or l.startswith("stval"):
# We do update some CSRs
# CSRs[csr] = val
#else:
# Others we preserve until changed later
# pageFaultCSRs[csr] = val
#elif pageFaultCSRs and (csr in pageFaultCSRs):
# if (val != pageFaultCSRs[csr]):
# del pageFaultCSRs[csr]
# CSRs[csr] = val
#else:
# CSRs[csr] = val
#
# However SEPC and STVAL do get corrupted upon exiting
if endPageFault and ((csr == 'sepc') or (csr == 'stval')):
CSRs[csr] = returnAdr
pageFaultCSRs[csr] = val
elif pageFaultCSRs and (csr in pageFaultCSRs):
if (val != pageFaultCSRs[csr]):
del pageFaultCSRs[csr]
CSRs[csr] = val
else:
CSRs[csr] = val
def parseRegs(l):
global parseState, inPageFault, CSRs, pageFaultCSRs, regs, pageFaultCSRs, instrs, pageFaultRegs
if "pc" in l:
printCSRs()
# New non-disassembled instruction
parseState = "CSRs"
parseCSRs(l)
elif l.startswith('--------'):
# End of disassembled instruction
printCSRs()
parseState = "idle"
else:
s = l.split()
for i in range(0,len(s),2):
if '/' in s[i]:
reg = s[i].split('/')[1]
val = int(s[i+1], 16)
if inPageFault:
pageFaultRegs[reg] = val
else:
if pageFaultRegs and (reg in pageFaultRegs):
if (val != pageFaultRegs[reg]):
del pageFaultRegs[reg]
regs[reg] = val
else:
regs[reg] = val
val = regs[reg]
print('{}{}{:#x} {}'.format(reg, ' '*(15-len(reg)), val, val))
else:
sys.stderr.write("Whoops. Expected a list of reg file regs; got:\n"+l)
#############
# Main Code #
#############
interrupt_line=""
for l in fileinput.input():
#sys.stderr.write(l)
if l.startswith('riscv_cpu_do_interrupt'):
sys.stderr.write(l)
interrupt_line = l.strip('\n')
elif l.startswith('qemu-system-riscv64: QEMU: Terminated via GDBstub'):
break
elif l.startswith('IN:'):
# New disassembled instr
parseState = "instr"
elif (parseState == "instr") and l.startswith('0x'):
# New instruction
if "out of bounds" in l:
sys.stderr.write("Detected QEMU page fault error\n")
beginPageFault = not inPageFault
if beginPageFault:
returnAdr = int(l.split()[0][2:-1], 16)
sys.stderr.write('Saving SEPC of '+hex(returnAdr)+'\n')
inPageFault = 1
else:
endPageFault = inPageFault
inPageFault = 0
adr = int(l.split()[0][2:-1], 16)
instrs[adr] = l
parseState = "CSRs"
elif parseState == "CSRs":
parseCSRs(l)
elif parseState == "regFile":
parseRegs(l)

View File

@ -1,99 +0,0 @@
#!/usr/bin/env python3
import sys, os
################
# Helper Funcs #
################
def tokenize(string):
tokens = []
token = ''
whitespace = 0
prevWhitespace = 0
for char in string:
prevWhitespace = whitespace
whitespace = char in ' \t\n'
if (whitespace):
if ((not prevWhitespace) and (token != '')):
tokens.append(token)
token = ''
else:
token = token + char
return tokens
#############
# Main Code #
#############
print("Begin parsing CPU state.")
# Parse Args
if len(sys.argv) != 2:
sys.exit('Error parseState.py expects 1 arg:\n parseState.py <path_to_checkpoint_dir>')
outDir = sys.argv[1]+'/'
stateGDBpath = outDir+'stateGDB.txt'
if not os.path.exists(stateGDBpath):
sys.exit('Error input file '+stateGDBpath+'not found')
singleCSRs = ['pc','mip','mie','mscratch','mcause','mepc','mtvec','medeleg','mideleg','sscratch','scause','sepc','stvec','sedeleg','sideleg','satp','mstatus','priv','sie','sip','sstatus']
# priv (current privilege mode) isn't technically a CSR but we can log it with the same machinery
thirtyTwoBitCSRs = ['mcounteren','scounteren']
listCSRs = ['hpmcounter','pmpaddr']
pmpcfg = ['pmpcfg']
# Initialize List CSR files to empty
# (because later we'll open them in append mode)
for csr in listCSRs+pmpcfg:
outFileName = 'checkpoint-'+csr.upper()
outFile = open(outDir+outFileName, 'w')
outFile.close()
# Initial State for Main Loop
currState = 'regFile'
regFileIndex = 0
outFileName = 'checkpoint-RF'
outFile = open(outDir+outFileName, 'w')
# Main Loop
with open(stateGDBpath, 'r') as stateGDB:
for line in stateGDB:
line = tokenize(line)
name = line[0]
val = line[1][2:]
if (currState == 'regFile'):
if (regFileIndex == 0 and name != 'zero'):
print('Whoops! Expected regFile registers to come first, starting with zero')
exit(1)
if (name != 'zero'):
# Wally doesn't need to know zero=0
outFile.write(val+'\n')
regFileIndex += 1
if (regFileIndex == 32):
outFile.close()
currState = 'CSRs'
elif (currState == 'CSRs'):
if name in singleCSRs:
outFileName = 'checkpoint-'+name.upper()
outFile = open(outDir+outFileName, 'w')
outFile.write(val+'\n')
outFile.close()
elif name in thirtyTwoBitCSRs:
outFileName = 'checkpoint-'+name.upper()
outFile = open(outDir+outFileName, 'w')
val = int(val,16) & 0xffffffff
outFile.write(hex(val)[2:]+'\n')
outFile.close()
elif name.strip('0123456789') in listCSRs:
outFileName = 'checkpoint-'+name.upper().strip('0123456789')
outFile = open(outDir+outFileName, 'a')
outFile.write(val+'\n')
outFile.close()
elif name.strip('0123456789') in pmpcfg:
outFileName = 'checkpoint-'+name.upper().strip('0123456789')
outFile = open(outDir+outFileName, 'a')
fourPmp = int(val,16)
for i in range(0,4):
byte = (fourPmp >> 8*i) & 0xff
outFile.write(hex(byte)[2:]+'\n')
outFile.close()
print("Finished parsing CPU state!")

View File

@ -1,50 +0,0 @@
#!/usr/bin/env python3
import sys, os
################
# Helper Funcs #
################
def tokenize(string):
tokens = []
token = ''
whitespace = 0
prevWhitespace = 0
for char in string:
prevWhitespace = whitespace
whitespace = char in ' \t\n'
if (whitespace):
if ((not prevWhitespace) and (token != '')):
tokens.append(token)
token = ''
else:
token = token + char
return tokens
#############
# Main Code #
#############
print("Begin parsing UART state.")
# Parse Args
if len(sys.argv) != 2:
sys.exit('Error parseUartState.py expects 1 arg: <path_to_checkpoint_dir>')
outDir = sys.argv[1]+'/'
rawUartStateFile = outDir+'uartStateGDB.txt'
if not os.path.exists(rawUartStateFile):
sys.exit('Error input file '+rawUartStateFile+'not found')
with open(rawUartStateFile, 'r') as rawUartStateFile:
uartBytes = []
for i in range(0,8):
uartBytes += tokenize(rawUartStateFile.readline())[1:]
with open(outDir+'checkpoint-UART_IER', 'w') as outFile:
outFile.write(uartBytes[1][2:])
with open(outDir+'checkpoint-UART_LCR', 'w') as outFile:
outFile.write(uartBytes[3][2:])
with open(outDir+'checkpoint-UART_MCR', 'w') as outFile:
outFile.write(uartBytes[4][2:])
with open(outDir+'checkpoint-UART_SCR', 'w') as outFile:
outFile.write(uartBytes[7][2:])
print("Finished parsing UART state!")

View File

@ -248,9 +248,9 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
// coverage off
// Not covered in testing because rv64gc is not RV64Q or RV32D
7'b1011001: if (P.ZFA_SUPPORTED & P.XLEN == 32 & P.D_SUPPORTED & Funct3D == 3'b000)
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fmvp.d.x (Zfa)
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0_1_0; // fmvp.d.x (Zfa)
7'b1011011: if (P.ZFA_SUPPORTED & P.XLEN == 64 & P.Q_SUPPORTED & Funct3D == 3'b000)
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fmvp.q.x (Zfa)
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0_1_0; // fmvp.q.x (Zfa)
// coverage on
endcase
endcase

View File

@ -47,19 +47,6 @@ module fetchbuffer import cvw::*; #(parameter cvw_t P) (
flopenl #(32) f1 (.clk, .load(reset | FlushD), .en(WritePtr[1]), .d(WriteData), .val(nop), .q(Readf1));
flopenl #(32) f2 (.clk, .load(reset | FlushD), .en(WritePtr[2]), .d(WriteData), .val(nop), .q(Readf2));
// always_comb begin : readMuxes
// // Mux read data from the three registers
// case (ReadPtr)
// 3'b001: ReadFetchBuffer = Readf0;
// 3'b010: ReadFetchBuffer = Readf1;
// 3'b100: ReadFetchBuffer = Readf2;
// default: ReadFetchBuffer = nop; // just in case?
// endcase
// // issue nop when appropriate
// ReadData = Empty ? nop : ReadFetchBuffer;
// end
// Fetch buffer entries anded with read ptr for AO Muxing
logic [31:0] DaoArr [2:0];
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Make parameterizable

View File

@ -48,7 +48,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
output logic SPICLK
);
// register map
// register map
localparam SPI_SCKDIV = 8'h00;
localparam SPI_SCKMODE = 8'h04;
localparam SPI_CSID = 8'h10;
@ -85,11 +85,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
// SPI Controller signals
logic SCLKenable;
logic EndOfFrame;
logic EndOfFrameDelay;
logic Transmitting;
logic InactiveState;
logic [3:0] FrameLength;
// Starting Transmission and restarting SCLKenable
logic ResetSCLKenable;
logic TransmitStart;
logic TransmitStartD;
@ -98,16 +98,19 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
typedef enum logic [1:0] {READY, START, WAIT} txState;
txState CurrState, NextState;
// FIFO FSM signals
// Watermark signals - TransmitReadMark = ip[0], ReceiveWriteMark = ip[1]
logic TransmitWriteMark, TransmitReadMark, RecieveWriteMark, RecieveReadMark;
logic TransmitFIFOWriteFull, TransmitFIFOReadEmpty;
logic TransmitFIFOWriteIncrement;
logic [7:0] TransmitFIFOReadData;
// FIFO Watermark signals - TransmitReadMark = ip[0], ReceiveWriteMark = ip[1]
logic TransmitWriteMark, TransmitReadMark, ReceiveWriteMark, ReceiveReadMark;
// Transmit FIFO Signals
logic TransmitFIFOFull, TransmitFIFOEmpty;
logic TransmitFIFOWriteInc;
logic TransmitFIFOReadInc; // Increments Tx FIFO read ptr 1 cycle after Tx FIFO is read
logic [7:0] TransmitReadData;
// ReceiveFIFO Signals
logic ReceiveFIFOWriteInc;
logic ReceiveFIFOReadIncrement;
logic ReceiveFIFOWriteFull, ReceiveFIFOReadEmpty;
logic ReceiveFIFOReadInc;
logic ReceiveFIFOFull, ReceiveFIFOEmpty;
/* verilator lint_off UNDRIVEN */
logic [2:0] TransmitWriteWatermarkLevel, ReceiveReadWatermarkLevel; // unused generic FIFO outputs
@ -115,16 +118,16 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
logic [7:0] ReceiveShiftRegEndian; // Reverses ReceiveShiftReg if Format[2] set (little endian transmission)
// Shift reg signals
logic ShiftEdge; // Determines which edge of sck to shift from TransmitReg
logic SampleEdge; // Determines which edge of sck to sample from ReceiveShiftReg
logic [7:0] TransmitReg; // Transmit shift register
logic ShiftEdge; // Determines which edge of sck to shift from TransmitReg
logic SampleEdge; // Determines which edge of sck to sample from ReceiveShiftReg
logic [7:0] TransmitReg; // Transmit shift register
logic [7:0] ReceiveShiftReg; // Receive shift register
logic [7:0] TransmitDataEndian; // Reverses TransmitData from txFIFO if littleendian, since TransmitReg always shifts MSB
logic TransmitLoad; // Determines when to load TransmitReg
logic TransmitFIFOReadIncrement; // Increments Tx FIFO read ptr 1 cycle after Tx FIFO is read
logic TransmitLoad; // Determines when to load TransmitReg
logic TransmitRegLoaded;
// Shift stuff due to Format register?
logic ShiftIn; // Determines whether to shift from SPIIn or SPIOut (if SPI_LOOPBACK_TEST)
logic ShiftIn; // Determines whether to shift from SPIIn or SPIOut (if SPI_LOOPBACK_TEST)
logic [3:0] LeftShiftAmount; // Determines left shift amount to left-align data when little endian
logic [7:0] ASR; // AlignedReceiveShiftReg
@ -135,7 +138,6 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
// APB access
assign Entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses
assign Memwrite = PWRITE & PENABLE & PSEL; // Only write in access phase
// assign PREADY = Entry == SPI_TXDATA | Entry == SPI_RXDATA | Entry == SPI_IP;
assign PREADY = 1'b1;
// Account for subword read/write circuitry
@ -162,7 +164,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
InterruptEnable <= 2'b0;
InterruptPending <= 2'b0;
end else begin // writes
/* verilator lint_off CASEINCOMPLETE */
/* verilator lint_off CASEINCOMPLETE */
if (Memwrite)
case(Entry) // flop to sample inputs
SPI_SCKDIV: SckDiv <= Din[11:0];
@ -180,14 +182,14 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
if (Memwrite)
case(Entry)
SPI_TXDATA: if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0];
SPI_TXDATA: if (~TransmitFIFOFull) TransmitData[7:0] <= Din[7:0];
endcase
/* verilator lint_off CASEINCOMPLETE */
// According to FU540 spec: Once interrupt is pending, it will remain set until number
// of entries in tx/rx fifo is strictly more/less than tx/rxmark
InterruptPending[0] <= TransmitReadMark;
InterruptPending[1] <= RecieveWriteMark;
InterruptPending[1] <= ReceiveWriteMark;
case(Entry) // Flop to sample inputs
SPI_SCKDIV: Dout <= {20'b0, SckDiv};
@ -198,8 +200,8 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
SPI_DELAY0: Dout <= {8'b0, Delay0[15:8], 8'b0, Delay0[7:0]};
SPI_DELAY1: Dout <= {8'b0, Delay1[15:8], 8'b0, Delay1[7:0]};
SPI_FMT: Dout <= {12'b0, Format[4:1], 13'b0, Format[0], 2'b0};
SPI_TXDATA: Dout <= {TransmitFIFOWriteFull, 23'b0, 8'b0};
SPI_RXDATA: Dout <= {ReceiveFIFOReadEmpty, 23'b0, ReceiveData[7:0]};
SPI_TXDATA: Dout <= {TransmitFIFOFull, 23'b0, 8'b0};
SPI_RXDATA: Dout <= {ReceiveFIFOEmpty, 23'b0, ReceiveData[7:0]};
SPI_TXMARK: Dout <= {29'b0, TransmitWatermark};
SPI_RXMARK: Dout <= {29'b0, ReceiveWatermark};
SPI_IE: Dout <= {30'b0, InterruptEnable};
@ -208,11 +210,6 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
endcase
end
// SPI enable generation, where SCLK = PCLK/(2*(SckDiv + 1))
// Asserts SCLKenable at the rising and falling edge of SCLK by counting from 0 to SckDiv
// Active at 2x SCLK frequency to account for implicit half cycle delays and actions on both clock edges depending on phase
// When SckDiv is 0, count doesn't work and SCLKenable is simply PCLK *** dh 10/26/24: this logic is seriously broken. SCLK is not scaled to PCLK/(2*(SckDiv + 1)).
// SPI Controller module -------------------------------------------
// This module controls state and timing signals that drive the rest of this module
assign ResetSCLKenable = Memwrite & (Entry == SPI_SCKDIV);
@ -220,59 +217,51 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
spi_controller controller(PCLK, PRESETn,
// Transmit Signals
TransmitStart, TransmitStartD, ResetSCLKenable,
TransmitStart, TransmitRegLoaded, ResetSCLKenable,
// Register Inputs
SckDiv, SckMode, ChipSelectMode, Delay0, Delay1, FrameLength,
// txFIFO stuff
TransmitFIFOReadEmpty,
TransmitFIFOEmpty,
// Timing
SCLKenable, ShiftEdge, SampleEdge, EndOfFrame, EndOfFrameDelay,
SCLKenable, ShiftEdge, SampleEdge, EndOfFrame,
// State stuff
Transmitting, InactiveState,
// Outputs
SPICLK);
// Transmit FIFO ---------------------------------------------------
always_ff @(posedge PCLK)
if (~PRESETn) begin
TransmitFIFOWriteIncrement <= 1'b0;
end else begin
TransmitFIFOWriteIncrement <= (Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOWriteFull);
end
always_ff @(posedge PCLK)
if (~PRESETn) begin
TransmitFIFOReadIncrement <= 1'b0;
end else if (SCLKenable) begin
TransmitFIFOReadIncrement <= TransmitStartD | (EndOfFrameDelay & ~TransmitFIFOReadEmpty) ;
end
// txFIFO write increment logic
flopr #(1) txwincreg(PCLK, ~PRESETn,
(Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOFull),
TransmitFIFOWriteInc);
// txFIFO read increment logic
flopenr #(1) txrincreg(PCLK, ~PRESETn, SCLKenable,
TransmitStartD | (EndOfFrame & ~TransmitFIFOEmpty),
TransmitFIFOReadInc);
// Check whether TransmitReg has been loaded.
// We use this signal to prevent returning to the Ready state for TransmitStart
logic TransmitRegLoaded;
always_ff @(posedge PCLK) begin
if (~PRESETn) begin
TransmitRegLoaded <= 1'b0;
end else if (TransmitLoad) begin
TransmitRegLoaded <= 1'b1;
end else if (ShiftEdge | EndOfFrameDelay) begin
end else if (ShiftEdge | EndOfFrame) begin
TransmitRegLoaded <= 1'b0;
end
end
// Setup TransmitStart state machine
always_ff @(posedge PCLK) begin
if (~PRESETn) begin
CurrState <= READY;
end else begin
CurrState <= NextState;
end
end
always_ff @(posedge PCLK)
if (~PRESETn) CurrState <= READY;
else CurrState <= NextState;
// State machine for starting transmissions
always_comb begin
case (CurrState)
READY: if (~TransmitFIFOReadEmpty & ~Transmitting) NextState = START;
READY: if (~TransmitFIFOEmpty & ~Transmitting) NextState = START;
else NextState = READY;
START: NextState = WAIT;
WAIT: if (~Transmitting & ~TransmitRegLoaded) NextState = READY;
@ -281,49 +270,48 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
endcase
end
// Delayed TransmitStart signal for incrementing tx read point.
assign TransmitStart = (CurrState == START);
always_ff @(posedge PCLK)
if (~PRESETn) TransmitStartD <= 1'b0;
else if (TransmitStart) TransmitStartD <= 1'b1;
else if (SCLKenable) TransmitStartD <= 1'b0;
// Transmit FIFO
spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn,
TransmitFIFOWriteIncrement, TransmitFIFOReadIncrement,
TransmitFIFOWriteInc, TransmitFIFOReadInc,
TransmitData[7:0],
TransmitWriteWatermarkLevel, TransmitWatermark[2:0],
TransmitFIFOReadData[7:0],
TransmitFIFOWriteFull,
TransmitFIFOReadEmpty,
TransmitReadData[7:0],
TransmitFIFOFull,
TransmitFIFOEmpty,
TransmitWriteMark, TransmitReadMark);
// Receive FIFO ----------------------------------------------------
always_ff @(posedge PCLK)
if (~PRESETn) begin
ReceiveFIFOReadIncrement <= 1'b0;
end else begin
ReceiveFIFOReadIncrement <= ((Entry == SPI_RXDATA) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement);
end
always_ff @(posedge PCLK)
if (~PRESETn) begin
ReceiveFIFOWriteInc <= 1'b0;
end else if (SCLKenable) begin
ReceiveFIFOWriteInc <= EndOfFrameDelay;
end
// Receive FIFO Read Increment register
flopr #(1) rxfiforincreg(PCLK, ~PRESETn,
((Entry == SPI_RXDATA) & ~ReceiveFIFOEmpty & PSEL & ~ReceiveFIFOReadInc),
ReceiveFIFOReadInc);
// Receive FIFO Write Increment register
flopenr #(1) rxfifowincreg(PCLK, ~PRESETn, SCLKenable,
EndOfFrame, ReceiveFIFOWriteInc);
// Receive FIFO
spi_fifo #(3,8) rxFIFO(PCLK, SCLKenable, 1'b1, PRESETn,
ReceiveFIFOWriteInc, ReceiveFIFOReadIncrement,
ReceiveFIFOWriteInc, ReceiveFIFOReadInc,
ReceiveShiftRegEndian, ReceiveWatermark[2:0],
ReceiveReadWatermarkLevel,
ReceiveData[7:0],
ReceiveFIFOWriteFull,
ReceiveFIFOReadEmpty,
RecieveWriteMark, RecieveReadMark);
ReceiveFIFOFull,
ReceiveFIFOEmpty,
ReceiveWriteMark, ReceiveReadMark);
// Shift Registers --------------------------------------------------
// Transmit shift register
assign TransmitLoad = TransmitStart | (EndOfFrameDelay & ~TransmitFIFOReadEmpty);
assign TransmitDataEndian = Format[0] ? {<<{TransmitFIFOReadData[7:0]}} : TransmitFIFOReadData[7:0];
assign TransmitLoad = TransmitStart | (EndOfFrame & ~TransmitFIFOEmpty);
assign TransmitDataEndian = Format[0] ? {<<{TransmitReadData[7:0]}} : TransmitReadData[7:0];
always_ff @(posedge PCLK)
if(~PRESETn) TransmitReg <= 8'b0;
else if (TransmitLoad) TransmitReg <= TransmitDataEndian;
@ -342,12 +330,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
if(~PRESETn) begin
ReceiveShiftReg <= 8'b0;
end else if (SampleEdge) begin
if (~Transmitting) ReceiveShiftReg <= 8'b0;
else ReceiveShiftReg <= {ReceiveShiftReg[6:0], ShiftIn};
ReceiveShiftReg <= {ReceiveShiftReg[6:0], ShiftIn};
end
// Aligns received data and reverses if little-endian
assign LeftShiftAmount = 4'h8 - Format[4:1];
assign LeftShiftAmount = 4'h8 - FrameLength;
assign ASR = ReceiveShiftReg << LeftShiftAmount[2:0];
assign ReceiveShiftRegEndian = Format[0] ? {<<{ASR[7:0]}} : ASR[7:0];

View File

@ -33,7 +33,7 @@ module spi_controller (
// Start Transmission
input logic TransmitStart,
input logic TransmitStartD,
input logic TransmitRegLoaded,
input logic ResetSCLKenable,
// Registers
@ -45,14 +45,13 @@ module spi_controller (
input logic [3:0] FrameLength,
// Is the Transmit FIFO Empty?
input logic txFIFOReadEmpty,
input logic TransmitFIFOEmpty,
// Control signals
output logic SCLKenable,
output logic ShiftEdge,
output logic SampleEdge,
output logic EndOfFrame,
output logic EndOfFrameDelay,
output logic EndOfFrame,
output logic Transmitting,
output logic InactiveState,
output logic SPICLK
@ -63,43 +62,31 @@ module spi_controller (
localparam AUTOMODE = 2'b00;
localparam OFFMODE = 2'b11;
// FSM States
typedef enum logic [2:0] {INACTIVE, CSSCK, TRANSMIT, SCKCS, HOLD, INTERCS, INTERXFR} statetype;
statetype CurrState, NextState;
// SCLKenable stuff
logic [11:0] DivCounter;
// logic SCLKenable;
// logic SCLKenableEarly;
logic ZeroDiv;
logic SCK; // SUPER IMPORTANT, THIS CAN'T BE THE SAME AS SPICLK!
logic SCK;
// Shift and Sample Edges
logic PreShiftEdge;
logic PreSampleEdge;
// logic ShiftEdge;
// logic SampleEdge;
logic EdgePulse;
logic ShiftEdgePulse;
logic SampleEdgePulse;
logic EndOfFramePulse;
logic PhaseOneOffset;
// Frame stuff
logic [3:0] BitNum;
logic LastBit;
//logic EndOfFrame;
//logic EndOfFrameDelay;
logic PhaseOneOffset;
// Transmit Stuff
logic ContinueTransmit;
// SPIOUT Stuff
// logic TransmitLoad;
logic [7:0] TransmitReg;
//logic Transmitting;
logic EndTransmission;
logic HoldMode;
// logic TransmitRegLoaded; // TODO: Could be replaced by TransmitRegLoaded?
logic NextEndDelay;
logic CurrentEndDelay;
// Delay Stuff
logic [7:0] cssck;
@ -116,13 +103,12 @@ module spi_controller (
logic EndOfSCKCS;
logic EndOfINTERCS;
logic EndOfINTERXFR;
logic EndOfDelay;
logic [7:0] CSSCKCounter;
logic [7:0] SCKCSCounter;
logic [7:0] INTERCSCounter;
logic [7:0] INTERXFRCounter;
logic [7:0] DelayCounter;
logic DelayIsNext;
logic DelayState;
// Convenient Delay Reg Names
assign cssck = Delay0[7:0];
@ -137,23 +123,25 @@ module spi_controller (
assign HasINTERXFR = interxfr > 8'b0;
// Have we hit full delay for any of the delays?
assign EndOfCSSCK = CSSCKCounter == cssck;
assign EndOfSCKCS = SCKCSCounter == sckcs;
assign EndOfINTERCS = INTERCSCounter == intercs;
assign EndOfINTERXFR = INTERXFRCounter == interxfr;
assign EndOfCSSCK = (DelayCounter == cssck) & (CurrState == CSSCK);
assign EndOfSCKCS = (DelayCounter == sckcs) & (CurrState == SCKCS);
assign EndOfINTERCS = (DelayCounter == intercs) & (CurrState == INTERCS);
assign EndOfINTERXFR = (DelayCounter == interxfr) & (CurrState == INTERXFR);
assign EndOfDelay = EndOfCSSCK | EndOfSCKCS | EndOfINTERCS | EndOfINTERXFR;
// Clock Signal Stuff -----------------------------------------------
// I'm going to handle all clock stuff here, including ShiftEdge and
// SampleEdge. This makes sure that SPICLK is an output of a register
// and it properly synchronizes signals.
assign SCLKenable = DivCounter == SckDiv;
// assign SCLKenableEarly = (DivCounter + 1'b1) == SckDiv;
assign LastBit = (BitNum == FrameLength - 4'b1);
//assign EndOfFrame = SCLKenable & LastBit & Transmitting;
assign ContinueTransmit = ~txFIFOReadEmpty & EndOfFrameDelay;
assign EndTransmission = txFIFOReadEmpty & EndOfFrameDelay;
// SPI enable generation, where SCLK = PCLK/(2*(SckDiv + 1))
// Asserts SCLKenable at the rising and falling edge of SCLK by counting from 0 to SckDiv
// Active at 2x SCLK frequency to account for implicit half cycle delays and actions on both clock edges depending on phase
assign SCLKenable = DivCounter == SckDiv;
assign ContinueTransmit = ~TransmitFIFOEmpty & EndOfFrame;
assign EndTransmission = TransmitFIFOEmpty & EndOfFrame;
always_ff @(posedge PCLK) begin
if (~PRESETn) begin
@ -161,44 +149,20 @@ module spi_controller (
SPICLK <= SckMode[1];
SCK <= 0;
BitNum <= 4'h0;
PreShiftEdge <= 0;
PreSampleEdge <= 0;
EndOfFrame <= 0;
CSSCKCounter <= 0;
SCKCSCounter <= 0;
INTERCSCounter <= 0;
INTERXFRCounter <= 0;
DelayCounter <= 0;
end else begin
// TODO: Consolidate into one delay counter since none of the
// delays happen at the same time?
// SCK logic for delay times
if (TransmitStart) begin
SCK <= 0;
end else if (SCLKenable) begin
SCK <= ~SCK;
end
if ((CurrState == CSSCK) & SCK & SCLKenable) begin
CSSCKCounter <= CSSCKCounter + 8'd1;
end else if (SCLKenable & EndOfCSSCK) begin
CSSCKCounter <= 8'd0;
end
if ((CurrState == SCKCS) & SCK & SCLKenable) begin
SCKCSCounter <= SCKCSCounter + 8'd1;
end else if (SCLKenable & EndOfSCKCS) begin
SCKCSCounter <= 8'd0;
end
if ((CurrState == INTERCS) & SCK & SCLKenable) begin
INTERCSCounter <= INTERCSCounter + 8'd1;
end else if (SCLKenable & EndOfINTERCS) begin
INTERCSCounter <= 8'd0;
end
if ((CurrState == INTERXFR) & SCK & SCLKenable) begin
INTERXFRCounter <= INTERXFRCounter + 8'd1;
end else if (SCLKenable & EndOfINTERXFR) begin
INTERXFRCounter <= 8'd0;
// Counter for all four delay types
if (DelayState & SCK & SCLKenable) begin
DelayCounter <= DelayCounter + 8'd1;
end else if (SCLKenable & EndOfDelay) begin
DelayCounter <= 8'd0;
end
// SPICLK Logic
@ -215,95 +179,69 @@ module spi_controller (
DivCounter <= DivCounter + 12'd1;
end
// EndOfFrame controller
// if (SckDiv > 0 ? SCLKenableEarly & LastBit & SPICLK : LastBit & ~SPICLK) begin
// EndOfFrame <= 1'b1;
// end else begin
// EndOfFrame <= 1'b0;
// end
// TODO: Rename EndOfFrameDelay to EndOfFrame and remove this logic
if (~TransmitStart) begin
EndOfFrame <= (SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & LastBit & Transmitting;
end
// Increment BitNum
if (ShiftEdge & Transmitting) begin
BitNum <= BitNum + 4'd1;
end else if (EndOfFrameDelay) begin
end else if (EndOfFrame) begin
BitNum <= 4'b0;
end
end
end
// The very last bit in a frame of any length.
assign LastBit = (BitNum == FrameLength - 4'b1);
// Any SCLKenable pulse aligns with leading or trailing edge during
// Transmission. We can use this signal as the basis for ShiftEdge
// and SampleEdge.
assign EdgePulse = SCLKenable & Transmitting;
// Possible pulses for all edge types. Combined with SPICLK to get
// edges for different phase and polarity modes.
assign ShiftEdgePulse = EdgePulse & ~LastBit;
assign SampleEdgePulse = EdgePulse & ~DelayIsNext;
assign EndOfFramePulse = EdgePulse & LastBit;
// Delay ShiftEdge and SampleEdge by a half PCLK period
// Aligned EXACTLY ON THE MIDDLE of the leading and trailing edges.
// Sweeeeeeeeeet...
assign ShiftEdgePulse = SCLKenable & ~LastBit & Transmitting;
assign SampleEdgePulse = SCLKenable & Transmitting & ~DelayIsNext;
assign EndOfFramePulse = SCLKenable & LastBit & Transmitting;
always_ff @(posedge ~PCLK) begin
if (~PRESETn | TransmitStart) begin
ShiftEdge <= 0;
PhaseOneOffset <= 0;
SampleEdge <= 0;
EndOfFrameDelay <= 0;
EndOfFrame <= 0;
end else begin
PhaseOneOffset <= (PhaseOneOffset == 0) ? Transmitting & SCLKenable : ~EndOfFrameDelay;
PhaseOneOffset <= (PhaseOneOffset == 0) ? Transmitting & SCLKenable : ~EndOfFrame;
case(SckMode)
2'b00: begin
ShiftEdge <= SPICLK & ShiftEdgePulse;
SampleEdge <= ~SPICLK & SampleEdgePulse;
EndOfFrameDelay <= SPICLK & EndOfFramePulse;
EndOfFrame <= SPICLK & EndOfFramePulse;
end
2'b01: begin
ShiftEdge <= ~SPICLK & ShiftEdgePulse & PhaseOneOffset;
SampleEdge <= SPICLK & SampleEdgePulse;
EndOfFrameDelay <= ~SPICLK & EndOfFramePulse;
EndOfFrame <= ~SPICLK & EndOfFramePulse;
end
2'b10: begin
ShiftEdge <= ~SPICLK & ShiftEdgePulse;
SampleEdge <= SPICLK & SampleEdgePulse;
EndOfFrameDelay <= ~SPICLK & EndOfFramePulse;
EndOfFrame <= ~SPICLK & EndOfFramePulse;
end
2'b11: begin
ShiftEdge <= SPICLK & ShiftEdgePulse & PhaseOneOffset;
SampleEdge <= ~SPICLK & SampleEdgePulse;
EndOfFrameDelay <= SPICLK & EndOfFramePulse;
EndOfFrame <= SPICLK & EndOfFramePulse;
end
// ShiftEdge <= ((SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & ~LastBit & Transmitting) & PhaseOneOffset;
// PhaseOneOffset <= PhaseOneOffset == 0 ? Transmitting & SCLKenable : ~EndOfFrameDelay;
// SampleEdge <= (SckMode[1] ^ SckMode[0] ^ ~SPICLK) & SCLKenable & Transmitting & ~DelayIsNext;
// EndOfFrameDelay <= (SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & LastBit & Transmitting;
endcase
end
end
// typedef enum logic [2:0] {INACTIVE, CSSCK, TRANSMIT, SCKCS, HOLD, INTERCS, INTERXFR} statetype;
// statetype CurrState, NextState;
assign HoldMode = CSMode == HOLDMODE;
// assign TransmitLoad = TransmitStart | (EndOfFrameDelay & ~txFIFOReadEmpty);
logic ContinueTransmitD;
logic NextEndDelay;
logic CurrentEndDelay;
// Logic for continuing to transmit through Delay states after end of frame
assign NextEndDelay = NextState == SCKCS | NextState == INTERCS | NextState == INTERXFR;
assign CurrentEndDelay = CurrState == SCKCS | CurrState == INTERCS | CurrState == INTERXFR;
always_ff @(posedge PCLK) begin
if (~PRESETn) begin
ContinueTransmitD <= 1'b0;
end else if (NextEndDelay & ~CurrentEndDelay) begin
ContinueTransmitD <= ContinueTransmit;
end else if (EndOfSCKCS & SCLKenable) begin
ContinueTransmitD <= 1'b0;
end
end
always_ff @(posedge PCLK) begin
if (~PRESETn) begin
CurrState <= INACTIVE;
@ -314,7 +252,7 @@ module spi_controller (
always_comb begin
case (CurrState)
INACTIVE: if (TransmitStartD) begin
INACTIVE: if (TransmitRegLoaded) begin
if (~HasCSSCK) NextState = TRANSMIT;
else NextState = CSSCK;
end else begin
@ -326,7 +264,7 @@ module spi_controller (
case(CSMode)
AUTOMODE: begin
if (EndTransmission) NextState = INACTIVE;
else if (EndOfFrameDelay) NextState = SCKCS;
else if (EndOfFrame) NextState = SCKCS;
else NextState = TRANSMIT;
end
HOLDMODE: begin
@ -344,7 +282,7 @@ module spi_controller (
end
SCKCS: begin // SCKCS case --------------------------------------
if (EndOfSCKCS) begin
if (~ContinueTransmitD) begin
if (~TransmitRegLoaded) begin
// if (CSMode == AUTOMODE) NextState = INACTIVE;
if (CSMode == HOLDMODE) NextState = HOLD;
else NextState = INACTIVE;
@ -359,7 +297,7 @@ module spi_controller (
HOLD: begin // HOLD mode case -----------------------------------
if (CSMode == AUTOMODE) begin
NextState = INACTIVE;
end else if (TransmitStartD) begin // If FIFO is written to, start again.
end else if (TransmitRegLoaded) begin // If FIFO is written to, start again.
NextState = TRANSMIT;
end else NextState = HOLD;
end
@ -386,6 +324,7 @@ module spi_controller (
assign Transmitting = CurrState == TRANSMIT;
assign DelayIsNext = (NextState == CSSCK | NextState == SCKCS | NextState == INTERCS | NextState == INTERXFR);
assign DelayState = (CurrState == CSSCK | CurrState == SCKCS | CurrState == INTERCS | CurrState == INTERXFR);
assign InactiveState = CurrState == INACTIVE | CurrState == INTERCS;
endmodule

View File

@ -19,6 +19,10 @@ module spi_fifo #(parameter M=3, N=8)( // 2^M entries of N bits
logic [M:0] rptrnext, wptrnext;
logic [M-1:0] raddr;
logic [M-1:0] waddr;
logic [M-1:0] numVals;
assign numVals = waddr - raddr;
assign rdata = mem[raddr];
always_ff @(posedge PCLK)

View File

@ -28,7 +28,7 @@ all: $(OBJDUMPS) $(MEMFILES)
# Assemble into object files
%.$(OBJEXT): %.$(AEXT)
riscv64-unknown-elf-as -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom_zbkb_zbkx_zknd_zkne_zknh -mabi=lp64 $<
riscv64-unknown-elf-as -g -o $@ -march=rv64gqc_zcb_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom_zbkb_zbkx_zknd_zkne_zknh_svinval -mabi=lp64 $<
# Preprocess assembly files
%.$(AEXT): %.$(SRCEXT) WALLY-init-lib.h

View File

@ -38,6 +38,9 @@ main:
csrrw t1, menvcfg, t0
csrrw t2, senvcfg, t0
# Test writing to TIME CSR
csrw time, zero
# testing FIOM with different privilege modes
# setting environment config (to both 1 and 0) in each privilege mode
csrsi menvcfg, 1

View File

@ -1,18 +0,0 @@
// fround.s
#include "WALLY-init-lib.h"
# run-elf.bash find this in project description
main:
bseti t0, zero, 14 # turn on FPU
csrs mstatus, t0
# test fround behavior on NaN
li t0, 0x7FC00001
fmv.w.x ft0, t0
fround.s ft1, ft0
j done
.align 10
data_start:

View File

@ -81,6 +81,7 @@ main:
.word 0xFF00302F // illegal Atomic instruction
.word 0xFF00402F // illegal Atomic instruction
.word 0x00000873 // illegal CSR instruction
.word 0x31bf1f93 // illegal aes64ksli1 instruction
# Illegal CMO instructions because envcfg is 0 and system is in user Mode
li a0, 0

View File

@ -43,35 +43,23 @@ main:
.hword 0x9C41 // line 134 Illegal compressed instruction
# Zcb coverage tests
# could restore assembly language versions when GCC supports Zcb
mv s0, sp
#c.lbu s1, 0(s0) // exercise c.lbu
.hword 0x8004 // c.lbu s1, 0(s0)
#c.lh s1, 0(s0) // exercise c.lh
.hword 0x8444 // c.lh s1, 0(s0)
#c.lhu s1, 0(s0) // exercise c.lhu
.hword 0x8404 // c.lhu s1, 0(s0)
#c.sb s1, 0(s0) // exercise c.sb
.hword 0x8804 // c.sb s1, 0(s0)
#c.sh s1, 0(s0) // exercise c.sh
.hword 0x8C04 // c.sh s1, 0(s0)
c.lbu s1, 0(s0) // exercise c.lbu
c.lh s1, 0(s0) // exercise c.lh
c.lhu s1, 0(s0) // exercise c.lhu
c.sb s1, 0(s0) // exercise c.sb
c.sh s1, 0(s0) // exercise c.sh
.hword 0x8C44 // Illegal compressed instruction with op = 00, Instr[15:10] = 100011, Instr[6] = 1 and 0's everywhere else. Line 119 illegal instruction
.hword 0x9C00 // Illegal compressed instruction with op = 00, Instr[15:10] = 100111, and 0's everywhere else. Line 119 illegal instruction
li s0, 0xFF
# c.zext.b s0 // exercise c.zext.b
.hword 0x9C61 // c.zext.b s0
# c.sext.b s0 // exercise c.sext.b
.hword 0x9C65 // c.sext.b s0
# c.zext.h s0 // exercise c.zext.h
.hword 0x9C69 // c.zext.h s0
# c.sext.h s0 // exercise c.sext.h
.hword 0x9C6D // c.sext.h s0
# c.zext.w s0 // exercise c.zext.w
.hword 0x9C71 // c.zext.w s0
# c.not s0 // exercise c.not
.hword 0x9C75 // c.not s0
c.zext.b s0 // exercise c.zext.b
c.sext.b s0 // exercise c.sext.b
c.zext.h s0 // exercise c.zext.h
c.sext.h s0 // exercise c.sext.h
c.zext.w s0 // exercise c.zext.w
c.not s0 // exercise c.not
.hword 0x9C7D // Reserved instruction from line 187 with op = 01, Instr[15:10] = 100111, Instr[6:5] = 11, and 0's everywhere else

View File

@ -304,7 +304,7 @@ sretdone:
li a0, 3
ecall
# exercise sfence.inval.ir instruction
.word 0x18100073
sfence.inval.ir
# exercise sret with rs1 not 0
.word 0x102F8073

View File

@ -1,144 +0,0 @@
///////////////////////////////////////////
// lsu_test.S
//
// Written: mmendozamanriquez@hmc.edu 4 April 2023
// nlimpert@hmc.edu
//
// Purpose: Test coverage for LSU
//
// A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the License); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
// load code to initalize stack, handle interrupts, terminate
#include "WALLY-init-lib.h"
# run-elf.bash find this in project description
main:
# Page table root address at 0x80010000
li t5, 0x9000000000080010
csrw satp, t5
# sfence.vma x0, x0
# switch to supervisor mode
li a0, 1
ecall
li t0, 0x80015000
li t2, 0 # i = 0
li t3, 33 # Max amount of Loops = 32
loop: bge t2, t3, finished # exit loop if i >= loops
lw t1, 0(t0)
li t4, 0x1000
add t0, t0, t4
addi t2, t2, 1
j loop
finished:
j done
.data
.align 16
# Page table situated at 0x80010000
pagetable:
.8byte 0x200044C1 // old page table was 200040 which just pointed to itself! wrong
.align 12
.8byte 0x0000000000000000
.8byte 0x00000000200048C1
.8byte 0x00000000200048C1
.align 12
.8byte 0x0000000020004CC1
//.8byte 0x00000200800CF// ADD IN THE MEGAPAGE should 3 nibbles of zeros be removed?
.align 12
#80000000
.8byte 0x200000CF
.8byte 0x200004CF
.8byte 0x200008CF
.8byte 0x20000CCF
.8byte 0x200010CF
.8byte 0x200014CF
.8byte 0x200018CF
.8byte 0x20001CCF
.8byte 0x200020CF
.8byte 0x200024CF
.8byte 0x200028CF
.8byte 0x20002CCF
.8byte 0x200030CF
.8byte 0x200034CF
.8byte 0x200038CF
.8byte 0x20003CCF
.8byte 0x200040CF
.8byte 0x200044CF
.8byte 0x200048CF
.8byte 0x20004CCF
.8byte 0x200050CF
.8byte 0x200054CF
.8byte 0x200058CF
.8byte 0x20005CCF
.8byte 0x200060CF
.8byte 0x200064CF
.8byte 0x200068CF
.8byte 0x20006CCF
.8byte 0x200070CF
.8byte 0x200074CF
.8byte 0x200078CF
.8byte 0x20007CCF
.8byte 0x200080CF
.8byte 0x200084CF
.8byte 0x200088CF
.8byte 0x20008CCF
.8byte 0x200090CF
.8byte 0x200094CF
.8byte 0x200098CF
.8byte 0x20009CCF
.8byte 0x200100CF
.8byte 0x200104CF
.8byte 0x200108CF
.8byte 0x20010CCF
.8byte 0x200110CF
.8byte 0x200114CF
.8byte 0x200118CF
.8byte 0x20011CCF
.8byte 0x200120CF
.8byte 0x200124CF
.8byte 0x200128CF
.8byte 0x20012CCF
.8byte 0x200130CF
.8byte 0x200134CF

View File

@ -1,156 +0,0 @@
///////////////////////////////////////////
// tlbKP.S
//
// Written: mmendozamanriquez@hmc.edu 4 April 2023
// nlimpert@hmc.edu
//
// Purpose: Test coverage for LSU
//
// A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the License); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
// load code to initalize stack, handle interrupts, terminate
#include "WALLY-init-lib.h"
# run-elf.bash find this in project description
main:
# Page table root address at 0x80010000
li t5, 0x9000000000080010
csrw satp, t5
# sfence.vma x0, x0
# switch to supervisor mode
li a0, 1
ecall
li t0, 0x1000
li t2, 0 # i = 0
li t3, 64 # Max amount of Loops = 32
li t4, 0x1000
loop: bge t2, t3, interim # exit loop if i >= loops
lw t1, 0(t0)
# sfence.vma x0, x0
add t0, t0, t4
addi t2, t2, 1
j loop
interim:
li t0, 0xFFFFFFFF000
li t2, 0 # i = 0
loop2:bge t2, t3, finished # exit loop if i >= loops
lw t1, 0(t0)
add t0, t0, t4
addi t2, t2, 1
j loop2
finished:
j done
.data
.align 16
# Page table situated at 0x80010000
pagetable:
.8byte 0x200044C1 // old page table was 200040 which just pointed to itself! wrong
.align 12
.8byte 0x00000000200048C1
.8byte 0x00000000200048C1
.8byte 0x00000000200048C1
.align 12
.8byte 0x0000000020004CC1
//.8byte 0x00000200800CF// ADD IN THE MEGAPAGE should 3 nibbles of zeros be removed?
.align 12
#80000000
.8byte 0x200000CF
.8byte 0x200004CF
.8byte 0x200008CF
.8byte 0x20000CCF
.8byte 0x200010CF
.8byte 0x200014CF
.8byte 0x200018CF
.8byte 0x20001CCF
.8byte 0x200020CF
.8byte 0x200024CF
.8byte 0x200028CF
.8byte 0x20002CCF
.8byte 0x200030CF
.8byte 0x200034CF
.8byte 0x200038CF
.8byte 0x20003CCF
.8byte 0x200040CF
.8byte 0x200044CF
.8byte 0x200048CF
.8byte 0x20004CCF
.8byte 0x200050CF
.8byte 0x200054CF
.8byte 0x200058CF
.8byte 0x20005CCF
.8byte 0x200060CF
.8byte 0x200064CF
.8byte 0x200068CF
.8byte 0x20006CCF
.8byte 0x200070CF
.8byte 0x200074CF
.8byte 0x200078CF
.8byte 0x20007CCF
.8byte 0x200080CF
.8byte 0x200084CF
.8byte 0x200088CF
.8byte 0x20008CCF
.8byte 0x200090CF
.8byte 0x200094CF
.8byte 0x200098CF
.8byte 0x20009CCF
.8byte 0x2000A0CF
.8byte 0x2000A4CF
.8byte 0x2000A8CF
.8byte 0x2000ACCF
.8byte 0x2000B0CF
.8byte 0x2000B4CF
.8byte 0x2000B8CF
.8byte 0x2000BCCF
.8byte 0x2000C0CF
.8byte 0x2000C4CF
.8byte 0x2000C8CF
.8byte 0x2000CCCF
.8byte 0x2000D0CF
.8byte 0x2000D4CF

View File

@ -146,6 +146,30 @@
00000015
00000010
00000010
00000010
00000010
00000010
00000010
00000011
00000011
00000011
00000011
00000011
00000011
00000011 #delay1
00000022

View File

@ -316,11 +316,87 @@ test_cases:
.4byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end
.4byte rx_data, 0x00000015, read32_test # read rx_data
# SCKCS Delay of 0, SCKMODE 10
.4byte sck_mode, 0x00000002, write32_test #set sckmode to 10
.4byte delay0, 0x00000001, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000010, read32_test # reade rx_data
# Arbitrary SCKCS delay, SCKMODE 10
.4byte delay0, 0x00050001, write32_test # set sckcs delay to 5
.4byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000010, read32_test # reade rx_data
# Long SCKCS delay, SCKMODE 10
.4byte delay0, 0x00A50001, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000010, read32_test # reade rx_data
# CSSCK Delay 0, SCKMODE 10
.4byte delay0, 0x00010000, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000010, read32_test # reade rx_data
# Arbitrary CSSCK delay, SCKMODE 10
.4byte delay0, 0x00010005, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000010, read32_test # reade rx_data
# Long CSSCK delay, SCKMODE 10
.4byte delay0, 0x000100A5, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000010, read32_test # reade rx_data
# SCKCS Delay of 0, SCKMODE 11
.4byte sck_mode, 0x00000003, write32_test
.4byte delay0, 0x00000001, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000011, read32_test # reade rx_data
# Arbitrary SCKCS delay, SCKMODE 11
.4byte delay0, 0x00050001, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000011, read32_test # reade rx_data
# Long SCKCS delay, SCKMODE 11
.4byte delay0, 0x00A50001, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000011, read32_test # reade rx_data
# CSSCK Delay 0, SCKMODE 11
.4byte delay0, 0x00010000, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000011, read32_test # reade rx_data
# Arbitrary CSSCK delay, SCKMODE 11
.4byte delay0, 0x00010005, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000011, read32_test # reade rx_data
# Long CSSCK delay, SCKMODE 11
.4byte delay0, 0x000100A5, write32_test # set sckcs delay to 0
.4byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.4byte rx_data, 0x00000011, read32_test # reade rx_data
# =========== Test delay1 register ===========
# Test inter cs delay
.4byte sck_mode, 0x00000000, write32_test #reset sck_mode
.4byte delay0, 0x00010001, write32_test # reset delay0 register
.4byte delay1, 0x00000005, write32_test # set inter_cs delay to 5
.4byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock

View File

@ -146,6 +146,30 @@
00000000
00000015
00000000
00000010
00000000
00000010
00000000
00000010
00000000
00000010
00000000
00000010
00000000
00000010
00000000
00000011
00000000
00000011
00000000
00000011
00000000
00000011
00000000
00000011
00000000
00000011
00000000
00000011 #delay1
00000000
00000022

View File

@ -258,7 +258,7 @@ test_cases:
.8byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end
.8byte rx_data, 0x00000011, read32_test # read rx_data
# =========== Test delay0 register ===========
# =========== Test delay0 register (mode auto)===========
# Test cs-sck delay of 0 with sck phase = 0 (implicit half cycle delay)
@ -320,11 +320,87 @@ test_cases:
.8byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end
.8byte rx_data, 0x00000015, read32_test # read rx_data
# SCKCS Delay of 0, SCKMODE 10
.8byte sck_mode, 0x00000002, write32_test #set sckmode to 10
.8byte delay0, 0x00000001, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000010, read32_test # reade rx_data
# Arbitrary SCKCS delay, SCKMODE 10
.8byte delay0, 0x00050001, write32_test # set sckcs delay to 5
.8byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000010, read32_test # reade rx_data
# Long SCKCS delay, SCKMODE 10
.8byte delay0, 0x00A50001, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000010, read32_test # reade rx_data
# CSSCK Delay 0, SCKMODE 10
.8byte delay0, 0x00010000, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000010, read32_test # reade rx_data
# Arbitrary CSSCK delay, SCKMODE 10
.8byte delay0, 0x00010005, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000010, read32_test # reade rx_data
# Long CSSCK delay, SCKMODE 10
.8byte delay0, 0x000100A5, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000010, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000010, read32_test # reade rx_data
# SCKCS Delay of 0, SCKMODE 11
.8byte sck_mode, 0x00000003, write32_test
.8byte delay0, 0x00000001, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000011, read32_test # reade rx_data
# Arbitrary SCKCS delay, SCKMODE 11
.8byte delay0, 0x00050001, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000011, read32_test # reade rx_data
# Long SCKCS delay, SCKMODE 11
.8byte delay0, 0x00A50001, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000011, read32_test # reade rx_data
# CSSCK Delay 0, SCKMODE 11
.8byte delay0, 0x00010000, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000011, read32_test # reade rx_data
# Arbitrary CSSCK delay, SCKMODE 11
.8byte delay0, 0x00010005, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000011, read32_test # reade rx_data
# Long CSSCK delay, SCKMODE 11
.8byte delay0, 0x000100A5, write32_test # set sckcs delay to 0
.8byte tx_data, 0x00000011, write32_test # place 10 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait #wait for transmission
.8byte rx_data, 0x00000011, read32_test # reade rx_data
# =========== Test delay1 register ===========
# Test inter cs delay
.8byte sck_mode, 0x00000000, write32_test #reset sck_mode
.8byte delay0, 0x00010001, write32_test # reset delay0 register
.8byte delay1, 0x00000005, write32_test # set inter_cs delay to 5
.8byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock