Skip to content

v0.33-C: SYNC + AGENT profile-specific commit paths (no more stubs) #362

v0.33-C: SYNC + AGENT profile-specific commit paths (no more stubs)

v0.33-C: SYNC + AGENT profile-specific commit paths (no more stubs) #362

Workflow file for this run

name: ATOMiK CI/CD
on:
push:
branches: [main, develop, 'phase/**']
pull_request:
branches: [main, develop]
schedule:
# Weekly: Monday 06:00 UTC (Sunday 11pm Pacific) — keeps badges green
- cron: '0 6 * * 1'
workflow_dispatch:
inputs:
phase:
description: 'Phase to execute (1-4 or all)'
required: true
default: 'all'
permissions:
contents: write
pull-requests: write
issues: write
jobs:
# ===========================================================================
# CORE VALIDATION — runs on every push/PR
# ===========================================================================
validate:
name: Python Lint & Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ./software[dev] || pip install -e ./software
- name: Install atomik_core
run: |
pip install -e ./software/atomik_core
- name: Run linting
run: |
pip install ruff
ruff check software/atomik_sdk/
ruff check software/atomik_core/
- name: Run unit tests
run: |
pip install pytest pytest-cov
pytest software/tests/ software/atomik_sdk/tests/ -v --tb=short --cov=atomik_sdk --cov-report=xml
- name: Run atomik_core tests
run: |
cd software/atomik_core
pytest tests/ -v --tb=short
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
fail_ci_if_error: false
# ===========================================================================
# VERILOG SIMULATION — runs on every push/PR (ungated)
# ===========================================================================
verilog-sim:
name: Verilog Simulation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Verilog tools
run: |
sudo apt-get update
sudo apt-get install -y iverilog verilator
- name: Run Zynq CDC testbench (37 tests)
run: |
echo "=== Zynq CDC + AXI4-Lite Wrapper Tests ==="
cd hardware/zynq
# Phase A RTL only (accelerator path — no v3 CPU deps)
iverilog -o sim_cdc_wrapper \
-DSIMULATION \
-I rtl \
rtl/atomik_axi4lite_wrapper.v \
rtl/atomik_cdc_bridge.v \
rtl/atomik_core_zynq.v \
rtl/atomik_core_zynq_parallel.v \
rtl/atomik_zynq_clk.v \
rtl/atomik_zynq_top.v \
sim/tb_cdc_wrapper.v \
2>&1 | tee /tmp/zynq_compile.log
if [ $? -ne 0 ]; then
echo "::error::Zynq CDC testbench failed to compile"
exit 1
fi
vvp sim_cdc_wrapper 2>&1 | tee /tmp/zynq_sim.log
# Check for explicit pass/fail
if grep -q "ALL TESTS PASSED" /tmp/zynq_sim.log; then
echo "::notice::Zynq CDC tests passed (37/37)"
elif grep -q "TESTS FAILED\|TIMEOUT" /tmp/zynq_sim.log; then
echo "::error::Zynq CDC testbench had failures"
exit 1
else
echo "::error::Zynq CDC testbench did not produce a summary"
exit 1
fi
- name: Run Zynq parallel bank testbench (N=4, 10 tests)
run: |
echo "=== Zynq Parallel Bank Tests (N_BANKS=4) ==="
cd hardware/zynq
iverilog -o sim_parallel_banks \
-DSIMULATION \
-I rtl \
rtl/atomik_axi4lite_wrapper.v \
rtl/atomik_cdc_bridge.v \
rtl/atomik_core_zynq.v \
rtl/atomik_core_zynq_parallel.v \
rtl/atomik_zynq_clk.v \
rtl/atomik_zynq_top.v \
sim/tb_parallel_banks.v \
2>&1 | tee /tmp/zynq_parallel_compile.log
if [ $? -ne 0 ]; then
echo "::error::Zynq parallel testbench failed to compile"
exit 1
fi
vvp sim_parallel_banks 2>&1 | tee /tmp/zynq_parallel_sim.log
if grep -q "ALL TESTS PASSED" /tmp/zynq_parallel_sim.log; then
echo "::notice::Zynq parallel bank tests passed (10/10)"
elif grep -q "TESTS FAILED\|TIMEOUT" /tmp/zynq_parallel_sim.log; then
echo "::error::Zynq parallel testbench had failures"
exit 1
else
echo "::error::Zynq parallel testbench did not produce a summary"
exit 1
fi
- name: Run Zynq co-processor testbench (13 tests)
run: |
echo "=== Zynq Co-Processor Tests (Phase B: RV64I + mailbox) ==="
cd hardware/zynq
iverilog -o sim_coprocessor \
-DSIMULATION \
rtl/atomik_coprocessor_top.v \
rtl/atomik_v3_cpu_zynq.v \
rtl/atomik_v3_regfile_zynq.v \
rtl/atomik_v3_atomik_zynq.v \
rtl/atomik_v3_bus_to_axi.v \
rtl/atomik_mailbox.v \
../v3/rtl/atomik_v3_alu.v \
../v3/rtl/atomik_v3_branch.v \
../v3/rtl/atomik_v3_control.v \
../v3/rtl/atomik_v3_csr.v \
../v3/rtl/atomik_v3_decode.v \
../v3/rtl/atomik_v3_fetch.v \
../v3/rtl/atomik_v3_lsu.v \
sim/tb_coprocessor.v \
2>&1 | tee /tmp/zynq_coproc_compile.log
if [ $? -ne 0 ]; then
echo "::error::Zynq co-processor testbench failed to compile"
exit 1
fi
vvp sim_coprocessor 2>&1 | tee /tmp/zynq_coproc_sim.log
if grep -q "ALL TESTS PASSED" /tmp/zynq_coproc_sim.log; then
echo "::notice::Zynq co-processor tests passed (13/13)"
elif grep -q "TESTS FAILED\|TIMEOUT" /tmp/zynq_coproc_sim.log; then
echo "::error::Zynq co-processor testbench had failures"
exit 1
else
echo "::error::Zynq co-processor testbench did not produce a summary"
exit 1
fi
- name: Run ASIC BIST testbench (10 tests)
run: |
echo "=== ASIC BIST + Functional Tests ==="
cd hardware/asic
iverilog -DSIMULATION -o sim_asic_top \
sim/tb_asic_top.v \
rtl/atomik_asic_top.v \
rtl/atomik_core_asic.v \
rtl/atomik_sram_dp.v \
rtl/atomik_bist.v \
rtl/atomik_dft_wrapper.v \
2>&1 | tee /tmp/asic_compile.log
if [ $? -ne 0 ]; then
echo "::error::ASIC testbench failed to compile"
exit 1
fi
vvp sim_asic_top 2>&1 | tee /tmp/asic_sim.log
if grep -q "All tests passed" /tmp/asic_sim.log; then
echo "::notice::ASIC BIST + functional tests passed (10/10)"
else
echo "::error::ASIC testbench had failures"
exit 1
fi
rm -f sim_asic_top
- name: Verilator lint check (ASIC RTL)
run: |
echo "=== Verilator Lint: ASIC RTL ==="
verilator --lint-only -Wall --top-module atomik_asic_top \
hardware/asic/rtl/atomik_asic_top.v \
hardware/asic/rtl/atomik_core_asic.v \
hardware/asic/rtl/atomik_sram_dp.v \
hardware/asic/rtl/atomik_bist.v \
hardware/asic/rtl/atomik_dft_wrapper.v
echo "::notice::ASIC RTL lint clean (0 warnings)"
- name: Run ATOMiK Core C library tests (14 tests)
run: |
echo "=== ATOMiK Core C Library ==="
cd software/atomik_core_c
gcc -o test_atomik_core test_atomik_core.c -Wall -Wextra -O2
./test_atomik_core
rm -f test_atomik_core
- name: Run v3 iverilog testbenches
run: |
echo "=== v3 RTL iverilog Tests ==="
PASS=0
FAIL=0
for tb in hardware/v3/sim/iverilog/tb_*.v; do
name=$(basename "$tb" .v)
echo "--- Running $name ---"
# Compile with all RTL sources
# Build source list: rtl/*.v + only sim-safe soc modules (exclude BRAM-dependent files)
SOC_SAFE=""
for sv in hardware/v3/soc/*.v; do
# Skip files that instantiate synthesis-only primitives (bootram, BRAM, etc.)
if ! grep -q 'bootram_\|Gowin_\|SDP_\|pROM' "$sv" 2>/dev/null; then
SOC_SAFE="$SOC_SAFE $sv"
fi
done
if iverilog -o "hardware/v3/sim/iverilog/${name}" \
-I hardware/v3/rtl \
-I hardware/v3/soc \
hardware/v3/rtl/*.v \
$SOC_SAFE \
"$tb" 2>&1; then
if vvp "hardware/v3/sim/iverilog/${name}" 2>&1 | tee /tmp/${name}.log; then
if grep -qi "FAIL\|ERROR" /tmp/${name}.log && ! grep -qi "0 failed\|ALL.*PASS" /tmp/${name}.log; then
echo "::warning::$name had potential failures"
FAIL=$((FAIL + 1))
else
PASS=$((PASS + 1))
fi
else
echo "::error::$name simulation crashed"
FAIL=$((FAIL + 1))
fi
else
echo "::error::$name failed to compile"
FAIL=$((FAIL + 1))
fi
done
echo ""
echo "=== v3 Testbench Summary: $PASS passed, $FAIL failed ==="
# Known issues:
# - tb_spimemio: accumulator persistence assertion failures (flash SPI model)
# - tb_v3_atomik: tests 15-16 fail (acc persistence across multi-context SWAP —
# v3 core limitation, Zynq core handles this correctly with 4-stage pipeline)
KNOWN_FAILS="tb_spimemio tb_v3_atomik"
REAL_FAIL=0
if [ "$FAIL" -gt 0 ]; then
echo "::warning::$FAIL testbench(es) failed — checking if known issues..."
# Only fail CI if non-known testbenches failed
for tb in hardware/v3/sim/iverilog/tb_*.v; do
name=$(basename "$tb" .v)
if echo "$KNOWN_FAILS" | grep -q "$name"; then continue; fi
if [ -f "/tmp/${name}.log" ] && grep -qi "FAIL\|ERROR" "/tmp/${name}.log" && ! grep -qi "0 failed\|ALL.*PASS" "/tmp/${name}.log"; then
REAL_FAIL=$((REAL_FAIL + 1))
fi
done
if [ "$REAL_FAIL" -gt 0 ]; then
echo "::error::$REAL_FAIL unexpected test failure(s)"
exit 1
else
echo "All failures are known issues — CI passes"
fi
fi
# ===========================================================================
# SDK VALIDATION — runs on every push/PR (ungated)
# ===========================================================================
sdk-validate:
name: SDK Validation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install SDK
run: |
python -m pip install --upgrade pip
pip install -e ./software[dev] || pip install -e ./software
pip install -e ./software/atomik_core || true
pip install pytest
- name: Discover and run all SDK tests
run: |
echo "=== SDK Test Discovery ==="
# Find all test directories
TEST_DIRS=$(find software -type f -name "test_*.py" -exec dirname {} \; | sort -u)
echo "Found test directories:"
echo "$TEST_DIRS"
echo ""
# Run pytest across all discovered test locations
pytest $TEST_DIRS -v --tb=short 2>&1 | tee /tmp/sdk_results.log
- name: SDK import smoke test
run: |
python -c "
import atomik_sdk
print(f'SDK version: {getattr(atomik_sdk, \"__version__\", \"dev\")}')
print('SDK import: OK')
" || echo "::warning::SDK import check had issues"
- name: atomik_core import smoke test
run: |
python -c "
import atomik_core
print(f'atomik_core version: {atomik_core.__version__}')
from atomik_core import AtomikContext, AtomikTable, Fingerprint
ctx = AtomikContext()
ctx.load(0xDEADBEEF)
ctx.accum(0xFF)
assert ctx.read() == 0xDEADBEEF ^ 0xFF
print('atomik_core import + smoke test: OK')
"
- name: atomik_core CLI smoke test
run: |
python -m atomik_core version
# ===========================================================================
# GATED JOBS — triggered by commit message tags
# ===========================================================================
proof-check:
name: Lean4 Proof Verification
needs: validate
if: >-
contains(github.event.head_commit.message, '[proof]') ||
github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Lean4
run: |
curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh -s -- -y
echo "$HOME/.elan/bin" >> $GITHUB_PATH
- name: Verify Lean4 proofs
run: |
if [ -d "math/proofs" ]; then
cd math/proofs && lake build
else
echo "::error::math/proofs directory not found"
exit 1
fi
benchmark:
name: Benchmark Suite
needs: validate
if: >-
contains(github.event.head_commit.message, '[benchmark]') ||
github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ./software[dev] || pip install -e ./software
pip install numpy scipy matplotlib
- name: Execute benchmark suite
run: |
if [ -d "hardware/experiments/benchmarks" ]; then
python hardware/experiments/benchmarks/run_all.py \
--output math/benchmarks/results/benchmark_results.json \
|| echo "::warning::Benchmark script encountered issues"
else
echo "::notice::No benchmark directory found, skipping"
fi
- name: Upload benchmark results
uses: actions/upload-artifact@v4
with:
name: benchmark-results
path: math/benchmarks/results/
retention-days: 30
if-no-files-found: ignore
synthesis:
name: Synthesis & RTL Lint
needs: validate
if: >-
contains(github.event.head_commit.message, '[synthesis]') ||
github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Verilog tools
run: |
sudo apt-get update
sudo apt-get install -y verilator iverilog
- name: Verilog lint and simulation
run: |
echo "=== Verilator Lint ==="
if [ -d "hardware/rtl" ]; then
verilator --lint-only hardware/rtl/*.v 2>&1 || echo "::warning::Lint warnings in hardware/rtl"
fi
if [ -d "hardware/v3/rtl" ]; then
verilator --lint-only -Ihardware/v3/rtl hardware/v3/rtl/*.v 2>&1 || echo "::warning::Lint warnings in hardware/v3/rtl"
fi
# ===========================================================================
# V3 RTL JOBS — triggered by [v3] or [rtl] tags
# ===========================================================================
v3-rtl-lint:
name: v3 RTL Lint
runs-on: ubuntu-latest
if: >-
contains(github.event.head_commit.message, '[v3]') ||
contains(github.event.head_commit.message, '[rtl]') ||
github.event_name == 'schedule'
steps:
- uses: actions/checkout@v4
- name: Install Verilog tools
run: |
sudo apt-get update
sudo apt-get install -y verilator iverilog
- name: Verilator lint
run: make -C hardware/v3 lint
- name: iverilog smoke tests
run: make -C hardware/v3 sim-iverilog
v3-compliance:
name: v3 RISC-V Compliance
runs-on: ubuntu-latest
if: >-
contains(github.event.head_commit.message, '[compliance]') ||
contains(github.event.head_commit.message, '[v3]') ||
github.event_name == 'schedule'
steps:
- uses: actions/checkout@v4
- name: Install tools
run: |
sudo apt-get update
sudo apt-get install -y verilator gcc-riscv64-unknown-elf
- name: RISC-V compliance tests
run: make -C hardware/v3 compliance
# ===========================================================================
# DOCUMENTATION — main branch only
# ===========================================================================
deploy-docs:
name: Deploy Documentation
needs: validate
if: github.ref == 'refs/heads/main' && github.event_name != 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ./software[dev] || pip install -e ./software
- name: Generate documentation
run: |
pip install pdoc3
if [ -d "software/atomik_sdk" ]; then
pdoc --html --output-dir docs/api software/atomik_sdk
fi
- name: Generate demo site
run: |
pip install rich
python -m software.demos.state_sync_benchmark || true
python demos/web/export/generate_static.py || true
- name: Deploy to GitHub Pages
# gh-pages pushes occasionally hit transient 5xx errors from
# GitHub. Don't let that fail an otherwise green build — the docs
# site catches up on the next push that actually changed anything.
continue-on-error: true
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
# ===========================================================================
# HARDWARE VALIDATION — self-hosted runner (gated)
# ===========================================================================
hardware-validate:
name: FPGA Hardware Validation
needs: validate
if: contains(github.event.head_commit.message, '[hardware]')
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- name: Run FPGA pipeline
run: python hardware/scripts/fpga_pipeline.py --report hw_results.json
- name: Upload hardware results
uses: actions/upload-artifact@v4
with:
name: hardware-validation
path: hw_results.json