Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

This commit is contained in:
Ross Thompson 2022-03-30 11:09:44 -05:00
commit e4f4e1bd43
36 changed files with 860 additions and 568 deletions

@ -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

View File

@ -8,6 +8,7 @@ BR2_HOST_GCC_AT_LEAST_5=y
BR2_HOST_GCC_AT_LEAST_6=y
BR2_HOST_GCC_AT_LEAST_7=y
BR2_HOST_GCC_AT_LEAST_8=y
BR2_HOST_GCC_AT_LEAST_9=y
#
# Target options
@ -87,7 +88,7 @@ BR2_BZCAT="bzcat"
BR2_XZCAT="xzcat"
BR2_LZCAT="lzip -d -c"
BR2_TAR_OPTIONS=""
BR2_DEFCONFIG="./configs/wally-qemu_riscv64_virt_defconfig"
BR2_DEFCONFIG="./board/wally/main.config"
BR2_DL_DIR="$(TOPDIR)/dl"
BR2_HOST_DIR="$(BASE_DIR)/host"
@ -406,11 +407,10 @@ BR2_GENERATE_LOCALE=""
# BR2_SYSTEM_ENABLE_NLS is not set
# BR2_TARGET_TZ_INFO is not set
BR2_ROOTFS_USERS_TABLES=""
BR2_ROOTFS_OVERLAY=""
BR2_ROOTFS_OVERLAY="./board/wally/rootfs_overlay"
BR2_ROOTFS_POST_BUILD_SCRIPT=""
BR2_ROOTFS_POST_FAKEROOT_SCRIPT=""
BR2_ROOTFS_POST_IMAGE_SCRIPT="board/qemu/post-image.sh"
BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_DEFCONFIG)"
BR2_ROOTFS_POST_IMAGE_SCRIPT=""
#
# Kernel
@ -430,7 +430,7 @@ BR2_LINUX_KERNEL_PATCH=""
# BR2_LINUX_KERNEL_USE_DEFCONFIG is not set
# BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG is not set
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="./linux.config"
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="./board/wally/linux.config"
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES=""
BR2_LINUX_KERNEL_CUSTOM_LOGO_PATH=""
BR2_LINUX_KERNEL_IMAGE=y
@ -473,7 +473,7 @@ BR2_LINUX_KERNEL_GZIP=y
# Target packages
#
BR2_PACKAGE_BUSYBOX=y
BR2_PACKAGE_BUSYBOX_CONFIG="./busybox.config"
BR2_PACKAGE_BUSYBOX_CONFIG="./board/wally/busybox.config"
BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES=""
# BR2_PACKAGE_BUSYBOX_SHOW_OTHERS is not set
# BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES is not set

View 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

View 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

View File

@ -15,7 +15,7 @@
memory@80000000 {
device_type = "memory";
reg = <0x00 0x80000000 0x00 0x8000000>;
reg = <0x00 0x80000000 0x00 0x08000000>;
};
cpus {

View File

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

View File

@ -101,13 +101,15 @@ then
set logging on
# Priority Levels for sources 1 thru 63
x/63xw 0x0C000004
# Interrupt Enables
# Interrupt Enables for sources 1 thru 63 for contexts 0 and 1
x/2xw 0x0C020000
# Global Priority Threshold
x/2xw 0x0C020080
# Global Priority Threshold for contexts 0 and 1
x/1xw 0x0C200000
x/1xw 0x0C201000
set logging off
shell echo \"GDB storing RAM to $rawRamFile\"
dump binary memory $rawRamFile 0x80000000 0xffffffff
dump binary memory $rawRamFile 0x80000000 0x87ffffff
kill
q
end_of_script

View File

@ -138,9 +138,9 @@ if len(sys.argv) != 2:
sys.exit('Error parseGDBtoTrace.py expects 1 arg:\n <interrupt filename>>')
interruptFname = sys.argv[1]
# reg number
RegNumber = {'zero': 0, 'ra': 1, 'sp': 2, 'gp': 3, 'tp': 4, 't0': 5, 't1': 6, 't2': 7, 's0': 8, 's1': 9, 'a0': 10, 'a1': 11, 'a2': 12, 'a3': 13, 'a4': 14, 'a5': 15, 'a6': 16, 'a7': 17, 's2': 18, 's3': 19, 's4': 20, 's5': 21, 's6': 22, 's7': 23, 's8': 24, 's9': 25, 's10': 26, 's11': 27, 't3': 28, 't4': 29, 't5': 30, 't6': 31, 'mhartid': 32, 'mstatus': 33, 'mip': 34, 'mie': 35, 'mideleg': 36, 'medeleg': 37, 'mtvec': 38, 'stvec': 39, 'mepc': 40, 'sepc': 41, 'mcause': 42, 'scause': 43, 'mtval': 44, 'stval': 45, 'sstatus': 46, 'sip': 47, 'sie': 48}
RegNumber = {'zero': 0, 'ra': 1, 'sp': 2, 'gp': 3, 'tp': 4, 't0': 5, 't1': 6, 't2': 7, 's0': 8, 's1': 9, 'a0': 10, 'a1': 11, 'a2': 12, 'a3': 13, 'a4': 14, 'a5': 15, 'a6': 16, 'a7': 17, 's2': 18, 's3': 19, 's4': 20, 's5': 21, 's6': 22, 's7': 23, 's8': 24, 's9': 25, 's10': 26, 's11': 27, 't3': 28, 't4': 29, 't5': 30, 't6': 31, 'mhartid': 32, 'mstatus': 33, 'mip': 34, 'mie': 35, 'mideleg': 36, 'medeleg': 37, 'mtvec': 38, 'stvec': 39, 'mepc': 40, 'sepc': 41, 'mcause': 42, 'scause': 43, 'mtval': 44, 'stval': 45, 'mscratch': 46, 'sscratch': 47, 'satp': 48}
# initial state
CurrentInstr = ['0', '0', None, 'other', {'zero': 0, 'ra': 0, 'sp': 0, 'gp': 0, 'tp': 0, 't0': 0, 't1': 0, 't2': 0, 's0': 0, 's1': 0, 'a0': 0, 'a1': 0, 'a2': 0, 'a3': 0, 'a4': 0, 'a5': 0, 'a6': 0, 'a7': 0, 's2': 0, 's3': 0, 's4': 0, 's5': 0, 's6': 0, 's7': 0, 's8': 0, 's9': 0, 's10': 0, 's11': 0, 't3': 0, 't4': 0, 't5': 0, 't6': 0, 'mhartid': 0, 'mstatus': 0, 'mip': 0, 'mie': 0, 'mideleg': 0, 'medeleg': 0, 'mtvec': 0, 'stvec': 0, 'mepc': 0, 'sepc': 0, 'mcause': 0, 'scause': 0, 'mtval': 0, 'stval': 0, 'sstatus': 0, 'sip': 0, 'sie': 0}, {}, None, None, None]
CurrentInstr = ['0', '0', None, 'other', {'zero': 0, 'ra': 0, 'sp': 0, 'gp': 0, 'tp': 0, 't0': 0, 't1': 0, 't2': 0, 's0': 0, 's1': 0, 'a0': 0, 'a1': 0, 'a2': 0, 'a3': 0, 'a4': 0, 'a5': 0, 'a6': 0, 'a7': 0, 's2': 0, 's3': 0, 's4': 0, 's5': 0, 's6': 0, 's7': 0, 's8': 0, 's9': 0, 's10': 0, 's11': 0, 't3': 0, 't4': 0, 't5': 0, 't6': 0, 'mhartid': 0, 'mstatus': 0, 'mip': 0, 'mie': 0, 'mideleg': 0, 'medeleg': 0, 'mtvec': 0, 'stvec': 0, 'mepc': 0, 'sepc': 0, 'mcause': 0, 'scause': 0, 'mtval': 0, 'stval': 0, 'mscratch': 0, 'sscratch': 0, 'satp': 0}, {}, None, None, None]
#with open (InputFile, 'r') as InputFileFP:
#lines = InputFileFP.readlines()

View File

@ -1,5 +1,6 @@
#! /usr/bin/python3
import sys, os
from functools import reduce
################
# Helper Funcs #
@ -21,6 +22,9 @@ def tokenize(string):
token = token + char
return tokens
def strip0x(num):
return num[2:]
def stripZeroes(num):
num = num.strip('0')
if num=='':
@ -42,7 +46,7 @@ if not os.path.exists(rawPlicStateFile):
sys.exit('Error input file '+rawPlicStateFile+'not found')
with open(rawPlicStateFile, 'r') as rawPlicStateFile:
plicIntPriorityArray=[]
plicIntPriorityArray = [] # iterates over number of different sources
# 0x0C000004 thru 0x0C000010
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C000014 thru 0x0C000020
@ -76,20 +80,30 @@ with open(rawPlicStateFile, 'r') as rawPlicStateFile:
# 0x0C0000f4 thru 0x0C0000fc
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
plicIntEnableArray = [] # iterates over number of different contexts
# 0x0C020000 thru 0x0C020004
plicIntEnable = tokenize(rawPlicStateFile.readline())[1:]
plicIntEnable = map(strip0x,plicIntEnable)
plicIntEnableArray.append(reduce(lambda x,y: x+y,plicIntEnable))
# 0x0C020080 thru 0x0C020084
plicIntEnable = tokenize(rawPlicStateFile.readline())[1:]
plicIntEnable = map(strip0x,plicIntEnable)
plicIntEnableArray.append(reduce(lambda x,y: x+y,plicIntEnable))
plicIntPriorityThresholdArray = [] # iterates over number of different contexts
# 0x0C200000
plicIntPriorityThreshold = tokenize(rawPlicStateFile.readline())[1:]
plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:]
# 0x0C201000
plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:]
with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile:
for word in plicIntPriorityArray:
outFile.write(stripZeroes(word[2:])+'\n')
with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile:
for word in plicIntEnable:
outFile.write(stripZeroes(word[2:]))
for word in plicIntEnableArray:
outFile.write(stripZeroes(word)+'\n')
with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile:
for word in plicIntPriorityThreshold:
for word in plicIntPriorityThresholdArray:
outFile.write(stripZeroes(word[2:])+'\n')
print("Finished parsing PLIC state!")

View File

@ -4,7 +4,7 @@ import sys, os, subprocess
def main():
maxGoodCount = 400e6 # num instrs that execute sucessfully starting from 0
currInstrCount = maxGoodCount
linuxTestvectors = "../../tests/linux-testgen/linux-testvectors"
linuxTestvectors = "/opt/riscv/linux-testvectors"
if not os.path.exists(linuxTestvectors):
sys.stderr.write("Error: Linux testvectors not found at "+linuxTestvectors+"\n")
exit(1)
@ -22,7 +22,7 @@ def main():
break
checkpoint = checkpointList[0]
logFile = logDir+"checkpoint"+str(checkpoint)+".log"
runCommand="{\nvsim -c <<!\ndo wally-pipelined-batch.do buildroot buildroot 0 "+str(checkpoint+1)+" "+str(checkpoint)+"\n!\n} | tee "+logFile
runCommand="{\nvsim -c <<!\ndo wally-pipelined-batch.do buildroot buildroot /opt/riscv 0 "+str(checkpoint+1)+" "+str(checkpoint)+"\n!\n} | tee "+logFile
print(runCommand)
os.system(runCommand)
try:

View File

@ -4,6 +4,7 @@ add wave -noupdate /testbench/clk
add wave -noupdate /testbench/reset
add wave -noupdate /testbench/reset_ext
add wave -noupdate -radix unsigned /testbench/InstrCountW
add wave -noupdate -radix unsigned /testbench/AttemptedInstructionCount
add wave -noupdate /testbench/dut/core/SATP_REGW
add wave -noupdate /testbench/dut/core/IllegalFPUInstrD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/BPPredWrongE
@ -388,7 +389,6 @@ add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/cor
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PTE
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissOrDAFaultF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBMissM
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBWriteF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBWriteM
add wave -noupdate -group AHB -color Gold /testbench/dut/core/ebu/BusState
@ -526,9 +526,7 @@ add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/TakeSpillF
add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/SpillF
add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/IFUCacheBusStallF
add wave -noupdate -color Yellow /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DAPageFault
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/OtherPageFault
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissF
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/Accessed
add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/WriteAccess
add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/TLBPageFault
TreeUpdate [SetDefaultTree]

View File

@ -70,7 +70,7 @@ for test in tests64gc:
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64gc "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests32gc = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32m", "wally32a", "imperas32c", "wally32priv"] #, "imperas32mmu""wally32i",
tests32gc = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32m", "wally32a", "imperas32c"] #, "imperas32mmu""wally32i",
for test in tests32gc:
tc = TestCase(
name=test,
@ -79,6 +79,25 @@ for test in tests32gc:
grepstr="All tests ran without failures")
configs.append(tc)
tests64ia = ["wally64priv"]
for test in tests64ia:
tc = TestCase(
name=test,
variant="rv64ia",
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64ia "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests32ia = ["wally32priv"]
for test in tests32ia:
tc = TestCase(
name=test,
variant="rv32ia",
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv32ia "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c"]
for test in tests32ic:
tc = TestCase(

View File

@ -23,40 +23,32 @@ module fcmp (
output logic [`FLEN-1:0] CmpResE // compare resilt
);
logic LT, EQ; // is X < or > or = Y
// X is less than Y:
// Signs:
// X Y answer
// pos pos idk - keep checking
// pos neg no
// neg pos yes
// neg neg idk - keep checking
// Exponent
// - if XExp < YExp
// - if negitive - no
// - if positive - yes
// - otherwise keep checking
// Mantissa
// - XMan < YMan then
// - if negitive - no
// - if positive - yes
// note: LT does -0 < 0
//*** compare Exp and Man together
assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
logic LTabs, LT, EQ; // is X < or > or = Y
logic BothZeroE, EitherNaNE, EitherSNaNE;
assign LTabs= {1'b0, XExpE, XManE} < {1'b0, YExpE, YManE}; // unsigned comparison, treating FP as integers
assign LT = (XSgnE & ~YSgnE) | (XSgnE & YSgnE & ~LTabs & ~EQ) | (~XSgnE & ~YSgnE & LTabs);
//assign LT = $signed({XSgnE, XExpE, XManE[`NF-1:0]}) < $signed({YSgnE, YExpE, YManE[`NF-1:0]});
//assign LT = XInt < YInt;
// assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
assign EQ = (FSrcXE == FSrcYE);
assign BothZeroE = XZeroE&YZeroE;
assign EitherNaNE = XNaNE|YNaNE;
assign EitherSNaNE = XSNaNE|YSNaNE;
// flags
// Min/Max - if an input is a signaling NaN set invalid flag
// LT/LE - signaling - sets invalid if NaN input
// EQ - quiet - sets invalid if signaling NaN input
always_comb begin
case (FOpCtrlE[2:0])
3'b111: CmpNVE = XSNaNE|YSNaNE;//min
3'b101: CmpNVE = XSNaNE|YSNaNE;//max
3'b010: CmpNVE = XSNaNE|YSNaNE;//equal
3'b001: CmpNVE = XNaNE|YNaNE;//less than
3'b011: CmpNVE = XNaNE|YNaNE;//less than or equal
3'b111: CmpNVE = EitherSNaNE;//min
3'b101: CmpNVE = EitherSNaNE;//max
3'b010: CmpNVE = EitherSNaNE;//equal
3'b001: CmpNVE = EitherNaNE;//less than
3'b011: CmpNVE = EitherNaNE;//less than or equal
default: CmpNVE = 1'b0;
endcase
end
@ -71,24 +63,22 @@ module fcmp (
// - inf = inf and -inf = -inf
// - return 0 if comparison with NaN (unordered)
logic [`FLEN-1:0] QNaNX, QNaNY;
if(`IEEE754) begin
assign QNaNX = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]};
assign QNaNY = FmtE ? {YSgnE, YExpE, 1'b1, YManE[`NF-2:0]} : {{32{1'b1}}, YSgnE, YExpE[7:0], 1'b1, YManE[50:29]};
end else begin
assign QNaNX = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0};
assign QNaNY = FmtE ? {1'b0, YExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpE[7:0], 1'b1, 22'b0};
end
logic [`FLEN-1:0] QNaN;
// fmin/fmax of two NaNs returns a quiet NaN of the appropriate size
// for IEEE, return the payload of X
// for RISC-V, return the canonical NaN
if(`IEEE754) assign QNaN = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]};
else assign QNaN = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0};
always_comb begin
case (FOpCtrlE[2:0])
3'b111: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Min
3'b111: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Min
: YNaNE ? FSrcXE : LT ? FSrcXE : FSrcYE;
3'b101: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Max
3'b101: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Max
: YNaNE ? FSrcXE : LT ? FSrcYE : FSrcXE;
3'b010: CmpResE = {63'b0, (EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Equal
3'b001: CmpResE = {63'b0, LT&~(XZeroE&YZeroE)&~(XNaNE|YNaNE)}; // Less than
3'b011: CmpResE = {63'b0, (LT|EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Less than or equal
3'b010: CmpResE = {63'b0, (EQ|BothZeroE) & ~EitherNaNE}; // Equal
3'b001: CmpResE = {63'b0, LT & ~BothZeroE & ~EitherNaNE}; // Less than
3'b011: CmpResE = {63'b0, (LT|EQ|BothZeroE) & ~EitherNaNE}; // Less than or equal
default: CmpResE = 64'b0;
endcase
end

View File

@ -102,6 +102,7 @@ module BTBPredictor
// Another optimization may be using a PC relative address.
// *** need to add forwarding.
// *** optimize for byte write enables
SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk),
.reset(reset),
.RA1(LookUpPCIndex),

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////
// ram.sv
// swbytemask.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Modified:

View File

@ -43,13 +43,13 @@ module csr #(parameter
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM, SrcAM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM,
input logic TimerIntM, ExtIntM, SwIntM,
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
input logic [63:0] MTIME_CLINT,
input logic InstrValidM, FRegWriteM, LoadStallD,
input logic BPPredDirWrongM,
input logic BTBPredPCWrongM,
input logic RASPredPCWrongM,
input logic BPPredClassNonCFIWrongM,
input logic BPPredDirWrongM,
input logic BTBPredPCWrongM,
input logic RASPredPCWrongM,
input logic BPPredClassNonCFIWrongM,
input logic [4:0] InstrClassM,
input logic DCacheMiss,
input logic DCacheAccess,
@ -123,7 +123,7 @@ module csr #(parameter
assign CSRUWriteM = CSRWriteM;
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM,
.CSRAdrM, .ExtIntM, .TimerIntM, .SwIntM,
.CSRAdrM, .ExtIntM, .ExtIntS, .TimerIntM, .SwIntM,
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM);
csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteSSTATUSM,
@ -167,7 +167,7 @@ module csr #(parameter
// merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient
assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != `M_MODE) |
(CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE);
(CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE);
assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM &
IllegalCSRSAccessM & IllegalCSRUAccessM |
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;

View File

@ -41,7 +41,7 @@ module csri #(parameter
input logic InstrValidNotFlushedM, StallW,
input logic CSRMWriteM, CSRSWriteM,
input logic [11:0] CSRAdrM,
input logic ExtIntM, TimerIntM, SwIntM,
input logic ExtIntM, ExtIntS, TimerIntM, SwIntM,
input logic [`XLEN-1:0] MIDELEG_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
input logic [`XLEN-1:0] CSRWriteValM
@ -57,12 +57,12 @@ module csri #(parameter
always_comb begin
IntInM = 0;
IntInM[11] = ExtIntM;; // MEIP
IntInM[9] = ExtIntM & MIDELEG_REGW[9]; // SEIP
IntInM[7] = TimerIntM; // MTIP
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
IntInM[3] = SwIntM; // MSIP
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
IntInM[11] = ExtIntM; // MEIP
IntInM[9] = (ExtIntM & MIDELEG_REGW[9]); // SEIP
IntInM[7] = TimerIntM; // MTIP
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
IntInM[3] = SwIntM; // MSIP
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
end
// Interrupt Write Enables
@ -82,22 +82,20 @@ module csri #(parameter
assign MIP_WRITE_MASK = 12'h000;
assign SIP_WRITE_MASK = 12'h000;
end
always @(posedge clk) //, posedge reset) begin // *** I strongly feel that IntInM should go directly to IP_REGW -- Ben 9/7/21
always @(posedge clk)
if (reset) IP_REGW_writeable <= 10'b0;
else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable
else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable
// else if (WriteUIPM) IP_REGW = (CSRWriteValM & 12'hBBB) | (NextIPM & 12'h080); // MTIP unclearable
else IP_REGW_writeable <= IP_REGW_writeable | IntInM[9:0]; // *** check this turns off interrupts properly even when MIDELEG changes
always @(posedge clk) //, posedge reset) begin
else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable
else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable
else IP_REGW_writeable <= IP_REGW_writeable | {1'b0, IntInM[8:0]}; // *** check this turns off interrupts properly even when MIDELEG changes
always @(posedge clk)
if (reset) IE_REGW <= 12'b0;
else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields
else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields
// else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field
// restricted views of registers
// Add MEIP read-only signal
assign IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable};
// Add ExtIntM read-only signal
assign IP_REGW = {ExtIntM,1'b0,ExtIntS,1'b0, IntInM[7], 7'b0} | {2'b0, IP_REGW_writeable[9], 3'b0, IP_REGW_writeable[5], 3'b0, IP_REGW_writeable[1], 1'b0}; // *** This is just to force the Machine level bits of IP to be unwriteable and to only come from intInM. PLEASE CHANGE ME!!!
// Machine Mode
assign MIP_REGW = IP_REGW;
assign MIE_REGW = IE_REGW;

View File

@ -55,7 +55,7 @@ module privileged (
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD,
input logic LoadMisalignedFaultM,
input logic StoreAmoMisalignedFaultM,
input logic TimerIntM, ExtIntM, SwIntM,
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
input logic [63:0] MTIME_CLINT,
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
input logic [4:0] SetFflagsM,
@ -150,7 +150,7 @@ module privileged (
.StallE, .StallM, .StallW,
.InstrM, .PCM, .SrcAM,
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
.TimerIntM, .ExtIntM, .SwIntM,
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
.MTIME_CLINT,
.InstrValidM, .FRegWriteM, .LoadStallD,
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,

View File

@ -102,7 +102,7 @@ module trap (
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
always_comb
if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1)
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + {CauseM[`XLEN-5:0], 2'b00}, 2'b00};
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + CauseM[`XLEN-3:0], 2'b00};
else
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
end

View File

@ -37,6 +37,15 @@
`include "wally-config.vh"
`define N `PLIC_NUM_SRC
// number of interrupt sources
// does not include source 0, which does not connect to anything according to spec
// up to 63 sources supported; *** in the future, allow up to 1023 sources
`define C 2
// number of conexts
// hardcoded to 2 contexts for now; *** later upgrade to arbitrary (up to 15872) contexts
module plic (
input logic HCLK, HRESETn,
input logic HSELPLIC,
@ -48,25 +57,26 @@ module plic (
input logic UARTIntr,GPIOIntr,
output logic [`XLEN-1:0] HREADPLIC,
output logic HRESPPLIC, HREADYPLIC,
output logic ExtIntM);
localparam N=`PLIC_NUM_SRC; // should not exceed 63; does not inlcude source 0, which does not connect to anything according to spec
output logic ExtIntM, ExtIntS);
logic memwrite, memread, initTrans;
logic [23:0] entry, entryd;
logic [31:0] Din, Dout;
logic [N:1] requests;
logic [2:0] intPriority[N:1];
logic [2:0] intThreshold;
logic [N:1] intPending, nextIntPending, intEn, intInProgress;
logic [5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
logic [N:1] pendingArray[7:1];
logic [7:1] pendingPGrouped;
logic [7:1] pendingMaxP;
logic [N:1] pendingRequestsAtMaxP;
logic [7:1] threshMask;
// context-independent signals
logic [`N:1] requests;
logic [`N:1][2:0] intPriority;
logic [`N:1] intInProgress, intPending, nextIntPending;
// context-dependent signals
logic [`C-1:0][2:0] intThreshold;
logic [`C-1:0][`N:1] intEn;
logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
logic [`C-1:0][7:1][`N:1] irqMatrix;
logic [`C-1:0][7:1] priorities_with_irqs;
logic [`C-1:0][7:1] max_priority_with_irqs;
logic [`C-1:0][`N:1] irqs_at_max_priority;
logic [`C-1:0][7:1] threshMask;
// =======
// AHB I/O
@ -82,12 +92,12 @@ module plic (
// account for subword read/write circuitry
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
if (`XLEN == 64) begin
if (`XLEN == 64) begin
assign Din = entryd[2] ? HWDATA[63:32] : HWDATA[31:0];
assign HREADPLIC = entryd[2] ? {Dout,32'b0} : {32'b0,Dout};
end else begin // 32-bit
assign Din = HWDATA[31:0];
assign HREADPLIC = Dout;
assign Din = HWDATA[31:0];
end
// ==================
@ -96,43 +106,56 @@ module plic (
always @(posedge HCLK,negedge HRESETn) begin
// resetting
if (~HRESETn) begin
intPriority <= #1 '{default:3'b0};
intEn <= #1 {N{1'b0}};
intThreshold <= #1 3'b0;
intInProgress <= #1 {N{1'b0}};
intPriority <= #1 {`N{3'b0}};
intEn <= #1 {2{`N'b0}};
intThreshold <= #1 {2{3'b0}};
intInProgress <= #1 `N'b0;
// writing
end else begin
if (memwrite)
casez(entryd)
24'h0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
`ifdef PLIC_NUM_SRC_LT_32
24'h002000: intEn[N:1] <= #1 Din[N:1];
`ifdef PLIC_NUM_SRC_LT_32 // *** switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources
24'h002000: intEn[0][`N:1] <= #1 Din[`N:1];
24'h002080: intEn[1][`N:1] <= #1 Din[`N:1];
`endif
`ifndef PLIC_NUM_SRC_LT_32
24'h002000: intEn[31:1] <= #1 Din[31:1];
24'h002004: intEn[N:32] <= #1 Din[31:0];
24'h002000: intEn[0][31:1] <= #1 Din[31:1];
24'h002004: intEn[0][`N:32] <= #1 Din[31:0];
24'h002080: intEn[1][31:1] <= #1 Din[31:1];
24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
`endif
24'h200000: intThreshold[2:0] <= #1 Din[2:0];
24'h200004: intInProgress <= #1 intInProgress & ~(`PLIC_NUM_SRC'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
24'h200000: intThreshold[0] <= #1 Din[2:0];
24'h200004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
24'h201000: intThreshold[1] <= #1 Din[2:0];
24'h201004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
endcase
// reading
if (memread)
casez(entry)
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
`ifdef PLIC_NUM_SRC_LT_32
24'h001000: Dout <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
24'h002000: Dout <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0};
24'h001000: Dout <= #1 {{(31-`N){1'b0}},intPending,1'b0};
24'h002000: Dout <= #1 {{(31-`N){1'b0}},intEn[0],1'b0};
24'h002080: Dout <= #1 {{(31-`N){1'b0}},intEn[1],1'b0};
`endif
`ifndef PLIC_NUM_SRC_LT_32
24'h001000: Dout <= #1 {intPending[31:1],1'b0};
24'h001004: Dout <= #1 {{(63-N){1'b0}},intPending[N:32]};
24'h002000: Dout <= #1 {intEn[31:1],1'b0};
24'h002004: Dout <= #1 {{(63-N){1'b0}},intEn[N:32]};
24'h001004: Dout <= #1 {{(63-`N){1'b0}},intPending[`N:32]};
24'h002000: Dout <= #1 {intEn[0][31:1],1'b0};
24'h002004: Dout <= #1 {{(63-`N){1'b0}},intEn[0][`N:32]};
24'h002080: Dout <= #1 {intEn[0][31:1],1'b0};
24'h002084: Dout <= #1 {{(63-`N){1'b0}},intEn[1][`N:32]};
`endif
24'h200000: Dout <= #1 {29'b0,intThreshold[2:0]};
24'h200000: Dout <= #1 {29'b0,intThreshold[0]};
24'h200004: begin
Dout <= #1 {26'b0,intClaim};
intInProgress <= #1 intInProgress | (`PLIC_NUM_SRC'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
Dout <= #1 {26'b0,intClaim[0]};
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed
end
24'h201000: Dout <= #1 {29'b0,intThreshold[1]};
24'h201004: begin
Dout <= #1 {26'b0,intClaim[1]};
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed
end
default: Dout <= #1 32'h0; // invalid access
endcase
@ -143,7 +166,7 @@ module plic (
// connect sources to requests
always_comb begin
requests = {N{1'b0}};
requests = `N'b0;
`ifdef PLIC_GPIO_ID
requests[`PLIC_GPIO_ID] = GPIOIntr;
`endif
@ -152,66 +175,88 @@ module plic (
`endif
end
// pending updates
// *** verify that this matches the expectations of the things that make requests (in terms of timing, edge-triggered vs level-triggered)
assign nextIntPending = (intPending | (requests & ~intInProgress)) & // requests should raise intPending except when their service routine is already in progress
~({N{((entry == 24'h200004) & memread)}} << (intClaim-1)); // clear pending bit when claim register is read
flopr #(N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
// pending interrupt requests
assign nextIntPending =
(intPending | // existing pending requests
(requests & ~intInProgress)) & // assert new requests (if they aren't already being serviced)
~({`N{((entry == 24'h200004) & memread)}} << (intClaim[0]-1)) & // deassert requests that just completed
~({`N{((entry == 24'h201004) & memread)}} << (intClaim[1]-1));
flopr #(`N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
// pending array - indexed by priority_lvl x source_ID
genvar i, j;
for (j=1; j<=7; j++) begin: pending
for (i=1; i<=N; i=i+1) begin: pendingbit
assign pendingArray[j][i] = (intPriority[i]==j) & intEn[i] & intPending[i];
// context-dependent signals
genvar ctx;
for (ctx=0; ctx<`C; ctx++) begin
// request matrix
// priority level (rows) X source ID (columns)
//
// irqMatrix[ctx][pri][src] is high if source <src>
// has priority level <pri> and has an "active" interrupt request
// ("active" meaning it is enabled in context <ctx> and is pending)
genvar src, pri;
for (pri=1; pri<=7; pri++) begin
for (src=1; src<=`N; src++) begin
assign irqMatrix[ctx][pri][src] = (intPriority[src]==pri) & intPending[src] & intEn[ctx][src];
end
end
end
// pending array, except grouped by priority
assign pendingPGrouped[7:1] = {|pendingArray[7],
|pendingArray[6],
|pendingArray[5],
|pendingArray[4],
|pendingArray[3],
|pendingArray[2],
|pendingArray[1]};
//assign pendingPGrouped = pendingArray.or;
// pendingPGrouped, except only topmost priority is active
assign pendingMaxP[7:1] = {pendingPGrouped[7],
pendingPGrouped[6] & ~|pendingPGrouped[7],
pendingPGrouped[5] & ~|pendingPGrouped[7:6],
pendingPGrouped[4] & ~|pendingPGrouped[7:5],
pendingPGrouped[3] & ~|pendingPGrouped[7:4],
pendingPGrouped[2] & ~|pendingPGrouped[7:3],
pendingPGrouped[1] & ~|pendingPGrouped[7:2]};
// select the pending requests at that priority
assign pendingRequestsAtMaxP[N:1] = ({N{pendingMaxP[7]}} & pendingArray[7])
| ({N{pendingMaxP[6]}} & pendingArray[6])
| ({N{pendingMaxP[5]}} & pendingArray[5])
| ({N{pendingMaxP[4]}} & pendingArray[4])
| ({N{pendingMaxP[3]}} & pendingArray[3])
| ({N{pendingMaxP[2]}} & pendingArray[2])
| ({N{pendingMaxP[1]}} & pendingArray[1]);
// find the lowest ID amongst active interrupts at the highest priority
logic [5:0] k;
always_comb begin
intClaim = 6'b0;
for (k=N; k>0; k=k-1) begin
if (pendingRequestsAtMaxP[k]) intClaim = k;
// which prority levels have one or more active requests?
assign priorities_with_irqs[ctx][7:1] = {
|irqMatrix[ctx][7],
|irqMatrix[ctx][6],
|irqMatrix[ctx][5],
|irqMatrix[ctx][4],
|irqMatrix[ctx][3],
|irqMatrix[ctx][2],
|irqMatrix[ctx][1]
};
// get the highest priority level that has active requests
assign max_priority_with_irqs[ctx][7:1] = {
priorities_with_irqs[ctx][7],
priorities_with_irqs[ctx][6] & ~|priorities_with_irqs[ctx][7],
priorities_with_irqs[ctx][5] & ~|priorities_with_irqs[ctx][7:6],
priorities_with_irqs[ctx][4] & ~|priorities_with_irqs[ctx][7:5],
priorities_with_irqs[ctx][3] & ~|priorities_with_irqs[ctx][7:4],
priorities_with_irqs[ctx][2] & ~|priorities_with_irqs[ctx][7:3],
priorities_with_irqs[ctx][1] & ~|priorities_with_irqs[ctx][7:2]
};
// of the sources at the highest priority level that has active requests,
// which sources have active requests?
assign irqs_at_max_priority[ctx][`N:1] =
({`N{max_priority_with_irqs[ctx][7]}} & irqMatrix[ctx][7]) |
({`N{max_priority_with_irqs[ctx][6]}} & irqMatrix[ctx][6]) |
({`N{max_priority_with_irqs[ctx][5]}} & irqMatrix[ctx][5]) |
({`N{max_priority_with_irqs[ctx][4]}} & irqMatrix[ctx][4]) |
({`N{max_priority_with_irqs[ctx][3]}} & irqMatrix[ctx][3]) |
({`N{max_priority_with_irqs[ctx][2]}} & irqMatrix[ctx][2]) |
({`N{max_priority_with_irqs[ctx][1]}} & irqMatrix[ctx][1]);
// of the sources at the highest priority level that has active requests,
// choose the source with the lowest source ID to be the most urgent
// and set intClaim to the source ID of the most urgent active request
integer k;
always_comb begin
intClaim[ctx] = 6'b0;
for (k=`N; k>0; k--) begin
if (irqs_at_max_priority[ctx][k]) intClaim[ctx] = k[5:0];
end
end
end
// create threshold mask
always_comb begin
threshMask[7] = (intThreshold != 7);
threshMask[6] = (intThreshold != 6) & threshMask[7];
threshMask[5] = (intThreshold != 5) & threshMask[6];
threshMask[4] = (intThreshold != 4) & threshMask[5];
threshMask[3] = (intThreshold != 3) & threshMask[4];
threshMask[2] = (intThreshold != 2) & threshMask[3];
threshMask[1] = (intThreshold != 1) & threshMask[2];
end
// is the max priority > threshold?
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
assign ExtIntM = |(threshMask & pendingPGrouped);
// create threshold mask
always_comb begin
threshMask[ctx][7] = (intThreshold[ctx] != 7);
threshMask[ctx][6] = (intThreshold[ctx] != 6) & threshMask[ctx][7];
threshMask[ctx][5] = (intThreshold[ctx] != 5) & threshMask[ctx][6];
threshMask[ctx][4] = (intThreshold[ctx] != 4) & threshMask[ctx][5];
threshMask[ctx][3] = (intThreshold[ctx] != 3) & threshMask[ctx][4];
threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3];
threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2];
end
// is the max priority > threshold?
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
end
assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]);
assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]);
endmodule

View File

@ -55,7 +55,7 @@ module uncore (
input logic [3:0] HSIZED,
input logic HWRITED,
// peripheral pins
output logic TimerIntM, SwIntM, ExtIntM,
output logic TimerIntM, SwIntM, ExtIntM, ExtIntS,
input logic [31:0] GPIOPinsIn,
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
input logic UARTSin,
@ -133,9 +133,10 @@ module uncore (
.HWRITE, .HREADY, .HTRANS, .HWDATA,
.UARTIntr, .GPIOIntr,
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
.ExtIntM);
.ExtIntM, .ExtIntS);
end else begin : plic
assign ExtIntM = 0;
assign ExtIntS = 0;
end
if (`GPIO_SUPPORTED == 1) begin : gpio
gpio gpio(

View File

@ -32,137 +32,137 @@
/* verilator lint_on UNUSED */
module wallypipelinedcore (
input logic clk, reset,
input logic clk, reset,
// Privileged
input logic TimerIntM, ExtIntM, SwIntM,
input logic [63:0] MTIME_CLINT,
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
input logic [63:0] MTIME_CLINT,
// Bus Interface
input logic [`AHBW-1:0] HRDATA,
input logic HREADY, HRESP,
output logic HCLK, HRESETn,
output logic [31:0] HADDR,
input logic HREADY, HRESP,
output logic HCLK, HRESETn,
output logic [31:0] HADDR,
output logic [`AHBW-1:0] HWDATA,
output logic HWRITE,
output logic [2:0] HSIZE,
output logic [2:0] HBURST,
output logic [3:0] HPROT,
output logic [1:0] HTRANS,
output logic HMASTLOCK,
output logic HWRITE,
output logic [2:0] HSIZE,
output logic [2:0] HBURST,
output logic [3:0] HPROT,
output logic [1:0] HTRANS,
output logic HMASTLOCK,
// Delayed signals for subword write
output logic [2:0] HADDRD,
output logic [3:0] HSIZED,
output logic HWRITED
output logic [2:0] HADDRD,
output logic [3:0] HSIZED,
output logic HWRITED
);
// logic [1:0] ForwardAE, ForwardBE;
logic StallF, StallD, StallE, StallM, StallW;
logic FlushF, FlushD, FlushE, FlushM, FlushW;
logic RetM;
logic StallF, StallD, StallE, StallM, StallW;
logic FlushF, FlushD, FlushE, FlushM, FlushW;
logic RetM;
(* mark_debug = "true" *) logic TrapM;
// new signals that must connect through DP
logic MDUE, W64E;
logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicE;
logic [1:0] AtomicM;
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E;
logic MDUE, W64E;
logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicE;
logic [1:0] AtomicM;
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E;
// logic [31:0] InstrF;
logic [31:0] InstrD, InstrW;
(* mark_debug = "true" *) logic [31:0] InstrM;
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
logic [`XLEN-1:0] PrivilegedNextPCM;
(* mark_debug = "true" *) logic [1:0] MemRWM;
(* mark_debug = "true" *) logic InstrValidM;
logic InstrMisalignedFaultM;
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
logic LoadMisalignedFaultM, LoadAccessFaultM;
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
logic [`XLEN-1:0] InstrMisalignedAdrM;
logic [31:0] InstrD, InstrW;
(* mark_debug = "true" *) logic [31:0] InstrM;
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
logic [`XLEN-1:0] PrivilegedNextPCM;
(* mark_debug = "true" *) logic [1:0] MemRWM;
(* mark_debug = "true" *) logic InstrValidM;
logic InstrMisalignedFaultM;
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
logic LoadMisalignedFaultM, LoadAccessFaultM;
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
logic [`XLEN-1:0] InstrMisalignedAdrM;
logic InvalidateICacheM, FlushDCacheM;
logic PCSrcE;
logic CSRWritePendingDEM;
logic DivBusyE;
logic PCSrcE;
logic CSRWritePendingDEM;
logic DivBusyE;
logic DivE;
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
logic SquashSCW;
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
logic SquashSCW;
// floating point unit signals
logic [2:0] FRM_REGW;
logic [2:0] FRM_REGW;
logic [4:0] RdM, RdW;
logic FStallD;
logic FWriteIntE;
logic [`XLEN-1:0] FWriteDataE;
logic [`XLEN-1:0] FIntResM;
logic FDivBusyE;
logic IllegalFPUInstrD, IllegalFPUInstrE;
logic FRegWriteM;
logic FPUStallD;
logic [4:0] SetFflagsM;
logic FStallD;
logic FWriteIntE;
logic [`XLEN-1:0] FWriteDataE;
logic [`XLEN-1:0] FIntResM;
logic FDivBusyE;
logic IllegalFPUInstrD, IllegalFPUInstrE;
logic FRegWriteM;
logic FPUStallD;
logic [4:0] SetFflagsM;
// memory management unit signals
logic ITLBWriteF;
logic ITLBFlushF, DTLBFlushM;
logic ITLBMissF;
logic [`XLEN-1:0] SATP_REGW;
logic ITLBWriteF;
logic ITLBFlushF, DTLBFlushM;
logic ITLBMissF;
logic [`XLEN-1:0] SATP_REGW;
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
logic [1:0] STATUS_MPP;
logic [1:0] PrivilegeModeW;
logic [`XLEN-1:0] PTE;
logic [1:0] PageType;
logic [1:0] PrivilegeModeW;
logic [`XLEN-1:0] PTE;
logic [1:0] PageType;
// PMA checker signals
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
// IMem stalls
logic IFUStallF;
logic LSUStallM;
logic IFUStallF;
logic LSUStallM;
// cpu lsu interface
logic [2:0] Funct3M;
logic [`XLEN-1:0] IEUAdrE;
logic [2:0] Funct3M;
logic [`XLEN-1:0] IEUAdrE;
(* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataE;
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
(* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM;
logic [`XLEN-1:0] ReadDataW;
logic CommittedM;
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
(* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM;
logic [`XLEN-1:0] ReadDataW;
logic CommittedM;
// AHB ifu interface
logic [`PA_BITS-1:0] IFUBusAdr;
logic [`XLEN-1:0] IFUBusHRDATA;
logic IFUBusRead;
logic IFUBusAck;
logic [`PA_BITS-1:0] IFUBusAdr;
logic [`XLEN-1:0] IFUBusHRDATA;
logic IFUBusRead;
logic IFUBusAck;
// AHB LSU interface
logic [`PA_BITS-1:0] LSUBusAdr;
logic LSUBusRead;
logic LSUBusWrite;
logic LSUBusAck;
logic [`XLEN-1:0] LSUBusHRDATA;
logic [`XLEN-1:0] LSUBusHWDATA;
logic [`PA_BITS-1:0] LSUBusAdr;
logic LSUBusRead;
logic LSUBusWrite;
logic LSUBusAck;
logic [`XLEN-1:0] LSUBusHRDATA;
logic [`XLEN-1:0] LSUBusHWDATA;
logic BPPredWrongE;
logic BPPredDirWrongM;
logic BTBPredPCWrongM;
logic RASPredPCWrongM;
logic BPPredClassNonCFIWrongM;
logic [4:0] InstrClassM;
logic InstrAccessFaultF;
logic [2:0] LSUBusSize;
logic BPPredWrongE;
logic BPPredDirWrongM;
logic BTBPredPCWrongM;
logic RASPredPCWrongM;
logic BPPredClassNonCFIWrongM;
logic [4:0] InstrClassM;
logic InstrAccessFaultF;
logic [2:0] LSUBusSize;
logic ExceptionM;
logic PendingInterruptM;
logic DCacheMiss;
logic DCacheAccess;
logic ICacheMiss;
logic ICacheAccess;
logic BreakpointFaultM, EcallFaultM;
logic ExceptionM;
logic PendingInterruptM;
logic DCacheMiss;
logic DCacheAccess;
logic ICacheMiss;
logic ICacheAccess;
logic BreakpointFaultM, EcallFaultM;
logic InstrDAPageFaultF;
ifu ifu(
@ -182,7 +182,7 @@ module wallypipelinedcore (
// Mem
.RetM, .TrapM, .PrivilegedNextPCM, .InvalidateICacheM,
.InstrD, .InstrM, . PCM, .InstrClassM, .BPPredDirWrongM,
.InstrD, .InstrM, .PCM, .InstrClassM, .BPPredDirWrongM,
.BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
// Writeback
@ -203,8 +203,8 @@ module wallypipelinedcore (
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.InstrAccessFaultF,
.InstrDAPageFaultF
); // instruction fetch unit: PC, branch prediction, instruction cache
); // instruction fetch unit: PC, branch prediction, instruction cache
ieu ieu(
.clk, .reset,
@ -221,7 +221,7 @@ module wallypipelinedcore (
// Memory stage interface
.SquashSCW, // from LSU
.MemRWM, // read/write control goes to LSU
.AtomicE, // atomic control goes to LSU
.AtomicE, // atomic control goes to LSU
.AtomicM, // atomic control goes to LSU
.WriteDataE, // Write data to LSU
.Funct3M, // size and signedness to LSU
@ -245,41 +245,41 @@ module wallypipelinedcore (
lsu lsu(
.clk, .reset, .StallM, .FlushM, .StallW,
.FlushW,
// CPU interface
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
.AtomicM, .TrapM,
.CommittedM, .DCacheMiss, .DCacheAccess,
.SquashSCW,
//.DataMisalignedM(DataMisalignedM),
.IEUAdrE, .IEUAdrM, .WriteDataE,
.ReadDataM, .FlushDCacheM,
// connected to ahb (all stay the same)
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
.FlushW,
// CPU interface
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
.AtomicM, .TrapM,
.CommittedM, .DCacheMiss, .DCacheAccess,
.SquashSCW,
//.DataMisalignedM(DataMisalignedM),
.IEUAdrE, .IEUAdrM, .WriteDataE,
.ReadDataM, .FlushDCacheM,
// connected to ahb (all stay the same)
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
// connect to csr or privilege and stay the same.
.PrivilegeModeW, // connects to csr
.PMPCFG_ARRAY_REGW, // connects to csr
.PMPADDR_ARRAY_REGW, // connects to csr
// hptw keep i/o
.SATP_REGW, // from csr
.STATUS_MXR, // from csr
.STATUS_SUM, // from csr
.STATUS_MPRV, // from csr
.STATUS_MPP, // from csr
// connect to csr or privilege and stay the same.
.PrivilegeModeW, // connects to csr
.PMPCFG_ARRAY_REGW, // connects to csr
.PMPADDR_ARRAY_REGW, // connects to csr
// hptw keep i/o
.SATP_REGW, // from csr
.STATUS_MXR, // from csr
.STATUS_SUM, // from csr
.STATUS_MPRV, // from csr
.STATUS_MPP, // from csr
.DTLBFlushM, // connects to privilege
.LoadPageFaultM, // connects to privilege
.StoreAmoPageFaultM, // connects to privilege
.LoadMisalignedFaultM, // connects to privilege
.LoadAccessFaultM, // connects to privilege
.StoreAmoMisalignedFaultM, // connects to privilege
.StoreAmoAccessFaultM, // connects to privilege
.DTLBFlushM, // connects to privilege
.LoadPageFaultM, // connects to privilege
.StoreAmoPageFaultM, // connects to privilege
.LoadMisalignedFaultM, // connects to privilege
.LoadAccessFaultM, // connects to privilege
.StoreAmoMisalignedFaultM, // connects to privilege
.StoreAmoAccessFaultM, // connects to privilege
.InstrDAPageFaultF,
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
.LSUStallM); // change to LSUStallM
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
.LSUStallM); // change to LSUStallM
// *** Ross: please make EBU conditional when only supporting internal memories
@ -306,13 +306,13 @@ module wallypipelinedcore (
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
.LSUStallM, .IFUStallF,
.FPUStallD, .FStallD,
.DivBusyE, .FDivBusyE,
.EcallFaultM, .BreakpointFaultM,
.DivBusyE, .FDivBusyE,
.EcallFaultM, .BreakpointFaultM,
.InvalidateICacheM,
// Stall & flush outputs
.StallF, .StallD, .StallE, .StallM, .StallW,
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
); // global stall and flush control
.StallF, .StallD, .StallE, .StallM, .StallW,
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
); // global stall and flush control
if (`ZICSR_SUPPORTED) begin:priv
privileged priv(
@ -331,7 +331,7 @@ module wallypipelinedcore (
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.TimerIntM, .ExtIntM, .SwIntM,
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
.MTIME_CLINT,
.InstrMisalignedAdrM, .IEUAdrM,
.SetFflagsM,

View File

@ -74,7 +74,7 @@ module wallypipelinedsoc (
logic HRESP;
logic TimerIntM, SwIntM; // from CLINT
logic [63:0] MTIME_CLINT; // from CLINT to CSRs
logic ExtIntM; // from PLIC
logic ExtIntM,ExtIntS; // from PLIC
logic [2:0] HADDRD;
logic [3:0] HSIZED;
logic HWRITED;
@ -84,7 +84,7 @@ module wallypipelinedsoc (
// instantiate processor and memories
wallypipelinedcore core(.clk, .reset,
.TimerIntM, .ExtIntM, .SwIntM,
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
.MTIME_CLINT,
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA,
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
@ -94,7 +94,7 @@ module wallypipelinedsoc (
uncore uncore(.HCLK, .HRESETn, .TIMECLK,
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED,
.TimerIntM, .SwIntM, .ExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
.TimerIntM, .SwIntM, .ExtIntM, .ExtIntS, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
.HSELEXT,
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK

View File

@ -176,6 +176,7 @@ module testbench;
integer CheckMIPFutureM;
integer CheckSIPFutureE;
integer CheckSIPFutureM;
logic [`XLEN-1:0] AttemptedInstructionCount;
// Useful Aliases
`define RF dut.core.ieu.dp.regf.rf
`define PC dut.core.ifu.pcreg.q
@ -266,6 +267,19 @@ module testbench;
end \
end
`define INIT_CHECKPOINT_PACKED_ARRAY(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
`MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
for (i=ARRAY_MIN; i<ARRAY_MAX+1; i=i+1) begin \
initial begin \
if (CHECKPOINT!=0) begin \
force `SIGNAL[i] = init``SIGNAL[i]; \
while (reset!==1) #1; \
while (reset!==0) #1; \
#1; \
release `SIGNAL[i]; \
end \
end \
end
// For the annoying case where the pathname to the array elements includes
// a "genblk<i>" in the signal name
`define INIT_CHECKPOINT_GENBLK_ARRAY(SIGNAL_BASE,SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
@ -296,6 +310,7 @@ module testbench;
end \
end
genvar i;
`INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1);
`INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,0);
`INIT_CHECKPOINT_VAL(PC, [`XLEN-1:0]);
@ -333,9 +348,9 @@ module testbench;
//`INIT_CHECKPOINT_VAL(UART_LSR, [7:0]);
//`INIT_CHECKPOINT_VAL(UART_MSR, [7:0]);
`INIT_CHECKPOINT_VAL(UART_SCR, [7:0]);
`INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
`INIT_CHECKPOINT_VAL(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1]);
`INIT_CHECKPOINT_VAL(PLIC_THRESHOLD, [2:0]);
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0);
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_THRESHOLD, [2:0],1,0);
integer memFile;
integer readResult;
@ -366,11 +381,13 @@ module testbench;
traceFileM = $fopen({testvectorDir,"all.txt"}, "r");
traceFileE = $fopen({testvectorDir,"all.txt"}, "r");
InstrCountW = '0;
AttemptedInstructionCount = '0;
end else begin // checkpoint
//$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.memory.RAM);
traceFileE = $fopen({checkpointDir,"all.txt"}, "r");
traceFileM = $fopen({checkpointDir,"all.txt"}, "r");
InstrCountW = CHECKPOINT;
AttemptedInstructionCount = CHECKPOINT;
// manual checkpoint initializations that don't neatly fit into MACRO
force {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV} = initMSTATUS[0][22:17];
force {`STATUS_FS,`STATUS_MPP} = initMSTATUS[0][14:11];
@ -426,6 +443,9 @@ module testbench;
for(index``STAGE = 0; index``STAGE < line``STAGE.len(); index``STAGE++) begin \
//$display("char = %s", line``STAGE[index]); \
if (line``STAGE[index``STAGE] == " " | line``STAGE[index``STAGE] == "\n") begin \
if (line``STAGE[index``STAGE] == "\n" & `"STAGE`"=="M") begin \
AttemptedInstructionCount += 1; \
end \
EndIndex``STAGE = index``STAGE; \
ExpectedTokens``STAGE[TokenIndex``STAGE] = line``STAGE.substr(StartIndex``STAGE, EndIndex``STAGE-1); \
//$display("In Tokenizer %s", line``STAGE.substr(StartIndex, EndIndex-1)); \

View File

@ -959,7 +959,7 @@ string imperas32f[] = '{
"rv64i_m/I/andi-01", "6010",
"rv64i_m/I/auipc-01", "2010",
"rv64i_m/I/beq-01", "47010",
"rv64i_m/I/bge-01", "47010",
"rv64i_m/I/bge-01", "46010",
"rv64i_m/I/bgeu-01", "56010",
"rv64i_m/I/blt-01", "4d010",
"rv64i_m/I/bltu-01", "57010",
@ -1450,34 +1450,36 @@ string imperas32f[] = '{
string wally64priv[] = '{
`WALLYTEST,
"rv64i_m/privilege/WALLY-CSR-permission-s-01", "004080",
"rv64i_m/privilege/WALLY-CSR-permission-s-01", "0050a0",
//"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-M", "005070",
//"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-S", "003070",
"rv64i_m/privilege/WALLY-CSR-permission-u-01", "005080",
"rv64i_m/privilege/WALLY-CSR-permission-u-01", "0050a0",
// "rv64i_m/privilege/WALLY-MARCHID", "003070",
/* "rv64i_m/privilege/WALLY-MCAUSE", "003070",
"rv64i_m/privilege/WALLY-MEDELEG", "003070",
"rv64i_m/privilege/WALLY-MHARTID", "003070",
"rv64i_m/privilege/WALLY-MIMPID", "003070",*/
"rv64i_m/privilege/WALLY-minfo-01", "004080",
"rv64i_m/privilege/WALLY-misa-01", "004080",
"rv64i_m/privilege/WALLY-MMU-SV39", "004080",
"rv64i_m/privilege/WALLY-MMU-SV48", "004080",
"rv64i_m/privilege/WALLY-minfo-01", "0040a0",
"rv64i_m/privilege/WALLY-misa-01", "0040a0",
"rv64i_m/privilege/WALLY-MMU-SV39", "0040a0",
"rv64i_m/privilege/WALLY-MMU-SV48", "0040a0",
/* "rv64i_m/privilege/WALLY-MSTATUS", "002070",
"rv64i_m/privilege/WALLY-MTVEC", "002070",
"rv64i_m/privilege/WALLY-MVENDORID", "003070", */
"rv64i_m/privilege/WALLY-PMA", "004080",
"rv64i_m/privilege/WALLY-PMP", "004080",
"rv64i_m/privilege/WALLY-PMA", "0040a0",
"rv64i_m/privilege/WALLY-PMP", "0040a0",
// "rv64i_m/privilege/WALLY-SCAUSE", "002070",
"rv64i_m/privilege/WALLY-scratch-01", "004080",
"rv64i_m/privilege/WALLY-sscratch-s-01", "004080"
"rv64i_m/privilege/WALLY-scratch-01", "0040a0",
"rv64i_m/privilege/WALLY-sscratch-s-01", "0040a0"
// "rv64i_m/privilege/WALLY-trap-01", "0040a0"
// "rv64i_m/privilege/WALLY-STVEC", "002070",
// "rv64i_m/privilege/WALLY-UCAUSE", "002070"
// "rv64i_m/privilege/WALLY-UCAUSE", "002070",
};
string wally64periph[] = '{
`WALLYTEST,
"rv64i_m/privilege/WALLY-PERIPH", "22f0"
"rv64i_m/privilege/WALLY-PERIPH", "3310"
};
string wally32e[] = '{

View File

@ -50,10 +50,47 @@
// Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries)
`define PMPCFG_ENTRIES (`PMP_ENTRIES/8)
// Floating-point half-precision
`define ZFH_SUPPORTED 0
// Floating point constants for Quad, Double, Single, and Half precisions
`define Q_LEN 128
`define Q_NE 15
`define Q_NF 112
`define Q_BIAS 16383
`define D_LEN 64
`define D_NE 11
`define D_NF 52
`define D_BIAS 1023
`define S_LEN 32
`define S_NE 8
`define S_NF 23
`define S_BIAS 127
`define H_LEN 16
`define H_NE 5
`define H_NF 10
`define H_BIAS 15
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits
`define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32)
`define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
`define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
`define FLEN (`Q_SUPPORTED ? `Q_LEN : `D_SUPPORTED ? `D_LEN : `F_SUPPORTED ? `S_LEN : `H_LEN)
`define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE)
`define NF (`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF)
`define FMT (`Q_SUPPORTED ? 3 : `D_SUPPORTED ? 1 : `F_SUPPORTED ? 0 : 2)
`define BIAS (`Q_SUPPORTED ? `Q_BIAS : `D_SUPPORTED ? `D_BIAS : `F_SUPPORTED ? `S_BIAS : `H_BIAS)
// Floating point constants needed for FPU paramerterization
`define FPSIZES (`Q_SUPPORTED+`D_SUPPORTED+`F_SUPPORTED+`ZFH_SUPPORTED)
`define LEN1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_LEN : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_LEN : `H_LEN)
`define NE1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NE : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NE : `H_NE)
`define NF1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NF : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NF : `H_NF)
`define FMT1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? 1 : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? 0 : 2)
`define BIAS1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_BIAS : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_BIAS : `H_BIAS)
`define LEN2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_LEN : `H_LEN)
`define NE2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NE : `H_NE)
`define NF2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NF : `H_NF)
`define FMT2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? 0 : 2)
`define BIAS2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_BIAS : `H_BIAS)
// Disable spurious Verilator warnings

View File

@ -56,7 +56,8 @@ target_tests_nosim = \
WALLY-MIMPID \
WALLY-MVENDORID \
WALLY-CSR-PERMISSIONS-M \
WALLY-CSR-PERMISSIONS-S
WALLY-CSR-PERMISSIONS-S \
WALLY-trap-01 \
# Have all 0's in references!
#WALLY-MEPC \
#WALLY-SEPC \

View File

@ -1,3 +1,93 @@
00000aaa # Test 5.3.1.4: readback value from writing mie to enable interrupts
00000000
00000001 # mcause from an instruction access fault
00000000
00000000 # mtval of faulting instruction address (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000002 # mcause from an Illegal instruction
00000000
00000000 # mtval of faulting instruction (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000003 # mcause from Breakpoint
00000000
800003ec # mtval of breakpoint instruction adress (0x800003ec)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000004 # mcause from load address misaligned
00000000
800003f5 # mtval of misaligned address (0x800003f5)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000005 # mcause from load access
00000000
00000000 # mtval of accessed adress (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000006 # mcause from store misaligned
00000000
80000411 # mtval of address with misaligned store instr (0x80000410)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000007 # mcause from store access
00000000
00000000 # mtval of accessed address (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
0000000b # mcause from M mode ecall
00000000
00000000 # mtval of ecall (*** defined to be zero for now)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000008 # mcause from U mode ecall
00000000
00000000 # mtval of ecall (*** defined to be zero for now)
00000000
00000080 # masked out mstatus.MPP = 00 (from U mode), mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000009 # mcause from S mode ecall
00000000
00000000 # mtval of ecall (*** defined to be zero for now)
00000000
00000880 # masked out mstatus.MPP = 01 (from S mode), mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
000007ec # value to indicate a vectored interrupts
00000000
00000007 # mcause value from m time interrupt
80000000
00000000 # mtval for mtime interrupt (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
000007ec # value to indicate a vectored interrupts
00000000
00000001 # mcause value from m soft interrupt
80000000
00000000 # mtval for msoft interrupt (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
000007ec # value to indicate a vectored interrupts
00000000
0000000b # mcause value from m ext interrupt
80000000
00000000 # mtval for mext interrupt (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
0000b309 # medeleg after attempted write of all 1's (only some bits are writeable)
00000000
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
00000000
00000001 # Test 5.3.1.4: mcause from an instruction access fault
00000000
00000000 # mtval of faulting instruction address (0x0)
@ -12,49 +102,67 @@
00000000
00000003 # mcause from Breakpoint
00000000
00000000 # mtval of breakpoint instruction adress (*** Determined from make)
800003ec # mtval of breakpoint instruction adress (0x800003ec)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000004 # mcause from load address misaligned
00000000
00000000 # mtval of misaligned address (*** Determined from make)
800003f5 # mtval of misaligned address (0x800003f5)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000005 # mcause from load access
00000000
00000000 # mtval of address with access faulting instr (*** Determined from make)
00000000 # mtval of accessed adress (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000006 # mcause from store misaligned
00000000
00000000 # mtval of address with misaligned store instr (*** Determined from make)
80000411 # mtval of address with misaligned store instr (0x80000410)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000007 # mcause from store access
00000000
00000000 # mtval of address with faulting store instr (*** Determined from make)
00000000 # mtval of accessed address (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
0000000b # mcause from M mode ecall
00000000
00000000 # mtval of
00000000 # mtval of ecall (*** defined to be zero for now)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000008 # mcause from U mode ecall
000007ec # value to indicate a vectored interrupts
00000000
00000000 # mtval of
00000007 # mcause value from time interrupt
80000000
00000000 # mtval for mtime interrupt (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
00000009 # mcause from S mode ecall
000007ec # value to indicate a vectored interrupts
00000000
00000000 # mtval of address with faulting store instr (*** Determined from make)
00000001 # mcause value from m soft interrupt
80000000
00000000 # mtval for msoft interrupt (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
000007ec # value to indicate a vectored interrupts
00000000
0000000b # mcause value from m ext interrupt
80000000
00000000 # mtval for mext interrupt (0x0)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
0000000b # mcause from M mode ecall from test termination
00000000
00000000 # mtval of ecall (*** defined to be zero for now)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
@ -964,119 +1072,3 @@ deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef

View File

@ -55,6 +55,99 @@ RVTEST_CODE_BEGIN
.endm
// Code to trigger traps goes here so we have consistent mtvals for instruction adresses
// Even if more tests are added.
.macro CAUSE_TRAP_TRIGGERS
j end_trap_triggers
// The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines
// This effectively includes everything that isn't to do with page faults (virtual memory)
cause_instr_addr_misaligned:
// cause a misaligned address trap
auipc x28, 0 // get current PC, which is aligned
addi x28, x28, 0x3 // add 1 to pc to create misaligned address
jr x28 // cause instruction address midaligned trap
ret
cause_instr_access:
la x28, 0x0 // address zero is an address with no memory
sd x1, -8(sp) // push the return adress ontot the stack
addi sp, sp, -8
jalr x28 // cause instruction access trap
ld x1, 0(sp) // pop return adress back from the stack
addi sp, sp, 8
ret
cause_illegal_instr:
.word 0x00000000 // a 32 bit zros is an illegal instruction
ret
cause_breakpnt: // ****
ebreak
ret
cause_load_addr_misaligned:
auipc x28, 0 // get current PC, which is aligned
addi x28, x28, 1
lw x29, 0(x28) // load from a misaligned address
ret
cause_load_acc:
la x28, 0 // 0 is an address with no memory
lw x29, 0(x28) // load from unimplemented address
ret
cause_store_addr_misaligned:
auipc x28, 0 // get current PC, which is aligned
addi x28, x28, 1
sw x29, 0(x28) // store to a misaligned address
ret
cause_store_acc:
la x28, 0 // 0 is an address with no memory
sw x29, 0(x28) // store to unimplemented address
ret
cause_ecall:
// *** ASSUMES you have already gone to the mode you need to call this from.
ecall
ret
cause_time_interrupt:
// The following code works for both RV32 and RV64.
// RV64 alone would be easier using double-word adds and stores
li x28, 0x100 // Desired offset from the present time
la x29, 0x02004000 // MTIMECMP register in CLINT
la x30, 0x0200BFF8 // MTIME register in CLINT
lw x7, 0(x30) // low word of MTIME
lw x31, 4(x30) // high word of MTIME
add x28, x7, x28 // add desired offset to the current time
bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound)
addi x31, x31, 1 // if wrap, increment most significant word
sw x31,4(x29) // store into most significant word of MTIMECMP
nowrap:
sw x28, 0(x29) // store into least significant word of MTIMECMP
loop: j loop // wait until interrupt occurs
ret
cause_soft_interrupt:
la x28, 0x02000000 // MSIP register in CLINT
li x29, 1 // 1 in the lsb
sw x29, 0(x28) // Write MSIP bit
ret
cause_ext_interrupt:
li x28, 0x10060000 // load base GPIO memory location
li x29, 0x1
sw x29, 8(x28) // enable the first pin as an output
sw x29, 28(x28) // set first pin to high interrupt enable
sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt)
ret
end_trap_triggers:
.endm
.macro TRAP_HANDLER MODE, VECTORED=1, DEBUG=0
// MODE decides which mode this trap handler will be taken in (M or S mode)
// Vectored decides whether interrumpts are handled with the vector table at trap_handler_MODE (1)
@ -577,7 +670,7 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a
// The previous CSR value before write attempt
// *** Most likely 0x2, the mcause for illegal instruction if we don't have write or read access
li x30, 0xbad // load bad value to be overwritten by csrr
li x29, \VAL
li x29, \VAL\()
csrw \CSR\(), x29
csrr x30, \CSR
sd x30, 0(x6)
@ -627,86 +720,86 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a
addi x16, x16, 8
.endm
// The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines
// This effectively includes everything that isn't to do with page faults (virtual memory)
// // The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines
// // This effectively includes everything that isn't to do with page faults (virtual memory)
.macro CAUSE_INSTR_ADDR_MISALIGNED
// cause a misaligned address trap
auipc x28, 0 // get current PC, which is aligned
addi x28, x28, 0x1 // add 1 to pc to create misaligned address
jalr x28 // cause instruction address midaligned trap
.endm
// .macro CAUSE_INSTR_ADDR_MISALIGNED
// // cause a misaligned address trap
// auipc x28, 0 // get current PC, which is aligned
// addi x28, x28, 0x1 // add 1 to pc to create misaligned address
// jalr x28 // cause instruction address midaligned trap
// .endm
.macro CAUSE_INSTR_ACCESS
la x28, 0x0 // address zero is an address with no memory
jalr x28 // cause instruction access trap
.endm
// .macro CAUSE_INSTR_ACCESS
// la x28, 0x0 // address zero is an address with no memory
// jalr x28 // cause instruction access trap
// .endm
.macro CAUSE_ILLEGAL_INSTR
.word 0x00000000 // a 32 bit zros is an illegal instruction
.endm
// .macro CAUSE_ILLEGAL_INSTR
// .word 0x00000000 // a 32 bit zros is an illegal instruction
// .endm
.macro CAUSE_BREAKPNT // ****
ebreak
.endm
// .macro CAUSE_BREAKPNT // ****
// ebreak
// .endm
.macro CAUSE_LOAD_ADDR_MISALIGNED
auipc x28, 0 // get current PC, which is aligned
addi x28, x28, 1
lw x29, 0(x28) // load from a misaligned address
.endm
// .macro CAUSE_LOAD_ADDR_MISALIGNED
// auipc x28, 0 // get current PC, which is aligned
// addi x28, x28, 1
// lw x29, 0(x28) // load from a misaligned address
// .endm
.macro CAUSE_LOAD_ACC
la x28, 0 // 0 is an address with no memory
lw x29, 0(x28) // load from unimplemented address
.endm
// .macro CAUSE_LOAD_ACC
// la x28, 0 // 0 is an address with no memory
// lw x29, 0(x28) // load from unimplemented address
// .endm
.macro CAUSE_STORE_ADDR_MISALIGNED
auipc x28, 0 // get current PC, which is aligned
addi x28, x28, 1
sw x29, 0(x28) // store to a misaligned address
.endm
// .macro CAUSE_STORE_ADDR_MISALIGNED
// auipc x28, 0 // get current PC, which is aligned
// addi x28, x28, 1
// sw x29, 0(x28) // store to a misaligned address
// .endm
.macro CAUSE_STORE_ACC
la x28, 0 // 0 is an address with no memory
sw x29, 0(x28) // store to unimplemented address
.endm
// .macro CAUSE_STORE_ACC
// la x28, 0 // 0 is an address with no memory
// sw x29, 0(x28) // store to unimplemented address
// .endm
.macro CAUSE_ECALL
// *** ASSUMES you have already gone to the mode you need to call this from.
ecall
.endm
// .macro CAUSE_ECALL
// // *** ASSUMES you have already gone to the mode you need to call this from.
// ecall
// .endm
.macro CAUSE_TIME_INTERRUPT
// The following code works for both RV32 and RV64.
// RV64 alone would be easier using double-word adds and stores
li x28, 0x100 // Desired offset from the present time
la x29, 0x02004000 // MTIMECMP register in CLINT
la x30, 0x0200BFF8 // MTIME register in CLINT
lw x7, 0(x30) // low word of MTIME
lw x31, 4(x30) // high word of MTIME
add x28, x7, x28 // add desired offset to the current time
bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound)
addi x31, x31, 1 // if wrap, increment most significant word
sw x31,4(x29) // store into most significant word of MTIMECMP
nowrap:
sw x28, 0(x29) // store into least significant word of MTIMECMP
loop: j loop // wait until interrupt occurs
.endm
// .macro CAUSE_TIME_INTERRUPT
// // The following code works for both RV32 and RV64.
// // RV64 alone would be easier using double-word adds and stores
// li x28, 0x100 // Desired offset from the present time
// la x29, 0x02004000 // MTIMECMP register in CLINT
// la x30, 0x0200BFF8 // MTIME register in CLINT
// lw x7, 0(x30) // low word of MTIME
// lw x31, 4(x30) // high word of MTIME
// add x28, x7, x28 // add desired offset to the current time
// bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound)
// addi x31, x31, 1 // if wrap, increment most significant word
// sw x31,4(x29) // store into most significant word of MTIMECMP
// nowrap:
// sw x28, 0(x29) // store into least significant word of MTIMECMP
// loop: j loop // wait until interrupt occurs
// .endm
.macro CAUSE_SOFT_INTERRUPT
la x28, 0x02000000 // MSIP register in CLINT
li x29, 1 // 1 in the lsb
sw x29, 0(x28) // Write MSIP bit
.endm
// .macro CAUSE_SOFT_INTERRUPT
// la x28, 0x02000000 // MSIP register in CLINT
// li x29, 1 // 1 in the lsb
// sw x29, 0(x28) // Write MSIP bit
// .endm
.macro CAUSE_EXT_INTERRUPT
li x28, 0x10060000 // load base GPIO memory location
li x29, 0x1
sw x29, 8(x28) // enable the first pin as an output
sw x29, 28(x28) // set first pin to high interrupt enable
sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt)
.endm
// .macro CAUSE_EXT_INTERRUPT
// li x28, 0x10060000 // load base GPIO memory location
// li x29, 0x1
// sw x29, 8(x28) // enable the first pin as an output
// sw x29, 28(x28) // set first pin to high interrupt enable
// sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt)
// .endm
.macro END_TESTS
// invokes one final ecall to return to machine mode then terminates this program, so the output is

View File

@ -25,50 +25,50 @@
INIT_TESTS
CAUSE_TRAP_TRIGGERS // initialize code that will cause traps for consistent mtval addresses
TRAP_HANDLER m, DEBUG=1 // turn on recording mtval and status bits on traps
li x28, 0x8
csrs mstatus, x28 // set mstatus.MIE bit to 1
// WRITE_READ_CSR mie, 0xFFFF *** commented out until I can get the trap handler (and spike for time interrupts) to work correctly with interrupts
WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources // *** commented out until I can get the trap handler (and spike for time interrupts) to work correctly with interrupts
// test 5.3.1.4 Basic trap tests
// CAUSE_INSTR_ADDR_MISALIGNED //skipped becuase this exception may be impossible when compressed instructions are enabled)
CAUSE_INSTR_ACCESS
CAUSE_ILLEGAL_INSTR
CAUSE_BREAKPNT
CAUSE_LOAD_ADDR_MISALIGNED
CAUSE_LOAD_ACC
CAUSE_STORE_ADDR_MISALIGNED
CAUSE_STORE_ACC
// jal cause_instr_addr_misaligned //skipped becuase this exception may be impossible when compressed instructions are enabled)
jal cause_instr_access
jal cause_illegal_instr
jal cause_breakpnt
jal cause_load_addr_misaligned
jal cause_load_acc
jal cause_store_addr_misaligned
jal cause_store_acc
GOTO_U_MODE // Causes M mode ecall
GOTO_S_MODE // Causes U mode ecall
GOTO_M_MODE // Causes S mode ecall
// CAUSE_TIME_INTERRUPT *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen.
// CAUSE_SOFT_INTERRUPT *** exiting out of the trap handler after these is current;y broken
// CAUSE_EXT_INTERRUPT
jal cause_time_interrupt // *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen.
jal cause_soft_interrupt // *** exiting out of the trap handler after these is current;y broken
jal cause_ext_interrupt
// try the traps again with mideleg = medeleg = all 1's to ensure traps still go to M mode from M mode
WRITE_READ_CSR medeleg, 0xFFFFFFFFFFFFFFFF
WRITE_READ_CSR mideleg, 0xFFFFFFFFFFFFFFFF
// CAUSE_INSTR_ADDR_MISALIGNED //skipped becuase this exception may be impossible when compressed instructions are enabled)
CAUSE_INSTR_ACCESS
CAUSE_ILLEGAL_INSTR
CAUSE_BREAKPNT
CAUSE_LOAD_ADDR_MISALIGNED
CAUSE_LOAD_ACC
CAUSE_STORE_ADDR_MISALIGNED
CAUSE_STORE_ACC
CAUSE_ECALL // M mode ecall
// GOTO_U_MODE // leave these untested since we only need to ensure that from M mode are not delegated
// GOTO_S_MODE
// jal cause_instr_addr_misaligned //skipped becuase this exception may be impossible when compressed instructions are enabled)
jal cause_instr_access
jal cause_illegal_instr
jal cause_breakpnt
jal cause_load_addr_misaligned
jal cause_load_acc
jal cause_store_addr_misaligned
jal cause_store_acc
jal cause_ecall // M mode ecall
// CAUSE_TIME_INTERRUPT *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen.
// CAUSE_SOFT_INTERRUPT *** exiting out of the trap handler after these is current;y broken
// CAUSE_EXT_INTERRUPT
jal cause_time_interrupt // *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen.
jal cause_soft_interrupt // *** exiting out of the trap handler after these is current;y broken
jal cause_ext_interrupt
END_TESTS