diff --git a/addins/SoftFloat-3e/build/Linux-x86_64-GCC/softfloat.a b/addins/SoftFloat-3e/build/Linux-x86_64-GCC/softfloat.a index b4466d62..44254483 100644 Binary files a/addins/SoftFloat-3e/build/Linux-x86_64-GCC/softfloat.a and b/addins/SoftFloat-3e/build/Linux-x86_64-GCC/softfloat.a differ diff --git a/addins/embench-iot b/addins/embench-iot index 261a65e0..2d2aaa7b 160000 --- a/addins/embench-iot +++ b/addins/embench-iot @@ -1 +1 @@ -Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9 +Subproject commit 2d2aaa7b85c60219c591555b647dfa1785ffe1b3 diff --git a/addins/riscv-arch-test b/addins/riscv-arch-test index be67c99b..effd553a 160000 --- a/addins/riscv-arch-test +++ b/addins/riscv-arch-test @@ -1 +1 @@ -Subproject commit be67c99bd461742aa1c100bcc0732657faae2230 +Subproject commit effd553a6a91ed9b0ba251796a8a44505a45174f diff --git a/addins/riscv-dv b/addins/riscv-dv index a7e27bc0..cb4295f9 160000 --- a/addins/riscv-dv +++ b/addins/riscv-dv @@ -1 +1 @@ -Subproject commit a7e27bc046405f0dbcde091be99f5a5d564e2172 +Subproject commit cb4295f9ce5da2881d7746015a6105adb8f09071 diff --git a/addins/riscv-tests b/addins/riscv-tests index cf04274f..3e2bf06b 160000 --- a/addins/riscv-tests +++ b/addins/riscv-tests @@ -1 +1 @@ -Subproject commit cf04274f50621fd9ef9147793cca6dd1657985c7 +Subproject commit 3e2bf06b071a77ae62c09bf07c5229d1f9397d94 diff --git a/linux/buildroot-config-src/busybox.config b/linux/buildroot-config-src/wally/busybox.config similarity index 100% rename from linux/buildroot-config-src/busybox.config rename to linux/buildroot-config-src/wally/busybox.config diff --git a/linux/buildroot-config-src/linux.config b/linux/buildroot-config-src/wally/linux.config similarity index 100% rename from linux/buildroot-config-src/linux.config rename to linux/buildroot-config-src/wally/linux.config diff --git a/linux/buildroot-config-src/main.config b/linux/buildroot-config-src/wally/main.config similarity index 99% rename from linux/buildroot-config-src/main.config rename to linux/buildroot-config-src/wally/main.config index bcdd727f..7e5f68df 100644 --- a/linux/buildroot-config-src/main.config +++ b/linux/buildroot-config-src/wally/main.config @@ -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 diff --git a/linux/buildroot-config-src/wally/rootfs_overlay/.profile b/linux/buildroot-config-src/wally/rootfs_overlay/.profile new file mode 100644 index 00000000..65dccfef --- /dev/null +++ b/linux/buildroot-config-src/wally/rootfs_overlay/.profile @@ -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 diff --git a/linux/buildroot-config-src/wally/rootfs_overlay/etc/inittab b/linux/buildroot-config-src/wally/rootfs_overlay/etc/inittab new file mode 100644 index 00000000..7ae8de33 --- /dev/null +++ b/linux/buildroot-config-src/wally/rootfs_overlay/etc/inittab @@ -0,0 +1,41 @@ +# /etc/inittab +# +# Copyright (C) 2001 Erik Andersen +# +# 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 == 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 diff --git a/linux/devicetree/wally-virt.dts b/linux/devicetree/wally-virt.dts index f35848c5..6d795585 100644 --- a/linux/devicetree/wally-virt.dts +++ b/linux/devicetree/wally-virt.dts @@ -15,7 +15,7 @@ memory@80000000 { device_type = "memory"; - reg = <0x00 0x80000000 0x00 0x8000000>; + reg = <0x00 0x80000000 0x00 0x08000000>; }; cpus { diff --git a/linux/testvector-generation/checkpointSweep.sh b/linux/testvector-generation/checkpointSweep.sh index c1543677..075ca253 100755 --- a/linux/testvector-generation/checkpointSweep.sh +++ b/linux/testvector-generation/checkpointSweep.sh @@ -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 diff --git a/linux/testvector-generation/genCheckpoint.sh b/linux/testvector-generation/genCheckpoint.sh index 8f4d0a11..447377b3 100755 --- a/linux/testvector-generation/genCheckpoint.sh +++ b/linux/testvector-generation/genCheckpoint.sh @@ -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 diff --git a/linux/testvector-generation/parseGDBtoTrace.py b/linux/testvector-generation/parseGDBtoTrace.py index 412db5bb..97145a35 100755 --- a/linux/testvector-generation/parseGDBtoTrace.py +++ b/linux/testvector-generation/parseGDBtoTrace.py @@ -138,9 +138,9 @@ if len(sys.argv) != 2: sys.exit('Error parseGDBtoTrace.py expects 1 arg:\n >') 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() diff --git a/linux/testvector-generation/parsePlicState.py b/linux/testvector-generation/parsePlicState.py index a3c3787c..b917bfdc 100755 --- a/linux/testvector-generation/parsePlicState.py +++ b/linux/testvector-generation/parsePlicState.py @@ -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!") diff --git a/pipelined/regression/buildrootBugFinder.py b/pipelined/regression/buildrootBugFinder.py index b6639e71..89a838d2 100755 --- a/pipelined/regression/buildrootBugFinder.py +++ b/pipelined/regression/buildrootBugFinder.py @@ -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 < {} -c < {} -c < {} -c < 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 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 + // has priority level and has an "active" interrupt request + // ("active" meaning it is enabled in context 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 diff --git a/pipelined/src/uncore/uncore.sv b/pipelined/src/uncore/uncore.sv index d90a30d7..f48b9696 100644 --- a/pipelined/src/uncore/uncore.sv +++ b/pipelined/src/uncore/uncore.sv @@ -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( diff --git a/pipelined/src/wally/wallypipelinedcore.sv b/pipelined/src/wally/wallypipelinedcore.sv index 336e73f4..dd07949b 100644 --- a/pipelined/src/wally/wallypipelinedcore.sv +++ b/pipelined/src/wally/wallypipelinedcore.sv @@ -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, diff --git a/pipelined/src/wally/wallypipelinedsoc.sv b/pipelined/src/wally/wallypipelinedsoc.sv index 1b7f3831..0d844d3c 100644 --- a/pipelined/src/wally/wallypipelinedsoc.sv +++ b/pipelined/src/wally/wallypipelinedsoc.sv @@ -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 diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index dfaa70e6..50893cf6 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -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" 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)); \ diff --git a/pipelined/testbench/tests.vh b/pipelined/testbench/tests.vh index 8ae9bc19..81cc0628 100644 --- a/pipelined/testbench/tests.vh +++ b/pipelined/testbench/tests.vh @@ -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[] = '{ diff --git a/synthDC/hdl/wally-shared.vh b/synthDC/hdl/wally-shared.vh index 277814f8..198a4ab2 100644 --- a/synthDC/hdl/wally-shared.vh +++ b/synthDC/hdl/wally-shared.vh @@ -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 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag index adf32839..73ef3c20 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag @@ -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 \ diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output index 6fbd0f38..eef583de 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output @@ -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 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h index 99e000fa..534fd433 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h @@ -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 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S index be1ca650..45d34c34 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S @@ -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