Skip to content

nathanaelhuffman Building FPGA bitstreams #821

nathanaelhuffman Building FPGA bitstreams

nathanaelhuffman Building FPGA bitstreams #821

Workflow file for this run

name: fpga-build
run-name: ${{ github.actor }} Building FPGA bitstreams
on:
[push]
jobs:
detect-changes:
runs-on: self-hosted
outputs:
ice40_bitstreams: ${{ steps.parse.outputs.ice40_bitstreams }}
ecp5_bitstreams: ${{ steps.parse.outputs.ecp5_bitstreams }}
vivado_bitstreams: ${{ steps.parse.outputs.vivado_bitstreams }}
has_changes: ${{ steps.parse.outputs.has_changes }}
# Legacy outputs for cobble job
cobble: ${{ steps.parse.outputs.cobble }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 0 # Need full history
- name: Setup environment
run: |
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
python3 -m pip install --upgrade -r tools/requirements.txt --break-system-packages
- name: Get changed files and base commit
id: changed-files
run: |
# Determine base commit
if [ "${{ github.event_name }}" == "pull_request" ]; then
BASE_COMMIT="${{ github.event.pull_request.base.sha }}"
else
BASE_COMMIT="HEAD~1"
fi
# Generate list of changed files
git diff --name-only "$BASE_COMMIT" HEAD > /tmp/changes.txt
echo "Changed files ($(wc -l < /tmp/changes.txt)):"
head -20 /tmp/changes.txt
echo "base_commit=$BASE_COMMIT" >> "$GITHUB_OUTPUT"
- name: Generate base snapshot
run: |
git checkout ${{ steps.changed-files.outputs.base_commit }}
supertd targets //... > /tmp/base.jsonl
echo "Base snapshot: $(wc -l < /tmp/base.jsonl) targets"
git checkout ${{ github.sha }}
- name: Generate diff snapshot
run: |
supertd targets //... > /tmp/diff.jsonl
echo "Diff snapshot: $(wc -l < /tmp/diff.jsonl) targets"
- name: Run buck2-change-detector
id: btd
continue-on-error: true
run: |
# Note: Requires supertd to be installed
# Install with: cargo install --git https://github.com/facebookincubator/buck2-change-detector.git supertd
echo "Checking for supertd installation..."
which supertd || echo "supertd not found in PATH"
command -v supertd && supertd --version || echo "supertd command failed"
if command -v supertd &> /dev/null; then
echo "Running BTD analysis..."
if supertd btd \
--changes /tmp/changes.txt \
--base /tmp/base.jsonl \
--diff /tmp/diff.jsonl \
--format json > /tmp/btd_output.json 2>&1; then
echo "BTD completed successfully"
# Count targets without jq dependency
TARGETS=$(python3 -c "import json; print(len(json.load(open('/tmp/btd_output.json')).get('targets', [])))" 2>/dev/null || echo "unknown")
echo "Found $TARGETS affected targets"
echo "BTD output preview:"
head -20 /tmp/btd_output.json || true
else
EXIT_CODE=$?
echo "::error::BTD command failed with exit code $EXIT_CODE"
echo "BTD error output:"
cat /tmp/btd_output.json || echo "No output file generated"
echo "::warning::BTD failed, will run all targets"
echo '{"targets": []}' > /tmp/btd_output.json
fi
else
echo "::warning::supertd not installed, will run all targets"
echo "PATH: $PATH"
# Fallback: empty targets means run everything
echo '{"targets": []}' > /tmp/btd_output.json
fi
- name: Parse affected targets
id: parse
run: |
mkdir -p /tmp/btd_results
# Run parser script
python3 .github/scripts/parse-affected-targets.py \
/tmp/btd_output.json \
/tmp/btd_results || {
echo "::warning::Parser failed, creating empty matrices"
# Create empty matrices on failure
for matrix in vunit_matrix bsv_test_matrix ice40_matrix ecp5_matrix vivado_matrix; do
echo '{"target": []}' > /tmp/btd_results/$matrix.json
done
echo '{"total_affected": 0, "vunit_tests": 0, "bsv_tests": 0, "ice40_bitstreams": 0, "ecp5_bitstreams": 0, "vivado_bitstreams": 0}' > /tmp/btd_results/summary.json
}
# Load matrix JSONs and set outputs
echo "ice40_bitstreams=$(cat /tmp/btd_results/ice40_matrix.json)" >> "$GITHUB_OUTPUT"
echo "ecp5_bitstreams=$(cat /tmp/btd_results/ecp5_matrix.json)" >> "$GITHUB_OUTPUT"
echo "vivado_bitstreams=$(cat /tmp/btd_results/vivado_matrix.json)" >> "$GITHUB_OUTPUT"
# Set has_changes flag
TOTAL=$(python3 -c "import json; print(json.load(open('/tmp/btd_results/summary.json'))['total_affected'])" 2>/dev/null || echo "0")
if [ "$TOTAL" -gt 0 ]; then
echo "has_changes=true" >> "$GITHUB_OUTPUT"
else
echo "has_changes=false" >> "$GITHUB_OUTPUT"
fi
# Display summary
cat /tmp/btd_results/summary.json
# VHDL bitstream builds (existing projects using Vivado)
vivado-bitstreams:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.has_changes == 'true' && fromJson(needs.detect-changes.outputs.vivado_bitstreams).target[0] != null }}
runs-on: self-hosted
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.detect-changes.outputs.vivado_bitstreams) }}
steps:
- run: echo "Building Vivado bitstream ${{ matrix.target }} on branch ${{ github.ref }}"
- name: Check out repository code
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Update pip reqs
run: python3 -m pip install --upgrade -r tools/requirements.txt --break-system-packages
- name: Setup PATH
run: echo "$HOME/.cargo/bin:/opt/Xilinx/Vivado/2024.1/bin" >> "$GITHUB_PATH"
- name: Build bitstream
run: buck2 build ${{ matrix.target }} --show-output
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}-image
path: "./buck-out/v2/gen/root/**/*"
- name: Cleanup
run: bash .github/cleanup.sh
# BSV bitstream builds (iCE40 and ECP5)
bsv-ice40-bitstreams:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.has_changes == 'true' && fromJson(needs.detect-changes.outputs.ice40_bitstreams).target[0] != null }}
runs-on: self-hosted
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.detect-changes.outputs.ice40_bitstreams) }}
steps:
- run: echo "Building iCE40 bitstream ${{ matrix.target }} on branch ${{ github.ref }}"
- name: Check out repository code
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Update pip reqs
run: python3 -m pip install --upgrade -r tools/requirements.txt --break-system-packages
- name: Setup PATH
run: |
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
echo "/opt/oss-cad-suite-20250211/bin" >> "$GITHUB_PATH"
- name: Build bitstream
run: buck2 build ${{ matrix.target }} --show-output
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}-image
path: "./buck-out/v2/gen/root/**/*"
- name: Cleanup
run: bash .github/cleanup.sh
bsv-ecp5-bitstreams:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.has_changes == 'true' && fromJson(needs.detect-changes.outputs.ecp5_bitstreams).target[0] != null }}
runs-on: self-hosted
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.detect-changes.outputs.ecp5_bitstreams) }}
steps:
- run: echo "Building ECP5 bitstream ${{ matrix.target }} on branch ${{ github.ref }}"
- name: Check out repository code
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Update pip reqs
run: python3 -m pip install --upgrade -r tools/requirements.txt --break-system-packages
- name: Setup PATH
run: |
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
echo "/opt/oss-cad-suite-20250211/bin" >> "$GITHUB_PATH"
- name: Build bitstream
run: buck2 build ${{ matrix.target }} --show-output
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}-image
path: "./buck-out/v2/gen/root/**/*"
- name: Cleanup
run: bash .github/cleanup.sh