| name | bitstream-program |
| description | Generate a bitstream and program a Xilinx FPGA over JTAG, or build an MCS image and burn it into SPI/BPI configuration flash for power-on boot. Invoke when the user says "program the board", "generate bitstream", "flash the device", "download to FPGA", "burn the flash", "load my design onto the board", "make a .mcs / .bit", or "why won't my board come up after power cycle". Covers the full hand-off from a routed implementation to live silicon: DRC + route + timing sign-off gating, .bit generation, hardware-server / JTAG connect, volatile JTAG download, and non-volatile flash programming (generate_mcs + add_flash_configuration + program_flash). Requires the SynthPilot MCP server with Vivado running and the Tcl server connected; flash / JTAG steps additionally require a physical board cabled to the host (or reachable through a remote hw_server).
|
Bitstream Generation & Device Programming
A methodology playbook for taking a routed implementation all the way to
live silicon โ either a volatile JTAG download (lost on power cycle) or a
non-volatile flash burn (boots on power-up). Programming hardware is a one-way,
physical action: this skill is deliberately conservative. It refuses to fabricate
a "programmed OK" claim, refuses to skip sign-off gates, and hands control back
to the human at every ambiguous fork (which device, which flash part, which
boot mode).
This skill is a strategy layer over the SynthPilot MCP server. It does not
write code; it decides which real tools to call, in what order, and when to STOP.
When to use
- User wants a
.bit produced from the current implemented design.
- User wants to download a design to a board over JTAG for a bench test
(volatile โ gone after power cycle).
- User wants to flash the design (
.mcs/.bin) into SPI/BPI configuration
memory so the FPGA boots it automatically on power-up.
- User reports a board that "doesn't come up after power cycle" (almost always a
flash / boot-mode issue, not a JTAG issue).
- User wants an
.xsa hand-off to Vitis (export hardware with bitstream).
When NOT to use
- Timing is not met / design is not routed. A
.bit from a design with
setup/hold violations may program but will behave non-deterministically. Close
timing first (use the timing-closure skill). Do not generate a sign-off
bitstream over an open WNS violation without an explicit, stated user override.
- Synthesis/implementation has not run or is stale relative to the RTL.
Generating a bitstream does not re-run P&R; it ships whatever is in the run.
Run/refresh implementation first.
- Debug-core insertion (ILA/VIO) โ that belongs to the debug/instrumentation
skill. This skill only consumes an already-inserted
.ltx probes file.
- Pure simulation requests โ use the simulation skill.
- Block-design / IP build โ use the block-design skill; come back here once a
routed implementation exists.
Prerequisites (verify first)
Do not assume state. Probe it with real tools before acting.
- MCP / Vivado / Tcl bridge alive โ
test_connection. If this fails,
nothing downstream can work; stop and tell the user to start Vivado and the
Tcl server.
- A project is open and is the right one โ
get_project_info. Confirm the
part/board matches what the user intends to program. The wrong part silently
produces a bitstream the device will reject.
- Implementation is complete and current โ
get_run_status. The
implementation run must be route_design Complete (or equivalent "routed").
If it is synth-only, out of date, or failed, the design is not ready โ
go run/finish implementation (see Methodology step 1) before any bitstream.
- For any JTAG/flash step: a board is physically present. This cannot be
inferred from software state alone. The hardware-manager connect chain
(Methodology step 5) is what discovers it; if no target appears, STOP and ask
the user to plug in / power on the board and check the cable.
State everything you found before proceeding. If a prerequisite is missing,
report it and stop โ do not improvise around a missing board or an unrouted run.
Methodology (real tool calls, in order)
The flow has three phases: (A) sign-off gate โ (B) bitstream โ (C) deliver to
device. Phase C splits into a volatile JTAG lane and a non-volatile flash
lane. Pick the lane from the decision table below; do not run both blindly.
Phase A โ Sign-off gate (MUST pass before any bitstream)
A bitstream is only as trustworthy as the implemented design behind it. These are
fresh-evidence gates: read them now, do not trust a prior claim.
-
Ensure a complete implementation exists.
get_run_status โ if not routed, run it. For multi-minute P&R prefer the
async pattern: run_implementation_async, then poll get_run_status until
complete. (run_implementation is the synchronous fallback for short runs.)
- On completion,
open_implemented_design so the reports below read the
routed netlist, not synthesis.
-
Route completeness โ report_route_status. Every net must be fully
routed. Any unrouted / partially-routed / conflict nets โ not signable โ
stop and route (or report the failure). A .bit over an incomplete route is
invalid.
-
DRC โ report_drc. Resolve (or consciously, with the user, accept)
Critical Warnings/Errors before programming. Bitstream-relevant DRCs
(e.g. DRC BIVRT, unconstrained I/O, config-bank/voltage, BUFGCE/clock
placement) can produce a .bit that damages or refuses to configure the part.
Do not waive a config/IO DRC just to get a green light โ see Safety rails.
-
Timing sign-off โ report_timing_summary. Read WNS/TNS/WHS fresh.
- WNS โฅ 0 and WHS โฅ 0 (no setup/hold failures) โ pass the timing gate.
- WNS < 0 or WHS < 0 โ the design is not signed off. Do not silently
proceed. Report the violation and hand back to timing-closure. Only generate
a bitstream over open violations if the user explicitly says "I know timing
fails, build it anyway for a quick bench test" โ and then label the artifact
as not sign-off quality in the Output.
Gate rule: a "ready to program" claim REQUIRES fresh report_route_status +
report_drc + report_timing_summary output in this session. Never infer it.
Phase B โ Generate the bitstream
- Generate โ
generate_bitstream (synchronous; jobs defaults to 4).
- This step embeds the routed configuration and (if debug cores were inserted)
emits a
.ltx probes file next to the .bit.
- On return, capture the reported
.bit path. If generation fails, read
the error summary it returns โ common causes are config-bank voltage
(CONFIG_VOLTAGE/CFGBVS) or BITSTREAM.* property DRCs surfaced only at
write time. Fix the property/constraint (smallest safe change), re-run the
Phase-A DRC, and regenerate. Do not retry blindly.
Phase C โ Deliver to the device
Choose the lane from the Decision table. Establish the hardware connection
(common to both lanes) first.
-
Connect to hardware (JTAG/flash both need this):
open_hardware_manager
connect_hardware_server (defaults to localhost:3121; pass a url for a
remote hw_server).
open_hardware_target (empty arg auto-selects the first target).
list_hardware_devices โ confirm the discovered device matches the
project part from step (Prereq 2). If the chain is empty, STOP: no board /
bad cable / hw_server not running. If the part mismatches, STOP and ask โ
programming the wrong device is a hardware risk.
Shortcut: quick_program auto-connects and downloads the current project
bitstream in one call (and auto-skips Zynq arm_* debug devices). Prefer it
only when the chain is unambiguous (single FPGA, default hw_server) and
Phase A has already passed. For multi-device chains, remote servers, or any
ambiguity, use the explicit connect chain above so you can verify the device
before committing.
Lane 1 โ Volatile JTAG download (bench test; lost on power cycle)
- Program over JTAG โ
program_device.
- Leave
bitstream_path empty to use the project default, or pass the path
captured in step 5.
- It auto-associates a
.ltx probes file found beside the bitstream and
refreshes the device afterward.
- If you need a fresh status snapshot,
refresh_hardware_device.
- Verify, don't assume: report the tool's success/DONE status as the
evidence. A volatile download is not persistent โ say so explicitly so the
user knows a power cycle wipes it.
Lane 2 โ Non-volatile flash (boots on power-up)
-
Pick the flash part โ ask, don't guess. The configuration-memory part
number and interface (SPI x1/x2/x4, QSPI, BPI) are board-specific. The
wrong part/width burns a non-bootable image. If the user hasn't named the
exact part, ask. Then add_flash_configuration with the correct
flash_type (e.g. a s25flโฆ, mt25qโฆ, etc. part string).
-
Build the flash image โ generate_mcs.
- Inputs:
bitstream_path (from step 5), an output mcs_path, and
flash_size (MB) that matches the physical flash density (default 128).
A size larger than the device, or a wrong start address, yields a
non-bootable image.
- For QSPI boot, confirm the design's
BITSTREAM.CONFIG.SPI_BUSWIDTH /
CONFIG.CONFIGRATE match the flash wiring; a x4 image into x1 wiring won't
boot. If these properties are unset, raise it before burning.
-
Burn the flash โ program_flash with the mcs_file from step 8.
- This writes (and the tool verifies) the configuration memory. Report the
tool's verify result as evidence.
-
Prove it boots from flash โ the only real test of a flash burn. A
successful write+verify proves the bytes are in flash; it does not prove
the FPGA will configure from them. Instruct the user to set the board to the
correct boot mode (e.g. QSPI/Master-SPI strap or MODE[2:0] pins),
power-cycle, and confirm the DONE LED / design behavior. Then
refresh_hardware_device / list_hardware_devices to see the device now
re-configured from flash. If it doesn't come up, this is the classic
"won't come up after power cycle" failure โ go to the troubleshooting table.
Optional โ Hand off to embedded software
- If the user wants Vitis / bare-metal / Linux work,
export_hardware
(include_bitstream=True) to emit the .xsa, then hand off to the embedded
skill. Do not attempt the software build here.
Decision table โ which lane and which fix
| Symptom / request | Likely cause | Smallest safe action (in order) |
|---|
| "Just test it on the bench now" | Volatile download is fine | Lane 1: program_device (or quick_program if chain is unambiguous) |
| "It must boot by itself on power-up" | Needs non-volatile config memory | Lane 2: add_flash_configuration โ generate_mcs โ program_flash โ verify boot |
generate_bitstream fails with CFGBVS/CONFIG_VOLTAGE DRC | Config bank voltage not declared | Add/correct CFGBVS/CONFIG_VOLTAGE in XDC (constraint, not RTL), re-run report_drc, regen |
generate_bitstream fails with unconstrained-I/O DRC | Pins/IOSTANDARD missing | Add I/O constraints (create_io_constraint), re-run report_drc, regenerate |
list_hardware_devices returns empty | No board / cable / hw_server down | STOP. Ask user to connect & power the board; check JTAG cable; confirm hw_server running |
| Discovered device โ project part | Wrong board, wrong target, or wrong project open | STOP. Do not program. Reconcile target vs part with the user |
Zynq: extra arm_* targets on chain | PS debug devices appear alongside the PL | Program the PL FPGA device; quick_program auto-skips arm_* |
| JTAG download works, but dead after power cycle | Design was only in volatile SRAM config, not in flash | Lane 2: program flash + set correct boot-mode straps + power-cycle |
| Flash burned + verified, still won't boot from flash | Wrong boot mode, wrong flash part/size, or bus width | Re-check flash_type & flash_size vs board; check boot-mode pins & SPI_BUSWIDTH; re-burn |
| WNS < 0 but user wants a bitstream | Design not signed off | Report violation; default = refuse sign-off .bit; build only on explicit "bench test anyway" |
| Need Vitis / software image | Hardware hand-off | export_hardware(include_bitstream=True) โ embedded skill |
Programming loop + STOP conditions
Programming is iterative only on failure-to-configure; a clean program is a
single pass. The loop exists to converge a non-booting device, one change-class
per iteration so causeโeffect is attributable.
[Phase A gates] โ generate_bitstream โ connect HW โ verify device==part
โ program (Lane 1 or Lane 2) โ READ device status (fresh)
โ
configured/DONE asserted? โโyesโโโบ STOP (success, with evidence)
โ no
โผ
Classify ONE failure class (boot mode | flash part/size | bus width |
config DRC | wrong device) โ apply ONE fix
โ re-verify with a tool โ loop
STOP immediately (do not iterate) when:
- No board / chain empty โ hand back to user (physical action required).
- Discovered device โ project part โ never program a mismatched device.
- A DRC/timing gate is failing and the user has not explicitly authorized a
non-sign-off build โ hand back to the relevant skill.
- Success: the device reports configured / DONE asserted (JTAG lane), or the
board re-configures from flash after a power cycle (flash lane), confirmed by a
fresh
refresh_hardware_device / list_hardware_devices.
STOP and present options (don't thrash) when:
- You've tried the obvious fix in a failure class (e.g. corrected
flash_type
once) and it still won't boot. Surface the remaining hypotheses (boot-mode
straps, flash density, bus width, board power) with their costs, and hand
back to the human. Do not loop on flash parts blindly โ each burn wears the
device and may not be the real cause.
Safety rails (do not violate)
-
No fake-pass on the sign-off gate. Never waive a route/DRC/timing failure
โ or apply set_false_path / waive_lint_violation / disable a DRC โ purely
to make generate_bitstream succeed or to declare the design "ready". A
config-bank, I/O, or clocking DRC can mean the bitstream will not configure
or could electrically stress the part. If a violation might be real, fix it
or ask the user; state any assumption explicitly.
-
Evidence before claims โ always. "Bitstream generated", "device
programmed", "flash verified", "boots from flash" each REQUIRE the
corresponding fresh tool output in this session
(generate_bitstream path, program_device/program_flash status,
refresh_hardware_device/list_hardware_devices). Never infer success from a
prior step, and never report a flash burn as "boots" until a power-cycle
re-config is observed.
-
Confirm the target device before you commit. Always reconcile
list_hardware_devices against the project part before program_device /
program_flash. Programming the wrong device or wrong flash part is a physical
hazard, not a software typo.
-
Ask before destructive / board-specific choices. Flash part number, flash
size, bus width, and boot mode are board facts you cannot derive from the
project. If unknown, ask โ do not pick a plausible default and burn it.
-
Smallest safe change first. Bitstream-write DRC failures are almost always
constraint/property fixes (XDC: CFGBVS, CONFIG_VOLTAGE, IOSTANDARD,
BITSTREAM.*), not RTL. Fix constraints first. Recommend โ never silently
apply โ any RTL change; that re-opens synth/impl and a new sign-off.
-
Volatile vs non-volatile must be stated. Always tell the user whether what
you just did survives a power cycle. A JTAG program_device does not; only
a flash burn does.
-
One change-class per iteration. When chasing a non-booting board, change
exactly one thing (boot mode or flash part or bus width) and re-measure, so
the fix that worked is unambiguous.
Output
Report concisely, with evidence quoted from tool output, not narration:
- Readiness gate โ route status (fully routed?), DRC (Critical count and any
un-waived items), and timing (WNS / WHS / TNS), each with the tool that
produced it. State pass/fail explicitly. If any gate failed and you proceeded
anyway, label the artifact NOT sign-off quality and name the override.
- Bitstream โ the
.bit path returned by generate_bitstream, and whether a
.ltx probes file accompanied it.
- Target โ the discovered device(s) from
list_hardware_devices and explicit
confirmation it matches the project part.
- Programming result โ
- Lane 1:
program_device status (DONE asserted / configured), and a clear
note that this is volatile (lost on power cycle).
- Lane 2:
flash_type, flash_size, the .mcs path, the program_flash
write+verify result, and the boot-mode + power-cycle instruction the user
must perform โ plus the post-power-cycle list_hardware_devices evidence if
obtained.
- If stopped: the exact blocking condition (no board / device mismatch /
failing gate / exhausted safe options) and the specific decision or physical
action handed back to the user โ with options + costs, not a guess.
Never end with an unverified "done." End with the evidence, or with the precise
reason you stopped.