Add GPU arrival time readback for timing-aware VCD output #210
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main, staged-aig-release] | |
| pull_request: | |
| branches: [main, staged-aig-release] | |
| permissions: | |
| contents: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| # Run library unit tests on Linux (no GPU required) | |
| test: | |
| name: Unit Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| - name: Init required submodules | |
| run: git submodule update --init vendor/eda-infra-rs vendor/sky130_fd_sc_hd | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Run library tests | |
| run: cargo test --lib | |
| # Build and run Metal simulation on macOS | |
| metal: | |
| name: Metal Tests (macOS) | |
| runs-on: macos-latest-xlarge | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| - name: Init required submodules | |
| run: git submodule update --init vendor/eda-infra-rs vendor/sky130_fd_sc_hd | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install LLVM (for OpenMP support) | |
| run: | | |
| brew install llvm | |
| LLVM_PREFIX=$(brew --prefix llvm) | |
| echo "CC=${LLVM_PREFIX}/bin/clang" >> $GITHUB_ENV | |
| echo "CXX=${LLVM_PREFIX}/bin/clang++" >> $GITHUB_ENV | |
| # Use Homebrew LLVM's libc++ for linking (not runtime — DYLD_LIBRARY_PATH | |
| # poisons system frameworks). LIBRARY_PATH is used by the compiler for -lc++. | |
| echo "LIBRARY_PATH=${LLVM_PREFIX}/lib/c++:${LLVM_PREFIX}/lib" >> $GITHUB_ENV | |
| LLVM_VER=$(${LLVM_PREFIX}/bin/clang --version | head -1 | grep -o '[0-9]*\.[0-9]*\.[0-9]*') | |
| echo "LLVM_VERSION=$LLVM_VER" >> $GITHUB_ENV | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-metal-llvm${{ env.LLVM_VERSION }}-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-metal-llvm${{ env.LLVM_VERSION }}- | |
| - name: Build jacquard (Metal) | |
| run: cargo build --release --features metal --bin jacquard | |
| - name: Run Metal simulation (timing test) | |
| run: | | |
| # Capture timing output | |
| time (cargo run --release --features metal --bin jacquard -- sim \ | |
| tests/timing_test/dff_test_synth.gv \ | |
| tests/timing_test/dff_test.vcd \ | |
| tests/timing_test/ci_output.vcd \ | |
| 1) 2>&1 | tee metal_timing.txt | |
| - name: Report Metal performance | |
| run: | | |
| { | |
| echo "## Metal Simulation Performance" | |
| echo "\`\`\`" | |
| cat metal_timing.txt | |
| echo "\`\`\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Verify simulation output | |
| run: | | |
| echo "Comparing GEM output with golden VCD..." | |
| # Extract q signal values from both VCDs and compare | |
| # Golden VCD uses 'q' signal, GEM output should match | |
| if diff -q <(grep '^[01]!' tests/timing_test/dff_test.vcd | head -20) \ | |
| <(grep '^[01]!' tests/timing_test/ci_output.vcd | head -20); then | |
| echo "✓ VCD outputs match!" | |
| else | |
| echo "VCD comparison (first 20 signal changes):" | |
| echo "=== Golden (iverilog) ===" | |
| grep '^[01]!' tests/timing_test/dff_test.vcd | head -20 | |
| echo "=== GEM output ===" | |
| grep '^[01]!' tests/timing_test/ci_output.vcd | head -20 | |
| echo "" | |
| echo "Note: Minor differences may be acceptable depending on signal timing" | |
| fi | |
| - name: Run Metal simulation with X-propagation | |
| run: | | |
| cargo run --release --features metal --bin jacquard -- sim \ | |
| tests/timing_test/dff_test_synth.gv \ | |
| tests/timing_test/dff_test.vcd \ | |
| tests/timing_test/ci_xprop_output.vcd \ | |
| 1 --xprop 2>&1 | tee metal_xprop.txt | |
| - name: Verify X-propagation output | |
| run: | | |
| # The dff_test has 1 DFF, so Q should start as X then become known | |
| if grep -q 'x' tests/timing_test/ci_xprop_output.vcd; then | |
| echo "X-propagation VCD contains X values as expected" | |
| else | |
| echo "WARNING: No X values in xprop output VCD" | |
| fi | |
| - name: Run Metal simulation with timing VCD (inv_chain_pnr) | |
| run: | | |
| cargo run --release --features metal --bin jacquard -- sim \ | |
| tests/timing_test/inv_chain_pnr/inv_chain.v \ | |
| tests/timing_test/inv_chain_pnr/inv_chain_stimulus.vcd \ | |
| tests/timing_test/inv_chain_pnr/loom_timed_output.vcd \ | |
| 1 \ | |
| --sdf tests/timing_test/inv_chain_pnr/inv_chain_test_ps.sdf \ | |
| --sdf-corner typ \ | |
| --timing-vcd \ | |
| 2>&1 | tee metal_timed.txt | |
| - name: Upload VCD artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: vcd-outputs | |
| path: | | |
| tests/timing_test/ci_output.vcd | |
| tests/timing_test/ci_xprop_output.vcd | |
| tests/timing_test/inv_chain_pnr/loom_timed_output.vcd | |
| metal_timing.txt | |
| metal_xprop.txt | |
| metal_timed.txt | |
| perf_metrics/ | |
| # Build and run CUDA simulation on NVIDIA GPU | |
| cuda: | |
| name: CUDA Tests | |
| runs-on: nvidia-runner-1 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| - name: Init required submodules | |
| run: git submodule update --init vendor/eda-infra-rs vendor/sky130_fd_sc_hd | |
| - name: Install CUDA Toolkit (driver already present on GPU runner) | |
| run: | | |
| nvidia-smi | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends cuda-toolkit-12-8 | |
| echo "PATH=/usr/local/cuda-12.8/bin:$PATH" >> $GITHUB_ENV | |
| echo "CUDA_PATH=/usr/local/cuda-12.8" >> $GITHUB_ENV | |
| /usr/local/cuda-12.8/bin/nvcc --version | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-cuda-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-cuda- | |
| - name: Build jacquard (CUDA) | |
| run: cargo build --release --features cuda --bin jacquard | |
| - name: Run CUDA simulation (timing test) | |
| run: | | |
| time (cargo run --release --features cuda --bin jacquard -- sim \ | |
| tests/timing_test/dff_test_synth.gv \ | |
| tests/timing_test/dff_test.vcd \ | |
| tests/timing_test/ci_cuda_output.vcd \ | |
| 1) 2>&1 | tee cuda_timing.txt | |
| - name: Report CUDA performance | |
| run: | | |
| { | |
| echo "## CUDA Simulation Performance" | |
| echo "\`\`\`" | |
| cat cuda_timing.txt | |
| echo "\`\`\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Run CUDA simulation with X-propagation | |
| run: | | |
| cargo run --release --features cuda --bin jacquard -- sim \ | |
| tests/timing_test/dff_test_synth.gv \ | |
| tests/timing_test/dff_test.vcd \ | |
| tests/timing_test/ci_cuda_xprop_output.vcd \ | |
| 1 --xprop 2>&1 | tee cuda_xprop.txt | |
| - name: Verify CUDA X-propagation output | |
| run: | | |
| if grep -q 'x' tests/timing_test/ci_cuda_xprop_output.vcd; then | |
| echo "X-propagation VCD contains X values as expected" | |
| else | |
| echo "WARNING: No X values in CUDA xprop output VCD" | |
| fi | |
| - name: Upload CUDA artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: cuda-outputs | |
| path: | | |
| tests/timing_test/ci_cuda_output.vcd | |
| tests/timing_test/ci_cuda_xprop_output.vcd | |
| cuda_timing.txt | |
| cuda_xprop.txt | |
| perf_metrics/ | |
| # Build and run HIP simulation on NVIDIA GPU (HIP's NVIDIA backend) | |
| # This validates the HIP code path using hipcc targeting NVIDIA via HIP_PLATFORM=nvidia. | |
| # When an AMD GPU runner becomes available, a native AMD job can be added. | |
| hip-on-nvidia: | |
| name: HIP Tests (NVIDIA backend) | |
| runs-on: nvidia-runner-1 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| - name: Init required submodules | |
| run: git submodule update --init vendor/eda-infra-rs vendor/sky130_fd_sc_hd | |
| - name: Install CUDA Toolkit (driver already present on GPU runner) | |
| run: | | |
| nvidia-smi | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends cuda-toolkit-12-8 | |
| echo "PATH=/usr/local/cuda-12.8/bin:$PATH" >> $GITHUB_ENV | |
| echo "CUDA_PATH=/usr/local/cuda-12.8" >> $GITHUB_ENV | |
| /usr/local/cuda-12.8/bin/nvcc --version | |
| - name: Install ROCm/HIP (NVIDIA backend) | |
| run: | | |
| # Import ROCm GPG signing key | |
| wget -q -O - https://repo.radeon.com/rocm/rocm.gpg.key | sudo apt-key add - | |
| sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9386B48A1A693C5C 2>/dev/null || true | |
| # Add ROCm repo | |
| CODENAME=$(. /etc/os-release && echo "$VERSION_CODENAME") | |
| echo "deb [arch=amd64] https://repo.radeon.com/rocm/apt/6.2.4 ${CODENAME} main" | \ | |
| sudo tee /etc/apt/sources.list.d/rocm.list | |
| sudo apt-get update | |
| # hip-runtime-nvidia pulls nvidia driver packages that conflict with the | |
| # server-variant drivers pre-installed on the GPU runner. Download the HIP | |
| # .deb files individually and force-install, bypassing driver dep conflicts. | |
| DLDIR=$(mktemp -d) | |
| pushd "$DLDIR" | |
| for pkg in hip-runtime-nvidia hip-dev hipcc-nvidia rocm-core; do | |
| echo "Downloading ${pkg}..." | |
| sudo apt-get download "$pkg" 2>&1 || echo " (skipped: $pkg not available)" | |
| done | |
| echo "Downloaded packages:" | |
| ls -la *.deb 2>/dev/null || { echo "ERROR: No .deb files downloaded!"; exit 1; } | |
| sudo dpkg --force-depends --force-conflicts -i *.deb | |
| popd | |
| # Verify hipcc is available | |
| /opt/rocm/bin/hipcc --version | |
| echo "PATH=/opt/rocm/bin:$PATH" >> $GITHUB_ENV | |
| echo "HIP_PLATFORM=nvidia" >> $GITHUB_ENV | |
| echo "HIP_COMPILER=nvcc" >> $GITHUB_ENV | |
| echo "HIP_RUNTIME=cuda" >> $GITHUB_ENV | |
| echo "LD_LIBRARY_PATH=/opt/rocm/lib:${LD_LIBRARY_PATH:-}" >> $GITHUB_ENV | |
| echo "LIBRARY_PATH=/opt/rocm/lib:${LIBRARY_PATH:-}" >> $GITHUB_ENV | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-hip-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-hip- | |
| - name: Build jacquard (HIP) | |
| run: cargo build --release --features hip --bin jacquard | |
| - name: Run HIP simulation (timing test) | |
| run: | | |
| time (cargo run --release --features hip --bin jacquard -- sim \ | |
| tests/timing_test/dff_test_synth.gv \ | |
| tests/timing_test/dff_test.vcd \ | |
| tests/timing_test/ci_hip_output.vcd \ | |
| 1) 2>&1 | tee hip_timing.txt | |
| - name: Report HIP performance | |
| run: | | |
| { | |
| echo "## HIP (NVIDIA backend) Simulation Performance" | |
| echo "\`\`\`" | |
| cat hip_timing.txt | |
| echo "\`\`\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Run HIP simulation with X-propagation | |
| run: | | |
| cargo run --release --features hip --bin jacquard -- sim \ | |
| tests/timing_test/dff_test_synth.gv \ | |
| tests/timing_test/dff_test.vcd \ | |
| tests/timing_test/ci_hip_xprop_output.vcd \ | |
| 1 --xprop 2>&1 | tee hip_xprop.txt | |
| - name: Verify HIP X-propagation output | |
| run: | | |
| if grep -q 'x' tests/timing_test/ci_hip_xprop_output.vcd; then | |
| echo "X-propagation VCD contains X values as expected" | |
| else | |
| echo "WARNING: No X values in HIP xprop output VCD" | |
| fi | |
| - name: Upload HIP artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: hip-outputs | |
| path: | | |
| tests/timing_test/ci_hip_output.vcd | |
| tests/timing_test/ci_hip_xprop_output.vcd | |
| hip_timing.txt | |
| hip_xprop.txt | |
| perf_metrics/ | |
| # Check formatting and clippy | |
| # Note: Currently set to warn-only due to existing issues in codebase | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| - name: Init required submodules | |
| run: git submodule update --init vendor/eda-infra-rs vendor/sky130_fd_sc_hd | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check || echo "::warning::Formatting issues found" | |
| - name: Clippy | |
| run: cargo clippy --lib 2>&1 | tee clippy_output.txt || true | |
| - name: Check for clippy errors (not warnings) | |
| run: | | |
| if grep -q "^error" clippy_output.txt; then | |
| echo "Clippy errors found!" | |
| exit 1 | |
| fi | |
| # Run benchmarks and track performance | |
| benchmark: | |
| name: Benchmarks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| - name: Init required submodules | |
| run: git submodule update --init vendor/eda-infra-rs | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-bench-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-bench- | |
| - name: Run benchmarks | |
| run: | | |
| cargo bench --bench event_buffer -- --noplot 2>&1 | tee benchmark_results.txt | |
| cargo bench --bench xprop -- --noplot 2>&1 | tee -a benchmark_results.txt | |
| - name: Extract benchmark summary | |
| run: | | |
| { | |
| echo "## Benchmark Results" | |
| echo "\`\`\`" | |
| grep -E "^(event_buffer|buffer_ops|xprop)" benchmark_results.txt | head -30 || true | |
| grep -E "time:" benchmark_results.txt | head -30 || true | |
| echo "\`\`\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload benchmark results | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: benchmark-results | |
| path: benchmark_results.txt | |
| # Run GPU simulation on macOS with pre-built post-P&R netlist | |
| mcu-soc-metal: | |
| name: MCU SoC Metal Simulation | |
| runs-on: macos-latest-xlarge | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| persist-credentials: true | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install LLVM (for OpenMP support) | |
| run: | | |
| brew install llvm | |
| LLVM_PREFIX=$(brew --prefix llvm) | |
| echo "CC=${LLVM_PREFIX}/bin/clang" >> $GITHUB_ENV | |
| echo "CXX=${LLVM_PREFIX}/bin/clang++" >> $GITHUB_ENV | |
| echo "LIBRARY_PATH=${LLVM_PREFIX}/lib/c++:${LLVM_PREFIX}/lib" >> $GITHUB_ENV | |
| LLVM_VER=$(${LLVM_PREFIX}/bin/clang --version | head -1 | grep -o '[0-9]*\.[0-9]*\.[0-9]*') | |
| echo "LLVM_VERSION=$LLVM_VER" >> $GITHUB_ENV | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-mcu-soc-llvm${{ env.LLVM_VERSION }}-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-mcu-soc-llvm${{ env.LLVM_VERSION }}- | |
| - name: Build firmware | |
| run: | | |
| cd designs/mcu_soc_sky130 | |
| uv sync | |
| uv run chipflow software | |
| - name: Generate sim_config.json | |
| run: | | |
| python3 scripts/gen_sim_config.py \ | |
| designs/mcu_soc_sky130/pins.lock tests/mcu_soc/ \ | |
| --netlist tests/mcu_soc/data/6_final.v \ | |
| --firmware designs/mcu_soc_sky130/build/software/software.bin \ | |
| --port-mapping \ | |
| --constant-port por_l=1 \ | |
| --constant-port porb_h=1 \ | |
| --constant-port porb_l=1 \ | |
| --constant-port resetb_h=1 \ | |
| --constant-port resetb_l=1 | |
| - name: Run GPU co-simulation (500K ticks) | |
| timeout-minutes: 30 | |
| run: | | |
| cargo run --release --features metal --bin jacquard -- cosim \ | |
| tests/mcu_soc/data/6_final.v \ | |
| --config tests/mcu_soc/sim_config.json --top-module top \ | |
| --max-cycles 500000 \ | |
| 2>&1 | tee cosim_output.txt | |
| - name: Verify UART boot output | |
| run: | | |
| if grep -q "nyaa" cosim_output.txt; then | |
| echo "MCU SoC booted successfully - UART output detected" | |
| else | |
| echo "FAIL: Expected UART output 'nyaa' not found in cosim output" | |
| echo "--- Last 50 lines of simulation output ---" | |
| tail -50 cosim_output.txt | |
| exit 1 | |
| fi | |
| - name: Strip SDF timing checks for GPU simulation | |
| run: | | |
| # Remove TIMINGCHECK directives from SDF (timing checks can cause parser errors) | |
| uv run tests/mcu_soc/cvc/strip_sdf_checks.py \ | |
| tests/mcu_soc/data/6_final.sdf \ | |
| tests/mcu_soc/data/6_final_stripped.sdf | |
| - name: Capture stimulus + timing VCD via cosim (10K ticks) | |
| timeout-minutes: 15 | |
| run: | | |
| cargo run --release --features metal --bin jacquard -- cosim \ | |
| tests/mcu_soc/data/6_final.v \ | |
| --config tests/mcu_soc/sim_config.json --top-module top \ | |
| --max-cycles 10000 \ | |
| --sdf tests/mcu_soc/data/6_final_stripped.sdf \ | |
| --sdf-corner typ \ | |
| --stimulus-vcd tests/mcu_soc/stimulus.vcd \ | |
| --timing-vcd tests/mcu_soc/loom_timed_mcu.vcd \ | |
| 2>&1 | tee cosim_stimulus.txt | |
| - name: Replay stimulus (non-timed, for CVC comparison) | |
| timeout-minutes: 15 | |
| run: | | |
| set -o pipefail | |
| cargo run --release --features metal --bin jacquard -- sim \ | |
| tests/mcu_soc/data/6_final.v \ | |
| tests/mcu_soc/stimulus.vcd \ | |
| tests/mcu_soc/loom_replay_mcu.vcd \ | |
| 1 \ | |
| --top-module top \ | |
| --max-cycles 10000 \ | |
| 2>&1 | tee metal_mcu_replay.txt | |
| - name: Report simulation results | |
| if: always() | |
| run: | | |
| { | |
| echo "## MCU SoC Metal Co-simulation" | |
| echo "\`\`\`" | |
| tail -20 cosim_output.txt | |
| echo "\`\`\`" | |
| if [ -f metal_mcu_replay.txt ]; then | |
| echo "## MCU SoC Non-timed Replay" | |
| echo "\`\`\`" | |
| tail -20 metal_mcu_replay.txt | |
| echo "\`\`\`" | |
| fi | |
| if [ -f cosim_stimulus.txt ]; then | |
| echo "## MCU SoC Cosim Timing VCD" | |
| echo "\`\`\`" | |
| tail -20 cosim_stimulus.txt | |
| echo "\`\`\`" | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: mcu-soc-results | |
| path: | | |
| cosim_output.txt | |
| cosim_stimulus.txt | |
| metal_mcu_replay.txt | |
| tests/mcu_soc/sim_config.json | |
| tests/mcu_soc/stimulus.vcd | |
| tests/mcu_soc/loom_replay_mcu.vcd | |
| tests/mcu_soc/loom_timed_mcu.vcd | |
| # Build documentation (cargo doc + mdbook) and deploy to GitHub Pages | |
| docs: | |
| name: Documentation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| - name: Init required submodules | |
| run: git submodule update --init vendor/eda-infra-rs vendor/sky130_fd_sc_hd | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-docs-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-docs- | |
| - name: Build cargo docs | |
| run: cargo doc --no-deps --lib | |
| - name: Install mdbook | |
| run: | | |
| mkdir -p ~/.cargo/bin | |
| curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.44/mdbook-v0.4.44-x86_64-unknown-linux-gnu.tar.gz \ | |
| | tar -xz -C ~/.cargo/bin | |
| - name: Build mdbook | |
| run: mdbook build | |
| - name: Prepare Pages site | |
| run: | | |
| cp -r target/doc book/api | |
| touch book/.nojekyll | |
| - name: Deploy to gh-pages branch | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: peaceiris/actions-gh-pages@v4 | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| publish_dir: ./book | |
| # CVC reference simulation for timing correctness validation | |
| cvc-reference: | |
| name: CVC Reference Simulation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Cache CVC binary | |
| id: cache-cvc | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/cvc/bin | |
| key: cvc-binary-debug-v2 | |
| - name: Build CVC from source | |
| if: steps.cache-cvc.outputs.cache-hit != 'true' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends build-essential zlib1g-dev | |
| git clone --depth 1 https://github.com/cambridgehackers/open-src-cvc.git ~/cvc-src | |
| cd ~/cvc-src/src | |
| # Build with -O0: CVC has undefined behavior in SDF annotation code that | |
| # causes segfaults under -O2 optimization (NULL deref after opening SDF file). | |
| make -f makefile.cvc64 -j$(nproc) \ | |
| OPTFLGS="" \ | |
| CFLAGS="-Wall -I../pli_incs -D__RHEL6X__ -fno-pie -no-pie -O0" | |
| mkdir -p ~/cvc/bin | |
| cp cvc64 ~/cvc/bin/ | |
| - name: Add CVC to PATH | |
| run: echo "$HOME/cvc/bin" >> "$GITHUB_PATH" | |
| - name: Run CVC simulation with SDF | |
| working-directory: tests/timing_test/inv_chain_pnr | |
| run: | | |
| echo "=== Running CVC on inv_chain with SDF ===" | |
| # +typdelays selects typical corner; $sdf_annotate in tb_cvc.v loads the SDF file | |
| cvc64 +typdelays tb_cvc.v inv_chain.v 2>&1 | tee cvc_compile.log | |
| # NOTE: CVC must be built with -O0 (debug build). The -O2 optimized build | |
| # triggers undefined behavior in CVC's SDF annotation code, causing a segfault. | |
| ./cvcsim 2>&1 | tee cvc_output.log | |
| echo "" | |
| echo "=== CVC simulation complete ===" | |
| - name: Validate CVC timing results | |
| working-directory: tests/timing_test/inv_chain_pnr | |
| run: | | |
| echo "Checking CVC produced timing results..." | |
| if grep -q "RESULT: total_delay=" cvc_output.log; then | |
| echo "CVC timing results found:" | |
| grep "RESULT:" cvc_output.log | |
| else | |
| echo "ERROR: CVC did not produce expected RESULT: lines" | |
| echo "--- Full CVC output ---" | |
| cat cvc_output.log | |
| exit 1 | |
| fi | |
| - name: Validate CVC timing range | |
| working-directory: tests/timing_test/inv_chain_pnr | |
| run: | | |
| echo "=== Validating CVC timing results ===" | |
| # Compare timing measurements from CVC stdout | |
| # CVC RESULT: lines report IOPATH+INTERCONNECT delays | |
| # Expected: clk_to_q ~350ps, total_delay ~1323ps (IOPATH+wire) | |
| CVC_TOTAL=$(grep "RESULT: total_delay=" cvc_output.log | sed 's/.*=//') | |
| echo "CVC total delay: ${CVC_TOTAL}ps" | |
| # Basic sanity check: total delay should be between 800ps and 2000ps | |
| if [ "$CVC_TOTAL" -gt 800 ] && [ "$CVC_TOTAL" -lt 2000 ]; then | |
| echo "PASS: CVC total delay is in expected range (800-2000ps)" | |
| else | |
| echo "FAIL: CVC total delay ${CVC_TOTAL}ps outside expected range" | |
| exit 1 | |
| fi | |
| - name: Report results | |
| if: always() | |
| run: | | |
| { | |
| echo "## CVC Reference Simulation Results" | |
| echo "" | |
| echo "### CVC Output" | |
| echo "\`\`\`" | |
| cat tests/timing_test/inv_chain_pnr/cvc_output.log 2>/dev/null || echo "No CVC output" | |
| echo "\`\`\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: cvc-reference-results | |
| path: | | |
| tests/timing_test/inv_chain_pnr/cvc_compile.log | |
| tests/timing_test/inv_chain_pnr/cvc_output.log | |
| tests/timing_test/inv_chain_pnr/cvc_inv_chain_output.vcd | |
| # Compare timing results between CVC (event-driven) and Loom (GPU) | |
| timing-comparison: | |
| name: Timing Comparison (CVC vs Loom) | |
| runs-on: ubuntu-latest | |
| needs: [metal, cvc-reference] | |
| if: always() && needs.metal.result == 'success' && needs.cvc-reference.result == 'success' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: astral-sh/setup-uv@v4 | |
| - name: Download Metal artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: vcd-outputs | |
| path: metal-results/ | |
| - name: Download CVC artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cvc-reference-results | |
| path: cvc-results/ | |
| - name: Compare timing | |
| run: | | |
| uv run scripts/compare_timing.py \ | |
| --cvc-log cvc-results/tests/timing_test/inv_chain_pnr/cvc_output.log \ | |
| --cvc-vcd cvc-results/tests/timing_test/inv_chain_pnr/cvc_inv_chain_output.vcd \ | |
| --loom-vcd metal-results/tests/timing_test/inv_chain_pnr/loom_timed_output.vcd \ | |
| --clock-period-ps 10000 \ | |
| --clock-signal CLK \ | |
| --output-signal Q \ | |
| --output-json timing_comparison.json \ | |
| 2>&1 | tee comparison.txt | |
| - name: Report | |
| if: always() | |
| run: | | |
| { | |
| echo "## Timing Comparison (CVC vs Loom)" | |
| echo "" | |
| echo "\`\`\`" | |
| cat comparison.txt 2>/dev/null || echo "No comparison output" | |
| echo "\`\`\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: timing-comparison-results | |
| path: | | |
| timing_comparison.json | |
| comparison.txt | |
| # CVC SDF-annotated simulation of MCU SoC for timing correctness validation | |
| mcu-soc-cvc: | |
| name: MCU SoC CVC Reference | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| needs: [mcu-soc-metal] | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: false | |
| - name: Init required submodules | |
| run: git submodule update --init vendor/sky130_fd_sc_hd | |
| - uses: astral-sh/setup-uv@v4 | |
| - name: Cache CVC binary | |
| id: cache-cvc | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/cvc/bin | |
| key: cvc-binary-debug-v2 | |
| - name: Build CVC from source | |
| if: steps.cache-cvc.outputs.cache-hit != 'true' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends build-essential zlib1g-dev | |
| git clone --depth 1 https://github.com/cambridgehackers/open-src-cvc.git ~/cvc-src | |
| cd ~/cvc-src/src | |
| make -f makefile.cvc64 -j$(nproc) \ | |
| OPTFLGS="" \ | |
| CFLAGS="-Wall -I../pli_incs -D__RHEL6X__ -fno-pie -no-pie -O0" | |
| mkdir -p ~/cvc/bin | |
| cp cvc64 ~/cvc/bin/ | |
| - name: Add CVC to PATH | |
| run: echo "$HOME/cvc/bin" >> "$GITHUB_PATH" | |
| - name: Download Metal artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: mcu-soc-results | |
| path: metal-results/ | |
| - name: Generate cell models | |
| run: uv run tests/mcu_soc/cvc/gen_cell_models.py | |
| - name: Strip SDF timing checks | |
| run: | | |
| uv run tests/mcu_soc/cvc/strip_sdf_checks.py \ | |
| tests/mcu_soc/data/6_final.sdf \ | |
| tests/mcu_soc/cvc/6_final_nocheck.sdf | |
| - name: Convert stimulus to Verilog | |
| run: | | |
| uv run tests/mcu_soc/cvc/convert_stimulus.py \ | |
| metal-results/tests/mcu_soc/stimulus.vcd \ | |
| tests/mcu_soc/cvc/stimulus_gen.v \ | |
| --config metal-results/tests/mcu_soc/sim_config.json | |
| - name: Run CVC simulation | |
| timeout-minutes: 45 | |
| working-directory: tests/mcu_soc/cvc | |
| run: | | |
| ln -sf ../data/6_final.v . | |
| cvc64 +typdelays tb_cvc.v sky130_cells.v cf_sram.v 6_final.v \ | |
| 2>&1 | tee cvc_compile.log | |
| ./cvcsim 2>&1 | tee cvc_sim.log | |
| - name: Report results | |
| if: always() | |
| run: | | |
| { | |
| echo "## MCU SoC CVC Reference Simulation" | |
| echo "" | |
| echo "### CVC Compilation" | |
| echo "\`\`\`" | |
| tail -20 tests/mcu_soc/cvc/cvc_compile.log 2>/dev/null || echo "No compile output" | |
| echo "\`\`\`" | |
| echo "" | |
| echo "### CVC Simulation" | |
| echo "\`\`\`" | |
| tail -20 tests/mcu_soc/cvc/cvc_sim.log 2>/dev/null || echo "No sim output" | |
| echo "\`\`\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: mcu-soc-cvc-results | |
| path: | | |
| tests/mcu_soc/cvc/cvc_compile.log | |
| tests/mcu_soc/cvc/cvc_sim.log | |
| tests/mcu_soc/cvc/cvc_output.vcd | |
| # Compare MCU SoC results between CVC (event-driven) and Loom (GPU) | |
| mcu-soc-comparison: | |
| name: MCU SoC Functional Comparison | |
| runs-on: ubuntu-latest | |
| needs: [mcu-soc-metal, mcu-soc-cvc] | |
| if: always() && needs.mcu-soc-metal.result == 'success' && needs.mcu-soc-cvc.result == 'success' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: astral-sh/setup-uv@v4 | |
| - name: Download Metal artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: mcu-soc-results | |
| path: metal-results/ | |
| - name: Download CVC artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: mcu-soc-cvc-results | |
| path: cvc-results/ | |
| - name: Compare outputs (non-timed Loom vs CVC) | |
| run: | | |
| LOOM_VCD="metal-results/tests/mcu_soc/loom_replay_mcu.vcd" | |
| CVC_VCD="cvc-results/cvc_output.vcd" | |
| if [ ! -f "$LOOM_VCD" ]; then | |
| echo "SKIP: Loom replay VCD not found" | tee mcu_comparison.txt | |
| exit 0 | |
| fi | |
| if [ ! -f "$CVC_VCD" ]; then | |
| echo "SKIP: CVC output VCD not found (CVC simulation may have failed)" | tee mcu_comparison.txt | |
| exit 0 | |
| fi | |
| LOOM_TIMING_VCD="metal-results/tests/mcu_soc/loom_timed_mcu.vcd" | |
| TIMING_ARGS="" | |
| if [ -f "$LOOM_TIMING_VCD" ]; then | |
| TIMING_ARGS="--loom-timing-vcd $LOOM_TIMING_VCD" | |
| fi | |
| uv run tests/mcu_soc/cvc/compare_simulation.py \ | |
| "$LOOM_VCD" "$CVC_VCD" \ | |
| --skip-cycles 5 \ | |
| --num-cycles 10000 \ | |
| --skip-bits 0-5 \ | |
| --config metal-results/tests/mcu_soc/sim_config.json \ | |
| $TIMING_ARGS \ | |
| 2>&1 | tee mcu_comparison.txt | |
| - name: Report | |
| if: always() | |
| run: | | |
| { | |
| echo "## MCU SoC Simulation Comparison (CVC vs Loom)" | |
| echo "" | |
| echo "\`\`\`" | |
| cat mcu_comparison.txt 2>/dev/null || echo "No comparison output" | |
| echo "\`\`\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: mcu-soc-comparison-results | |
| path: mcu_comparison.txt |