forked from Github_Repos/cvw
Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
commit
e4f4e1bd43
Binary file not shown.
@ -1 +1 @@
|
||||
Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9
|
||||
Subproject commit 2d2aaa7b85c60219c591555b647dfa1785ffe1b3
|
@ -1 +1 @@
|
||||
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230
|
||||
Subproject commit effd553a6a91ed9b0ba251796a8a44505a45174f
|
@ -1 +1 @@
|
||||
Subproject commit a7e27bc046405f0dbcde091be99f5a5d564e2172
|
||||
Subproject commit cb4295f9ce5da2881d7746015a6105adb8f09071
|
@ -1 +1 @@
|
||||
Subproject commit cf04274f50621fd9ef9147793cca6dd1657985c7
|
||||
Subproject commit 3e2bf06b071a77ae62c09bf07c5229d1f9397d94
|
@ -8,6 +8,7 @@ BR2_HOST_GCC_AT_LEAST_5=y
|
||||
BR2_HOST_GCC_AT_LEAST_6=y
|
||||
BR2_HOST_GCC_AT_LEAST_7=y
|
||||
BR2_HOST_GCC_AT_LEAST_8=y
|
||||
BR2_HOST_GCC_AT_LEAST_9=y
|
||||
|
||||
#
|
||||
# Target options
|
||||
@ -87,7 +88,7 @@ BR2_BZCAT="bzcat"
|
||||
BR2_XZCAT="xzcat"
|
||||
BR2_LZCAT="lzip -d -c"
|
||||
BR2_TAR_OPTIONS=""
|
||||
BR2_DEFCONFIG="./configs/wally-qemu_riscv64_virt_defconfig"
|
||||
BR2_DEFCONFIG="./board/wally/main.config"
|
||||
BR2_DL_DIR="$(TOPDIR)/dl"
|
||||
BR2_HOST_DIR="$(BASE_DIR)/host"
|
||||
|
||||
@ -406,11 +407,10 @@ BR2_GENERATE_LOCALE=""
|
||||
# BR2_SYSTEM_ENABLE_NLS is not set
|
||||
# BR2_TARGET_TZ_INFO is not set
|
||||
BR2_ROOTFS_USERS_TABLES=""
|
||||
BR2_ROOTFS_OVERLAY=""
|
||||
BR2_ROOTFS_OVERLAY="./board/wally/rootfs_overlay"
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT=""
|
||||
BR2_ROOTFS_POST_FAKEROOT_SCRIPT=""
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="board/qemu/post-image.sh"
|
||||
BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_DEFCONFIG)"
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT=""
|
||||
|
||||
#
|
||||
# Kernel
|
||||
@ -430,7 +430,7 @@ BR2_LINUX_KERNEL_PATCH=""
|
||||
# BR2_LINUX_KERNEL_USE_DEFCONFIG is not set
|
||||
# BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG is not set
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="./linux.config"
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="./board/wally/linux.config"
|
||||
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES=""
|
||||
BR2_LINUX_KERNEL_CUSTOM_LOGO_PATH=""
|
||||
BR2_LINUX_KERNEL_IMAGE=y
|
||||
@ -473,7 +473,7 @@ BR2_LINUX_KERNEL_GZIP=y
|
||||
# Target packages
|
||||
#
|
||||
BR2_PACKAGE_BUSYBOX=y
|
||||
BR2_PACKAGE_BUSYBOX_CONFIG="./busybox.config"
|
||||
BR2_PACKAGE_BUSYBOX_CONFIG="./board/wally/busybox.config"
|
||||
BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES=""
|
||||
# BR2_PACKAGE_BUSYBOX_SHOW_OTHERS is not set
|
||||
# BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES is not set
|
37
linux/buildroot-config-src/wally/rootfs_overlay/.profile
Normal file
37
linux/buildroot-config-src/wally/rootfs_overlay/.profile
Normal file
@ -0,0 +1,37 @@
|
||||
echo "Hello this ~/.profile is meant to demonstrate running some basic commands on Wally."
|
||||
echo "I am $(whoami)"
|
||||
echo "And I am on $(hostname)"
|
||||
touch myFile.txt
|
||||
echo "This is a line of text." > myFile.txt
|
||||
echo "A second line of text." >> myFile.txt
|
||||
mkdir myDir
|
||||
mv myFile.txt myDir
|
||||
echo "Created myFile.txt and moved it to myDir. It contains:"
|
||||
cat myDir/myFile.txt
|
||||
touch myScript.sh
|
||||
echo "echo \"Hello this is another example script\"" > myScript.sh
|
||||
chmod +x myScript.sh
|
||||
echo "Created myScript.sh. Running it yields:"
|
||||
./myScript.sh
|
||||
cd myDir
|
||||
ln -s ../myScript.sh symLinkToMyScript.sh
|
||||
echo "Created symLinkToMyScript.sh. Running it yields:"
|
||||
./symLinkToMyScript.sh
|
||||
ln ../myScript.sh hardLinkToMyScript.sh
|
||||
echo "Created hardLinkToMyScript.sh. Running it yields:"
|
||||
./hardLinkToMyScript.sh
|
||||
echo "Now let\'s remove all these example files and scripts"
|
||||
cd /
|
||||
rm -r myDir
|
||||
rm myScript.sh
|
||||
echo "Here is disk usage:"
|
||||
df -h
|
||||
echo "And here are the current processes:"
|
||||
ps
|
||||
echo "We can create a user."
|
||||
cd /
|
||||
mkdir home
|
||||
echo "password\npassword\n" | adduser myUser
|
||||
su -c "cd ~; echo \"I am $(whoami) (a new user) and my home directory is $(pwd)\""
|
||||
echo "And finally a login prompt."
|
||||
login
|
41
linux/buildroot-config-src/wally/rootfs_overlay/etc/inittab
Normal file
41
linux/buildroot-config-src/wally/rootfs_overlay/etc/inittab
Normal file
@ -0,0 +1,41 @@
|
||||
# /etc/inittab
|
||||
#
|
||||
# Copyright (C) 2001 Erik Andersen <andersen@codepoet.org>
|
||||
#
|
||||
# Note: BusyBox init doesn't support runlevels. The runlevels field is
|
||||
# completely ignored by BusyBox init. If you want runlevels, use
|
||||
# sysvinit.
|
||||
#
|
||||
# Format for each entry: <id>:<runlevels>:<action>:<process>
|
||||
#
|
||||
# id == tty to run on, or empty for /dev/console
|
||||
# runlevels == ignored
|
||||
# action == one of sysinit, respawn, askfirst, wait, and once
|
||||
# process == program to run
|
||||
|
||||
# Startup the system
|
||||
::sysinit:/bin/mount -t proc proc /proc
|
||||
::sysinit:/bin/mount -o remount,rw /
|
||||
::sysinit:/bin/mkdir -p /dev/pts /dev/shm
|
||||
::sysinit:/bin/mount -a
|
||||
::sysinit:/sbin/swapon -a
|
||||
null::sysinit:/bin/ln -sf /proc/self/fd /dev/fd
|
||||
null::sysinit:/bin/ln -sf /proc/self/fd/0 /dev/stdin
|
||||
null::sysinit:/bin/ln -sf /proc/self/fd/1 /dev/stdout
|
||||
null::sysinit:/bin/ln -sf /proc/self/fd/2 /dev/stderr
|
||||
::sysinit:/bin/hostname -F /etc/hostname
|
||||
# now run any rc scripts
|
||||
::sysinit:/etc/init.d/rcS
|
||||
|
||||
# (commented out) Put a getty on the serial port
|
||||
#console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL
|
||||
# Actually no, let's automatically login
|
||||
console::respawn:-/bin/sh
|
||||
|
||||
# Stuff to do for the 3-finger salute
|
||||
#::ctrlaltdel:/sbin/reboot
|
||||
|
||||
# Stuff to do before rebooting
|
||||
::shutdown:/etc/init.d/rcK
|
||||
::shutdown:/sbin/swapoff -a
|
||||
::shutdown:/bin/umount -a -r
|
@ -15,7 +15,7 @@
|
||||
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x00 0x80000000 0x00 0x8000000>;
|
||||
reg = <0x00 0x80000000 0x00 0x08000000>;
|
||||
};
|
||||
|
||||
cpus {
|
||||
|
@ -1,4 +1,5 @@
|
||||
for index in {450..500}
|
||||
#!/bin/bash
|
||||
for index in {450..500};
|
||||
do
|
||||
instrs=$(($index*1000000))
|
||||
echo "y" | nice -n 5 ./genCheckpoint.sh $instrs
|
||||
|
@ -101,13 +101,15 @@ then
|
||||
set logging on
|
||||
# Priority Levels for sources 1 thru 63
|
||||
x/63xw 0x0C000004
|
||||
# Interrupt Enables
|
||||
# Interrupt Enables for sources 1 thru 63 for contexts 0 and 1
|
||||
x/2xw 0x0C020000
|
||||
# Global Priority Threshold
|
||||
x/2xw 0x0C020080
|
||||
# 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 0xffffffff
|
||||
dump binary memory $rawRamFile 0x80000000 0x87ffffff
|
||||
kill
|
||||
q
|
||||
end_of_script
|
||||
|
@ -138,9 +138,9 @@ 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, 'sstatus': 46, 'sip': 47, 'sie': 48}
|
||||
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, 'sstatus': 0, 'sip': 0, 'sie': 0}, {}, None, None, None]
|
||||
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()
|
||||
|
@ -1,5 +1,6 @@
|
||||
#! /usr/bin/python3
|
||||
import sys, os
|
||||
from functools import reduce
|
||||
|
||||
################
|
||||
# Helper Funcs #
|
||||
@ -21,6 +22,9 @@ def tokenize(string):
|
||||
token = token + char
|
||||
return tokens
|
||||
|
||||
def strip0x(num):
|
||||
return num[2:]
|
||||
|
||||
def stripZeroes(num):
|
||||
num = num.strip('0')
|
||||
if num=='':
|
||||
@ -42,7 +46,7 @@ if not os.path.exists(rawPlicStateFile):
|
||||
sys.exit('Error input file '+rawPlicStateFile+'not found')
|
||||
|
||||
with open(rawPlicStateFile, 'r') as rawPlicStateFile:
|
||||
plicIntPriorityArray=[]
|
||||
plicIntPriorityArray = [] # iterates over number of different sources
|
||||
# 0x0C000004 thru 0x0C000010
|
||||
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
|
||||
# 0x0C000014 thru 0x0C000020
|
||||
@ -76,20 +80,30 @@ with open(rawPlicStateFile, 'r') as rawPlicStateFile:
|
||||
# 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: x+y,plicIntEnable))
|
||||
# 0x0C020080 thru 0x0C020084
|
||||
plicIntEnable = tokenize(rawPlicStateFile.readline())[1:]
|
||||
plicIntEnable = map(strip0x,plicIntEnable)
|
||||
plicIntEnableArray.append(reduce(lambda x,y: x+y,plicIntEnable))
|
||||
|
||||
plicIntPriorityThresholdArray = [] # iterates over number of different contexts
|
||||
# 0x0C200000
|
||||
plicIntPriorityThreshold = tokenize(rawPlicStateFile.readline())[1:]
|
||||
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 plicIntEnable:
|
||||
outFile.write(stripZeroes(word[2:]))
|
||||
for word in plicIntEnableArray:
|
||||
outFile.write(stripZeroes(word)+'\n')
|
||||
with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile:
|
||||
for word in plicIntPriorityThreshold:
|
||||
for word in plicIntPriorityThresholdArray:
|
||||
outFile.write(stripZeroes(word[2:])+'\n')
|
||||
|
||||
print("Finished parsing PLIC state!")
|
||||
|
@ -4,7 +4,7 @@ import sys, os, subprocess
|
||||
def main():
|
||||
maxGoodCount = 400e6 # num instrs that execute sucessfully starting from 0
|
||||
currInstrCount = maxGoodCount
|
||||
linuxTestvectors = "../../tests/linux-testgen/linux-testvectors"
|
||||
linuxTestvectors = "/opt/riscv/linux-testvectors"
|
||||
if not os.path.exists(linuxTestvectors):
|
||||
sys.stderr.write("Error: Linux testvectors not found at "+linuxTestvectors+"\n")
|
||||
exit(1)
|
||||
@ -22,7 +22,7 @@ def main():
|
||||
break
|
||||
checkpoint = checkpointList[0]
|
||||
logFile = logDir+"checkpoint"+str(checkpoint)+".log"
|
||||
runCommand="{\nvsim -c <<!\ndo wally-pipelined-batch.do buildroot buildroot 0 "+str(checkpoint+1)+" "+str(checkpoint)+"\n!\n} | tee "+logFile
|
||||
runCommand="{\nvsim -c <<!\ndo wally-pipelined-batch.do buildroot buildroot /opt/riscv 0 "+str(checkpoint+1)+" "+str(checkpoint)+"\n!\n} | tee "+logFile
|
||||
print(runCommand)
|
||||
os.system(runCommand)
|
||||
try:
|
||||
|
@ -4,6 +4,7 @@ add wave -noupdate /testbench/clk
|
||||
add wave -noupdate /testbench/reset
|
||||
add wave -noupdate /testbench/reset_ext
|
||||
add wave -noupdate -radix unsigned /testbench/InstrCountW
|
||||
add wave -noupdate -radix unsigned /testbench/AttemptedInstructionCount
|
||||
add wave -noupdate /testbench/dut/core/SATP_REGW
|
||||
add wave -noupdate /testbench/dut/core/IllegalFPUInstrD
|
||||
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/BPPredWrongE
|
||||
@ -388,7 +389,6 @@ add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/cor
|
||||
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PTE
|
||||
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissF
|
||||
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissOrDAFaultF
|
||||
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBMissM
|
||||
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBWriteF
|
||||
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBWriteM
|
||||
add wave -noupdate -group AHB -color Gold /testbench/dut/core/ebu/BusState
|
||||
@ -526,9 +526,7 @@ add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/TakeSpillF
|
||||
add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/SpillF
|
||||
add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/IFUCacheBusStallF
|
||||
add wave -noupdate -color Yellow /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DAPageFault
|
||||
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/OtherPageFault
|
||||
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissF
|
||||
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/Accessed
|
||||
add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/WriteAccess
|
||||
add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/TLBPageFault
|
||||
TreeUpdate [SetDefaultTree]
|
||||
|
@ -70,7 +70,7 @@ for test in tests64gc:
|
||||
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64gc "+test+"\n!",
|
||||
grepstr="All tests ran without failures")
|
||||
configs.append(tc)
|
||||
tests32gc = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32m", "wally32a", "imperas32c", "wally32priv"] #, "imperas32mmu""wally32i",
|
||||
tests32gc = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32m", "wally32a", "imperas32c"] #, "imperas32mmu""wally32i",
|
||||
for test in tests32gc:
|
||||
tc = TestCase(
|
||||
name=test,
|
||||
@ -79,6 +79,25 @@ for test in tests32gc:
|
||||
grepstr="All tests ran without failures")
|
||||
configs.append(tc)
|
||||
|
||||
|
||||
tests64ia = ["wally64priv"]
|
||||
for test in tests64ia:
|
||||
tc = TestCase(
|
||||
name=test,
|
||||
variant="rv64ia",
|
||||
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64ia "+test+"\n!",
|
||||
grepstr="All tests ran without failures")
|
||||
configs.append(tc)
|
||||
|
||||
tests32ia = ["wally32priv"]
|
||||
for test in tests32ia:
|
||||
tc = TestCase(
|
||||
name=test,
|
||||
variant="rv32ia",
|
||||
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv32ia "+test+"\n!",
|
||||
grepstr="All tests ran without failures")
|
||||
configs.append(tc)
|
||||
|
||||
tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c"]
|
||||
for test in tests32ic:
|
||||
tc = TestCase(
|
||||
|
@ -23,40 +23,32 @@ module fcmp (
|
||||
output logic [`FLEN-1:0] CmpResE // compare resilt
|
||||
);
|
||||
|
||||
logic LT, EQ; // is X < or > or = Y
|
||||
|
||||
// X is less than Y:
|
||||
// Signs:
|
||||
// X Y answer
|
||||
// pos pos idk - keep checking
|
||||
// pos neg no
|
||||
// neg pos yes
|
||||
// neg neg idk - keep checking
|
||||
// Exponent
|
||||
// - if XExp < YExp
|
||||
// - if negitive - no
|
||||
// - if positive - yes
|
||||
// - otherwise keep checking
|
||||
// Mantissa
|
||||
// - XMan < YMan then
|
||||
// - if negitive - no
|
||||
// - if positive - yes
|
||||
// note: LT does -0 < 0
|
||||
//*** compare Exp and Man together
|
||||
assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
|
||||
logic LTabs, LT, EQ; // is X < or > or = Y
|
||||
logic BothZeroE, EitherNaNE, EitherSNaNE;
|
||||
|
||||
assign LTabs= {1'b0, XExpE, XManE} < {1'b0, YExpE, YManE}; // unsigned comparison, treating FP as integers
|
||||
assign LT = (XSgnE & ~YSgnE) | (XSgnE & YSgnE & ~LTabs & ~EQ) | (~XSgnE & ~YSgnE & LTabs);
|
||||
//assign LT = $signed({XSgnE, XExpE, XManE[`NF-1:0]}) < $signed({YSgnE, YExpE, YManE[`NF-1:0]});
|
||||
//assign LT = XInt < YInt;
|
||||
// assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
|
||||
assign EQ = (FSrcXE == FSrcYE);
|
||||
|
||||
assign BothZeroE = XZeroE&YZeroE;
|
||||
assign EitherNaNE = XNaNE|YNaNE;
|
||||
assign EitherSNaNE = XSNaNE|YSNaNE;
|
||||
|
||||
|
||||
// flags
|
||||
// Min/Max - if an input is a signaling NaN set invalid flag
|
||||
// LT/LE - signaling - sets invalid if NaN input
|
||||
// EQ - quiet - sets invalid if signaling NaN input
|
||||
always_comb begin
|
||||
case (FOpCtrlE[2:0])
|
||||
3'b111: CmpNVE = XSNaNE|YSNaNE;//min
|
||||
3'b101: CmpNVE = XSNaNE|YSNaNE;//max
|
||||
3'b010: CmpNVE = XSNaNE|YSNaNE;//equal
|
||||
3'b001: CmpNVE = XNaNE|YNaNE;//less than
|
||||
3'b011: CmpNVE = XNaNE|YNaNE;//less than or equal
|
||||
3'b111: CmpNVE = EitherSNaNE;//min
|
||||
3'b101: CmpNVE = EitherSNaNE;//max
|
||||
3'b010: CmpNVE = EitherSNaNE;//equal
|
||||
3'b001: CmpNVE = EitherNaNE;//less than
|
||||
3'b011: CmpNVE = EitherNaNE;//less than or equal
|
||||
default: CmpNVE = 1'b0;
|
||||
endcase
|
||||
end
|
||||
@ -71,24 +63,22 @@ module fcmp (
|
||||
// - inf = inf and -inf = -inf
|
||||
// - return 0 if comparison with NaN (unordered)
|
||||
|
||||
logic [`FLEN-1:0] QNaNX, QNaNY;
|
||||
if(`IEEE754) begin
|
||||
assign QNaNX = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]};
|
||||
assign QNaNY = FmtE ? {YSgnE, YExpE, 1'b1, YManE[`NF-2:0]} : {{32{1'b1}}, YSgnE, YExpE[7:0], 1'b1, YManE[50:29]};
|
||||
end else begin
|
||||
assign QNaNX = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0};
|
||||
assign QNaNY = FmtE ? {1'b0, YExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpE[7:0], 1'b1, 22'b0};
|
||||
end
|
||||
logic [`FLEN-1:0] QNaN;
|
||||
// fmin/fmax of two NaNs returns a quiet NaN of the appropriate size
|
||||
// for IEEE, return the payload of X
|
||||
// for RISC-V, return the canonical NaN
|
||||
if(`IEEE754) assign QNaN = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]};
|
||||
else assign QNaN = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0};
|
||||
|
||||
always_comb begin
|
||||
case (FOpCtrlE[2:0])
|
||||
3'b111: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Min
|
||||
3'b111: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Min
|
||||
: YNaNE ? FSrcXE : LT ? FSrcXE : FSrcYE;
|
||||
3'b101: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Max
|
||||
3'b101: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Max
|
||||
: YNaNE ? FSrcXE : LT ? FSrcYE : FSrcXE;
|
||||
3'b010: CmpResE = {63'b0, (EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Equal
|
||||
3'b001: CmpResE = {63'b0, LT&~(XZeroE&YZeroE)&~(XNaNE|YNaNE)}; // Less than
|
||||
3'b011: CmpResE = {63'b0, (LT|EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Less than or equal
|
||||
3'b010: CmpResE = {63'b0, (EQ|BothZeroE) & ~EitherNaNE}; // Equal
|
||||
3'b001: CmpResE = {63'b0, LT & ~BothZeroE & ~EitherNaNE}; // Less than
|
||||
3'b011: CmpResE = {63'b0, (LT|EQ|BothZeroE) & ~EitherNaNE}; // Less than or equal
|
||||
default: CmpResE = 64'b0;
|
||||
endcase
|
||||
end
|
||||
|
@ -102,6 +102,7 @@ module BTBPredictor
|
||||
// Another optimization may be using a PC relative address.
|
||||
// *** need to add forwarding.
|
||||
|
||||
// *** optimize for byte write enables
|
||||
SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk),
|
||||
.reset(reset),
|
||||
.RA1(LookUpPCIndex),
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////
|
||||
// ram.sv
|
||||
// swbytemask.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
|
@ -43,13 +43,13 @@ module csr #(parameter
|
||||
input logic [31:0] InstrM,
|
||||
input logic [`XLEN-1:0] PCM, SrcAM,
|
||||
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM,
|
||||
input logic TimerIntM, ExtIntM, SwIntM,
|
||||
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
input logic InstrValidM, FRegWriteM, LoadStallD,
|
||||
input logic BPPredDirWrongM,
|
||||
input logic BTBPredPCWrongM,
|
||||
input logic RASPredPCWrongM,
|
||||
input logic BPPredClassNonCFIWrongM,
|
||||
input logic BPPredDirWrongM,
|
||||
input logic BTBPredPCWrongM,
|
||||
input logic RASPredPCWrongM,
|
||||
input logic BPPredClassNonCFIWrongM,
|
||||
input logic [4:0] InstrClassM,
|
||||
input logic DCacheMiss,
|
||||
input logic DCacheAccess,
|
||||
@ -123,7 +123,7 @@ module csr #(parameter
|
||||
assign CSRUWriteM = CSRWriteM;
|
||||
|
||||
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM,
|
||||
.CSRAdrM, .ExtIntM, .TimerIntM, .SwIntM,
|
||||
.CSRAdrM, .ExtIntM, .ExtIntS, .TimerIntM, .SwIntM,
|
||||
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM);
|
||||
csrsr csrsr(.clk, .reset, .StallW,
|
||||
.WriteMSTATUSM, .WriteSSTATUSM,
|
||||
@ -167,7 +167,7 @@ module csr #(parameter
|
||||
|
||||
// merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient
|
||||
assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != `M_MODE) |
|
||||
(CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE);
|
||||
(CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE);
|
||||
assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM &
|
||||
IllegalCSRSAccessM & IllegalCSRUAccessM |
|
||||
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;
|
||||
|
@ -41,7 +41,7 @@ module csri #(parameter
|
||||
input logic InstrValidNotFlushedM, StallW,
|
||||
input logic CSRMWriteM, CSRSWriteM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic ExtIntM, TimerIntM, SwIntM,
|
||||
input logic ExtIntM, ExtIntS, TimerIntM, SwIntM,
|
||||
input logic [`XLEN-1:0] MIDELEG_REGW,
|
||||
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
|
||||
input logic [`XLEN-1:0] CSRWriteValM
|
||||
@ -57,12 +57,12 @@ module csri #(parameter
|
||||
|
||||
always_comb begin
|
||||
IntInM = 0;
|
||||
IntInM[11] = ExtIntM;; // MEIP
|
||||
IntInM[9] = ExtIntM & MIDELEG_REGW[9]; // SEIP
|
||||
IntInM[7] = TimerIntM; // MTIP
|
||||
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
|
||||
IntInM[3] = SwIntM; // MSIP
|
||||
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
|
||||
IntInM[11] = ExtIntM; // MEIP
|
||||
IntInM[9] = (ExtIntM & MIDELEG_REGW[9]); // SEIP
|
||||
IntInM[7] = TimerIntM; // MTIP
|
||||
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
|
||||
IntInM[3] = SwIntM; // MSIP
|
||||
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
|
||||
end
|
||||
|
||||
// Interrupt Write Enables
|
||||
@ -82,22 +82,20 @@ module csri #(parameter
|
||||
assign MIP_WRITE_MASK = 12'h000;
|
||||
assign SIP_WRITE_MASK = 12'h000;
|
||||
end
|
||||
always @(posedge clk) //, posedge reset) begin // *** I strongly feel that IntInM should go directly to IP_REGW -- Ben 9/7/21
|
||||
always @(posedge clk)
|
||||
if (reset) IP_REGW_writeable <= 10'b0;
|
||||
else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable
|
||||
else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable
|
||||
// else if (WriteUIPM) IP_REGW = (CSRWriteValM & 12'hBBB) | (NextIPM & 12'h080); // MTIP unclearable
|
||||
else IP_REGW_writeable <= IP_REGW_writeable | IntInM[9:0]; // *** check this turns off interrupts properly even when MIDELEG changes
|
||||
always @(posedge clk) //, posedge reset) begin
|
||||
else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable
|
||||
else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable
|
||||
else IP_REGW_writeable <= IP_REGW_writeable | {1'b0, IntInM[8:0]}; // *** check this turns off interrupts properly even when MIDELEG changes
|
||||
always @(posedge clk)
|
||||
if (reset) IE_REGW <= 12'b0;
|
||||
else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields
|
||||
else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields
|
||||
// else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field
|
||||
|
||||
// restricted views of registers
|
||||
// Add MEIP read-only signal
|
||||
assign IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable};
|
||||
|
||||
// Add ExtIntM read-only signal
|
||||
assign IP_REGW = {ExtIntM,1'b0,ExtIntS,1'b0, IntInM[7], 7'b0} | {2'b0, IP_REGW_writeable[9], 3'b0, IP_REGW_writeable[5], 3'b0, IP_REGW_writeable[1], 1'b0}; // *** This is just to force the Machine level bits of IP to be unwriteable and to only come from intInM. PLEASE CHANGE ME!!!
|
||||
|
||||
// Machine Mode
|
||||
assign MIP_REGW = IP_REGW;
|
||||
assign MIE_REGW = IE_REGW;
|
||||
|
@ -55,7 +55,7 @@ module privileged (
|
||||
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD,
|
||||
input logic LoadMisalignedFaultM,
|
||||
input logic StoreAmoMisalignedFaultM,
|
||||
input logic TimerIntM, ExtIntM, SwIntM,
|
||||
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
|
||||
input logic [4:0] SetFflagsM,
|
||||
@ -150,7 +150,7 @@ module privileged (
|
||||
.StallE, .StallM, .StallW,
|
||||
.InstrM, .PCM, .SrcAM,
|
||||
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
|
||||
.TimerIntM, .ExtIntM, .SwIntM,
|
||||
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
|
||||
.MTIME_CLINT,
|
||||
.InstrValidM, .FRegWriteM, .LoadStallD,
|
||||
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,
|
||||
|
@ -102,7 +102,7 @@ module trap (
|
||||
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
|
||||
always_comb
|
||||
if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1)
|
||||
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + {CauseM[`XLEN-5:0], 2'b00}, 2'b00};
|
||||
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + CauseM[`XLEN-3:0], 2'b00};
|
||||
else
|
||||
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
|
||||
end
|
||||
|
@ -37,6 +37,15 @@
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
`define N `PLIC_NUM_SRC
|
||||
// number of interrupt sources
|
||||
// does not include source 0, which does not connect to anything according to spec
|
||||
// up to 63 sources supported; *** in the future, allow up to 1023 sources
|
||||
|
||||
`define C 2
|
||||
// number of conexts
|
||||
// hardcoded to 2 contexts for now; *** later upgrade to arbitrary (up to 15872) contexts
|
||||
|
||||
module plic (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic HSELPLIC,
|
||||
@ -48,25 +57,26 @@ module plic (
|
||||
input logic UARTIntr,GPIOIntr,
|
||||
output logic [`XLEN-1:0] HREADPLIC,
|
||||
output logic HRESPPLIC, HREADYPLIC,
|
||||
output logic ExtIntM);
|
||||
|
||||
localparam N=`PLIC_NUM_SRC; // should not exceed 63; does not inlcude source 0, which does not connect to anything according to spec
|
||||
output logic ExtIntM, ExtIntS);
|
||||
|
||||
logic memwrite, memread, initTrans;
|
||||
logic [23:0] entry, entryd;
|
||||
logic [31:0] Din, Dout;
|
||||
logic [N:1] requests;
|
||||
|
||||
logic [2:0] intPriority[N:1];
|
||||
logic [2:0] intThreshold;
|
||||
logic [N:1] intPending, nextIntPending, intEn, intInProgress;
|
||||
logic [5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
||||
|
||||
logic [N:1] pendingArray[7:1];
|
||||
logic [7:1] pendingPGrouped;
|
||||
logic [7:1] pendingMaxP;
|
||||
logic [N:1] pendingRequestsAtMaxP;
|
||||
logic [7:1] threshMask;
|
||||
// context-independent signals
|
||||
logic [`N:1] requests;
|
||||
logic [`N:1][2:0] intPriority;
|
||||
logic [`N:1] intInProgress, intPending, nextIntPending;
|
||||
|
||||
// context-dependent signals
|
||||
logic [`C-1:0][2:0] intThreshold;
|
||||
logic [`C-1:0][`N:1] intEn;
|
||||
logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
||||
logic [`C-1:0][7:1][`N:1] irqMatrix;
|
||||
logic [`C-1:0][7:1] priorities_with_irqs;
|
||||
logic [`C-1:0][7:1] max_priority_with_irqs;
|
||||
logic [`C-1:0][`N:1] irqs_at_max_priority;
|
||||
logic [`C-1:0][7:1] threshMask;
|
||||
|
||||
// =======
|
||||
// AHB I/O
|
||||
@ -82,12 +92,12 @@ module plic (
|
||||
|
||||
// account for subword read/write circuitry
|
||||
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
||||
if (`XLEN == 64) begin
|
||||
if (`XLEN == 64) begin
|
||||
assign Din = entryd[2] ? HWDATA[63:32] : HWDATA[31:0];
|
||||
assign HREADPLIC = entryd[2] ? {Dout,32'b0} : {32'b0,Dout};
|
||||
end else begin // 32-bit
|
||||
assign Din = HWDATA[31:0];
|
||||
assign HREADPLIC = Dout;
|
||||
assign Din = HWDATA[31:0];
|
||||
end
|
||||
|
||||
// ==================
|
||||
@ -96,43 +106,56 @@ module plic (
|
||||
always @(posedge HCLK,negedge HRESETn) begin
|
||||
// resetting
|
||||
if (~HRESETn) begin
|
||||
intPriority <= #1 '{default:3'b0};
|
||||
intEn <= #1 {N{1'b0}};
|
||||
intThreshold <= #1 3'b0;
|
||||
intInProgress <= #1 {N{1'b0}};
|
||||
intPriority <= #1 {`N{3'b0}};
|
||||
intEn <= #1 {2{`N'b0}};
|
||||
intThreshold <= #1 {2{3'b0}};
|
||||
intInProgress <= #1 `N'b0;
|
||||
// writing
|
||||
end else begin
|
||||
if (memwrite)
|
||||
casez(entryd)
|
||||
24'h0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
|
||||
`ifdef PLIC_NUM_SRC_LT_32
|
||||
24'h002000: intEn[N:1] <= #1 Din[N:1];
|
||||
`ifdef PLIC_NUM_SRC_LT_32 // *** switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources
|
||||
24'h002000: intEn[0][`N:1] <= #1 Din[`N:1];
|
||||
24'h002080: intEn[1][`N:1] <= #1 Din[`N:1];
|
||||
`endif
|
||||
`ifndef PLIC_NUM_SRC_LT_32
|
||||
24'h002000: intEn[31:1] <= #1 Din[31:1];
|
||||
24'h002004: intEn[N:32] <= #1 Din[31:0];
|
||||
24'h002000: intEn[0][31:1] <= #1 Din[31:1];
|
||||
24'h002004: intEn[0][`N:32] <= #1 Din[31:0];
|
||||
24'h002080: intEn[1][31:1] <= #1 Din[31:1];
|
||||
24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
|
||||
`endif
|
||||
24'h200000: intThreshold[2:0] <= #1 Din[2:0];
|
||||
24'h200004: intInProgress <= #1 intInProgress & ~(`PLIC_NUM_SRC'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
24'h200000: intThreshold[0] <= #1 Din[2:0];
|
||||
24'h200004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
24'h201000: intThreshold[1] <= #1 Din[2:0];
|
||||
24'h201004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
endcase
|
||||
// reading
|
||||
if (memread)
|
||||
casez(entry)
|
||||
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
||||
`ifdef PLIC_NUM_SRC_LT_32
|
||||
24'h001000: Dout <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
|
||||
24'h002000: Dout <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0};
|
||||
24'h001000: Dout <= #1 {{(31-`N){1'b0}},intPending,1'b0};
|
||||
24'h002000: Dout <= #1 {{(31-`N){1'b0}},intEn[0],1'b0};
|
||||
24'h002080: Dout <= #1 {{(31-`N){1'b0}},intEn[1],1'b0};
|
||||
`endif
|
||||
`ifndef PLIC_NUM_SRC_LT_32
|
||||
24'h001000: Dout <= #1 {intPending[31:1],1'b0};
|
||||
24'h001004: Dout <= #1 {{(63-N){1'b0}},intPending[N:32]};
|
||||
24'h002000: Dout <= #1 {intEn[31:1],1'b0};
|
||||
24'h002004: Dout <= #1 {{(63-N){1'b0}},intEn[N:32]};
|
||||
24'h001004: Dout <= #1 {{(63-`N){1'b0}},intPending[`N:32]};
|
||||
24'h002000: Dout <= #1 {intEn[0][31:1],1'b0};
|
||||
24'h002004: Dout <= #1 {{(63-`N){1'b0}},intEn[0][`N:32]};
|
||||
24'h002080: Dout <= #1 {intEn[0][31:1],1'b0};
|
||||
24'h002084: Dout <= #1 {{(63-`N){1'b0}},intEn[1][`N:32]};
|
||||
`endif
|
||||
24'h200000: Dout <= #1 {29'b0,intThreshold[2:0]};
|
||||
24'h200000: Dout <= #1 {29'b0,intThreshold[0]};
|
||||
24'h200004: begin
|
||||
Dout <= #1 {26'b0,intClaim};
|
||||
intInProgress <= #1 intInProgress | (`PLIC_NUM_SRC'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
Dout <= #1 {26'b0,intClaim[0]};
|
||||
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
end
|
||||
24'h201000: Dout <= #1 {29'b0,intThreshold[1]};
|
||||
24'h201004: begin
|
||||
Dout <= #1 {26'b0,intClaim[1]};
|
||||
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
end
|
||||
default: Dout <= #1 32'h0; // invalid access
|
||||
endcase
|
||||
@ -143,7 +166,7 @@ module plic (
|
||||
|
||||
// connect sources to requests
|
||||
always_comb begin
|
||||
requests = {N{1'b0}};
|
||||
requests = `N'b0;
|
||||
`ifdef PLIC_GPIO_ID
|
||||
requests[`PLIC_GPIO_ID] = GPIOIntr;
|
||||
`endif
|
||||
@ -152,66 +175,88 @@ module plic (
|
||||
`endif
|
||||
end
|
||||
|
||||
// pending updates
|
||||
// *** verify that this matches the expectations of the things that make requests (in terms of timing, edge-triggered vs level-triggered)
|
||||
assign nextIntPending = (intPending | (requests & ~intInProgress)) & // requests should raise intPending except when their service routine is already in progress
|
||||
~({N{((entry == 24'h200004) & memread)}} << (intClaim-1)); // clear pending bit when claim register is read
|
||||
flopr #(N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
|
||||
// pending interrupt requests
|
||||
assign nextIntPending =
|
||||
(intPending | // existing pending requests
|
||||
(requests & ~intInProgress)) & // assert new requests (if they aren't already being serviced)
|
||||
~({`N{((entry == 24'h200004) & memread)}} << (intClaim[0]-1)) & // deassert requests that just completed
|
||||
~({`N{((entry == 24'h201004) & memread)}} << (intClaim[1]-1));
|
||||
flopr #(`N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
|
||||
|
||||
// pending array - indexed by priority_lvl x source_ID
|
||||
genvar i, j;
|
||||
for (j=1; j<=7; j++) begin: pending
|
||||
for (i=1; i<=N; i=i+1) begin: pendingbit
|
||||
assign pendingArray[j][i] = (intPriority[i]==j) & intEn[i] & intPending[i];
|
||||
// context-dependent signals
|
||||
genvar ctx;
|
||||
for (ctx=0; ctx<`C; ctx++) begin
|
||||
// request matrix
|
||||
// priority level (rows) X source ID (columns)
|
||||
//
|
||||
// irqMatrix[ctx][pri][src] is high if source <src>
|
||||
// has priority level <pri> and has an "active" interrupt request
|
||||
// ("active" meaning it is enabled in context <ctx> and is pending)
|
||||
genvar src, pri;
|
||||
for (pri=1; pri<=7; pri++) begin
|
||||
for (src=1; src<=`N; src++) begin
|
||||
assign irqMatrix[ctx][pri][src] = (intPriority[src]==pri) & intPending[src] & intEn[ctx][src];
|
||||
end
|
||||
end
|
||||
end
|
||||
// pending array, except grouped by priority
|
||||
assign pendingPGrouped[7:1] = {|pendingArray[7],
|
||||
|pendingArray[6],
|
||||
|pendingArray[5],
|
||||
|pendingArray[4],
|
||||
|pendingArray[3],
|
||||
|pendingArray[2],
|
||||
|pendingArray[1]};
|
||||
//assign pendingPGrouped = pendingArray.or;
|
||||
|
||||
// pendingPGrouped, except only topmost priority is active
|
||||
assign pendingMaxP[7:1] = {pendingPGrouped[7],
|
||||
pendingPGrouped[6] & ~|pendingPGrouped[7],
|
||||
pendingPGrouped[5] & ~|pendingPGrouped[7:6],
|
||||
pendingPGrouped[4] & ~|pendingPGrouped[7:5],
|
||||
pendingPGrouped[3] & ~|pendingPGrouped[7:4],
|
||||
pendingPGrouped[2] & ~|pendingPGrouped[7:3],
|
||||
pendingPGrouped[1] & ~|pendingPGrouped[7:2]};
|
||||
// select the pending requests at that priority
|
||||
assign pendingRequestsAtMaxP[N:1] = ({N{pendingMaxP[7]}} & pendingArray[7])
|
||||
| ({N{pendingMaxP[6]}} & pendingArray[6])
|
||||
| ({N{pendingMaxP[5]}} & pendingArray[5])
|
||||
| ({N{pendingMaxP[4]}} & pendingArray[4])
|
||||
| ({N{pendingMaxP[3]}} & pendingArray[3])
|
||||
| ({N{pendingMaxP[2]}} & pendingArray[2])
|
||||
| ({N{pendingMaxP[1]}} & pendingArray[1]);
|
||||
// find the lowest ID amongst active interrupts at the highest priority
|
||||
logic [5:0] k;
|
||||
always_comb begin
|
||||
intClaim = 6'b0;
|
||||
for (k=N; k>0; k=k-1) begin
|
||||
if (pendingRequestsAtMaxP[k]) intClaim = k;
|
||||
// which prority levels have one or more active requests?
|
||||
assign priorities_with_irqs[ctx][7:1] = {
|
||||
|irqMatrix[ctx][7],
|
||||
|irqMatrix[ctx][6],
|
||||
|irqMatrix[ctx][5],
|
||||
|irqMatrix[ctx][4],
|
||||
|irqMatrix[ctx][3],
|
||||
|irqMatrix[ctx][2],
|
||||
|irqMatrix[ctx][1]
|
||||
};
|
||||
|
||||
// get the highest priority level that has active requests
|
||||
assign max_priority_with_irqs[ctx][7:1] = {
|
||||
priorities_with_irqs[ctx][7],
|
||||
priorities_with_irqs[ctx][6] & ~|priorities_with_irqs[ctx][7],
|
||||
priorities_with_irqs[ctx][5] & ~|priorities_with_irqs[ctx][7:6],
|
||||
priorities_with_irqs[ctx][4] & ~|priorities_with_irqs[ctx][7:5],
|
||||
priorities_with_irqs[ctx][3] & ~|priorities_with_irqs[ctx][7:4],
|
||||
priorities_with_irqs[ctx][2] & ~|priorities_with_irqs[ctx][7:3],
|
||||
priorities_with_irqs[ctx][1] & ~|priorities_with_irqs[ctx][7:2]
|
||||
};
|
||||
|
||||
// of the sources at the highest priority level that has active requests,
|
||||
// which sources have active requests?
|
||||
assign irqs_at_max_priority[ctx][`N:1] =
|
||||
({`N{max_priority_with_irqs[ctx][7]}} & irqMatrix[ctx][7]) |
|
||||
({`N{max_priority_with_irqs[ctx][6]}} & irqMatrix[ctx][6]) |
|
||||
({`N{max_priority_with_irqs[ctx][5]}} & irqMatrix[ctx][5]) |
|
||||
({`N{max_priority_with_irqs[ctx][4]}} & irqMatrix[ctx][4]) |
|
||||
({`N{max_priority_with_irqs[ctx][3]}} & irqMatrix[ctx][3]) |
|
||||
({`N{max_priority_with_irqs[ctx][2]}} & irqMatrix[ctx][2]) |
|
||||
({`N{max_priority_with_irqs[ctx][1]}} & irqMatrix[ctx][1]);
|
||||
|
||||
// of the sources at the highest priority level that has active requests,
|
||||
// choose the source with the lowest source ID to be the most urgent
|
||||
// and set intClaim to the source ID of the most urgent active request
|
||||
integer k;
|
||||
always_comb begin
|
||||
intClaim[ctx] = 6'b0;
|
||||
for (k=`N; k>0; k--) begin
|
||||
if (irqs_at_max_priority[ctx][k]) intClaim[ctx] = k[5:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// create threshold mask
|
||||
always_comb begin
|
||||
threshMask[7] = (intThreshold != 7);
|
||||
threshMask[6] = (intThreshold != 6) & threshMask[7];
|
||||
threshMask[5] = (intThreshold != 5) & threshMask[6];
|
||||
threshMask[4] = (intThreshold != 4) & threshMask[5];
|
||||
threshMask[3] = (intThreshold != 3) & threshMask[4];
|
||||
threshMask[2] = (intThreshold != 2) & threshMask[3];
|
||||
threshMask[1] = (intThreshold != 1) & threshMask[2];
|
||||
end
|
||||
// is the max priority > threshold?
|
||||
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
|
||||
assign ExtIntM = |(threshMask & pendingPGrouped);
|
||||
|
||||
// create threshold mask
|
||||
always_comb begin
|
||||
threshMask[ctx][7] = (intThreshold[ctx] != 7);
|
||||
threshMask[ctx][6] = (intThreshold[ctx] != 6) & threshMask[ctx][7];
|
||||
threshMask[ctx][5] = (intThreshold[ctx] != 5) & threshMask[ctx][6];
|
||||
threshMask[ctx][4] = (intThreshold[ctx] != 4) & threshMask[ctx][5];
|
||||
threshMask[ctx][3] = (intThreshold[ctx] != 3) & threshMask[ctx][4];
|
||||
threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3];
|
||||
threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2];
|
||||
end
|
||||
// is the max priority > threshold?
|
||||
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
|
||||
end
|
||||
assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]);
|
||||
assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]);
|
||||
endmodule
|
||||
|
||||
|
@ -55,7 +55,7 @@ module uncore (
|
||||
input logic [3:0] HSIZED,
|
||||
input logic HWRITED,
|
||||
// peripheral pins
|
||||
output logic TimerIntM, SwIntM, ExtIntM,
|
||||
output logic TimerIntM, SwIntM, ExtIntM, ExtIntS,
|
||||
input logic [31:0] GPIOPinsIn,
|
||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
||||
input logic UARTSin,
|
||||
@ -133,9 +133,10 @@ module uncore (
|
||||
.HWRITE, .HREADY, .HTRANS, .HWDATA,
|
||||
.UARTIntr, .GPIOIntr,
|
||||
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
|
||||
.ExtIntM);
|
||||
.ExtIntM, .ExtIntS);
|
||||
end else begin : plic
|
||||
assign ExtIntM = 0;
|
||||
assign ExtIntS = 0;
|
||||
end
|
||||
if (`GPIO_SUPPORTED == 1) begin : gpio
|
||||
gpio gpio(
|
||||
|
@ -32,137 +32,137 @@
|
||||
/* verilator lint_on UNUSED */
|
||||
|
||||
module wallypipelinedcore (
|
||||
input logic clk, reset,
|
||||
input logic clk, reset,
|
||||
// Privileged
|
||||
input logic TimerIntM, ExtIntM, SwIntM,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
// Bus Interface
|
||||
input logic [`AHBW-1:0] HRDATA,
|
||||
input logic HREADY, HRESP,
|
||||
output logic HCLK, HRESETn,
|
||||
output logic [31:0] HADDR,
|
||||
input logic HREADY, HRESP,
|
||||
output logic HCLK, HRESETn,
|
||||
output logic [31:0] HADDR,
|
||||
output logic [`AHBW-1:0] HWDATA,
|
||||
output logic HWRITE,
|
||||
output logic [2:0] HSIZE,
|
||||
output logic [2:0] HBURST,
|
||||
output logic [3:0] HPROT,
|
||||
output logic [1:0] HTRANS,
|
||||
output logic HMASTLOCK,
|
||||
output logic HWRITE,
|
||||
output logic [2:0] HSIZE,
|
||||
output logic [2:0] HBURST,
|
||||
output logic [3:0] HPROT,
|
||||
output logic [1:0] HTRANS,
|
||||
output logic HMASTLOCK,
|
||||
// Delayed signals for subword write
|
||||
output logic [2:0] HADDRD,
|
||||
output logic [3:0] HSIZED,
|
||||
output logic HWRITED
|
||||
output logic [2:0] HADDRD,
|
||||
output logic [3:0] HSIZED,
|
||||
output logic HWRITED
|
||||
);
|
||||
|
||||
// logic [1:0] ForwardAE, ForwardBE;
|
||||
logic StallF, StallD, StallE, StallM, StallW;
|
||||
logic FlushF, FlushD, FlushE, FlushM, FlushW;
|
||||
logic RetM;
|
||||
logic StallF, StallD, StallE, StallM, StallW;
|
||||
logic FlushF, FlushD, FlushE, FlushM, FlushW;
|
||||
logic RetM;
|
||||
(* mark_debug = "true" *) logic TrapM;
|
||||
|
||||
// new signals that must connect through DP
|
||||
logic MDUE, W64E;
|
||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||
logic [1:0] AtomicE;
|
||||
logic [1:0] AtomicM;
|
||||
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
|
||||
logic [`XLEN-1:0] SrcAM;
|
||||
logic [2:0] Funct3E;
|
||||
logic MDUE, W64E;
|
||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||
logic [1:0] AtomicE;
|
||||
logic [1:0] AtomicM;
|
||||
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
|
||||
logic [`XLEN-1:0] SrcAM;
|
||||
logic [2:0] Funct3E;
|
||||
// logic [31:0] InstrF;
|
||||
logic [31:0] InstrD, InstrW;
|
||||
(* mark_debug = "true" *) logic [31:0] InstrM;
|
||||
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
|
||||
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
||||
logic [`XLEN-1:0] PrivilegedNextPCM;
|
||||
(* mark_debug = "true" *) logic [1:0] MemRWM;
|
||||
(* mark_debug = "true" *) logic InstrValidM;
|
||||
logic InstrMisalignedFaultM;
|
||||
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
||||
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
|
||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
||||
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
||||
logic [31:0] InstrD, InstrW;
|
||||
(* mark_debug = "true" *) logic [31:0] InstrM;
|
||||
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
|
||||
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
||||
logic [`XLEN-1:0] PrivilegedNextPCM;
|
||||
(* mark_debug = "true" *) logic [1:0] MemRWM;
|
||||
(* mark_debug = "true" *) logic InstrValidM;
|
||||
logic InstrMisalignedFaultM;
|
||||
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
||||
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
|
||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
||||
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
||||
logic InvalidateICacheM, FlushDCacheM;
|
||||
logic PCSrcE;
|
||||
logic CSRWritePendingDEM;
|
||||
logic DivBusyE;
|
||||
logic PCSrcE;
|
||||
logic CSRWritePendingDEM;
|
||||
logic DivBusyE;
|
||||
logic DivE;
|
||||
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
||||
logic SquashSCW;
|
||||
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
||||
logic SquashSCW;
|
||||
// floating point unit signals
|
||||
logic [2:0] FRM_REGW;
|
||||
logic [2:0] FRM_REGW;
|
||||
logic [4:0] RdM, RdW;
|
||||
logic FStallD;
|
||||
logic FWriteIntE;
|
||||
logic [`XLEN-1:0] FWriteDataE;
|
||||
logic [`XLEN-1:0] FIntResM;
|
||||
logic FDivBusyE;
|
||||
logic IllegalFPUInstrD, IllegalFPUInstrE;
|
||||
logic FRegWriteM;
|
||||
logic FPUStallD;
|
||||
logic [4:0] SetFflagsM;
|
||||
logic FStallD;
|
||||
logic FWriteIntE;
|
||||
logic [`XLEN-1:0] FWriteDataE;
|
||||
logic [`XLEN-1:0] FIntResM;
|
||||
logic FDivBusyE;
|
||||
logic IllegalFPUInstrD, IllegalFPUInstrE;
|
||||
logic FRegWriteM;
|
||||
logic FPUStallD;
|
||||
logic [4:0] SetFflagsM;
|
||||
|
||||
// memory management unit signals
|
||||
logic ITLBWriteF;
|
||||
logic ITLBFlushF, DTLBFlushM;
|
||||
logic ITLBMissF;
|
||||
logic [`XLEN-1:0] SATP_REGW;
|
||||
logic ITLBWriteF;
|
||||
logic ITLBFlushF, DTLBFlushM;
|
||||
logic ITLBMissF;
|
||||
logic [`XLEN-1:0] SATP_REGW;
|
||||
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
|
||||
logic [1:0] STATUS_MPP;
|
||||
logic [1:0] PrivilegeModeW;
|
||||
logic [`XLEN-1:0] PTE;
|
||||
logic [1:0] PageType;
|
||||
logic [1:0] PrivilegeModeW;
|
||||
logic [`XLEN-1:0] PTE;
|
||||
logic [1:0] PageType;
|
||||
|
||||
// PMA checker signals
|
||||
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
|
||||
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
||||
|
||||
// IMem stalls
|
||||
logic IFUStallF;
|
||||
logic LSUStallM;
|
||||
logic IFUStallF;
|
||||
logic LSUStallM;
|
||||
|
||||
|
||||
|
||||
// cpu lsu interface
|
||||
logic [2:0] Funct3M;
|
||||
logic [`XLEN-1:0] IEUAdrE;
|
||||
logic [2:0] Funct3M;
|
||||
logic [`XLEN-1:0] IEUAdrE;
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataE;
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM;
|
||||
logic [`XLEN-1:0] ReadDataW;
|
||||
logic CommittedM;
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM;
|
||||
logic [`XLEN-1:0] ReadDataW;
|
||||
logic CommittedM;
|
||||
|
||||
// AHB ifu interface
|
||||
logic [`PA_BITS-1:0] IFUBusAdr;
|
||||
logic [`XLEN-1:0] IFUBusHRDATA;
|
||||
logic IFUBusRead;
|
||||
logic IFUBusAck;
|
||||
logic [`PA_BITS-1:0] IFUBusAdr;
|
||||
logic [`XLEN-1:0] IFUBusHRDATA;
|
||||
logic IFUBusRead;
|
||||
logic IFUBusAck;
|
||||
|
||||
// AHB LSU interface
|
||||
logic [`PA_BITS-1:0] LSUBusAdr;
|
||||
logic LSUBusRead;
|
||||
logic LSUBusWrite;
|
||||
logic LSUBusAck;
|
||||
logic [`XLEN-1:0] LSUBusHRDATA;
|
||||
logic [`XLEN-1:0] LSUBusHWDATA;
|
||||
logic [`PA_BITS-1:0] LSUBusAdr;
|
||||
logic LSUBusRead;
|
||||
logic LSUBusWrite;
|
||||
logic LSUBusAck;
|
||||
logic [`XLEN-1:0] LSUBusHRDATA;
|
||||
logic [`XLEN-1:0] LSUBusHWDATA;
|
||||
|
||||
logic BPPredWrongE;
|
||||
logic BPPredDirWrongM;
|
||||
logic BTBPredPCWrongM;
|
||||
logic RASPredPCWrongM;
|
||||
logic BPPredClassNonCFIWrongM;
|
||||
logic [4:0] InstrClassM;
|
||||
logic InstrAccessFaultF;
|
||||
logic [2:0] LSUBusSize;
|
||||
logic BPPredWrongE;
|
||||
logic BPPredDirWrongM;
|
||||
logic BTBPredPCWrongM;
|
||||
logic RASPredPCWrongM;
|
||||
logic BPPredClassNonCFIWrongM;
|
||||
logic [4:0] InstrClassM;
|
||||
logic InstrAccessFaultF;
|
||||
logic [2:0] LSUBusSize;
|
||||
|
||||
logic ExceptionM;
|
||||
logic PendingInterruptM;
|
||||
logic DCacheMiss;
|
||||
logic DCacheAccess;
|
||||
logic ICacheMiss;
|
||||
logic ICacheAccess;
|
||||
logic BreakpointFaultM, EcallFaultM;
|
||||
logic ExceptionM;
|
||||
logic PendingInterruptM;
|
||||
logic DCacheMiss;
|
||||
logic DCacheAccess;
|
||||
logic ICacheMiss;
|
||||
logic ICacheAccess;
|
||||
logic BreakpointFaultM, EcallFaultM;
|
||||
logic InstrDAPageFaultF;
|
||||
|
||||
ifu ifu(
|
||||
@ -182,7 +182,7 @@ module wallypipelinedcore (
|
||||
|
||||
// Mem
|
||||
.RetM, .TrapM, .PrivilegedNextPCM, .InvalidateICacheM,
|
||||
.InstrD, .InstrM, . PCM, .InstrClassM, .BPPredDirWrongM,
|
||||
.InstrD, .InstrM, .PCM, .InstrClassM, .BPPredDirWrongM,
|
||||
.BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
|
||||
|
||||
// Writeback
|
||||
@ -203,8 +203,8 @@ module wallypipelinedcore (
|
||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||
.InstrAccessFaultF,
|
||||
.InstrDAPageFaultF
|
||||
|
||||
); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||
|
||||
); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||
|
||||
ieu ieu(
|
||||
.clk, .reset,
|
||||
@ -221,7 +221,7 @@ module wallypipelinedcore (
|
||||
// Memory stage interface
|
||||
.SquashSCW, // from LSU
|
||||
.MemRWM, // read/write control goes to LSU
|
||||
.AtomicE, // atomic control goes to LSU
|
||||
.AtomicE, // atomic control goes to LSU
|
||||
.AtomicM, // atomic control goes to LSU
|
||||
.WriteDataE, // Write data to LSU
|
||||
.Funct3M, // size and signedness to LSU
|
||||
@ -245,41 +245,41 @@ module wallypipelinedcore (
|
||||
|
||||
lsu lsu(
|
||||
.clk, .reset, .StallM, .FlushM, .StallW,
|
||||
.FlushW,
|
||||
// CPU interface
|
||||
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
|
||||
.AtomicM, .TrapM,
|
||||
.CommittedM, .DCacheMiss, .DCacheAccess,
|
||||
.SquashSCW,
|
||||
//.DataMisalignedM(DataMisalignedM),
|
||||
.IEUAdrE, .IEUAdrM, .WriteDataE,
|
||||
.ReadDataM, .FlushDCacheM,
|
||||
// connected to ahb (all stay the same)
|
||||
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
|
||||
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
|
||||
.FlushW,
|
||||
// CPU interface
|
||||
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
|
||||
.AtomicM, .TrapM,
|
||||
.CommittedM, .DCacheMiss, .DCacheAccess,
|
||||
.SquashSCW,
|
||||
//.DataMisalignedM(DataMisalignedM),
|
||||
.IEUAdrE, .IEUAdrM, .WriteDataE,
|
||||
.ReadDataM, .FlushDCacheM,
|
||||
// connected to ahb (all stay the same)
|
||||
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
|
||||
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
|
||||
|
||||
// connect to csr or privilege and stay the same.
|
||||
.PrivilegeModeW, // connects to csr
|
||||
.PMPCFG_ARRAY_REGW, // connects to csr
|
||||
.PMPADDR_ARRAY_REGW, // connects to csr
|
||||
// hptw keep i/o
|
||||
.SATP_REGW, // from csr
|
||||
.STATUS_MXR, // from csr
|
||||
.STATUS_SUM, // from csr
|
||||
.STATUS_MPRV, // from csr
|
||||
.STATUS_MPP, // from csr
|
||||
// connect to csr or privilege and stay the same.
|
||||
.PrivilegeModeW, // connects to csr
|
||||
.PMPCFG_ARRAY_REGW, // connects to csr
|
||||
.PMPADDR_ARRAY_REGW, // connects to csr
|
||||
// hptw keep i/o
|
||||
.SATP_REGW, // from csr
|
||||
.STATUS_MXR, // from csr
|
||||
.STATUS_SUM, // from csr
|
||||
.STATUS_MPRV, // from csr
|
||||
.STATUS_MPP, // from csr
|
||||
|
||||
.DTLBFlushM, // connects to privilege
|
||||
.LoadPageFaultM, // connects to privilege
|
||||
.StoreAmoPageFaultM, // connects to privilege
|
||||
.LoadMisalignedFaultM, // connects to privilege
|
||||
.LoadAccessFaultM, // connects to privilege
|
||||
.StoreAmoMisalignedFaultM, // connects to privilege
|
||||
.StoreAmoAccessFaultM, // connects to privilege
|
||||
.DTLBFlushM, // connects to privilege
|
||||
.LoadPageFaultM, // connects to privilege
|
||||
.StoreAmoPageFaultM, // connects to privilege
|
||||
.LoadMisalignedFaultM, // connects to privilege
|
||||
.LoadAccessFaultM, // connects to privilege
|
||||
.StoreAmoMisalignedFaultM, // connects to privilege
|
||||
.StoreAmoAccessFaultM, // connects to privilege
|
||||
.InstrDAPageFaultF,
|
||||
|
||||
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
|
||||
.LSUStallM); // change to LSUStallM
|
||||
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
|
||||
.LSUStallM); // change to LSUStallM
|
||||
|
||||
|
||||
// *** Ross: please make EBU conditional when only supporting internal memories
|
||||
@ -306,13 +306,13 @@ module wallypipelinedcore (
|
||||
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
||||
.LSUStallM, .IFUStallF,
|
||||
.FPUStallD, .FStallD,
|
||||
.DivBusyE, .FDivBusyE,
|
||||
.EcallFaultM, .BreakpointFaultM,
|
||||
.DivBusyE, .FDivBusyE,
|
||||
.EcallFaultM, .BreakpointFaultM,
|
||||
.InvalidateICacheM,
|
||||
// Stall & flush outputs
|
||||
.StallF, .StallD, .StallE, .StallM, .StallW,
|
||||
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
||||
); // global stall and flush control
|
||||
.StallF, .StallD, .StallE, .StallM, .StallW,
|
||||
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
||||
); // global stall and flush control
|
||||
|
||||
if (`ZICSR_SUPPORTED) begin:priv
|
||||
privileged priv(
|
||||
@ -331,7 +331,7 @@ module wallypipelinedcore (
|
||||
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
|
||||
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
|
||||
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
|
||||
.TimerIntM, .ExtIntM, .SwIntM,
|
||||
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
|
||||
.MTIME_CLINT,
|
||||
.InstrMisalignedAdrM, .IEUAdrM,
|
||||
.SetFflagsM,
|
||||
|
@ -74,7 +74,7 @@ module wallypipelinedsoc (
|
||||
logic HRESP;
|
||||
logic TimerIntM, SwIntM; // from CLINT
|
||||
logic [63:0] MTIME_CLINT; // from CLINT to CSRs
|
||||
logic ExtIntM; // from PLIC
|
||||
logic ExtIntM,ExtIntS; // from PLIC
|
||||
logic [2:0] HADDRD;
|
||||
logic [3:0] HSIZED;
|
||||
logic HWRITED;
|
||||
@ -84,7 +84,7 @@ module wallypipelinedsoc (
|
||||
|
||||
// instantiate processor and memories
|
||||
wallypipelinedcore core(.clk, .reset,
|
||||
.TimerIntM, .ExtIntM, .SwIntM,
|
||||
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
|
||||
.MTIME_CLINT,
|
||||
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA,
|
||||
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
|
||||
@ -94,7 +94,7 @@ module wallypipelinedsoc (
|
||||
uncore uncore(.HCLK, .HRESETn, .TIMECLK,
|
||||
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
||||
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED,
|
||||
.TimerIntM, .SwIntM, .ExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
|
||||
.TimerIntM, .SwIntM, .ExtIntM, .ExtIntS, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
|
||||
.HSELEXT,
|
||||
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK
|
||||
|
||||
|
@ -176,6 +176,7 @@ module testbench;
|
||||
integer CheckMIPFutureM;
|
||||
integer CheckSIPFutureE;
|
||||
integer CheckSIPFutureM;
|
||||
logic [`XLEN-1:0] AttemptedInstructionCount;
|
||||
// Useful Aliases
|
||||
`define RF dut.core.ieu.dp.regf.rf
|
||||
`define PC dut.core.ifu.pcreg.q
|
||||
@ -266,6 +267,19 @@ module testbench;
|
||||
end \
|
||||
end
|
||||
|
||||
`define INIT_CHECKPOINT_PACKED_ARRAY(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
||||
`MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
||||
for (i=ARRAY_MIN; i<ARRAY_MAX+1; i=i+1) begin \
|
||||
initial begin \
|
||||
if (CHECKPOINT!=0) begin \
|
||||
force `SIGNAL[i] = init``SIGNAL[i]; \
|
||||
while (reset!==1) #1; \
|
||||
while (reset!==0) #1; \
|
||||
#1; \
|
||||
release `SIGNAL[i]; \
|
||||
end \
|
||||
end \
|
||||
end
|
||||
// For the annoying case where the pathname to the array elements includes
|
||||
// a "genblk<i>" in the signal name
|
||||
`define INIT_CHECKPOINT_GENBLK_ARRAY(SIGNAL_BASE,SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
||||
@ -296,6 +310,7 @@ module testbench;
|
||||
end \
|
||||
end
|
||||
|
||||
genvar i;
|
||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1);
|
||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,0);
|
||||
`INIT_CHECKPOINT_VAL(PC, [`XLEN-1:0]);
|
||||
@ -333,9 +348,9 @@ module testbench;
|
||||
//`INIT_CHECKPOINT_VAL(UART_LSR, [7:0]);
|
||||
//`INIT_CHECKPOINT_VAL(UART_MSR, [7:0]);
|
||||
`INIT_CHECKPOINT_VAL(UART_SCR, [7:0]);
|
||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
|
||||
`INIT_CHECKPOINT_VAL(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1]);
|
||||
`INIT_CHECKPOINT_VAL(PLIC_THRESHOLD, [2:0]);
|
||||
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
|
||||
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0);
|
||||
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_THRESHOLD, [2:0],1,0);
|
||||
|
||||
integer memFile;
|
||||
integer readResult;
|
||||
@ -366,11 +381,13 @@ module testbench;
|
||||
traceFileM = $fopen({testvectorDir,"all.txt"}, "r");
|
||||
traceFileE = $fopen({testvectorDir,"all.txt"}, "r");
|
||||
InstrCountW = '0;
|
||||
AttemptedInstructionCount = '0;
|
||||
end else begin // checkpoint
|
||||
//$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.memory.RAM);
|
||||
traceFileE = $fopen({checkpointDir,"all.txt"}, "r");
|
||||
traceFileM = $fopen({checkpointDir,"all.txt"}, "r");
|
||||
InstrCountW = CHECKPOINT;
|
||||
AttemptedInstructionCount = CHECKPOINT;
|
||||
// manual checkpoint initializations that don't neatly fit into MACRO
|
||||
force {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV} = initMSTATUS[0][22:17];
|
||||
force {`STATUS_FS,`STATUS_MPP} = initMSTATUS[0][14:11];
|
||||
@ -426,6 +443,9 @@ module testbench;
|
||||
for(index``STAGE = 0; index``STAGE < line``STAGE.len(); index``STAGE++) begin \
|
||||
//$display("char = %s", line``STAGE[index]); \
|
||||
if (line``STAGE[index``STAGE] == " " | line``STAGE[index``STAGE] == "\n") begin \
|
||||
if (line``STAGE[index``STAGE] == "\n" & `"STAGE`"=="M") begin \
|
||||
AttemptedInstructionCount += 1; \
|
||||
end \
|
||||
EndIndex``STAGE = index``STAGE; \
|
||||
ExpectedTokens``STAGE[TokenIndex``STAGE] = line``STAGE.substr(StartIndex``STAGE, EndIndex``STAGE-1); \
|
||||
//$display("In Tokenizer %s", line``STAGE.substr(StartIndex, EndIndex-1)); \
|
||||
|
@ -959,7 +959,7 @@ string imperas32f[] = '{
|
||||
"rv64i_m/I/andi-01", "6010",
|
||||
"rv64i_m/I/auipc-01", "2010",
|
||||
"rv64i_m/I/beq-01", "47010",
|
||||
"rv64i_m/I/bge-01", "47010",
|
||||
"rv64i_m/I/bge-01", "46010",
|
||||
"rv64i_m/I/bgeu-01", "56010",
|
||||
"rv64i_m/I/blt-01", "4d010",
|
||||
"rv64i_m/I/bltu-01", "57010",
|
||||
@ -1450,34 +1450,36 @@ string imperas32f[] = '{
|
||||
|
||||
string wally64priv[] = '{
|
||||
`WALLYTEST,
|
||||
"rv64i_m/privilege/WALLY-CSR-permission-s-01", "004080",
|
||||
"rv64i_m/privilege/WALLY-CSR-permission-s-01", "0050a0",
|
||||
//"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-M", "005070",
|
||||
//"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-S", "003070",
|
||||
"rv64i_m/privilege/WALLY-CSR-permission-u-01", "005080",
|
||||
"rv64i_m/privilege/WALLY-CSR-permission-u-01", "0050a0",
|
||||
// "rv64i_m/privilege/WALLY-MARCHID", "003070",
|
||||
/* "rv64i_m/privilege/WALLY-MCAUSE", "003070",
|
||||
"rv64i_m/privilege/WALLY-MEDELEG", "003070",
|
||||
"rv64i_m/privilege/WALLY-MHARTID", "003070",
|
||||
"rv64i_m/privilege/WALLY-MIMPID", "003070",*/
|
||||
"rv64i_m/privilege/WALLY-minfo-01", "004080",
|
||||
"rv64i_m/privilege/WALLY-misa-01", "004080",
|
||||
"rv64i_m/privilege/WALLY-MMU-SV39", "004080",
|
||||
"rv64i_m/privilege/WALLY-MMU-SV48", "004080",
|
||||
"rv64i_m/privilege/WALLY-minfo-01", "0040a0",
|
||||
"rv64i_m/privilege/WALLY-misa-01", "0040a0",
|
||||
"rv64i_m/privilege/WALLY-MMU-SV39", "0040a0",
|
||||
"rv64i_m/privilege/WALLY-MMU-SV48", "0040a0",
|
||||
/* "rv64i_m/privilege/WALLY-MSTATUS", "002070",
|
||||
"rv64i_m/privilege/WALLY-MTVEC", "002070",
|
||||
"rv64i_m/privilege/WALLY-MVENDORID", "003070", */
|
||||
"rv64i_m/privilege/WALLY-PMA", "004080",
|
||||
"rv64i_m/privilege/WALLY-PMP", "004080",
|
||||
"rv64i_m/privilege/WALLY-PMA", "0040a0",
|
||||
"rv64i_m/privilege/WALLY-PMP", "0040a0",
|
||||
// "rv64i_m/privilege/WALLY-SCAUSE", "002070",
|
||||
"rv64i_m/privilege/WALLY-scratch-01", "004080",
|
||||
"rv64i_m/privilege/WALLY-sscratch-s-01", "004080"
|
||||
"rv64i_m/privilege/WALLY-scratch-01", "0040a0",
|
||||
"rv64i_m/privilege/WALLY-sscratch-s-01", "0040a0"
|
||||
// "rv64i_m/privilege/WALLY-trap-01", "0040a0"
|
||||
// "rv64i_m/privilege/WALLY-STVEC", "002070",
|
||||
// "rv64i_m/privilege/WALLY-UCAUSE", "002070"
|
||||
// "rv64i_m/privilege/WALLY-UCAUSE", "002070",
|
||||
|
||||
};
|
||||
|
||||
string wally64periph[] = '{
|
||||
`WALLYTEST,
|
||||
"rv64i_m/privilege/WALLY-PERIPH", "22f0"
|
||||
"rv64i_m/privilege/WALLY-PERIPH", "3310"
|
||||
};
|
||||
|
||||
string wally32e[] = '{
|
||||
|
@ -50,10 +50,47 @@
|
||||
// Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries)
|
||||
`define PMPCFG_ENTRIES (`PMP_ENTRIES/8)
|
||||
|
||||
|
||||
// Floating-point half-precision
|
||||
`define ZFH_SUPPORTED 0
|
||||
|
||||
// Floating point constants for Quad, Double, Single, and Half precisions
|
||||
`define Q_LEN 128
|
||||
`define Q_NE 15
|
||||
`define Q_NF 112
|
||||
`define Q_BIAS 16383
|
||||
`define D_LEN 64
|
||||
`define D_NE 11
|
||||
`define D_NF 52
|
||||
`define D_BIAS 1023
|
||||
`define S_LEN 32
|
||||
`define S_NE 8
|
||||
`define S_NF 23
|
||||
`define S_BIAS 127
|
||||
`define H_LEN 16
|
||||
`define H_NE 5
|
||||
`define H_NF 10
|
||||
`define H_BIAS 15
|
||||
|
||||
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits
|
||||
`define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32)
|
||||
`define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
|
||||
`define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
|
||||
`define FLEN (`Q_SUPPORTED ? `Q_LEN : `D_SUPPORTED ? `D_LEN : `F_SUPPORTED ? `S_LEN : `H_LEN)
|
||||
`define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE)
|
||||
`define NF (`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF)
|
||||
`define FMT (`Q_SUPPORTED ? 3 : `D_SUPPORTED ? 1 : `F_SUPPORTED ? 0 : 2)
|
||||
`define BIAS (`Q_SUPPORTED ? `Q_BIAS : `D_SUPPORTED ? `D_BIAS : `F_SUPPORTED ? `S_BIAS : `H_BIAS)
|
||||
|
||||
// Floating point constants needed for FPU paramerterization
|
||||
`define FPSIZES (`Q_SUPPORTED+`D_SUPPORTED+`F_SUPPORTED+`ZFH_SUPPORTED)
|
||||
`define LEN1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_LEN : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_LEN : `H_LEN)
|
||||
`define NE1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NE : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NE : `H_NE)
|
||||
`define NF1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NF : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NF : `H_NF)
|
||||
`define FMT1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? 1 : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? 0 : 2)
|
||||
`define BIAS1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_BIAS : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_BIAS : `H_BIAS)
|
||||
`define LEN2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_LEN : `H_LEN)
|
||||
`define NE2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NE : `H_NE)
|
||||
`define NF2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NF : `H_NF)
|
||||
`define FMT2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? 0 : 2)
|
||||
`define BIAS2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_BIAS : `H_BIAS)
|
||||
|
||||
// Disable spurious Verilator warnings
|
||||
|
||||
|
@ -56,7 +56,8 @@ target_tests_nosim = \
|
||||
WALLY-MIMPID \
|
||||
WALLY-MVENDORID \
|
||||
WALLY-CSR-PERMISSIONS-M \
|
||||
WALLY-CSR-PERMISSIONS-S
|
||||
WALLY-CSR-PERMISSIONS-S \
|
||||
WALLY-trap-01 \
|
||||
# Have all 0's in references!
|
||||
#WALLY-MEPC \
|
||||
#WALLY-SEPC \
|
||||
|
@ -1,3 +1,93 @@
|
||||
00000aaa # Test 5.3.1.4: readback value from writing mie to enable interrupts
|
||||
00000000
|
||||
00000001 # mcause from an instruction access fault
|
||||
00000000
|
||||
00000000 # mtval of faulting instruction address (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000002 # mcause from an Illegal instruction
|
||||
00000000
|
||||
00000000 # mtval of faulting instruction (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000003 # mcause from Breakpoint
|
||||
00000000
|
||||
800003ec # mtval of breakpoint instruction adress (0x800003ec)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000004 # mcause from load address misaligned
|
||||
00000000
|
||||
800003f5 # mtval of misaligned address (0x800003f5)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000005 # mcause from load access
|
||||
00000000
|
||||
00000000 # mtval of accessed adress (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000006 # mcause from store misaligned
|
||||
00000000
|
||||
80000411 # mtval of address with misaligned store instr (0x80000410)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000007 # mcause from store access
|
||||
00000000
|
||||
00000000 # mtval of accessed address (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
0000000b # mcause from M mode ecall
|
||||
00000000
|
||||
00000000 # mtval of ecall (*** defined to be zero for now)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000008 # mcause from U mode ecall
|
||||
00000000
|
||||
00000000 # mtval of ecall (*** defined to be zero for now)
|
||||
00000000
|
||||
00000080 # masked out mstatus.MPP = 00 (from U mode), mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000009 # mcause from S mode ecall
|
||||
00000000
|
||||
00000000 # mtval of ecall (*** defined to be zero for now)
|
||||
00000000
|
||||
00000880 # masked out mstatus.MPP = 01 (from S mode), mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
000007ec # value to indicate a vectored interrupts
|
||||
00000000
|
||||
00000007 # mcause value from m time interrupt
|
||||
80000000
|
||||
00000000 # mtval for mtime interrupt (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
000007ec # value to indicate a vectored interrupts
|
||||
00000000
|
||||
00000001 # mcause value from m soft interrupt
|
||||
80000000
|
||||
00000000 # mtval for msoft interrupt (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
000007ec # value to indicate a vectored interrupts
|
||||
00000000
|
||||
0000000b # mcause value from m ext interrupt
|
||||
80000000
|
||||
00000000 # mtval for mext interrupt (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
0000b309 # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000000
|
||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000000
|
||||
00000001 # Test 5.3.1.4: mcause from an instruction access fault
|
||||
00000000
|
||||
00000000 # mtval of faulting instruction address (0x0)
|
||||
@ -12,49 +102,67 @@
|
||||
00000000
|
||||
00000003 # mcause from Breakpoint
|
||||
00000000
|
||||
00000000 # mtval of breakpoint instruction adress (*** Determined from make)
|
||||
800003ec # mtval of breakpoint instruction adress (0x800003ec)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000004 # mcause from load address misaligned
|
||||
00000000
|
||||
00000000 # mtval of misaligned address (*** Determined from make)
|
||||
800003f5 # mtval of misaligned address (0x800003f5)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000005 # mcause from load access
|
||||
00000000
|
||||
00000000 # mtval of address with access faulting instr (*** Determined from make)
|
||||
00000000 # mtval of accessed adress (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000006 # mcause from store misaligned
|
||||
00000000
|
||||
00000000 # mtval of address with misaligned store instr (*** Determined from make)
|
||||
80000411 # mtval of address with misaligned store instr (0x80000410)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000007 # mcause from store access
|
||||
00000000
|
||||
00000000 # mtval of address with faulting store instr (*** Determined from make)
|
||||
00000000 # mtval of accessed address (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
0000000b # mcause from M mode ecall
|
||||
00000000
|
||||
00000000 # mtval of
|
||||
00000000 # mtval of ecall (*** defined to be zero for now)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000008 # mcause from U mode ecall
|
||||
000007ec # value to indicate a vectored interrupts
|
||||
00000000
|
||||
00000000 # mtval of
|
||||
00000007 # mcause value from time interrupt
|
||||
80000000
|
||||
00000000 # mtval for mtime interrupt (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000009 # mcause from S mode ecall
|
||||
000007ec # value to indicate a vectored interrupts
|
||||
00000000
|
||||
00000000 # mtval of address with faulting store instr (*** Determined from make)
|
||||
00000001 # mcause value from m soft interrupt
|
||||
80000000
|
||||
00000000 # mtval for msoft interrupt (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
000007ec # value to indicate a vectored interrupts
|
||||
00000000
|
||||
0000000b # mcause value from m ext interrupt
|
||||
80000000
|
||||
00000000 # mtval for mext interrupt (0x0)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
0000000b # mcause from M mode ecall from test termination
|
||||
00000000
|
||||
00000000 # mtval of ecall (*** defined to be zero for now)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
@ -964,119 +1072,3 @@ deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
deadbeef
|
||||
|
@ -55,6 +55,99 @@ RVTEST_CODE_BEGIN
|
||||
|
||||
.endm
|
||||
|
||||
// Code to trigger traps goes here so we have consistent mtvals for instruction adresses
|
||||
// Even if more tests are added.
|
||||
.macro CAUSE_TRAP_TRIGGERS
|
||||
j end_trap_triggers
|
||||
|
||||
// The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines
|
||||
// This effectively includes everything that isn't to do with page faults (virtual memory)
|
||||
|
||||
cause_instr_addr_misaligned:
|
||||
// cause a misaligned address trap
|
||||
auipc x28, 0 // get current PC, which is aligned
|
||||
addi x28, x28, 0x3 // add 1 to pc to create misaligned address
|
||||
jr x28 // cause instruction address midaligned trap
|
||||
ret
|
||||
|
||||
cause_instr_access:
|
||||
la x28, 0x0 // address zero is an address with no memory
|
||||
sd x1, -8(sp) // push the return adress ontot the stack
|
||||
addi sp, sp, -8
|
||||
jalr x28 // cause instruction access trap
|
||||
ld x1, 0(sp) // pop return adress back from the stack
|
||||
addi sp, sp, 8
|
||||
ret
|
||||
|
||||
cause_illegal_instr:
|
||||
.word 0x00000000 // a 32 bit zros is an illegal instruction
|
||||
ret
|
||||
|
||||
cause_breakpnt: // ****
|
||||
ebreak
|
||||
ret
|
||||
|
||||
cause_load_addr_misaligned:
|
||||
auipc x28, 0 // get current PC, which is aligned
|
||||
addi x28, x28, 1
|
||||
lw x29, 0(x28) // load from a misaligned address
|
||||
ret
|
||||
|
||||
cause_load_acc:
|
||||
la x28, 0 // 0 is an address with no memory
|
||||
lw x29, 0(x28) // load from unimplemented address
|
||||
ret
|
||||
|
||||
cause_store_addr_misaligned:
|
||||
auipc x28, 0 // get current PC, which is aligned
|
||||
addi x28, x28, 1
|
||||
sw x29, 0(x28) // store to a misaligned address
|
||||
ret
|
||||
|
||||
cause_store_acc:
|
||||
la x28, 0 // 0 is an address with no memory
|
||||
sw x29, 0(x28) // store to unimplemented address
|
||||
ret
|
||||
|
||||
cause_ecall:
|
||||
// *** ASSUMES you have already gone to the mode you need to call this from.
|
||||
ecall
|
||||
ret
|
||||
|
||||
cause_time_interrupt:
|
||||
// The following code works for both RV32 and RV64.
|
||||
// RV64 alone would be easier using double-word adds and stores
|
||||
li x28, 0x100 // Desired offset from the present time
|
||||
la x29, 0x02004000 // MTIMECMP register in CLINT
|
||||
la x30, 0x0200BFF8 // MTIME register in CLINT
|
||||
lw x7, 0(x30) // low word of MTIME
|
||||
lw x31, 4(x30) // high word of MTIME
|
||||
add x28, x7, x28 // add desired offset to the current time
|
||||
bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound)
|
||||
addi x31, x31, 1 // if wrap, increment most significant word
|
||||
sw x31,4(x29) // store into most significant word of MTIMECMP
|
||||
nowrap:
|
||||
sw x28, 0(x29) // store into least significant word of MTIMECMP
|
||||
loop: j loop // wait until interrupt occurs
|
||||
ret
|
||||
|
||||
cause_soft_interrupt:
|
||||
la x28, 0x02000000 // MSIP register in CLINT
|
||||
li x29, 1 // 1 in the lsb
|
||||
sw x29, 0(x28) // Write MSIP bit
|
||||
ret
|
||||
|
||||
cause_ext_interrupt:
|
||||
li x28, 0x10060000 // load base GPIO memory location
|
||||
li x29, 0x1
|
||||
sw x29, 8(x28) // enable the first pin as an output
|
||||
sw x29, 28(x28) // set first pin to high interrupt enable
|
||||
sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt)
|
||||
ret
|
||||
|
||||
end_trap_triggers:
|
||||
.endm
|
||||
|
||||
.macro TRAP_HANDLER MODE, VECTORED=1, DEBUG=0
|
||||
// MODE decides which mode this trap handler will be taken in (M or S mode)
|
||||
// Vectored decides whether interrumpts are handled with the vector table at trap_handler_MODE (1)
|
||||
@ -577,7 +670,7 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a
|
||||
// The previous CSR value before write attempt
|
||||
// *** Most likely 0x2, the mcause for illegal instruction if we don't have write or read access
|
||||
li x30, 0xbad // load bad value to be overwritten by csrr
|
||||
li x29, \VAL
|
||||
li x29, \VAL\()
|
||||
csrw \CSR\(), x29
|
||||
csrr x30, \CSR
|
||||
sd x30, 0(x6)
|
||||
@ -627,86 +720,86 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a
|
||||
addi x16, x16, 8
|
||||
.endm
|
||||
|
||||
// The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines
|
||||
// This effectively includes everything that isn't to do with page faults (virtual memory)
|
||||
// // The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines
|
||||
// // This effectively includes everything that isn't to do with page faults (virtual memory)
|
||||
|
||||
.macro CAUSE_INSTR_ADDR_MISALIGNED
|
||||
// cause a misaligned address trap
|
||||
auipc x28, 0 // get current PC, which is aligned
|
||||
addi x28, x28, 0x1 // add 1 to pc to create misaligned address
|
||||
jalr x28 // cause instruction address midaligned trap
|
||||
.endm
|
||||
// .macro CAUSE_INSTR_ADDR_MISALIGNED
|
||||
// // cause a misaligned address trap
|
||||
// auipc x28, 0 // get current PC, which is aligned
|
||||
// addi x28, x28, 0x1 // add 1 to pc to create misaligned address
|
||||
// jalr x28 // cause instruction address midaligned trap
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_INSTR_ACCESS
|
||||
la x28, 0x0 // address zero is an address with no memory
|
||||
jalr x28 // cause instruction access trap
|
||||
.endm
|
||||
// .macro CAUSE_INSTR_ACCESS
|
||||
// la x28, 0x0 // address zero is an address with no memory
|
||||
// jalr x28 // cause instruction access trap
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_ILLEGAL_INSTR
|
||||
.word 0x00000000 // a 32 bit zros is an illegal instruction
|
||||
.endm
|
||||
// .macro CAUSE_ILLEGAL_INSTR
|
||||
// .word 0x00000000 // a 32 bit zros is an illegal instruction
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_BREAKPNT // ****
|
||||
ebreak
|
||||
.endm
|
||||
// .macro CAUSE_BREAKPNT // ****
|
||||
// ebreak
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_LOAD_ADDR_MISALIGNED
|
||||
auipc x28, 0 // get current PC, which is aligned
|
||||
addi x28, x28, 1
|
||||
lw x29, 0(x28) // load from a misaligned address
|
||||
.endm
|
||||
// .macro CAUSE_LOAD_ADDR_MISALIGNED
|
||||
// auipc x28, 0 // get current PC, which is aligned
|
||||
// addi x28, x28, 1
|
||||
// lw x29, 0(x28) // load from a misaligned address
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_LOAD_ACC
|
||||
la x28, 0 // 0 is an address with no memory
|
||||
lw x29, 0(x28) // load from unimplemented address
|
||||
.endm
|
||||
// .macro CAUSE_LOAD_ACC
|
||||
// la x28, 0 // 0 is an address with no memory
|
||||
// lw x29, 0(x28) // load from unimplemented address
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_STORE_ADDR_MISALIGNED
|
||||
auipc x28, 0 // get current PC, which is aligned
|
||||
addi x28, x28, 1
|
||||
sw x29, 0(x28) // store to a misaligned address
|
||||
.endm
|
||||
// .macro CAUSE_STORE_ADDR_MISALIGNED
|
||||
// auipc x28, 0 // get current PC, which is aligned
|
||||
// addi x28, x28, 1
|
||||
// sw x29, 0(x28) // store to a misaligned address
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_STORE_ACC
|
||||
la x28, 0 // 0 is an address with no memory
|
||||
sw x29, 0(x28) // store to unimplemented address
|
||||
.endm
|
||||
// .macro CAUSE_STORE_ACC
|
||||
// la x28, 0 // 0 is an address with no memory
|
||||
// sw x29, 0(x28) // store to unimplemented address
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_ECALL
|
||||
// *** ASSUMES you have already gone to the mode you need to call this from.
|
||||
ecall
|
||||
.endm
|
||||
// .macro CAUSE_ECALL
|
||||
// // *** ASSUMES you have already gone to the mode you need to call this from.
|
||||
// ecall
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_TIME_INTERRUPT
|
||||
// The following code works for both RV32 and RV64.
|
||||
// RV64 alone would be easier using double-word adds and stores
|
||||
li x28, 0x100 // Desired offset from the present time
|
||||
la x29, 0x02004000 // MTIMECMP register in CLINT
|
||||
la x30, 0x0200BFF8 // MTIME register in CLINT
|
||||
lw x7, 0(x30) // low word of MTIME
|
||||
lw x31, 4(x30) // high word of MTIME
|
||||
add x28, x7, x28 // add desired offset to the current time
|
||||
bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound)
|
||||
addi x31, x31, 1 // if wrap, increment most significant word
|
||||
sw x31,4(x29) // store into most significant word of MTIMECMP
|
||||
nowrap:
|
||||
sw x28, 0(x29) // store into least significant word of MTIMECMP
|
||||
loop: j loop // wait until interrupt occurs
|
||||
.endm
|
||||
// .macro CAUSE_TIME_INTERRUPT
|
||||
// // The following code works for both RV32 and RV64.
|
||||
// // RV64 alone would be easier using double-word adds and stores
|
||||
// li x28, 0x100 // Desired offset from the present time
|
||||
// la x29, 0x02004000 // MTIMECMP register in CLINT
|
||||
// la x30, 0x0200BFF8 // MTIME register in CLINT
|
||||
// lw x7, 0(x30) // low word of MTIME
|
||||
// lw x31, 4(x30) // high word of MTIME
|
||||
// add x28, x7, x28 // add desired offset to the current time
|
||||
// bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound)
|
||||
// addi x31, x31, 1 // if wrap, increment most significant word
|
||||
// sw x31,4(x29) // store into most significant word of MTIMECMP
|
||||
// nowrap:
|
||||
// sw x28, 0(x29) // store into least significant word of MTIMECMP
|
||||
// loop: j loop // wait until interrupt occurs
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_SOFT_INTERRUPT
|
||||
la x28, 0x02000000 // MSIP register in CLINT
|
||||
li x29, 1 // 1 in the lsb
|
||||
sw x29, 0(x28) // Write MSIP bit
|
||||
.endm
|
||||
// .macro CAUSE_SOFT_INTERRUPT
|
||||
// la x28, 0x02000000 // MSIP register in CLINT
|
||||
// li x29, 1 // 1 in the lsb
|
||||
// sw x29, 0(x28) // Write MSIP bit
|
||||
// .endm
|
||||
|
||||
.macro CAUSE_EXT_INTERRUPT
|
||||
li x28, 0x10060000 // load base GPIO memory location
|
||||
li x29, 0x1
|
||||
sw x29, 8(x28) // enable the first pin as an output
|
||||
sw x29, 28(x28) // set first pin to high interrupt enable
|
||||
sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt)
|
||||
.endm
|
||||
// .macro CAUSE_EXT_INTERRUPT
|
||||
// li x28, 0x10060000 // load base GPIO memory location
|
||||
// li x29, 0x1
|
||||
// sw x29, 8(x28) // enable the first pin as an output
|
||||
// sw x29, 28(x28) // set first pin to high interrupt enable
|
||||
// sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt)
|
||||
// .endm
|
||||
|
||||
.macro END_TESTS
|
||||
// invokes one final ecall to return to machine mode then terminates this program, so the output is
|
||||
|
@ -25,50 +25,50 @@
|
||||
|
||||
INIT_TESTS
|
||||
|
||||
CAUSE_TRAP_TRIGGERS // initialize code that will cause traps for consistent mtval addresses
|
||||
|
||||
TRAP_HANDLER m, DEBUG=1 // turn on recording mtval and status bits on traps
|
||||
|
||||
li x28, 0x8
|
||||
csrs mstatus, x28 // set mstatus.MIE bit to 1
|
||||
// WRITE_READ_CSR mie, 0xFFFF *** commented out until I can get the trap handler (and spike for time interrupts) to work correctly with interrupts
|
||||
WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources // *** commented out until I can get the trap handler (and spike for time interrupts) to work correctly with interrupts
|
||||
|
||||
// test 5.3.1.4 Basic trap tests
|
||||
|
||||
// CAUSE_INSTR_ADDR_MISALIGNED //skipped becuase this exception may be impossible when compressed instructions are enabled)
|
||||
CAUSE_INSTR_ACCESS
|
||||
CAUSE_ILLEGAL_INSTR
|
||||
CAUSE_BREAKPNT
|
||||
CAUSE_LOAD_ADDR_MISALIGNED
|
||||
CAUSE_LOAD_ACC
|
||||
CAUSE_STORE_ADDR_MISALIGNED
|
||||
CAUSE_STORE_ACC
|
||||
// jal cause_instr_addr_misaligned //skipped becuase this exception may be impossible when compressed instructions are enabled)
|
||||
jal cause_instr_access
|
||||
jal cause_illegal_instr
|
||||
jal cause_breakpnt
|
||||
jal cause_load_addr_misaligned
|
||||
jal cause_load_acc
|
||||
jal cause_store_addr_misaligned
|
||||
jal cause_store_acc
|
||||
GOTO_U_MODE // Causes M mode ecall
|
||||
GOTO_S_MODE // Causes U mode ecall
|
||||
GOTO_M_MODE // Causes S mode ecall
|
||||
|
||||
// CAUSE_TIME_INTERRUPT *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen.
|
||||
// CAUSE_SOFT_INTERRUPT *** exiting out of the trap handler after these is current;y broken
|
||||
// CAUSE_EXT_INTERRUPT
|
||||
jal cause_time_interrupt // *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen.
|
||||
jal cause_soft_interrupt // *** exiting out of the trap handler after these is current;y broken
|
||||
jal cause_ext_interrupt
|
||||
|
||||
// try the traps again with mideleg = medeleg = all 1's to ensure traps still go to M mode from M mode
|
||||
|
||||
WRITE_READ_CSR medeleg, 0xFFFFFFFFFFFFFFFF
|
||||
WRITE_READ_CSR mideleg, 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
// CAUSE_INSTR_ADDR_MISALIGNED //skipped becuase this exception may be impossible when compressed instructions are enabled)
|
||||
CAUSE_INSTR_ACCESS
|
||||
CAUSE_ILLEGAL_INSTR
|
||||
CAUSE_BREAKPNT
|
||||
CAUSE_LOAD_ADDR_MISALIGNED
|
||||
CAUSE_LOAD_ACC
|
||||
CAUSE_STORE_ADDR_MISALIGNED
|
||||
CAUSE_STORE_ACC
|
||||
CAUSE_ECALL // M mode ecall
|
||||
// GOTO_U_MODE // leave these untested since we only need to ensure that from M mode are not delegated
|
||||
// GOTO_S_MODE
|
||||
// jal cause_instr_addr_misaligned //skipped becuase this exception may be impossible when compressed instructions are enabled)
|
||||
jal cause_instr_access
|
||||
jal cause_illegal_instr
|
||||
jal cause_breakpnt
|
||||
jal cause_load_addr_misaligned
|
||||
jal cause_load_acc
|
||||
jal cause_store_addr_misaligned
|
||||
jal cause_store_acc
|
||||
jal cause_ecall // M mode ecall
|
||||
|
||||
// CAUSE_TIME_INTERRUPT *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen.
|
||||
// CAUSE_SOFT_INTERRUPT *** exiting out of the trap handler after these is current;y broken
|
||||
// CAUSE_EXT_INTERRUPT
|
||||
jal cause_time_interrupt // *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen.
|
||||
jal cause_soft_interrupt // *** exiting out of the trap handler after these is current;y broken
|
||||
jal cause_ext_interrupt
|
||||
|
||||
END_TESTS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user