103 lines
3.2 KiB
Bash
Executable File
103 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
env_root="${RV_ENV_ROOT:-/home/user/dev/edu/rv32i-hazard3-student-env}"
|
|
tb="${HAZARD3_TB:-$env_root/vendor/Hazard3/test/sim/tb_verilator/tb}"
|
|
objdump="${RISCV_PREFIX:-riscv64-unknown-elf-}objdump"
|
|
|
|
if [[ ! -x "$tb" ]]; then
|
|
make -C "$(dirname -- "$tb")" tb >/dev/null
|
|
fi
|
|
|
|
make -C "$root" -s tasks "RV_ENV_ROOT=$env_root"
|
|
|
|
run_task() {
|
|
local task="$1"
|
|
shift
|
|
local log="$root/build/$task/oracle.log"
|
|
"$tb" --bin "$root/build/$task/prog.bin" --cycles 500000 --cpuret --logfile "$log"
|
|
if grep -Eq 'Unhandled trap|Max cycles reached' "$log"; then
|
|
printf 'FAIL %s: trap or timeout\n' "$task" >&2
|
|
sed -n '1,160p' "$log" >&2
|
|
return 1
|
|
fi
|
|
local expected
|
|
for expected in "$@"; do
|
|
grep -Fqx "$expected" "$log" || {
|
|
printf 'FAIL %s: missing <%s>\n' "$task" "$expected" >&2
|
|
sed -n '1,160p' "$log" >&2
|
|
return 1
|
|
}
|
|
done
|
|
printf 'PASS Hazard3 oracle: %s\n' "$task"
|
|
}
|
|
|
|
run_task task01_mtime_consistent_read \
|
|
'T01 retry=00000001' \
|
|
'T01 value_high=00000001' \
|
|
'T01 monotonic=00000001' \
|
|
'T01 pass=00000001'
|
|
|
|
run_task task02_oneshot_timer_irq \
|
|
'T02 count=00000001' \
|
|
'T02 mcause=80000007' \
|
|
'T02 pending_before=00000000' \
|
|
'T02 pending_after=00000000' \
|
|
'T02 resumed=00000001' \
|
|
'T02 deadline_reached=00000001' \
|
|
'T02 pass=00000001'
|
|
|
|
run_task task03_periodic_absolute_deadline \
|
|
'T03 count=00000004' \
|
|
'T03 causes=00000004' \
|
|
'T03 period_low=00000640' \
|
|
'T03 step_ok=00000001' \
|
|
'T03 ordered=00000001' \
|
|
'T03 late_math=00000001' \
|
|
'T03 naive_shift_ok=00000001' \
|
|
'T03 pass=00000001'
|
|
|
|
# Independent relations: do not accept a program's pass flag as the only oracle.
|
|
t01_attempts_hex="$(sed -n 's/^T01 attempts=//p' \
|
|
"$root/build/task01_mtime_consistent_read/oracle.log")"
|
|
(( 16#$t01_attempts_hex > 1 )) || {
|
|
echo "FAIL task01: rollover did not force a retry" >&2
|
|
exit 1
|
|
}
|
|
|
|
mapfile -t t03_deadline < <(sed -n 's/^T03 deadline_low=//p' \
|
|
"$root/build/task03_periodic_absolute_deadline/oracle.log")
|
|
mapfile -t t03_observed < <(sed -n 's/^T03 observed_low=//p' \
|
|
"$root/build/task03_periodic_absolute_deadline/oracle.log")
|
|
mapfile -t t03_lateness < <(sed -n 's/^T03 lateness_low=//p' \
|
|
"$root/build/task03_periodic_absolute_deadline/oracle.log")
|
|
[[ ${#t03_deadline[@]} -eq 4 && ${#t03_observed[@]} -eq 4 && ${#t03_lateness[@]} -eq 4 ]]
|
|
for i in 0 1 2 3; do
|
|
d=$((16#${t03_deadline[$i]}))
|
|
o=$((16#${t03_observed[$i]}))
|
|
l=$((16#${t03_lateness[$i]}))
|
|
(( o >= d && o - d == l )) || {
|
|
echo "FAIL task03: invalid observed/deadline/lateness relation at tick $i" >&2
|
|
exit 1
|
|
}
|
|
if (( i > 0 )); then
|
|
previous=$((16#${t03_deadline[$((i - 1))]}))
|
|
(( d - previous == 1600 )) || {
|
|
echo "FAIL task03: deadline step is not 1600 at tick $i" >&2
|
|
exit 1
|
|
}
|
|
fi
|
|
done
|
|
|
|
for task in task02_oneshot_timer_irq task03_periodic_absolute_deadline; do
|
|
"$objdump" -d "$root/build/$task/prog.elf" |
|
|
sed -n '/<isr_machine_timer>:/,/^$/p' |
|
|
grep -Eq '[[:space:]]mret$' || {
|
|
echo "FAIL $task: ISR does not end in mret" >&2
|
|
exit 1
|
|
}
|
|
done
|
|
|
|
printf 'PASS independent oracle: rollover retry, periodic arithmetic, ISR mret\n'
|