diff options
Diffstat (limited to 'rv64cpu/scripts')
| -rw-r--r-- | rv64cpu/scripts/.gitkeep | 0 | ||||
| -rwxr-xr-x | rv64cpu/scripts/gen_hex.sh | 25 | ||||
| -rwxr-xr-x | rv64cpu/scripts/run_compliance.py | 120 | ||||
| -rwxr-xr-x | rv64cpu/scripts/wave_view.sh | 25 |
4 files changed, 170 insertions, 0 deletions
diff --git a/rv64cpu/scripts/.gitkeep b/rv64cpu/scripts/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/rv64cpu/scripts/.gitkeep diff --git a/rv64cpu/scripts/gen_hex.sh b/rv64cpu/scripts/gen_hex.sh new file mode 100755 index 0000000..8ba4c94 --- /dev/null +++ b/rv64cpu/scripts/gen_hex.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# ─── gen_hex.sh ────────────────────────────────────────────────────────────────── +# Convert an ELF file to Verilog hex format for $readmemh +# +# Usage: ./scripts/gen_hex.sh <input.elf> [output.hex] +# ───────────────────────────────────────────────────────────────────────────────── +set -euo pipefail + +CROSS_PREFIX="${CROSS_PREFIX:-riscv64-unknown-elf-}" + +if [ $# -lt 1 ]; then + echo "Usage: $0 <input.elf> [output.hex]" + exit 1 +fi + +INPUT="$1" +OUTPUT="${2:-${INPUT%.elf}.hex}" + +${CROSS_PREFIX}objcopy -O verilog "$INPUT" "$OUTPUT" +echo "[gen_hex] $INPUT → $OUTPUT" + +# Also generate .bin and disassembly for inspection +${CROSS_PREFIX}objcopy -O binary "$INPUT" "${INPUT%.elf}.bin" +${CROSS_PREFIX}objdump -d -M no-aliases "$INPUT" > "${INPUT%.elf}.dump" +echo "[gen_hex] Also generated .bin and .dump" diff --git a/rv64cpu/scripts/run_compliance.py b/rv64cpu/scripts/run_compliance.py new file mode 100755 index 0000000..92456ec --- /dev/null +++ b/rv64cpu/scripts/run_compliance.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +""" +run_compliance.py — riscv-arch-test 自动化运行脚本 + +Usage: + python3 scripts/run_compliance.py --suite rv64i + python3 scripts/run_compliance.py --suite rv64im --build-dir build + python3 scripts/run_compliance.py --list + +Requirements: + - Verilator simulation binary built (tb_soc or compliance_runner) + - riscv64-unknown-elf-gcc toolchain in PATH + - sw/riscv-arch-test submodule initialized +""" + +import argparse +import subprocess +import sys +import os +from pathlib import Path + +PROJECT_ROOT = Path(__file__).resolve().parent.parent +ARCH_TEST_DIR = PROJECT_ROOT / "sw" / "riscv-arch-test" +BUILD_DIR = PROJECT_ROOT / "build" + +SUITES = { + "rv64i": "riscv-test-suite/rv64i_m/I", + "rv64im": "riscv-test-suite/rv64i_m/M", + "rv64ia": "riscv-test-suite/rv64i_m/A", + "rv64if": "riscv-test-suite/rv64i_m/F", + "rv64id": "riscv-test-suite/rv64i_m/D", + "rv64ic": "riscv-test-suite/rv64i_m/C", + "rv64priv": "riscv-test-suite/rv64i_m/privilege", +} + + +def list_suites(): + print("Available test suites:") + for name, path in SUITES.items(): + exists = "✓" if (ARCH_TEST_DIR / path).exists() else "✗ (not found)" + print(f" {name:12s} → {path} {exists}") + + +def run_suite(suite_name: str, build_dir: Path, sim_binary: str, verbose: bool): + if suite_name not in SUITES: + print(f"Unknown suite: {suite_name}") + print(f"Available: {', '.join(SUITES.keys())}") + sys.exit(1) + + suite_path = ARCH_TEST_DIR / SUITES[suite_name] + if not suite_path.exists(): + print(f"Suite path not found: {suite_path}") + print("Did you initialize the submodule?") + print(" git submodule update --init --recursive") + sys.exit(1) + + sim_bin = build_dir / sim_binary + if not sim_bin.exists(): + print(f"Simulation binary not found: {sim_bin}") + print("Build it first: cmake --build build --target compliance_runner") + sys.exit(1) + + test_files = sorted(suite_path.glob("src/*.S")) + if not test_files: + print(f"No test sources found in {suite_path / 'src'}") + sys.exit(1) + + print(f"\n{'='*60}") + print(f"Running {suite_name} compliance tests ({len(test_files)} tests)") + print(f"{'='*60}\n") + + passed = 0 + failed = 0 + errors = [] + + for test_file in test_files: + test_name = test_file.stem + if verbose: + print(f" [{test_name}] ", end="", flush=True) + + # TODO: Implement actual test compilation and simulation + # This is a skeleton — fill in with your specific flow: + # 1. Compile test_file with riscv64-unknown-elf-gcc + # 2. Run the sim binary with the compiled ELF + # 3. Compare signature output against reference + if verbose: + print("⏭ SKIP (runner not yet implemented)") + + print(f"\n{'='*60}") + print(f"Results: {passed} passed, {failed} failed, {len(test_files) - passed - failed} skipped") + print(f"{'='*60}\n") + + return failed == 0 + + +def main(): + parser = argparse.ArgumentParser(description="Run riscv-arch-test compliance tests") + parser.add_argument("--suite", type=str, help="Test suite to run") + parser.add_argument("--build-dir", type=str, default="build", help="Build directory") + parser.add_argument("--sim", type=str, default="compliance_runner", help="Sim binary name") + parser.add_argument("--list", action="store_true", help="List available suites") + parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output") + + args = parser.parse_args() + + if args.list: + list_suites() + return + + if not args.suite: + parser.print_help() + sys.exit(1) + + build_dir = Path(args.build_dir) + success = run_suite(args.suite, build_dir, args.sim, args.verbose) + sys.exit(0 if success else 1) + + +if __name__ == "__main__": + main() diff --git a/rv64cpu/scripts/wave_view.sh b/rv64cpu/scripts/wave_view.sh new file mode 100755 index 0000000..5a3a6e4 --- /dev/null +++ b/rv64cpu/scripts/wave_view.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# ─── wave_view.sh ──────────────────────────────────────────────────────────────── +# Open a VCD/FST waveform file in GTKWave +# +# Usage: ./scripts/wave_view.sh [waveform_file] +# ./scripts/wave_view.sh # opens latest .vcd in waves/ +# ───────────────────────────────────────────────────────────────────────────────── +set -euo pipefail + +WAVES_DIR="$(dirname "$0")/../waves" +VIEWER="${WAVE_VIEWER:-gtkwave}" + +if [ $# -ge 1 ]; then + WAVE_FILE="$1" +else + # Open the most recently modified waveform file + WAVE_FILE=$(ls -t "$WAVES_DIR"/*.vcd "$WAVES_DIR"/*.fst 2>/dev/null | head -1) + if [ -z "$WAVE_FILE" ]; then + echo "No waveform files found in $WAVES_DIR" + exit 1 + fi +fi + +echo "[wave_view] Opening: $WAVE_FILE" +$VIEWER "$WAVE_FILE" & |
