feat: add lab-rv32i-c-machine-timer card

This commit is contained in:
user
2026-07-21 19:14:20 +02:00
commit a0e116f24e
23 changed files with 4720 additions and 0 deletions
+102
View File
@@ -0,0 +1,102 @@
#!/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'