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_6=y
|
||||||
BR2_HOST_GCC_AT_LEAST_7=y
|
BR2_HOST_GCC_AT_LEAST_7=y
|
||||||
BR2_HOST_GCC_AT_LEAST_8=y
|
BR2_HOST_GCC_AT_LEAST_8=y
|
||||||
|
BR2_HOST_GCC_AT_LEAST_9=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Target options
|
# Target options
|
||||||
@ -87,7 +88,7 @@ BR2_BZCAT="bzcat"
|
|||||||
BR2_XZCAT="xzcat"
|
BR2_XZCAT="xzcat"
|
||||||
BR2_LZCAT="lzip -d -c"
|
BR2_LZCAT="lzip -d -c"
|
||||||
BR2_TAR_OPTIONS=""
|
BR2_TAR_OPTIONS=""
|
||||||
BR2_DEFCONFIG="./configs/wally-qemu_riscv64_virt_defconfig"
|
BR2_DEFCONFIG="./board/wally/main.config"
|
||||||
BR2_DL_DIR="$(TOPDIR)/dl"
|
BR2_DL_DIR="$(TOPDIR)/dl"
|
||||||
BR2_HOST_DIR="$(BASE_DIR)/host"
|
BR2_HOST_DIR="$(BASE_DIR)/host"
|
||||||
|
|
||||||
@ -406,11 +407,10 @@ BR2_GENERATE_LOCALE=""
|
|||||||
# BR2_SYSTEM_ENABLE_NLS is not set
|
# BR2_SYSTEM_ENABLE_NLS is not set
|
||||||
# BR2_TARGET_TZ_INFO is not set
|
# BR2_TARGET_TZ_INFO is not set
|
||||||
BR2_ROOTFS_USERS_TABLES=""
|
BR2_ROOTFS_USERS_TABLES=""
|
||||||
BR2_ROOTFS_OVERLAY=""
|
BR2_ROOTFS_OVERLAY="./board/wally/rootfs_overlay"
|
||||||
BR2_ROOTFS_POST_BUILD_SCRIPT=""
|
BR2_ROOTFS_POST_BUILD_SCRIPT=""
|
||||||
BR2_ROOTFS_POST_FAKEROOT_SCRIPT=""
|
BR2_ROOTFS_POST_FAKEROOT_SCRIPT=""
|
||||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="board/qemu/post-image.sh"
|
BR2_ROOTFS_POST_IMAGE_SCRIPT=""
|
||||||
BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_DEFCONFIG)"
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Kernel
|
# Kernel
|
||||||
@ -430,7 +430,7 @@ BR2_LINUX_KERNEL_PATCH=""
|
|||||||
# BR2_LINUX_KERNEL_USE_DEFCONFIG is not set
|
# BR2_LINUX_KERNEL_USE_DEFCONFIG is not set
|
||||||
# BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG is not set
|
# BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG is not set
|
||||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
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_CONFIG_FRAGMENT_FILES=""
|
||||||
BR2_LINUX_KERNEL_CUSTOM_LOGO_PATH=""
|
BR2_LINUX_KERNEL_CUSTOM_LOGO_PATH=""
|
||||||
BR2_LINUX_KERNEL_IMAGE=y
|
BR2_LINUX_KERNEL_IMAGE=y
|
||||||
@ -473,7 +473,7 @@ BR2_LINUX_KERNEL_GZIP=y
|
|||||||
# Target packages
|
# Target packages
|
||||||
#
|
#
|
||||||
BR2_PACKAGE_BUSYBOX=y
|
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_CONFIG_FRAGMENT_FILES=""
|
||||||
# BR2_PACKAGE_BUSYBOX_SHOW_OTHERS is not set
|
# BR2_PACKAGE_BUSYBOX_SHOW_OTHERS is not set
|
||||||
# BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES 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 {
|
memory@80000000 {
|
||||||
device_type = "memory";
|
device_type = "memory";
|
||||||
reg = <0x00 0x80000000 0x00 0x8000000>;
|
reg = <0x00 0x80000000 0x00 0x08000000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
cpus {
|
cpus {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
for index in {450..500}
|
#!/bin/bash
|
||||||
|
for index in {450..500};
|
||||||
do
|
do
|
||||||
instrs=$(($index*1000000))
|
instrs=$(($index*1000000))
|
||||||
echo "y" | nice -n 5 ./genCheckpoint.sh $instrs
|
echo "y" | nice -n 5 ./genCheckpoint.sh $instrs
|
||||||
|
|||||||
@ -101,13 +101,15 @@ then
|
|||||||
set logging on
|
set logging on
|
||||||
# Priority Levels for sources 1 thru 63
|
# Priority Levels for sources 1 thru 63
|
||||||
x/63xw 0x0C000004
|
x/63xw 0x0C000004
|
||||||
# Interrupt Enables
|
# Interrupt Enables for sources 1 thru 63 for contexts 0 and 1
|
||||||
x/2xw 0x0C020000
|
x/2xw 0x0C020000
|
||||||
# Global Priority Threshold
|
x/2xw 0x0C020080
|
||||||
|
# Global Priority Threshold for contexts 0 and 1
|
||||||
x/1xw 0x0C200000
|
x/1xw 0x0C200000
|
||||||
|
x/1xw 0x0C201000
|
||||||
set logging off
|
set logging off
|
||||||
shell echo \"GDB storing RAM to $rawRamFile\"
|
shell echo \"GDB storing RAM to $rawRamFile\"
|
||||||
dump binary memory $rawRamFile 0x80000000 0xffffffff
|
dump binary memory $rawRamFile 0x80000000 0x87ffffff
|
||||||
kill
|
kill
|
||||||
q
|
q
|
||||||
end_of_script
|
end_of_script
|
||||||
|
|||||||
@ -138,9 +138,9 @@ if len(sys.argv) != 2:
|
|||||||
sys.exit('Error parseGDBtoTrace.py expects 1 arg:\n <interrupt filename>>')
|
sys.exit('Error parseGDBtoTrace.py expects 1 arg:\n <interrupt filename>>')
|
||||||
interruptFname = sys.argv[1]
|
interruptFname = sys.argv[1]
|
||||||
# reg number
|
# 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
|
# 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:
|
#with open (InputFile, 'r') as InputFileFP:
|
||||||
#lines = InputFileFP.readlines()
|
#lines = InputFileFP.readlines()
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#! /usr/bin/python3
|
#! /usr/bin/python3
|
||||||
import sys, os
|
import sys, os
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
################
|
################
|
||||||
# Helper Funcs #
|
# Helper Funcs #
|
||||||
@ -21,6 +22,9 @@ def tokenize(string):
|
|||||||
token = token + char
|
token = token + char
|
||||||
return tokens
|
return tokens
|
||||||
|
|
||||||
|
def strip0x(num):
|
||||||
|
return num[2:]
|
||||||
|
|
||||||
def stripZeroes(num):
|
def stripZeroes(num):
|
||||||
num = num.strip('0')
|
num = num.strip('0')
|
||||||
if num=='':
|
if num=='':
|
||||||
@ -42,7 +46,7 @@ if not os.path.exists(rawPlicStateFile):
|
|||||||
sys.exit('Error input file '+rawPlicStateFile+'not found')
|
sys.exit('Error input file '+rawPlicStateFile+'not found')
|
||||||
|
|
||||||
with open(rawPlicStateFile, 'r') as rawPlicStateFile:
|
with open(rawPlicStateFile, 'r') as rawPlicStateFile:
|
||||||
plicIntPriorityArray=[]
|
plicIntPriorityArray = [] # iterates over number of different sources
|
||||||
# 0x0C000004 thru 0x0C000010
|
# 0x0C000004 thru 0x0C000010
|
||||||
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
|
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
|
||||||
# 0x0C000014 thru 0x0C000020
|
# 0x0C000014 thru 0x0C000020
|
||||||
@ -76,20 +80,30 @@ with open(rawPlicStateFile, 'r') as rawPlicStateFile:
|
|||||||
# 0x0C0000f4 thru 0x0C0000fc
|
# 0x0C0000f4 thru 0x0C0000fc
|
||||||
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
|
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
|
||||||
|
|
||||||
|
plicIntEnableArray = [] # iterates over number of different contexts
|
||||||
# 0x0C020000 thru 0x0C020004
|
# 0x0C020000 thru 0x0C020004
|
||||||
plicIntEnable = tokenize(rawPlicStateFile.readline())[1:]
|
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
|
# 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:
|
with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile:
|
||||||
for word in plicIntPriorityArray:
|
for word in plicIntPriorityArray:
|
||||||
outFile.write(stripZeroes(word[2:])+'\n')
|
outFile.write(stripZeroes(word[2:])+'\n')
|
||||||
with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile:
|
with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile:
|
||||||
for word in plicIntEnable:
|
for word in plicIntEnableArray:
|
||||||
outFile.write(stripZeroes(word[2:]))
|
outFile.write(stripZeroes(word)+'\n')
|
||||||
with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile:
|
with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile:
|
||||||
for word in plicIntPriorityThreshold:
|
for word in plicIntPriorityThresholdArray:
|
||||||
outFile.write(stripZeroes(word[2:])+'\n')
|
outFile.write(stripZeroes(word[2:])+'\n')
|
||||||
|
|
||||||
print("Finished parsing PLIC state!")
|
print("Finished parsing PLIC state!")
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import sys, os, subprocess
|
|||||||
def main():
|
def main():
|
||||||
maxGoodCount = 400e6 # num instrs that execute sucessfully starting from 0
|
maxGoodCount = 400e6 # num instrs that execute sucessfully starting from 0
|
||||||
currInstrCount = maxGoodCount
|
currInstrCount = maxGoodCount
|
||||||
linuxTestvectors = "../../tests/linux-testgen/linux-testvectors"
|
linuxTestvectors = "/opt/riscv/linux-testvectors"
|
||||||
if not os.path.exists(linuxTestvectors):
|
if not os.path.exists(linuxTestvectors):
|
||||||
sys.stderr.write("Error: Linux testvectors not found at "+linuxTestvectors+"\n")
|
sys.stderr.write("Error: Linux testvectors not found at "+linuxTestvectors+"\n")
|
||||||
exit(1)
|
exit(1)
|
||||||
@ -22,7 +22,7 @@ def main():
|
|||||||
break
|
break
|
||||||
checkpoint = checkpointList[0]
|
checkpoint = checkpointList[0]
|
||||||
logFile = logDir+"checkpoint"+str(checkpoint)+".log"
|
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)
|
print(runCommand)
|
||||||
os.system(runCommand)
|
os.system(runCommand)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -4,6 +4,7 @@ add wave -noupdate /testbench/clk
|
|||||||
add wave -noupdate /testbench/reset
|
add wave -noupdate /testbench/reset
|
||||||
add wave -noupdate /testbench/reset_ext
|
add wave -noupdate /testbench/reset_ext
|
||||||
add wave -noupdate -radix unsigned /testbench/InstrCountW
|
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/SATP_REGW
|
||||||
add wave -noupdate /testbench/dut/core/IllegalFPUInstrD
|
add wave -noupdate /testbench/dut/core/IllegalFPUInstrD
|
||||||
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/BPPredWrongE
|
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 /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/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/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/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 -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
|
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/SpillF
|
||||||
add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/IFUCacheBusStallF
|
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 -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/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/WriteAccess
|
||||||
add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/TLBPageFault
|
add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/TLBPageFault
|
||||||
TreeUpdate [SetDefaultTree]
|
TreeUpdate [SetDefaultTree]
|
||||||
|
|||||||
@ -70,7 +70,7 @@ for test in tests64gc:
|
|||||||
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64gc "+test+"\n!",
|
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64gc "+test+"\n!",
|
||||||
grepstr="All tests ran without failures")
|
grepstr="All tests ran without failures")
|
||||||
configs.append(tc)
|
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:
|
for test in tests32gc:
|
||||||
tc = TestCase(
|
tc = TestCase(
|
||||||
name=test,
|
name=test,
|
||||||
@ -79,6 +79,25 @@ for test in tests32gc:
|
|||||||
grepstr="All tests ran without failures")
|
grepstr="All tests ran without failures")
|
||||||
configs.append(tc)
|
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"]
|
tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c"]
|
||||||
for test in tests32ic:
|
for test in tests32ic:
|
||||||
tc = TestCase(
|
tc = TestCase(
|
||||||
|
|||||||
@ -23,40 +23,32 @@ module fcmp (
|
|||||||
output logic [`FLEN-1:0] CmpResE // compare resilt
|
output logic [`FLEN-1:0] CmpResE // compare resilt
|
||||||
);
|
);
|
||||||
|
|
||||||
logic LT, EQ; // is X < or > or = Y
|
logic LTabs, LT, EQ; // is X < or > or = Y
|
||||||
|
logic BothZeroE, EitherNaNE, EitherSNaNE;
|
||||||
// X is less than Y:
|
|
||||||
// Signs:
|
assign LTabs= {1'b0, XExpE, XManE} < {1'b0, YExpE, YManE}; // unsigned comparison, treating FP as integers
|
||||||
// X Y answer
|
assign LT = (XSgnE & ~YSgnE) | (XSgnE & YSgnE & ~LTabs & ~EQ) | (~XSgnE & ~YSgnE & LTabs);
|
||||||
// pos pos idk - keep checking
|
//assign LT = $signed({XSgnE, XExpE, XManE[`NF-1:0]}) < $signed({YSgnE, YExpE, YManE[`NF-1:0]});
|
||||||
// pos neg no
|
//assign LT = XInt < YInt;
|
||||||
// neg pos yes
|
// assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
|
||||||
// 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;
|
|
||||||
assign EQ = (FSrcXE == FSrcYE);
|
assign EQ = (FSrcXE == FSrcYE);
|
||||||
|
|
||||||
|
assign BothZeroE = XZeroE&YZeroE;
|
||||||
|
assign EitherNaNE = XNaNE|YNaNE;
|
||||||
|
assign EitherSNaNE = XSNaNE|YSNaNE;
|
||||||
|
|
||||||
|
|
||||||
// flags
|
// flags
|
||||||
// Min/Max - if an input is a signaling NaN set invalid flag
|
// Min/Max - if an input is a signaling NaN set invalid flag
|
||||||
// LT/LE - signaling - sets invalid if NaN input
|
// LT/LE - signaling - sets invalid if NaN input
|
||||||
// EQ - quiet - sets invalid if signaling NaN input
|
// EQ - quiet - sets invalid if signaling NaN input
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case (FOpCtrlE[2:0])
|
case (FOpCtrlE[2:0])
|
||||||
3'b111: CmpNVE = XSNaNE|YSNaNE;//min
|
3'b111: CmpNVE = EitherSNaNE;//min
|
||||||
3'b101: CmpNVE = XSNaNE|YSNaNE;//max
|
3'b101: CmpNVE = EitherSNaNE;//max
|
||||||
3'b010: CmpNVE = XSNaNE|YSNaNE;//equal
|
3'b010: CmpNVE = EitherSNaNE;//equal
|
||||||
3'b001: CmpNVE = XNaNE|YNaNE;//less than
|
3'b001: CmpNVE = EitherNaNE;//less than
|
||||||
3'b011: CmpNVE = XNaNE|YNaNE;//less than or equal
|
3'b011: CmpNVE = EitherNaNE;//less than or equal
|
||||||
default: CmpNVE = 1'b0;
|
default: CmpNVE = 1'b0;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
@ -71,24 +63,22 @@ module fcmp (
|
|||||||
// - inf = inf and -inf = -inf
|
// - inf = inf and -inf = -inf
|
||||||
// - return 0 if comparison with NaN (unordered)
|
// - return 0 if comparison with NaN (unordered)
|
||||||
|
|
||||||
logic [`FLEN-1:0] QNaNX, QNaNY;
|
logic [`FLEN-1:0] QNaN;
|
||||||
if(`IEEE754) begin
|
// fmin/fmax of two NaNs returns a quiet NaN of the appropriate size
|
||||||
assign QNaNX = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]};
|
// for IEEE, return the payload of X
|
||||||
assign QNaNY = FmtE ? {YSgnE, YExpE, 1'b1, YManE[`NF-2:0]} : {{32{1'b1}}, YSgnE, YExpE[7:0], 1'b1, YManE[50:29]};
|
// for RISC-V, return the canonical NaN
|
||||||
end else begin
|
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]};
|
||||||
assign QNaNX = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0};
|
else assign QNaN = 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
|
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case (FOpCtrlE[2:0])
|
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;
|
: 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;
|
: YNaNE ? FSrcXE : LT ? FSrcYE : FSrcXE;
|
||||||
3'b010: CmpResE = {63'b0, (EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Equal
|
3'b010: CmpResE = {63'b0, (EQ|BothZeroE) & ~EitherNaNE}; // Equal
|
||||||
3'b001: CmpResE = {63'b0, LT&~(XZeroE&YZeroE)&~(XNaNE|YNaNE)}; // Less than
|
3'b001: CmpResE = {63'b0, LT & ~BothZeroE & ~EitherNaNE}; // Less than
|
||||||
3'b011: CmpResE = {63'b0, (LT|EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Less than or equal
|
3'b011: CmpResE = {63'b0, (LT|EQ|BothZeroE) & ~EitherNaNE}; // Less than or equal
|
||||||
default: CmpResE = 64'b0;
|
default: CmpResE = 64'b0;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|||||||
@ -102,6 +102,7 @@ module BTBPredictor
|
|||||||
// Another optimization may be using a PC relative address.
|
// Another optimization may be using a PC relative address.
|
||||||
// *** need to add forwarding.
|
// *** need to add forwarding.
|
||||||
|
|
||||||
|
// *** optimize for byte write enables
|
||||||
SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk),
|
SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.RA1(LookUpPCIndex),
|
.RA1(LookUpPCIndex),
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// ram.sv
|
// swbytemask.sv
|
||||||
//
|
//
|
||||||
// Written: David_Harris@hmc.edu 9 January 2021
|
// Written: David_Harris@hmc.edu 9 January 2021
|
||||||
// Modified:
|
// Modified:
|
||||||
|
|||||||
@ -43,13 +43,13 @@ module csr #(parameter
|
|||||||
input logic [31:0] InstrM,
|
input logic [31:0] InstrM,
|
||||||
input logic [`XLEN-1:0] PCM, SrcAM,
|
input logic [`XLEN-1:0] PCM, SrcAM,
|
||||||
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM,
|
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 [63:0] MTIME_CLINT,
|
||||||
input logic InstrValidM, FRegWriteM, LoadStallD,
|
input logic InstrValidM, FRegWriteM, LoadStallD,
|
||||||
input logic BPPredDirWrongM,
|
input logic BPPredDirWrongM,
|
||||||
input logic BTBPredPCWrongM,
|
input logic BTBPredPCWrongM,
|
||||||
input logic RASPredPCWrongM,
|
input logic RASPredPCWrongM,
|
||||||
input logic BPPredClassNonCFIWrongM,
|
input logic BPPredClassNonCFIWrongM,
|
||||||
input logic [4:0] InstrClassM,
|
input logic [4:0] InstrClassM,
|
||||||
input logic DCacheMiss,
|
input logic DCacheMiss,
|
||||||
input logic DCacheAccess,
|
input logic DCacheAccess,
|
||||||
@ -123,7 +123,7 @@ module csr #(parameter
|
|||||||
assign CSRUWriteM = CSRWriteM;
|
assign CSRUWriteM = CSRWriteM;
|
||||||
|
|
||||||
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM,
|
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);
|
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM);
|
||||||
csrsr csrsr(.clk, .reset, .StallW,
|
csrsr csrsr(.clk, .reset, .StallW,
|
||||||
.WriteMSTATUSM, .WriteSSTATUSM,
|
.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
|
// 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) |
|
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 &
|
assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM &
|
||||||
IllegalCSRSAccessM & IllegalCSRUAccessM |
|
IllegalCSRSAccessM & IllegalCSRUAccessM |
|
||||||
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;
|
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;
|
||||||
|
|||||||
@ -41,7 +41,7 @@ module csri #(parameter
|
|||||||
input logic InstrValidNotFlushedM, StallW,
|
input logic InstrValidNotFlushedM, StallW,
|
||||||
input logic CSRMWriteM, CSRSWriteM,
|
input logic CSRMWriteM, CSRSWriteM,
|
||||||
input logic [11:0] CSRAdrM,
|
input logic [11:0] CSRAdrM,
|
||||||
input logic ExtIntM, TimerIntM, SwIntM,
|
input logic ExtIntM, ExtIntS, TimerIntM, SwIntM,
|
||||||
input logic [`XLEN-1:0] MIDELEG_REGW,
|
input logic [`XLEN-1:0] MIDELEG_REGW,
|
||||||
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
|
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
|
||||||
input logic [`XLEN-1:0] CSRWriteValM
|
input logic [`XLEN-1:0] CSRWriteValM
|
||||||
@ -57,12 +57,12 @@ module csri #(parameter
|
|||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
IntInM = 0;
|
IntInM = 0;
|
||||||
IntInM[11] = ExtIntM;; // MEIP
|
IntInM[11] = ExtIntM; // MEIP
|
||||||
IntInM[9] = ExtIntM & MIDELEG_REGW[9]; // SEIP
|
IntInM[9] = (ExtIntM & MIDELEG_REGW[9]); // SEIP
|
||||||
IntInM[7] = TimerIntM; // MTIP
|
IntInM[7] = TimerIntM; // MTIP
|
||||||
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
|
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
|
||||||
IntInM[3] = SwIntM; // MSIP
|
IntInM[3] = SwIntM; // MSIP
|
||||||
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
|
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
|
||||||
end
|
end
|
||||||
|
|
||||||
// Interrupt Write Enables
|
// Interrupt Write Enables
|
||||||
@ -82,22 +82,20 @@ module csri #(parameter
|
|||||||
assign MIP_WRITE_MASK = 12'h000;
|
assign MIP_WRITE_MASK = 12'h000;
|
||||||
assign SIP_WRITE_MASK = 12'h000;
|
assign SIP_WRITE_MASK = 12'h000;
|
||||||
end
|
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;
|
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 (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]) | IntInM[9: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 if (WriteUIPM) IP_REGW = (CSRWriteValM & 12'hBBB) | (NextIPM & 12'h080); // MTIP unclearable
|
else IP_REGW_writeable <= IP_REGW_writeable | {1'b0, IntInM[8:0]}; // *** check this turns off interrupts properly even when MIDELEG changes
|
||||||
else IP_REGW_writeable <= IP_REGW_writeable | IntInM[9:0]; // *** check this turns off interrupts properly even when MIDELEG changes
|
always @(posedge clk)
|
||||||
always @(posedge clk) //, posedge reset) begin
|
|
||||||
if (reset) IE_REGW <= 12'b0;
|
if (reset) IE_REGW <= 12'b0;
|
||||||
else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields
|
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 (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
|
// restricted views of registers
|
||||||
// Add MEIP read-only signal
|
// Add ExtIntM read-only signal
|
||||||
assign IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable};
|
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
|
// Machine Mode
|
||||||
assign MIP_REGW = IP_REGW;
|
assign MIP_REGW = IP_REGW;
|
||||||
assign MIE_REGW = IE_REGW;
|
assign MIE_REGW = IE_REGW;
|
||||||
|
|||||||
@ -55,7 +55,7 @@ module privileged (
|
|||||||
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD,
|
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD,
|
||||||
input logic LoadMisalignedFaultM,
|
input logic LoadMisalignedFaultM,
|
||||||
input logic StoreAmoMisalignedFaultM,
|
input logic StoreAmoMisalignedFaultM,
|
||||||
input logic TimerIntM, ExtIntM, SwIntM,
|
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
|
||||||
input logic [63:0] MTIME_CLINT,
|
input logic [63:0] MTIME_CLINT,
|
||||||
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
|
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
|
||||||
input logic [4:0] SetFflagsM,
|
input logic [4:0] SetFflagsM,
|
||||||
@ -150,7 +150,7 @@ module privileged (
|
|||||||
.StallE, .StallM, .StallW,
|
.StallE, .StallM, .StallW,
|
||||||
.InstrM, .PCM, .SrcAM,
|
.InstrM, .PCM, .SrcAM,
|
||||||
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
|
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
|
||||||
.TimerIntM, .ExtIntM, .SwIntM,
|
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
|
||||||
.MTIME_CLINT,
|
.MTIME_CLINT,
|
||||||
.InstrValidM, .FRegWriteM, .LoadStallD,
|
.InstrValidM, .FRegWriteM, .LoadStallD,
|
||||||
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,
|
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,
|
||||||
|
|||||||
@ -102,7 +102,7 @@ module trap (
|
|||||||
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
|
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
|
||||||
always_comb
|
always_comb
|
||||||
if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1)
|
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
|
else
|
||||||
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
|
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
|
||||||
end
|
end
|
||||||
|
|||||||
@ -37,6 +37,15 @@
|
|||||||
|
|
||||||
`include "wally-config.vh"
|
`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 (
|
module plic (
|
||||||
input logic HCLK, HRESETn,
|
input logic HCLK, HRESETn,
|
||||||
input logic HSELPLIC,
|
input logic HSELPLIC,
|
||||||
@ -48,25 +57,26 @@ module plic (
|
|||||||
input logic UARTIntr,GPIOIntr,
|
input logic UARTIntr,GPIOIntr,
|
||||||
output logic [`XLEN-1:0] HREADPLIC,
|
output logic [`XLEN-1:0] HREADPLIC,
|
||||||
output logic HRESPPLIC, HREADYPLIC,
|
output logic HRESPPLIC, HREADYPLIC,
|
||||||
output logic ExtIntM);
|
output logic ExtIntM, ExtIntS);
|
||||||
|
|
||||||
localparam N=`PLIC_NUM_SRC; // should not exceed 63; does not inlcude source 0, which does not connect to anything according to spec
|
|
||||||
|
|
||||||
logic memwrite, memread, initTrans;
|
logic memwrite, memread, initTrans;
|
||||||
logic [23:0] entry, entryd;
|
logic [23:0] entry, entryd;
|
||||||
logic [31:0] Din, Dout;
|
logic [31:0] Din, Dout;
|
||||||
logic [N:1] requests;
|
|
||||||
|
|
||||||
logic [2:0] intPriority[N:1];
|
// context-independent signals
|
||||||
logic [2:0] intThreshold;
|
logic [`N:1] requests;
|
||||||
logic [N:1] intPending, nextIntPending, intEn, intInProgress;
|
logic [`N:1][2:0] intPriority;
|
||||||
logic [5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
logic [`N:1] intInProgress, intPending, nextIntPending;
|
||||||
|
|
||||||
logic [N:1] pendingArray[7:1];
|
// context-dependent signals
|
||||||
logic [7:1] pendingPGrouped;
|
logic [`C-1:0][2:0] intThreshold;
|
||||||
logic [7:1] pendingMaxP;
|
logic [`C-1:0][`N:1] intEn;
|
||||||
logic [N:1] pendingRequestsAtMaxP;
|
logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
||||||
logic [7:1] threshMask;
|
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
|
// AHB I/O
|
||||||
@ -82,12 +92,12 @@ module plic (
|
|||||||
|
|
||||||
// account for subword read/write circuitry
|
// account for subword read/write circuitry
|
||||||
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
// -- 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 Din = entryd[2] ? HWDATA[63:32] : HWDATA[31:0];
|
||||||
assign HREADPLIC = entryd[2] ? {Dout,32'b0} : {32'b0,Dout};
|
assign HREADPLIC = entryd[2] ? {Dout,32'b0} : {32'b0,Dout};
|
||||||
end else begin // 32-bit
|
end else begin // 32-bit
|
||||||
assign Din = HWDATA[31:0];
|
|
||||||
assign HREADPLIC = Dout;
|
assign HREADPLIC = Dout;
|
||||||
|
assign Din = HWDATA[31:0];
|
||||||
end
|
end
|
||||||
|
|
||||||
// ==================
|
// ==================
|
||||||
@ -96,43 +106,56 @@ module plic (
|
|||||||
always @(posedge HCLK,negedge HRESETn) begin
|
always @(posedge HCLK,negedge HRESETn) begin
|
||||||
// resetting
|
// resetting
|
||||||
if (~HRESETn) begin
|
if (~HRESETn) begin
|
||||||
intPriority <= #1 '{default:3'b0};
|
intPriority <= #1 {`N{3'b0}};
|
||||||
intEn <= #1 {N{1'b0}};
|
intEn <= #1 {2{`N'b0}};
|
||||||
intThreshold <= #1 3'b0;
|
intThreshold <= #1 {2{3'b0}};
|
||||||
intInProgress <= #1 {N{1'b0}};
|
intInProgress <= #1 `N'b0;
|
||||||
// writing
|
// writing
|
||||||
end else begin
|
end else begin
|
||||||
if (memwrite)
|
if (memwrite)
|
||||||
casez(entryd)
|
casez(entryd)
|
||||||
24'h0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
|
24'h0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
|
||||||
`ifdef PLIC_NUM_SRC_LT_32
|
`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[N:1] <= #1 Din[N:1];
|
24'h002000: intEn[0][`N:1] <= #1 Din[`N:1];
|
||||||
|
24'h002080: intEn[1][`N:1] <= #1 Din[`N:1];
|
||||||
`endif
|
`endif
|
||||||
`ifndef PLIC_NUM_SRC_LT_32
|
`ifndef PLIC_NUM_SRC_LT_32
|
||||||
24'h002000: intEn[31:1] <= #1 Din[31:1];
|
24'h002000: intEn[0][31:1] <= #1 Din[31:1];
|
||||||
24'h002004: intEn[N:32] <= #1 Din[31:0];
|
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
|
`endif
|
||||||
24'h200000: intThreshold[2:0] <= #1 Din[2:0];
|
24'h200000: intThreshold[0] <= #1 Din[2:0];
|
||||||
24'h200004: intInProgress <= #1 intInProgress & ~(`PLIC_NUM_SRC'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
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
|
endcase
|
||||||
// reading
|
// reading
|
||||||
if (memread)
|
if (memread)
|
||||||
casez(entry)
|
casez(entry)
|
||||||
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
||||||
`ifdef PLIC_NUM_SRC_LT_32
|
`ifdef PLIC_NUM_SRC_LT_32
|
||||||
24'h001000: Dout <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
|
24'h001000: Dout <= #1 {{(31-`N){1'b0}},intPending,1'b0};
|
||||||
24'h002000: Dout <= #1 {{(31-N){1'b0}},intEn[N:1],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
|
`endif
|
||||||
`ifndef PLIC_NUM_SRC_LT_32
|
`ifndef PLIC_NUM_SRC_LT_32
|
||||||
24'h001000: Dout <= #1 {intPending[31:1],1'b0};
|
24'h001000: Dout <= #1 {intPending[31:1],1'b0};
|
||||||
24'h001004: Dout <= #1 {{(63-N){1'b0}},intPending[N:32]};
|
24'h001004: Dout <= #1 {{(63-`N){1'b0}},intPending[`N:32]};
|
||||||
24'h002000: Dout <= #1 {intEn[31:1],1'b0};
|
24'h002000: Dout <= #1 {intEn[0][31:1],1'b0};
|
||||||
24'h002004: Dout <= #1 {{(63-N){1'b0}},intEn[N:32]};
|
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
|
`endif
|
||||||
24'h200000: Dout <= #1 {29'b0,intThreshold[2:0]};
|
24'h200000: Dout <= #1 {29'b0,intThreshold[0]};
|
||||||
24'h200004: begin
|
24'h200004: begin
|
||||||
Dout <= #1 {26'b0,intClaim};
|
Dout <= #1 {26'b0,intClaim[0]};
|
||||||
intInProgress <= #1 intInProgress | (`PLIC_NUM_SRC'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
|
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
|
end
|
||||||
default: Dout <= #1 32'h0; // invalid access
|
default: Dout <= #1 32'h0; // invalid access
|
||||||
endcase
|
endcase
|
||||||
@ -143,7 +166,7 @@ module plic (
|
|||||||
|
|
||||||
// connect sources to requests
|
// connect sources to requests
|
||||||
always_comb begin
|
always_comb begin
|
||||||
requests = {N{1'b0}};
|
requests = `N'b0;
|
||||||
`ifdef PLIC_GPIO_ID
|
`ifdef PLIC_GPIO_ID
|
||||||
requests[`PLIC_GPIO_ID] = GPIOIntr;
|
requests[`PLIC_GPIO_ID] = GPIOIntr;
|
||||||
`endif
|
`endif
|
||||||
@ -152,66 +175,88 @@ module plic (
|
|||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
|
|
||||||
// pending updates
|
// pending interrupt requests
|
||||||
// *** verify that this matches the expectations of the things that make requests (in terms of timing, edge-triggered vs level-triggered)
|
assign nextIntPending =
|
||||||
assign nextIntPending = (intPending | (requests & ~intInProgress)) & // requests should raise intPending except when their service routine is already in progress
|
(intPending | // existing pending requests
|
||||||
~({N{((entry == 24'h200004) & memread)}} << (intClaim-1)); // clear pending bit when claim register is read
|
(requests & ~intInProgress)) & // assert new requests (if they aren't already being serviced)
|
||||||
flopr #(N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
|
~({`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
|
// context-dependent signals
|
||||||
genvar i, j;
|
genvar ctx;
|
||||||
for (j=1; j<=7; j++) begin: pending
|
for (ctx=0; ctx<`C; ctx++) begin
|
||||||
for (i=1; i<=N; i=i+1) begin: pendingbit
|
// request matrix
|
||||||
assign pendingArray[j][i] = (intPriority[i]==j) & intEn[i] & intPending[i];
|
// 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
|
||||||
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
|
// which prority levels have one or more active requests?
|
||||||
assign pendingMaxP[7:1] = {pendingPGrouped[7],
|
assign priorities_with_irqs[ctx][7:1] = {
|
||||||
pendingPGrouped[6] & ~|pendingPGrouped[7],
|
|irqMatrix[ctx][7],
|
||||||
pendingPGrouped[5] & ~|pendingPGrouped[7:6],
|
|irqMatrix[ctx][6],
|
||||||
pendingPGrouped[4] & ~|pendingPGrouped[7:5],
|
|irqMatrix[ctx][5],
|
||||||
pendingPGrouped[3] & ~|pendingPGrouped[7:4],
|
|irqMatrix[ctx][4],
|
||||||
pendingPGrouped[2] & ~|pendingPGrouped[7:3],
|
|irqMatrix[ctx][3],
|
||||||
pendingPGrouped[1] & ~|pendingPGrouped[7:2]};
|
|irqMatrix[ctx][2],
|
||||||
// select the pending requests at that priority
|
|irqMatrix[ctx][1]
|
||||||
assign pendingRequestsAtMaxP[N:1] = ({N{pendingMaxP[7]}} & pendingArray[7])
|
};
|
||||||
| ({N{pendingMaxP[6]}} & pendingArray[6])
|
|
||||||
| ({N{pendingMaxP[5]}} & pendingArray[5])
|
// get the highest priority level that has active requests
|
||||||
| ({N{pendingMaxP[4]}} & pendingArray[4])
|
assign max_priority_with_irqs[ctx][7:1] = {
|
||||||
| ({N{pendingMaxP[3]}} & pendingArray[3])
|
priorities_with_irqs[ctx][7],
|
||||||
| ({N{pendingMaxP[2]}} & pendingArray[2])
|
priorities_with_irqs[ctx][6] & ~|priorities_with_irqs[ctx][7],
|
||||||
| ({N{pendingMaxP[1]}} & pendingArray[1]);
|
priorities_with_irqs[ctx][5] & ~|priorities_with_irqs[ctx][7:6],
|
||||||
// find the lowest ID amongst active interrupts at the highest priority
|
priorities_with_irqs[ctx][4] & ~|priorities_with_irqs[ctx][7:5],
|
||||||
logic [5:0] k;
|
priorities_with_irqs[ctx][3] & ~|priorities_with_irqs[ctx][7:4],
|
||||||
always_comb begin
|
priorities_with_irqs[ctx][2] & ~|priorities_with_irqs[ctx][7:3],
|
||||||
intClaim = 6'b0;
|
priorities_with_irqs[ctx][1] & ~|priorities_with_irqs[ctx][7:2]
|
||||||
for (k=N; k>0; k=k-1) begin
|
};
|
||||||
if (pendingRequestsAtMaxP[k]) intClaim = k;
|
|
||||||
|
// 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
|
||||||
end
|
|
||||||
|
// create threshold mask
|
||||||
// create threshold mask
|
always_comb begin
|
||||||
always_comb begin
|
threshMask[ctx][7] = (intThreshold[ctx] != 7);
|
||||||
threshMask[7] = (intThreshold != 7);
|
threshMask[ctx][6] = (intThreshold[ctx] != 6) & threshMask[ctx][7];
|
||||||
threshMask[6] = (intThreshold != 6) & threshMask[7];
|
threshMask[ctx][5] = (intThreshold[ctx] != 5) & threshMask[ctx][6];
|
||||||
threshMask[5] = (intThreshold != 5) & threshMask[6];
|
threshMask[ctx][4] = (intThreshold[ctx] != 4) & threshMask[ctx][5];
|
||||||
threshMask[4] = (intThreshold != 4) & threshMask[5];
|
threshMask[ctx][3] = (intThreshold[ctx] != 3) & threshMask[ctx][4];
|
||||||
threshMask[3] = (intThreshold != 3) & threshMask[4];
|
threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3];
|
||||||
threshMask[2] = (intThreshold != 2) & threshMask[3];
|
threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2];
|
||||||
threshMask[1] = (intThreshold != 1) & threshMask[2];
|
end
|
||||||
end
|
// is the max priority > threshold?
|
||||||
// is the max priority > threshold?
|
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
|
||||||
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
|
end
|
||||||
assign ExtIntM = |(threshMask & pendingPGrouped);
|
assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]);
|
||||||
|
assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,7 @@ module uncore (
|
|||||||
input logic [3:0] HSIZED,
|
input logic [3:0] HSIZED,
|
||||||
input logic HWRITED,
|
input logic HWRITED,
|
||||||
// peripheral pins
|
// peripheral pins
|
||||||
output logic TimerIntM, SwIntM, ExtIntM,
|
output logic TimerIntM, SwIntM, ExtIntM, ExtIntS,
|
||||||
input logic [31:0] GPIOPinsIn,
|
input logic [31:0] GPIOPinsIn,
|
||||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
||||||
input logic UARTSin,
|
input logic UARTSin,
|
||||||
@ -133,9 +133,10 @@ module uncore (
|
|||||||
.HWRITE, .HREADY, .HTRANS, .HWDATA,
|
.HWRITE, .HREADY, .HTRANS, .HWDATA,
|
||||||
.UARTIntr, .GPIOIntr,
|
.UARTIntr, .GPIOIntr,
|
||||||
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
|
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
|
||||||
.ExtIntM);
|
.ExtIntM, .ExtIntS);
|
||||||
end else begin : plic
|
end else begin : plic
|
||||||
assign ExtIntM = 0;
|
assign ExtIntM = 0;
|
||||||
|
assign ExtIntS = 0;
|
||||||
end
|
end
|
||||||
if (`GPIO_SUPPORTED == 1) begin : gpio
|
if (`GPIO_SUPPORTED == 1) begin : gpio
|
||||||
gpio gpio(
|
gpio gpio(
|
||||||
|
|||||||
@ -32,137 +32,137 @@
|
|||||||
/* verilator lint_on UNUSED */
|
/* verilator lint_on UNUSED */
|
||||||
|
|
||||||
module wallypipelinedcore (
|
module wallypipelinedcore (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
// Privileged
|
// Privileged
|
||||||
input logic TimerIntM, ExtIntM, SwIntM,
|
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
|
||||||
input logic [63:0] MTIME_CLINT,
|
input logic [63:0] MTIME_CLINT,
|
||||||
// Bus Interface
|
// Bus Interface
|
||||||
input logic [`AHBW-1:0] HRDATA,
|
input logic [`AHBW-1:0] HRDATA,
|
||||||
input logic HREADY, HRESP,
|
input logic HREADY, HRESP,
|
||||||
output logic HCLK, HRESETn,
|
output logic HCLK, HRESETn,
|
||||||
output logic [31:0] HADDR,
|
output logic [31:0] HADDR,
|
||||||
output logic [`AHBW-1:0] HWDATA,
|
output logic [`AHBW-1:0] HWDATA,
|
||||||
output logic HWRITE,
|
output logic HWRITE,
|
||||||
output logic [2:0] HSIZE,
|
output logic [2:0] HSIZE,
|
||||||
output logic [2:0] HBURST,
|
output logic [2:0] HBURST,
|
||||||
output logic [3:0] HPROT,
|
output logic [3:0] HPROT,
|
||||||
output logic [1:0] HTRANS,
|
output logic [1:0] HTRANS,
|
||||||
output logic HMASTLOCK,
|
output logic HMASTLOCK,
|
||||||
// Delayed signals for subword write
|
// Delayed signals for subword write
|
||||||
output logic [2:0] HADDRD,
|
output logic [2:0] HADDRD,
|
||||||
output logic [3:0] HSIZED,
|
output logic [3:0] HSIZED,
|
||||||
output logic HWRITED
|
output logic HWRITED
|
||||||
);
|
);
|
||||||
|
|
||||||
// logic [1:0] ForwardAE, ForwardBE;
|
// logic [1:0] ForwardAE, ForwardBE;
|
||||||
logic StallF, StallD, StallE, StallM, StallW;
|
logic StallF, StallD, StallE, StallM, StallW;
|
||||||
logic FlushF, FlushD, FlushE, FlushM, FlushW;
|
logic FlushF, FlushD, FlushE, FlushM, FlushW;
|
||||||
logic RetM;
|
logic RetM;
|
||||||
(* mark_debug = "true" *) logic TrapM;
|
(* mark_debug = "true" *) logic TrapM;
|
||||||
|
|
||||||
// new signals that must connect through DP
|
// new signals that must connect through DP
|
||||||
logic MDUE, W64E;
|
logic MDUE, W64E;
|
||||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||||
logic [1:0] AtomicE;
|
logic [1:0] AtomicE;
|
||||||
logic [1:0] AtomicM;
|
logic [1:0] AtomicM;
|
||||||
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
|
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
|
||||||
logic [`XLEN-1:0] SrcAM;
|
logic [`XLEN-1:0] SrcAM;
|
||||||
logic [2:0] Funct3E;
|
logic [2:0] Funct3E;
|
||||||
// logic [31:0] InstrF;
|
// logic [31:0] InstrF;
|
||||||
logic [31:0] InstrD, InstrW;
|
logic [31:0] InstrD, InstrW;
|
||||||
(* mark_debug = "true" *) logic [31:0] InstrM;
|
(* mark_debug = "true" *) logic [31:0] InstrM;
|
||||||
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
|
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
|
||||||
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
||||||
logic [`XLEN-1:0] PrivilegedNextPCM;
|
logic [`XLEN-1:0] PrivilegedNextPCM;
|
||||||
(* mark_debug = "true" *) logic [1:0] MemRWM;
|
(* mark_debug = "true" *) logic [1:0] MemRWM;
|
||||||
(* mark_debug = "true" *) logic InstrValidM;
|
(* mark_debug = "true" *) logic InstrValidM;
|
||||||
logic InstrMisalignedFaultM;
|
logic InstrMisalignedFaultM;
|
||||||
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
||||||
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
|
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
|
||||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||||
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
||||||
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
||||||
logic InvalidateICacheM, FlushDCacheM;
|
logic InvalidateICacheM, FlushDCacheM;
|
||||||
logic PCSrcE;
|
logic PCSrcE;
|
||||||
logic CSRWritePendingDEM;
|
logic CSRWritePendingDEM;
|
||||||
logic DivBusyE;
|
logic DivBusyE;
|
||||||
logic DivE;
|
logic DivE;
|
||||||
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
||||||
logic SquashSCW;
|
logic SquashSCW;
|
||||||
// floating point unit signals
|
// floating point unit signals
|
||||||
logic [2:0] FRM_REGW;
|
logic [2:0] FRM_REGW;
|
||||||
logic [4:0] RdM, RdW;
|
logic [4:0] RdM, RdW;
|
||||||
logic FStallD;
|
logic FStallD;
|
||||||
logic FWriteIntE;
|
logic FWriteIntE;
|
||||||
logic [`XLEN-1:0] FWriteDataE;
|
logic [`XLEN-1:0] FWriteDataE;
|
||||||
logic [`XLEN-1:0] FIntResM;
|
logic [`XLEN-1:0] FIntResM;
|
||||||
logic FDivBusyE;
|
logic FDivBusyE;
|
||||||
logic IllegalFPUInstrD, IllegalFPUInstrE;
|
logic IllegalFPUInstrD, IllegalFPUInstrE;
|
||||||
logic FRegWriteM;
|
logic FRegWriteM;
|
||||||
logic FPUStallD;
|
logic FPUStallD;
|
||||||
logic [4:0] SetFflagsM;
|
logic [4:0] SetFflagsM;
|
||||||
|
|
||||||
// memory management unit signals
|
// memory management unit signals
|
||||||
logic ITLBWriteF;
|
logic ITLBWriteF;
|
||||||
logic ITLBFlushF, DTLBFlushM;
|
logic ITLBFlushF, DTLBFlushM;
|
||||||
logic ITLBMissF;
|
logic ITLBMissF;
|
||||||
logic [`XLEN-1:0] SATP_REGW;
|
logic [`XLEN-1:0] SATP_REGW;
|
||||||
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
|
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
|
||||||
logic [1:0] STATUS_MPP;
|
logic [1:0] STATUS_MPP;
|
||||||
logic [1:0] PrivilegeModeW;
|
logic [1:0] PrivilegeModeW;
|
||||||
logic [`XLEN-1:0] PTE;
|
logic [`XLEN-1:0] PTE;
|
||||||
logic [1:0] PageType;
|
logic [1:0] PageType;
|
||||||
|
|
||||||
// PMA checker signals
|
// PMA checker signals
|
||||||
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
|
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
|
||||||
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
||||||
|
|
||||||
// IMem stalls
|
// IMem stalls
|
||||||
logic IFUStallF;
|
logic IFUStallF;
|
||||||
logic LSUStallM;
|
logic LSUStallM;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// cpu lsu interface
|
// cpu lsu interface
|
||||||
logic [2:0] Funct3M;
|
logic [2:0] Funct3M;
|
||||||
logic [`XLEN-1:0] IEUAdrE;
|
logic [`XLEN-1:0] IEUAdrE;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataE;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataE;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM;
|
||||||
logic [`XLEN-1:0] ReadDataW;
|
logic [`XLEN-1:0] ReadDataW;
|
||||||
logic CommittedM;
|
logic CommittedM;
|
||||||
|
|
||||||
// AHB ifu interface
|
// AHB ifu interface
|
||||||
logic [`PA_BITS-1:0] IFUBusAdr;
|
logic [`PA_BITS-1:0] IFUBusAdr;
|
||||||
logic [`XLEN-1:0] IFUBusHRDATA;
|
logic [`XLEN-1:0] IFUBusHRDATA;
|
||||||
logic IFUBusRead;
|
logic IFUBusRead;
|
||||||
logic IFUBusAck;
|
logic IFUBusAck;
|
||||||
|
|
||||||
// AHB LSU interface
|
// AHB LSU interface
|
||||||
logic [`PA_BITS-1:0] LSUBusAdr;
|
logic [`PA_BITS-1:0] LSUBusAdr;
|
||||||
logic LSUBusRead;
|
logic LSUBusRead;
|
||||||
logic LSUBusWrite;
|
logic LSUBusWrite;
|
||||||
logic LSUBusAck;
|
logic LSUBusAck;
|
||||||
logic [`XLEN-1:0] LSUBusHRDATA;
|
logic [`XLEN-1:0] LSUBusHRDATA;
|
||||||
logic [`XLEN-1:0] LSUBusHWDATA;
|
logic [`XLEN-1:0] LSUBusHWDATA;
|
||||||
|
|
||||||
logic BPPredWrongE;
|
logic BPPredWrongE;
|
||||||
logic BPPredDirWrongM;
|
logic BPPredDirWrongM;
|
||||||
logic BTBPredPCWrongM;
|
logic BTBPredPCWrongM;
|
||||||
logic RASPredPCWrongM;
|
logic RASPredPCWrongM;
|
||||||
logic BPPredClassNonCFIWrongM;
|
logic BPPredClassNonCFIWrongM;
|
||||||
logic [4:0] InstrClassM;
|
logic [4:0] InstrClassM;
|
||||||
logic InstrAccessFaultF;
|
logic InstrAccessFaultF;
|
||||||
logic [2:0] LSUBusSize;
|
logic [2:0] LSUBusSize;
|
||||||
|
|
||||||
logic ExceptionM;
|
logic ExceptionM;
|
||||||
logic PendingInterruptM;
|
logic PendingInterruptM;
|
||||||
logic DCacheMiss;
|
logic DCacheMiss;
|
||||||
logic DCacheAccess;
|
logic DCacheAccess;
|
||||||
logic ICacheMiss;
|
logic ICacheMiss;
|
||||||
logic ICacheAccess;
|
logic ICacheAccess;
|
||||||
logic BreakpointFaultM, EcallFaultM;
|
logic BreakpointFaultM, EcallFaultM;
|
||||||
logic InstrDAPageFaultF;
|
logic InstrDAPageFaultF;
|
||||||
|
|
||||||
ifu ifu(
|
ifu ifu(
|
||||||
@ -182,7 +182,7 @@ module wallypipelinedcore (
|
|||||||
|
|
||||||
// Mem
|
// Mem
|
||||||
.RetM, .TrapM, .PrivilegedNextPCM, .InvalidateICacheM,
|
.RetM, .TrapM, .PrivilegedNextPCM, .InvalidateICacheM,
|
||||||
.InstrD, .InstrM, . PCM, .InstrClassM, .BPPredDirWrongM,
|
.InstrD, .InstrM, .PCM, .InstrClassM, .BPPredDirWrongM,
|
||||||
.BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
|
.BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
|
||||||
|
|
||||||
// Writeback
|
// Writeback
|
||||||
@ -203,8 +203,8 @@ module wallypipelinedcore (
|
|||||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||||
.InstrAccessFaultF,
|
.InstrAccessFaultF,
|
||||||
.InstrDAPageFaultF
|
.InstrDAPageFaultF
|
||||||
|
|
||||||
); // instruction fetch unit: PC, branch prediction, instruction cache
|
); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||||
|
|
||||||
ieu ieu(
|
ieu ieu(
|
||||||
.clk, .reset,
|
.clk, .reset,
|
||||||
@ -221,7 +221,7 @@ module wallypipelinedcore (
|
|||||||
// Memory stage interface
|
// Memory stage interface
|
||||||
.SquashSCW, // from LSU
|
.SquashSCW, // from LSU
|
||||||
.MemRWM, // read/write control goes to 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
|
.AtomicM, // atomic control goes to LSU
|
||||||
.WriteDataE, // Write data to LSU
|
.WriteDataE, // Write data to LSU
|
||||||
.Funct3M, // size and signedness to LSU
|
.Funct3M, // size and signedness to LSU
|
||||||
@ -245,41 +245,41 @@ module wallypipelinedcore (
|
|||||||
|
|
||||||
lsu lsu(
|
lsu lsu(
|
||||||
.clk, .reset, .StallM, .FlushM, .StallW,
|
.clk, .reset, .StallM, .FlushM, .StallW,
|
||||||
.FlushW,
|
.FlushW,
|
||||||
// CPU interface
|
// CPU interface
|
||||||
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
|
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
|
||||||
.AtomicM, .TrapM,
|
.AtomicM, .TrapM,
|
||||||
.CommittedM, .DCacheMiss, .DCacheAccess,
|
.CommittedM, .DCacheMiss, .DCacheAccess,
|
||||||
.SquashSCW,
|
.SquashSCW,
|
||||||
//.DataMisalignedM(DataMisalignedM),
|
//.DataMisalignedM(DataMisalignedM),
|
||||||
.IEUAdrE, .IEUAdrM, .WriteDataE,
|
.IEUAdrE, .IEUAdrM, .WriteDataE,
|
||||||
.ReadDataM, .FlushDCacheM,
|
.ReadDataM, .FlushDCacheM,
|
||||||
// connected to ahb (all stay the same)
|
// connected to ahb (all stay the same)
|
||||||
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
|
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
|
||||||
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
|
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
|
||||||
|
|
||||||
// connect to csr or privilege and stay the same.
|
// connect to csr or privilege and stay the same.
|
||||||
.PrivilegeModeW, // connects to csr
|
.PrivilegeModeW, // connects to csr
|
||||||
.PMPCFG_ARRAY_REGW, // connects to csr
|
.PMPCFG_ARRAY_REGW, // connects to csr
|
||||||
.PMPADDR_ARRAY_REGW, // connects to csr
|
.PMPADDR_ARRAY_REGW, // connects to csr
|
||||||
// hptw keep i/o
|
// hptw keep i/o
|
||||||
.SATP_REGW, // from csr
|
.SATP_REGW, // from csr
|
||||||
.STATUS_MXR, // from csr
|
.STATUS_MXR, // from csr
|
||||||
.STATUS_SUM, // from csr
|
.STATUS_SUM, // from csr
|
||||||
.STATUS_MPRV, // from csr
|
.STATUS_MPRV, // from csr
|
||||||
.STATUS_MPP, // from csr
|
.STATUS_MPP, // from csr
|
||||||
|
|
||||||
.DTLBFlushM, // connects to privilege
|
.DTLBFlushM, // connects to privilege
|
||||||
.LoadPageFaultM, // connects to privilege
|
.LoadPageFaultM, // connects to privilege
|
||||||
.StoreAmoPageFaultM, // connects to privilege
|
.StoreAmoPageFaultM, // connects to privilege
|
||||||
.LoadMisalignedFaultM, // connects to privilege
|
.LoadMisalignedFaultM, // connects to privilege
|
||||||
.LoadAccessFaultM, // connects to privilege
|
.LoadAccessFaultM, // connects to privilege
|
||||||
.StoreAmoMisalignedFaultM, // connects to privilege
|
.StoreAmoMisalignedFaultM, // connects to privilege
|
||||||
.StoreAmoAccessFaultM, // connects to privilege
|
.StoreAmoAccessFaultM, // connects to privilege
|
||||||
.InstrDAPageFaultF,
|
.InstrDAPageFaultF,
|
||||||
|
|
||||||
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
|
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
|
||||||
.LSUStallM); // change to LSUStallM
|
.LSUStallM); // change to LSUStallM
|
||||||
|
|
||||||
|
|
||||||
// *** Ross: please make EBU conditional when only supporting internal memories
|
// *** Ross: please make EBU conditional when only supporting internal memories
|
||||||
@ -306,13 +306,13 @@ module wallypipelinedcore (
|
|||||||
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
||||||
.LSUStallM, .IFUStallF,
|
.LSUStallM, .IFUStallF,
|
||||||
.FPUStallD, .FStallD,
|
.FPUStallD, .FStallD,
|
||||||
.DivBusyE, .FDivBusyE,
|
.DivBusyE, .FDivBusyE,
|
||||||
.EcallFaultM, .BreakpointFaultM,
|
.EcallFaultM, .BreakpointFaultM,
|
||||||
.InvalidateICacheM,
|
.InvalidateICacheM,
|
||||||
// Stall & flush outputs
|
// Stall & flush outputs
|
||||||
.StallF, .StallD, .StallE, .StallM, .StallW,
|
.StallF, .StallD, .StallE, .StallM, .StallW,
|
||||||
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
||||||
); // global stall and flush control
|
); // global stall and flush control
|
||||||
|
|
||||||
if (`ZICSR_SUPPORTED) begin:priv
|
if (`ZICSR_SUPPORTED) begin:priv
|
||||||
privileged priv(
|
privileged priv(
|
||||||
@ -331,7 +331,7 @@ module wallypipelinedcore (
|
|||||||
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
|
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
|
||||||
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
|
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
|
||||||
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
|
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
|
||||||
.TimerIntM, .ExtIntM, .SwIntM,
|
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
|
||||||
.MTIME_CLINT,
|
.MTIME_CLINT,
|
||||||
.InstrMisalignedAdrM, .IEUAdrM,
|
.InstrMisalignedAdrM, .IEUAdrM,
|
||||||
.SetFflagsM,
|
.SetFflagsM,
|
||||||
|
|||||||
@ -74,7 +74,7 @@ module wallypipelinedsoc (
|
|||||||
logic HRESP;
|
logic HRESP;
|
||||||
logic TimerIntM, SwIntM; // from CLINT
|
logic TimerIntM, SwIntM; // from CLINT
|
||||||
logic [63:0] MTIME_CLINT; // from CLINT to CSRs
|
logic [63:0] MTIME_CLINT; // from CLINT to CSRs
|
||||||
logic ExtIntM; // from PLIC
|
logic ExtIntM,ExtIntS; // from PLIC
|
||||||
logic [2:0] HADDRD;
|
logic [2:0] HADDRD;
|
||||||
logic [3:0] HSIZED;
|
logic [3:0] HSIZED;
|
||||||
logic HWRITED;
|
logic HWRITED;
|
||||||
@ -84,7 +84,7 @@ module wallypipelinedsoc (
|
|||||||
|
|
||||||
// instantiate processor and memories
|
// instantiate processor and memories
|
||||||
wallypipelinedcore core(.clk, .reset,
|
wallypipelinedcore core(.clk, .reset,
|
||||||
.TimerIntM, .ExtIntM, .SwIntM,
|
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
|
||||||
.MTIME_CLINT,
|
.MTIME_CLINT,
|
||||||
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA,
|
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA,
|
||||||
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
|
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
|
||||||
@ -94,7 +94,7 @@ module wallypipelinedsoc (
|
|||||||
uncore uncore(.HCLK, .HRESETn, .TIMECLK,
|
uncore uncore(.HCLK, .HRESETn, .TIMECLK,
|
||||||
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
||||||
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED,
|
.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,
|
.HSELEXT,
|
||||||
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK
|
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK
|
||||||
|
|
||||||
|
|||||||
@ -176,6 +176,7 @@ module testbench;
|
|||||||
integer CheckMIPFutureM;
|
integer CheckMIPFutureM;
|
||||||
integer CheckSIPFutureE;
|
integer CheckSIPFutureE;
|
||||||
integer CheckSIPFutureM;
|
integer CheckSIPFutureM;
|
||||||
|
logic [`XLEN-1:0] AttemptedInstructionCount;
|
||||||
// Useful Aliases
|
// Useful Aliases
|
||||||
`define RF dut.core.ieu.dp.regf.rf
|
`define RF dut.core.ieu.dp.regf.rf
|
||||||
`define PC dut.core.ifu.pcreg.q
|
`define PC dut.core.ifu.pcreg.q
|
||||||
@ -266,6 +267,19 @@ module testbench;
|
|||||||
end \
|
end \
|
||||||
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
|
// For the annoying case where the pathname to the array elements includes
|
||||||
// a "genblk<i>" in the signal name
|
// a "genblk<i>" in the signal name
|
||||||
`define INIT_CHECKPOINT_GENBLK_ARRAY(SIGNAL_BASE,SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
`define INIT_CHECKPOINT_GENBLK_ARRAY(SIGNAL_BASE,SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
||||||
@ -296,6 +310,7 @@ module testbench;
|
|||||||
end \
|
end \
|
||||||
end
|
end
|
||||||
|
|
||||||
|
genvar i;
|
||||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1);
|
`INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1);
|
||||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,0);
|
`INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,0);
|
||||||
`INIT_CHECKPOINT_VAL(PC, [`XLEN-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_LSR, [7:0]);
|
||||||
//`INIT_CHECKPOINT_VAL(UART_MSR, [7:0]);
|
//`INIT_CHECKPOINT_VAL(UART_MSR, [7:0]);
|
||||||
`INIT_CHECKPOINT_VAL(UART_SCR, [7:0]);
|
`INIT_CHECKPOINT_VAL(UART_SCR, [7:0]);
|
||||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
|
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
|
||||||
`INIT_CHECKPOINT_VAL(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1]);
|
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0);
|
||||||
`INIT_CHECKPOINT_VAL(PLIC_THRESHOLD, [2:0]);
|
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_THRESHOLD, [2:0],1,0);
|
||||||
|
|
||||||
integer memFile;
|
integer memFile;
|
||||||
integer readResult;
|
integer readResult;
|
||||||
@ -366,11 +381,13 @@ module testbench;
|
|||||||
traceFileM = $fopen({testvectorDir,"all.txt"}, "r");
|
traceFileM = $fopen({testvectorDir,"all.txt"}, "r");
|
||||||
traceFileE = $fopen({testvectorDir,"all.txt"}, "r");
|
traceFileE = $fopen({testvectorDir,"all.txt"}, "r");
|
||||||
InstrCountW = '0;
|
InstrCountW = '0;
|
||||||
|
AttemptedInstructionCount = '0;
|
||||||
end else begin // checkpoint
|
end else begin // checkpoint
|
||||||
//$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.memory.RAM);
|
//$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.memory.RAM);
|
||||||
traceFileE = $fopen({checkpointDir,"all.txt"}, "r");
|
traceFileE = $fopen({checkpointDir,"all.txt"}, "r");
|
||||||
traceFileM = $fopen({checkpointDir,"all.txt"}, "r");
|
traceFileM = $fopen({checkpointDir,"all.txt"}, "r");
|
||||||
InstrCountW = CHECKPOINT;
|
InstrCountW = CHECKPOINT;
|
||||||
|
AttemptedInstructionCount = CHECKPOINT;
|
||||||
// manual checkpoint initializations that don't neatly fit into MACRO
|
// 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_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV} = initMSTATUS[0][22:17];
|
||||||
force {`STATUS_FS,`STATUS_MPP} = initMSTATUS[0][14:11];
|
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 \
|
for(index``STAGE = 0; index``STAGE < line``STAGE.len(); index``STAGE++) begin \
|
||||||
//$display("char = %s", line``STAGE[index]); \
|
//$display("char = %s", line``STAGE[index]); \
|
||||||
if (line``STAGE[index``STAGE] == " " | line``STAGE[index``STAGE] == "\n") begin \
|
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; \
|
EndIndex``STAGE = index``STAGE; \
|
||||||
ExpectedTokens``STAGE[TokenIndex``STAGE] = line``STAGE.substr(StartIndex``STAGE, EndIndex``STAGE-1); \
|
ExpectedTokens``STAGE[TokenIndex``STAGE] = line``STAGE.substr(StartIndex``STAGE, EndIndex``STAGE-1); \
|
||||||
//$display("In Tokenizer %s", line``STAGE.substr(StartIndex, EndIndex-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/andi-01", "6010",
|
||||||
"rv64i_m/I/auipc-01", "2010",
|
"rv64i_m/I/auipc-01", "2010",
|
||||||
"rv64i_m/I/beq-01", "47010",
|
"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/bgeu-01", "56010",
|
||||||
"rv64i_m/I/blt-01", "4d010",
|
"rv64i_m/I/blt-01", "4d010",
|
||||||
"rv64i_m/I/bltu-01", "57010",
|
"rv64i_m/I/bltu-01", "57010",
|
||||||
@ -1450,34 +1450,36 @@ string imperas32f[] = '{
|
|||||||
|
|
||||||
string wally64priv[] = '{
|
string wally64priv[] = '{
|
||||||
`WALLYTEST,
|
`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-M", "005070",
|
||||||
//"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-S", "003070",
|
//"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-MARCHID", "003070",
|
||||||
/* "rv64i_m/privilege/WALLY-MCAUSE", "003070",
|
/* "rv64i_m/privilege/WALLY-MCAUSE", "003070",
|
||||||
"rv64i_m/privilege/WALLY-MEDELEG", "003070",
|
"rv64i_m/privilege/WALLY-MEDELEG", "003070",
|
||||||
"rv64i_m/privilege/WALLY-MHARTID", "003070",
|
"rv64i_m/privilege/WALLY-MHARTID", "003070",
|
||||||
"rv64i_m/privilege/WALLY-MIMPID", "003070",*/
|
"rv64i_m/privilege/WALLY-MIMPID", "003070",*/
|
||||||
"rv64i_m/privilege/WALLY-minfo-01", "004080",
|
"rv64i_m/privilege/WALLY-minfo-01", "0040a0",
|
||||||
"rv64i_m/privilege/WALLY-misa-01", "004080",
|
"rv64i_m/privilege/WALLY-misa-01", "0040a0",
|
||||||
"rv64i_m/privilege/WALLY-MMU-SV39", "004080",
|
"rv64i_m/privilege/WALLY-MMU-SV39", "0040a0",
|
||||||
"rv64i_m/privilege/WALLY-MMU-SV48", "004080",
|
"rv64i_m/privilege/WALLY-MMU-SV48", "0040a0",
|
||||||
/* "rv64i_m/privilege/WALLY-MSTATUS", "002070",
|
/* "rv64i_m/privilege/WALLY-MSTATUS", "002070",
|
||||||
"rv64i_m/privilege/WALLY-MTVEC", "002070",
|
"rv64i_m/privilege/WALLY-MTVEC", "002070",
|
||||||
"rv64i_m/privilege/WALLY-MVENDORID", "003070", */
|
"rv64i_m/privilege/WALLY-MVENDORID", "003070", */
|
||||||
"rv64i_m/privilege/WALLY-PMA", "004080",
|
"rv64i_m/privilege/WALLY-PMA", "0040a0",
|
||||||
"rv64i_m/privilege/WALLY-PMP", "004080",
|
"rv64i_m/privilege/WALLY-PMP", "0040a0",
|
||||||
// "rv64i_m/privilege/WALLY-SCAUSE", "002070",
|
// "rv64i_m/privilege/WALLY-SCAUSE", "002070",
|
||||||
"rv64i_m/privilege/WALLY-scratch-01", "004080",
|
"rv64i_m/privilege/WALLY-scratch-01", "0040a0",
|
||||||
"rv64i_m/privilege/WALLY-sscratch-s-01", "004080"
|
"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-STVEC", "002070",
|
||||||
// "rv64i_m/privilege/WALLY-UCAUSE", "002070"
|
// "rv64i_m/privilege/WALLY-UCAUSE", "002070",
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
string wally64periph[] = '{
|
string wally64periph[] = '{
|
||||||
`WALLYTEST,
|
`WALLYTEST,
|
||||||
"rv64i_m/privilege/WALLY-PERIPH", "22f0"
|
"rv64i_m/privilege/WALLY-PERIPH", "3310"
|
||||||
};
|
};
|
||||||
|
|
||||||
string wally32e[] = '{
|
string wally32e[] = '{
|
||||||
|
|||||||
@ -50,10 +50,47 @@
|
|||||||
// Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries)
|
// Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries)
|
||||||
`define PMPCFG_ENTRIES (`PMP_ENTRIES/8)
|
`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
|
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits
|
||||||
`define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32)
|
`define FLEN (`Q_SUPPORTED ? `Q_LEN : `D_SUPPORTED ? `D_LEN : `F_SUPPORTED ? `S_LEN : `H_LEN)
|
||||||
`define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
|
`define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE)
|
||||||
`define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
|
`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
|
// Disable spurious Verilator warnings
|
||||||
|
|
||||||
|
|||||||
@ -56,7 +56,8 @@ target_tests_nosim = \
|
|||||||
WALLY-MIMPID \
|
WALLY-MIMPID \
|
||||||
WALLY-MVENDORID \
|
WALLY-MVENDORID \
|
||||||
WALLY-CSR-PERMISSIONS-M \
|
WALLY-CSR-PERMISSIONS-M \
|
||||||
WALLY-CSR-PERMISSIONS-S
|
WALLY-CSR-PERMISSIONS-S \
|
||||||
|
WALLY-trap-01 \
|
||||||
# Have all 0's in references!
|
# Have all 0's in references!
|
||||||
#WALLY-MEPC \
|
#WALLY-MEPC \
|
||||||
#WALLY-SEPC \
|
#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
|
00000001 # Test 5.3.1.4: mcause from an instruction access fault
|
||||||
00000000
|
00000000
|
||||||
00000000 # mtval of faulting instruction address (0x0)
|
00000000 # mtval of faulting instruction address (0x0)
|
||||||
@ -12,49 +102,67 @@
|
|||||||
00000000
|
00000000
|
||||||
00000003 # mcause from Breakpoint
|
00000003 # mcause from Breakpoint
|
||||||
00000000
|
00000000
|
||||||
00000000 # mtval of breakpoint instruction adress (*** Determined from make)
|
800003ec # mtval of breakpoint instruction adress (0x800003ec)
|
||||||
00000000
|
00000000
|
||||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||||
00000000
|
00000000
|
||||||
00000004 # mcause from load address misaligned
|
00000004 # mcause from load address misaligned
|
||||||
00000000
|
00000000
|
||||||
00000000 # mtval of misaligned address (*** Determined from make)
|
800003f5 # mtval of misaligned address (0x800003f5)
|
||||||
00000000
|
00000000
|
||||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||||
00000000
|
00000000
|
||||||
00000005 # mcause from load access
|
00000005 # mcause from load access
|
||||||
00000000
|
00000000
|
||||||
00000000 # mtval of address with access faulting instr (*** Determined from make)
|
00000000 # mtval of accessed adress (0x0)
|
||||||
00000000
|
00000000
|
||||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||||
00000000
|
00000000
|
||||||
00000006 # mcause from store misaligned
|
00000006 # mcause from store misaligned
|
||||||
00000000
|
00000000
|
||||||
00000000 # mtval of address with misaligned store instr (*** Determined from make)
|
80000411 # mtval of address with misaligned store instr (0x80000410)
|
||||||
00000000
|
00000000
|
||||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||||
00000000
|
00000000
|
||||||
00000007 # mcause from store access
|
00000007 # mcause from store access
|
||||||
00000000
|
00000000
|
||||||
00000000 # mtval of address with faulting store instr (*** Determined from make)
|
00000000 # mtval of accessed address (0x0)
|
||||||
00000000
|
00000000
|
||||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||||
00000000
|
00000000
|
||||||
0000000b # mcause from M mode ecall
|
0000000b # mcause from M mode ecall
|
||||||
00000000
|
00000000
|
||||||
00000000 # mtval of
|
00000000 # mtval of ecall (*** defined to be zero for now)
|
||||||
00000000
|
00000000
|
||||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||||
00000000
|
00000000
|
||||||
00000008 # mcause from U mode ecall
|
000007ec # value to indicate a vectored interrupts
|
||||||
00000000
|
00000000
|
||||||
00000000 # mtval of
|
00000007 # mcause value from time interrupt
|
||||||
|
80000000
|
||||||
|
00000000 # mtval for mtime interrupt (0x0)
|
||||||
00000000
|
00000000
|
||||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||||
00000000
|
00000000
|
||||||
00000009 # mcause from S mode ecall
|
000007ec # value to indicate a vectored interrupts
|
||||||
00000000
|
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
|
00000000
|
||||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||||
00000000
|
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
|
|
||||||
deadbeef
|
|
||||||
deadbeef
|
|
||||||
deadbeef
|
|
||||||
|
|||||||
@ -55,6 +55,99 @@ RVTEST_CODE_BEGIN
|
|||||||
|
|
||||||
.endm
|
.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
|
.macro TRAP_HANDLER MODE, VECTORED=1, DEBUG=0
|
||||||
// MODE decides which mode this trap handler will be taken in (M or S mode)
|
// 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)
|
// 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
|
// The previous CSR value before write attempt
|
||||||
// *** Most likely 0x2, the mcause for illegal instruction if we don't have write or read access
|
// *** 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 x30, 0xbad // load bad value to be overwritten by csrr
|
||||||
li x29, \VAL
|
li x29, \VAL\()
|
||||||
csrw \CSR\(), x29
|
csrw \CSR\(), x29
|
||||||
csrr x30, \CSR
|
csrr x30, \CSR
|
||||||
sd x30, 0(x6)
|
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
|
addi x16, x16, 8
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
// The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines
|
// // 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)
|
// // This effectively includes everything that isn't to do with page faults (virtual memory)
|
||||||
|
|
||||||
.macro CAUSE_INSTR_ADDR_MISALIGNED
|
// .macro CAUSE_INSTR_ADDR_MISALIGNED
|
||||||
// cause a misaligned address trap
|
// // cause a misaligned address trap
|
||||||
auipc x28, 0 // get current PC, which is aligned
|
// auipc x28, 0 // get current PC, which is aligned
|
||||||
addi x28, x28, 0x1 // add 1 to pc to create misaligned address
|
// addi x28, x28, 0x1 // add 1 to pc to create misaligned address
|
||||||
jalr x28 // cause instruction address midaligned trap
|
// jalr x28 // cause instruction address midaligned trap
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_INSTR_ACCESS
|
// .macro CAUSE_INSTR_ACCESS
|
||||||
la x28, 0x0 // address zero is an address with no memory
|
// la x28, 0x0 // address zero is an address with no memory
|
||||||
jalr x28 // cause instruction access trap
|
// jalr x28 // cause instruction access trap
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_ILLEGAL_INSTR
|
// .macro CAUSE_ILLEGAL_INSTR
|
||||||
.word 0x00000000 // a 32 bit zros is an illegal instruction
|
// .word 0x00000000 // a 32 bit zros is an illegal instruction
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_BREAKPNT // ****
|
// .macro CAUSE_BREAKPNT // ****
|
||||||
ebreak
|
// ebreak
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_LOAD_ADDR_MISALIGNED
|
// .macro CAUSE_LOAD_ADDR_MISALIGNED
|
||||||
auipc x28, 0 // get current PC, which is aligned
|
// auipc x28, 0 // get current PC, which is aligned
|
||||||
addi x28, x28, 1
|
// addi x28, x28, 1
|
||||||
lw x29, 0(x28) // load from a misaligned address
|
// lw x29, 0(x28) // load from a misaligned address
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_LOAD_ACC
|
// .macro CAUSE_LOAD_ACC
|
||||||
la x28, 0 // 0 is an address with no memory
|
// la x28, 0 // 0 is an address with no memory
|
||||||
lw x29, 0(x28) // load from unimplemented address
|
// lw x29, 0(x28) // load from unimplemented address
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_STORE_ADDR_MISALIGNED
|
// .macro CAUSE_STORE_ADDR_MISALIGNED
|
||||||
auipc x28, 0 // get current PC, which is aligned
|
// auipc x28, 0 // get current PC, which is aligned
|
||||||
addi x28, x28, 1
|
// addi x28, x28, 1
|
||||||
sw x29, 0(x28) // store to a misaligned address
|
// sw x29, 0(x28) // store to a misaligned address
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_STORE_ACC
|
// .macro CAUSE_STORE_ACC
|
||||||
la x28, 0 // 0 is an address with no memory
|
// la x28, 0 // 0 is an address with no memory
|
||||||
sw x29, 0(x28) // store to unimplemented address
|
// sw x29, 0(x28) // store to unimplemented address
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_ECALL
|
// .macro CAUSE_ECALL
|
||||||
// *** ASSUMES you have already gone to the mode you need to call this from.
|
// // *** ASSUMES you have already gone to the mode you need to call this from.
|
||||||
ecall
|
// ecall
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_TIME_INTERRUPT
|
// .macro CAUSE_TIME_INTERRUPT
|
||||||
// The following code works for both RV32 and RV64.
|
// // The following code works for both RV32 and RV64.
|
||||||
// RV64 alone would be easier using double-word adds and stores
|
// // RV64 alone would be easier using double-word adds and stores
|
||||||
li x28, 0x100 // Desired offset from the present time
|
// li x28, 0x100 // Desired offset from the present time
|
||||||
la x29, 0x02004000 // MTIMECMP register in CLINT
|
// la x29, 0x02004000 // MTIMECMP register in CLINT
|
||||||
la x30, 0x0200BFF8 // MTIME register in CLINT
|
// la x30, 0x0200BFF8 // MTIME register in CLINT
|
||||||
lw x7, 0(x30) // low word of MTIME
|
// lw x7, 0(x30) // low word of MTIME
|
||||||
lw x31, 4(x30) // high word of MTIME
|
// lw x31, 4(x30) // high word of MTIME
|
||||||
add x28, x7, x28 // add desired offset to the current time
|
// add x28, x7, x28 // add desired offset to the current time
|
||||||
bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound)
|
// bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound)
|
||||||
addi x31, x31, 1 // if wrap, increment most significant word
|
// addi x31, x31, 1 // if wrap, increment most significant word
|
||||||
sw x31,4(x29) // store into most significant word of MTIMECMP
|
// sw x31,4(x29) // store into most significant word of MTIMECMP
|
||||||
nowrap:
|
// nowrap:
|
||||||
sw x28, 0(x29) // store into least significant word of MTIMECMP
|
// sw x28, 0(x29) // store into least significant word of MTIMECMP
|
||||||
loop: j loop // wait until interrupt occurs
|
// loop: j loop // wait until interrupt occurs
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_SOFT_INTERRUPT
|
// .macro CAUSE_SOFT_INTERRUPT
|
||||||
la x28, 0x02000000 // MSIP register in CLINT
|
// la x28, 0x02000000 // MSIP register in CLINT
|
||||||
li x29, 1 // 1 in the lsb
|
// li x29, 1 // 1 in the lsb
|
||||||
sw x29, 0(x28) // Write MSIP bit
|
// sw x29, 0(x28) // Write MSIP bit
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro CAUSE_EXT_INTERRUPT
|
// .macro CAUSE_EXT_INTERRUPT
|
||||||
li x28, 0x10060000 // load base GPIO memory location
|
// li x28, 0x10060000 // load base GPIO memory location
|
||||||
li x29, 0x1
|
// li x29, 0x1
|
||||||
sw x29, 8(x28) // enable the first pin as an output
|
// sw x29, 8(x28) // enable the first pin as an output
|
||||||
sw x29, 28(x28) // set first pin to high interrupt enable
|
// 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)
|
// sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt)
|
||||||
.endm
|
// .endm
|
||||||
|
|
||||||
.macro END_TESTS
|
.macro END_TESTS
|
||||||
// invokes one final ecall to return to machine mode then terminates this program, so the output is
|
// invokes one final ecall to return to machine mode then terminates this program, so the output is
|
||||||
|
|||||||
@ -25,50 +25,50 @@
|
|||||||
|
|
||||||
INIT_TESTS
|
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
|
TRAP_HANDLER m, DEBUG=1 // turn on recording mtval and status bits on traps
|
||||||
|
|
||||||
li x28, 0x8
|
li x28, 0x8
|
||||||
csrs mstatus, x28 // set mstatus.MIE bit to 1
|
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
|
// test 5.3.1.4 Basic trap tests
|
||||||
|
|
||||||
// CAUSE_INSTR_ADDR_MISALIGNED //skipped becuase this exception may be impossible when compressed instructions are enabled)
|
// jal cause_instr_addr_misaligned //skipped becuase this exception may be impossible when compressed instructions are enabled)
|
||||||
CAUSE_INSTR_ACCESS
|
jal cause_instr_access
|
||||||
CAUSE_ILLEGAL_INSTR
|
jal cause_illegal_instr
|
||||||
CAUSE_BREAKPNT
|
jal cause_breakpnt
|
||||||
CAUSE_LOAD_ADDR_MISALIGNED
|
jal cause_load_addr_misaligned
|
||||||
CAUSE_LOAD_ACC
|
jal cause_load_acc
|
||||||
CAUSE_STORE_ADDR_MISALIGNED
|
jal cause_store_addr_misaligned
|
||||||
CAUSE_STORE_ACC
|
jal cause_store_acc
|
||||||
GOTO_U_MODE // Causes M mode ecall
|
GOTO_U_MODE // Causes M mode ecall
|
||||||
GOTO_S_MODE // Causes U mode ecall
|
GOTO_S_MODE // Causes U mode ecall
|
||||||
GOTO_M_MODE // Causes S 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.
|
jal 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
|
jal cause_soft_interrupt // *** exiting out of the trap handler after these is current;y broken
|
||||||
// CAUSE_EXT_INTERRUPT
|
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
|
// 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 medeleg, 0xFFFFFFFFFFFFFFFF
|
||||||
WRITE_READ_CSR mideleg, 0xFFFFFFFFFFFFFFFF
|
WRITE_READ_CSR mideleg, 0xFFFFFFFFFFFFFFFF
|
||||||
|
|
||||||
// CAUSE_INSTR_ADDR_MISALIGNED //skipped becuase this exception may be impossible when compressed instructions are enabled)
|
// jal cause_instr_addr_misaligned //skipped becuase this exception may be impossible when compressed instructions are enabled)
|
||||||
CAUSE_INSTR_ACCESS
|
jal cause_instr_access
|
||||||
CAUSE_ILLEGAL_INSTR
|
jal cause_illegal_instr
|
||||||
CAUSE_BREAKPNT
|
jal cause_breakpnt
|
||||||
CAUSE_LOAD_ADDR_MISALIGNED
|
jal cause_load_addr_misaligned
|
||||||
CAUSE_LOAD_ACC
|
jal cause_load_acc
|
||||||
CAUSE_STORE_ADDR_MISALIGNED
|
jal cause_store_addr_misaligned
|
||||||
CAUSE_STORE_ACC
|
jal cause_store_acc
|
||||||
CAUSE_ECALL // M mode ecall
|
jal 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
|
|
||||||
|
|
||||||
// CAUSE_TIME_INTERRUPT *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen.
|
jal 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
|
jal cause_soft_interrupt // *** exiting out of the trap handler after these is current;y broken
|
||||||
// CAUSE_EXT_INTERRUPT
|
jal cause_ext_interrupt
|
||||||
|
|
||||||
END_TESTS
|
END_TESTS
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user