#!/usr/bin/env bash set -euo pipefail # Vivado 2019.2 invokes the host gcc while elaborating XSIM-generated C. # A read-only ccache directory otherwise surfaces only as XSIM 43-3409. export CCACHE_DISABLE=1 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)" REPORT_DIR="$ROOT/doc/reports/system" EVIDENCE_DIR="$REPORT_DIR/evidence" SOFTWARE_EXAMPLES=(asm fft fft_dma mlkem_test mlkem_hello) find_vivado() { if [[ -n "${VIVADO:-}" && -x "${VIVADO}" ]]; then printf '%s\n' "$VIVADO" return 0 fi if command -v vivado >/dev/null 2>&1; then command -v vivado return 0 fi local candidate for candidate in \ /opt/Xilinx/Vivado/2019.2/bin/vivado \ /tools/Xilinx/Vivado/2019.2/bin/vivado; do if [[ -x "$candidate" ]]; then printf '%s\n' "$candidate" return 0 fi done return 1 } require_vivado() { if ! VIVADO_BIN="$(find_vivado)"; then echo "ERROR: Vivado not found." >&2 echo "Set VIVADO=/path/to/Vivado/bin/vivado or source Vivado settings64.sh." >&2 exit 127 fi } usage() { cat <<'EOF' Usage: run_report_tests.sh Commands: prepare Create evidence directories and Vivado project if absent lint Run the project-aware Verilator lint check build Build asm, fft, fft_dma, mlkem_test and mlkem_hello soc Build all five; simulate mlkem_test and mlkem_hello soc-fft Explicitly run the long fft and fft_dma simulations implement Run Vivado implementation and collect PPA/CDC/DRC reports refresh Parse collected evidence, regenerate figures and build the PDF quick Run lint and refresh only; does not run Vivado implementation Set SAVE_VCD=1 for SoC simulations to write evidence/soc/.vcd. Set VCD_SCOPE to a Vivado hierarchy glob to limit waveform size. Set SIM_RUN_TIME only for bounded waveform diagnostics; regressions use 'all'. Board-only tests (matmul official 5000-group timing and reset behavior) are listed in REPORT_RERUN_CHECKLIST.md and are intentionally not automated here. EOF } prepare() { mkdir -p "$EVIDENCE_DIR/build" "$EVIDENCE_DIR/soc" \ "$EVIDENCE_DIR/board" "$EVIDENCE_DIR/vivado" if [[ ! -f "$ROOT/fpga/project/Loongson_Soc.xpr" ]]; then require_vivado (cd "$ROOT/fpga" && "$VIVADO_BIN" -mode batch -source create_project.tcl) fi } lint() { prepare python3 "$ROOT/fpga/run-linter.py" "$ROOT/fpga/project/Loongson_Soc.xpr" \ 2>&1 | tee "$EVIDENCE_DIR/lint.log" } build_example() { local example="$1" local example_dir="$ROOT/sdk/software/examples/$example" local build_log="$EVIDENCE_DIR/build/$example.log" make -C "$example_dir" LA32RSOC_WINDOWS_HOME="$ROOT" clean \ 2>&1 | tee "$build_log" make -C "$example_dir" LA32RSOC_WINDOWS_HOME="$ROOT" all \ 2>&1 | tee -a "$build_log" } build() { prepare local example for example in "${SOFTWARE_EXAMPLES[@]}"; do build_example "$example" done } run_soc_case() { local example="$1" local vcd_path="$EVIDENCE_DIR/soc/$example.vcd" require_vivado build_example "$example" if [[ "${SAVE_VCD:-0}" != "0" ]]; then echo "VCD output: $vcd_path (scope: ${VCD_SCOPE:-top-level control signals})" fi (cd "$ROOT/fpga" && SOC_VCD_PATH="$vcd_path" "$VIVADO_BIN" -mode batch \ -source "$SCRIPT_DIR/run_soc_sim.tcl") 2>&1 | tee "$EVIDENCE_DIR/soc/$example.log" } soc() { prepare build_example asm build_example fft build_example fft_dma run_soc_case mlkem_test run_soc_case mlkem_hello } soc_fft() { prepare run_soc_case fft run_soc_case fft_dma } implement() { prepare require_vivado "$VIVADO_BIN" -mode batch -source "$SCRIPT_DIR/run_fresh_impl.tcl" \ 2>&1 | tee "$EVIDENCE_DIR/vivado/implementation.log" "$VIVADO_BIN" -mode batch -source "$SCRIPT_DIR/collect_report_evidence.tcl" \ 2>&1 | tee "$EVIDENCE_DIR/vivado/collection.log" python3 "$ROOT/fpga/check_dsp.py" "$ROOT/fpga/project/dsp_utilization.rpt" 0 \ 2>&1 | tee "$EVIDENCE_DIR/vivado/dsp_check.log" } refresh() { make -C "$REPORT_DIR" metrics all } case "${1:-}" in prepare) prepare ;; lint) lint ;; build) build ;; soc) soc ;; soc-fft) soc_fft ;; implement) implement ;; refresh) refresh ;; quick) lint; refresh ;; *) usage; exit 2 ;; esac