aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'rv64cpu/scripts')
-rw-r--r--rv64cpu/scripts/.gitkeep0
-rwxr-xr-xrv64cpu/scripts/gen_hex.sh25
-rwxr-xr-xrv64cpu/scripts/run_compliance.py120
-rwxr-xr-xrv64cpu/scripts/wave_view.sh25
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" &