Zynq bringup
Stand up a Zynq-7000 PS7-based SoC block design (Processing System bring-up). Invoke when the user says "build a zynq soc", "ps7", "zynq bring up", "add a processing system", "PS-PL design", "bring up the ARM cores", "wire AXI GP/HP to the PL", "generate the bd wrapper for a Zynq", or asks to create / configure / validate a Zynq-7000 block design (FCLK, DDR, MIO/UART/GPIO, AXI interconnect, address map, wrapper). Requires the SynthPilot MCP server (AI-driven Vivado control) with Vivado open and the tcl_server.tcl TCP bridge running, and a PRO/MAX license (Block Design tools are gated). Zynq-7000 (PS7) only — NOT Zynq UltraScale+ MPSoC (use the mpsoc skill). Stop conditions: stop and ASK on unknown hardware-critical config (DDR part / board / target FCLK on a bare part); stop and HAND OFF on timing/DRC that fails after correct constraints; declare DONE only when bd_validate_design is clean AND post-implementation report_timing_summary (setup WNS/TNS >= 0 AND hold/min-delay >= 0), check_timing (no unconstrained endpoints), report_cdc, report_drc, and report_methodology are all clean on fresh runs.From its SKILL.md
npx -y skills add LNC0831/oh-my-fpga --skill zynq-bringupAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 16 stars16 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
30.1 KB, as published. Nobody here has run it
Zynq-7000 (PS7) Bring-Up
A methodology playbook for standing up a Zynq-7000 SoC: create a block design, instantiate and configure the PS7 Processing System, wire PS↔PL AXI fabric with clean clock/reset, assign and verify the address map, validate, generate the HDL wrapper, then prove it through synthesis/implementation/DRC. This is a build-and-verify flow, not a fix-it flow — but the rigor is the same: every "it works" claim is backed by fresh tool output, never by assumption.
The PS7 is a hard ARM Cortex-A9 block. You do not write RTL for it — you configure it (FCLKs, DDR, MIO peripherals, PS-PL AXI ports) and wire the PL side to it correctly. Most bring-up failures are wiring/clocking/address errors, not logic errors, so this skill measures the graph state at each step.
A critical fact that shapes the whole flow: many wrong-but-plausible mistakes
pass bd_validate_design and even synthesis, and surface only at
post-implementation report_drc / check_timing / report_cdc (wrong DDR
part, polarity-mismatched reset, unconstrained PL-side IO, missing CDC
constraints). The graph being "valid" is therefore never sign-off — only fresh
post-implementation evidence is.
When to use
- User wants a fresh Zynq-7000 SoC scaffold: "build a zynq soc", "ps7 bring up".
- An existing project needs a PS7 added to a (new or existing) block design.
- User needs PS↔PL AXI plumbing: hang an AXI peripheral (GPIO, UARTlite, BRAM
controller, custom AXI IP) off
M_AXI_GP0, or feed a PL master intoS_AXI_HP0. - User needs FCLK / reset / address-map set up correctly and verified.
- User needs the BD validated, the HDL wrapper generated, and the design taken through synth/impl/bitstream as a sanity sign-off.
- User wants
export_hardware(XSA) output for a downstream software/BSP flow.
When NOT to use
- Zynq UltraScale+ MPSoC (
zynq_ultra_ps_e, A53/R5). Use the MPSoC bring-up skill andbd_create_mpsoc/bd_apply_mpsoc_presetfamily — PS7 tools do not apply. - Pure PL / RTL-only designs with no Processing System. Use the standard project + synthesis/timing skills.
- Timing closure of an already-built design — that is the timing-closure skill. (This skill checks timing as sign-off, it does not close it.)
- Software / firmware (BSP, FSBL, bare-metal app, debug of ARM code). That is
the embedded (
emb_*) flow; this skill stops at hardware handoff (XSA). - Detailed simulation of the SoC — PS7 has no behavioral RTL model in this flow; verify PL logic standalone with the simulation skill.
Prerequisites (verify first)
Do not start building blind. Confirm the environment and the part with tools:
test_connection— confirm the Tcl bridge to Vivado is live. If it fails, STOP and tell the user to open Vivado and starttcl_server.tcl. Nothing below works without this.get_license_status— required precondition. Block Design (bd_*) tools are PRO/MAX tier. If the license is FREE, thebd_*calls below are blocked; surface this now and stop, rather than failing opaquely mid-flow.get_project_info— is a project open, and what is the target part?- PS7 bring-up requires a Zynq-7000 part (
xc7z…, e.g.xc7z020clg484-1) or a Zynq board part. If the part is not Zynq-7000, STOP and ask the user — PS7 will not instantiate on a non-Zynq part, and silently guessing a part is a destructive surprise. - If no project is open,
create_projectwith the user-confirmed part/board. Ask for the exact part or board before creating one; never invent it.
- PS7 bring-up requires a Zynq-7000 part (
list_block_designs— is there already a BD? Reuse it (open_block_design) rather than creating a duplicate; onlycreate_block_designif none exists or the user wants a fresh one.
Record the part, board (if any), and target FCLK frequency before proceeding — these drive every later decision (DDR config, MIO, automation).
Board-aware vs. board-agnostic: the first decision
The single most important branch in PS7 bring-up is whether a board part is set on the project. It changes how DDR/MIO get configured and whether you can trust automation.
Condition (from get_project_info) | DDR + MIO strategy | Automation | Risk |
|---|---|---|---|
| Board part set (e.g. Zedboard, Cora, Pynq) | bd_create_ps7(run_automation=True) — this runs Vivado's PS block automation (the underlying apply_bd_automation Tcl command, invoked for you by the MCP tool; do not call apply_bd_automation directly — it is not an MCP tool), filling DDR part, MIO pinout and FIXED_IO from the board file | Trust bd_run_block_automation for the PS | Low — board file is authoritative |
Bare part only (xc7z…, no board) | bd_create_ps7(run_automation=False), then inspect with bd_get_ps7_config and explicitly set DDR part / bus width / MIO via bd_configure_ps7. DDR config MUST match the physical board's memory or hardware will not boot | Do NOT trust block automation for DDR/MIO — it has no board data | High — wrong DDR = dead board. Ask the user for the DDR part / board if unknown |
Tool-name note:
bd_create_ps7(run_automation=True)andbd_run_block_automationare the MCP tools.apply_bd_automation/run_bd_automationare native Vivado Tcl commands those tools wrap — never call them as if they were MCP tools.
Bare-part DDR safety rail (read this). On a bare part, do not invent DDR timing/part numbers to make validation pass. Be explicit that the tooling will not catch a wrong DDR part for you:
bd_validate_designwill pass with a wrong-but-plausible DDR part.- Synthesis will pass — the DDR/FIXED_IO are hard-pinned PS pins, not logic.
bd_get_ps7_configreadback only confirms the value you wrote, not that it matches the physical board — it cannot detect a wrong DDR part.- The only automated gate that catches a missing/wrong DDR + FIXED_IO pinout is post-implementation
report_drc(UCIO / FIXED_IO / DDR no-pin errors). Therefore, whenever you configure DDR on a bare part, the §13 post-implreport_drcgate is mandatory and is the decision's verification — never skip it. If the DDR part is unknown, state the assumption explicitly and ask the user before configuring it.
METHODOLOGY
One change-class per step, then measure before moving on. The recurring
verbs are: configure → inspect (bd_get_* / bd_list_*) → connect →
re-inspect (bd_get_unconnected_pins) → validate.
1. Open or create the block design
create_block_design(name=...)(oropen_block_designif reusing).- Note the design name for
bd_generate_*later.
2. Instantiate the PS7
bd_list_ps7_presets— see available presets (minimal,ddr_enabled,hp_slave,multi_clock).bd_create_ps7(name="ps7_0", preset=<chosen>, run_automation=<board-aware>):- Board part set →
run_automation=True(exports DDR + FIXED_IO from board via the wrapped block automation). - Bare part →
run_automation=False(you will configure DDR/MIO yourself).
- Board part set →
bd_get_ps7_config(cell="ps7_0")— read back the actual state (DDR, clocks, MIO/peripheral I/O, interrupts, PS-PL interfaces). This is your ground truth for what was written — but remember it does not prove DDR matches the board (see safety rail). Do not assume the preset did what its name implies; confirm it here.
3. Configure DDR and MIO (bare-part path only)
Skip if board automation already populated DDR/FIXED_IO (verify via
bd_get_ps7_config that DDR is configured before skipping).
bd_configure_ps7(cell="ps7_0", config="{...}")to set the board-correct DDR part, bus width, and any MIO peripheral pinout the design needs.- Re-run
bd_get_ps7_configto confirm the writes landed. If a parameter is read-only or silently ignored, you will see it here — surface it, don't paper over it. - Remember: this readback only confirms the write, not correctness. The real
verdict for the DDR/FIXED_IO config is the mandatory post-impl
report_drcgate in §13. Do not declare DDR "done" until that gate is clean.
4. Set the PL clock(s) — FCLK
The PS provides the PL clock; get this right before wiring anything.
bd_ps7_set_fclk(cell="ps7_0", fclk_id=0, freq_mhz=<target>, enable=True)for the primary PL clock. Add more FCLKs only if the design needs multiple clock domains.bd_get_ps7_config(cell="ps7_0")— confirm the FCLK is enabled at the requested frequency. The requested vs. actually-realizable frequency can differ (PLL granularity); note the actual value — it is your real timing constraint later.- Multi-FCLK note: if you enable more than one FCLK, you have created an
intrinsic clock-domain boundary. Flag it now — it forces the CDC checks in §13
and may require an
axi_clock_converter(see step 7/8 and Safety rails).
5. Enable the PS-PL AXI port(s) you actually need
Only enable ports the design uses; spurious ports create unconnected-pin noise.
- PS as master to PL peripherals → enable a general-purpose master:
bd_ps7_enable_axi_port(cell="ps7_0", ...)forM_AXI_GP0(or use theminimalpreset which already exposesM_AXI_GP0). - PL master needs high-bandwidth path to DDR → enable a high-perf slave
S_AXI_HP0(or thehp_slavepreset). bd_get_ps7_config(cell="ps7_0")— verify which PS-PL interfaces are now live.
6. Add PL-side peripherals (only what the user asked for)
Examples (use the exact tool; bd_search_ip / ToolSearch to confirm a specific
IP's tool name if unsure):
- AXI GPIO →
bd_create_axi_gpio(thenbd_gpio_set_width/bd_gpio_set_direction). - AXI UARTlite →
bd_create_axi_uartlite(thenbd_uartlite_set_baudrate). - AXI BRAM controller →
bd_create_axi_bram_ctrl. - A custom packaged AXI IP →
bd_add_ip. bd_list_ips— confirm every block you expect is present, named as you expect.
7. Wire clocks and resets correctly (the #1 source of bring-up bugs)
The PS does NOT provide a synchronized PL reset by itself — you need a Processor System Reset block driven by FCLK0 and the PS reset.
bd_create_proc_sys_reset(name="rst_ps7_0_<freq>").- Confirm reset polarity BEFORE wiring
aresetn. A polarity mismatch validates clean and passes DRC but breaks function on silicon (peripherals held in reset, or never reset). Callbd_proc_sys_reset_get_config(...)and confirm:peripheral_aresetnis active-low — it is by design, and matches what every downstream AXI IP'ss_axi_aresetnexpects (AXI uses active-low reset). No action needed if you drive AXI resets from it.ext_reset_inis fed by the PSFCLK_RESET0_N(active-low). Its polarity (C_EXT_RESET_HIGH) is fixed at IP creation and read-only — in the standard PS7/board-automation flow it is already correct.bd_proc_sys_reset_set_polaritydoes not changeext_reset_in; it only sets the auxiliary reset (aux_reset_active_low, used only if you wireaux_reset_in). Ifext_reset_inpolarity is genuinely wrong, recreate the proc_sys_reset block with the right setting — do not wire-and-hope.
- Connect:
- PS
FCLK_CLK0→ proc_sys_resetslowest_sync_clkand every AXI IP'ss_axi_aclkand the interconnect/smartconnect clocks (bd_connect_pins/bd_connect_interfaces). - PS
FCLK_RESET0_N→ proc_sys_resetext_reset_in. - proc_sys_reset
peripheral_aresetn→ every AXI IP'ss_axi_aresetnand interconnect reset.
- PS
- Every AXI clock pin in the design must come from the same FCLK domain as the
master driving it (unless you deliberately insert an
axi_clock_converterfor a CDC — see Safety rails). Mixing FCLK0 and FCLK1 across a single AXI link without a converter is a silent functional bug.
8. Build the AXI fabric and connect master → slaves
- For one or a few AXI-Lite slaves:
bd_create_smartconnect(auto width/clock conversion, preferred for new designs) orbd_create_axi_interconnect. - Connect PS master to the interconnect slave port, and each interconnect master
port to a peripheral's
S_AXI:bd_connect_interfaces(src="ps7_0/M_AXI_GP0", dst="<sc>/S00_AXI"), then<sc>/M0x_AXI→<periph>/S_AXI. - Alternative (let Vivado wire it):
bd_run_block_automation(cell="ps7_0")for the PS itself, and/orbd_run_automationto auto-connect AXI/clk/reset for a peripheral. If you use automation, still run step 9 — automation can mis-guess clock domains.
9. Verify connectivity BEFORE address assignment
bd_get_unconnected_pins— must be empty (or contain only pins you have a documented reason to leave open, e.g. an intentionally-external interrupt). If it lists clock/reset/AXI pins, go back to step 7/8. Do not proceed with dangling AXI clocks/resets — they produce a design that validates the graph but is functionally broken.bd_list_nets/bd_get_infoif you need to see how something actually wired.
10. Assign and verify the address map
bd_assign_addresses— auto-assign AXI addresses.bd_get_address_map— inspect the result and confirm it is sane:- Every AXI slave the PS master reaches has a non-zero-size, non-overlapping range inside the PS GP address window.
- No peripheral landed at an unintended/overlapping address. Overlaps = silently broken software access later. If anything looks wrong, fix and re-assign; do not hand off a questionable map.
11. Validate the block design
bd_validate_design— must return clean (errors include the offending pin/net path). Treat any ERROR as a hard stop; fix the specific net/pin it names, then re-validate. Warnings: read each one — distinguish benign (e.g. board-flow info) from real (unconnected interface, clock mismatch).- Validation is NOT sign-off. It does not check DDR correctness, reset polarity correctness, PL-side IO constraints, CDC, or timing. Those are §13.
save_block_design.
12. Generate output products + HDL wrapper, set top (long op — bounded poll)
bd_generate_output_and_wrapper(...)to produce IP output products and the top-level HDL wrapper.- Long op — use a bounded poll, never an unbounded one. For large designs
this is multi-minute. Poll
bd_check_output_status(and/orbd_wait_on_output_generation) with an explicit ceiling: pick a sane wall- clock budget (e.g. 15 min) and a max poll count; if generation has not completed by then, STOP and report it as a stalled long-op rather than looping forever. Do not assume success; confirm status is complete before proceeding. - Set and confirm the wrapper as top — do not assume it.
set_top_module(<wrapper>).- Then confirm it actually took, with
get_project_infoand/orlist_source_files: the active top in the synthesis fileset must equal the generated wrapper module. If the fileset top is still an old/placeholder module, synthesis will build the wrong thing. Do not start synthesis until this is confirmed.
report_ip_status— confirm no IP is locked/out-of-date. If locked, the design is not buildable as-is; surface it (anupgrade_ipmay be needed) rather than proceeding.
13. Hardware sign-off (necessary — graph-clean is not enough)
A valid BD that won't implement is not a bring-up. Prove it with fresh, post-implementation evidence. Synthesis success is necessary, not sufficient — it proves neither timing, nor routability, nor pin legality.
13a. Constrain PL-side IO before trusting timing. Any PL-side top-level port made external in the BD (e.g. a UART/GPIO pin, a PL clock/reset, an LED) is an unconstrained endpoint until you constrain it. Unconstrained IO produces an optimistic / false WNS ≥ 0. Where the design has PL-side IO:
- set
set_input_delay/set_output_delayon those ports against the relevant clock, and - add the pin-location/io-standard constraints (board XDC, or
create_io_constraint). The PS DDR/FIXED_IO pins are handled by the PS (do not constrain those by hand); this step is about the PL ports.
13b. Run the flow (bounded async poll).
run_synthesis_async, then pollget_run_statuswith an explicit max-poll / timeout ceiling (same bounded-poll rule as §12 — a poll loop with no ceiling can hang). On completion:check_synthesis_issues+get_synthesis_warnings.run_implementation_async, pollget_run_statusthe same bounded way until done.
13c. Sign-off evidence — ALL must be fresh and post-implementation:
check_timing— run this first, before trusting any WNS. It surfaces unconstrained endpoints / no-clock / missing input-output-delay problems. A cleanreport_timing_summaryWNS is meaningless ifcheck_timingshows unconstrained paths producing a false positive. There must be no unconstrained-endpoint / no-clock issues here.report_timing_summary— assert BOTH:- setup WNS ≥ 0 and TNS ≥ 0 on all paths, and
- hold / min-delay (WHS / THS) ≥ 0 on all paths. Reporting setup-only is not "timing met". A design can have setup slack and still fail hold. If either setup or hold is negative, hand off to the timing-closure skill; do not claim "works".
report_cdc— for any PS-PL crossing or multi-FCLK design, runreport_cdc(and, pre-synth,check_cdc_lint). The PS-PL boundary is an intrinsic clock crossing; multiple FCLKs add more. There must be no unsafe / missing-constraint CDC paths.report_methodologyalone does NOT catch every missing CDC constraint —report_cdcis the dedicated check and is required here.report_drc— no critical DRC violations. This is the mandatory gate for the bare-part DDR/FIXED_IO decision (UCIO / FIXED_IO / DDR no-pin errors): if you configured DDR on a bare part, this gate is what proves the pinout is real. It is non-optional.report_methodology— no critical methodology violations (catches additional clock/CDC/structural issues; complements, does not replace,report_cdc).report_utilization→ fits the device.- Only after check_timing (clean), setup AND hold WNS/TNS ≥ 0, report_cdc (clean), report_drc (clean), report_methodology (clean) all pass on fresh post-impl runs may you say the SoC is brought up.
14. (Optional) Bitstream + hardware export
generate_bitstream(orrun_full_flowend-to-end if the user wants one shot — but still verify §13 reports afterward;run_full_flowdoes not exempt you from evidence).export_hardwareto produce the XSA for the downstream software/BSP flow.
Connectivity decision table (symptom → cause → safe fix)
| Symptom (from a tool) | Likely cause | Smallest safe fix |
|---|---|---|
bd_validate_design ERROR naming an AXI s_axi_aclk pin | AXI clock unconnected or wrong FCLK domain | Connect that pin to the correct FCLK in step 7; re-validate. |
bd_get_unconnected_pins lists *aresetn | Missing proc_sys_reset wiring | Add/connect bd_create_proc_sys_reset outputs (step 7). |
| Peripheral held in reset / never resets, but graph validates clean | proc_sys_reset wiring/polarity | bd_proc_sys_reset_get_config: confirm ext_reset_in is fed by active-low FCLK_RESET0_N (its polarity is fixed at creation — recreate the block if wrong) and peripheral_aresetn (active-low by design) drives the AXI resets. set_polarity only changes the aux reset (step 7). |
bd_get_address_map shows a slave with no range | Slave not reachable from the PS master / not assigned | Confirm master→slave interface path (step 8), re-run bd_assign_addresses. |
| Address ranges overlap | Manual/partial assignment | Re-run bd_assign_addresses; if still overlapping, inspect and set non-overlapping ranges; never ship an overlap. |
check_timing shows unconstrained endpoints / no-clock | PL-side IO has no input/output delay or no clock | Add set_input_delay/set_output_delay + IO constraints (§13a); re-run. A WNS taken before this is false. |
| FCLK realized freq ≠ requested | PLL granularity | Accept the realized value and use it as the timing constraint; note it to the user. Do not over-constrain a clock the PS cannot produce. |
report_timing_summary setup WNS ≥ 0 but hold (WHS) < 0 | Hold violation (short paths / clock skew) | This is a real failure, not "timing met" — hand off to timing-closure; do not report success. |
report_timing_summary WNS < 0 on a PS-PL AXI path | PL too slow for FCLK, or a true CDC across FCLK domains | First confirm it's a real same-domain path (run report_clock_interaction / report_cdc). If real same-domain → timing-closure skill. If genuinely async across two FCLKs (proven by report_clock_interaction / report_cdc) → insert bd_create_axi_clock_converter (a real CDC fix), not a blanket set_false_path. |
report_cdc flags an unsafe/unconstrained crossing | PS-PL or multi-FCLK crossing without synchronizer/constraint | Add the correct CDC structure (axi_clock_converter for AXI, proper synchronizer for single bits) — never paper over with set_false_path unprovenly. |
report_ip_status shows a locked IP | Version mismatch | upgrade_ip / regenerate output products; re-validate. Surface to user if it changes behavior. |
report_drc UCIO/no-pin errors on FIXED_IO/DDR | DDR/FIXED_IO not exported (bare-part path) or board automation skipped | Run PS bd_run_block_automation / configure DDR+FIXED_IO (steps 2–3); these are hard-pinned by the PS and must be present. This DRC IS the bare-part DDR gate. |
| Synthesis built the wrong/old top | Wrapper not actually set as top in fileset | set_top_module(<wrapper>), then confirm via get_project_info/list_source_files (§12) before re-synth. |
Build → verify → re-measure loop (with STOP conditions)
Each step's bd_get_* / report_* is the "measure". Iterate only the failing
sub-step, change one class of thing, then re-measure. STOP and act when:
- STOP-DONE:
bd_validate_designclean and, on fresh post-impl runs:check_timingclean (no unconstrained endpoints),report_timing_summarysetup WNS/TNS ≥ 0 and hold/min-delay ≥ 0,report_cdcclean,report_drcclean, andreport_methodologyclean → declare bring-up complete with the metrics shown. - STOP-ASK (config unknown): DDR part / board / target FCLK unknown on a bare part → stop and ask the user. Do not guess hardware-critical config.
- STOP-ASK (could-be-real violation): a timing/DRC/CDC/methodology violation
that might be a genuine bug (real same-domain path failing, real CDC) → present
it and ask before waiving. Never
set_false_path/set_multicycle_path/waive_lint_violationa path that could be real just to turn a number green. - STOP-HANDOFF: timing fails after correct constraints (PL-side IO delays set,
clocks defined,
check_timingclean) → this is the timing-closure skill's job; hand off with the report, don't thrash on RTL here. - STOP-TRADEOFF: safe options exhausted (e.g. utilization over-budget, or a PS-PL bandwidth shortfall needing HP-port/architecture change) → present options + costs (e.g. "add S_AXI_HP for DMA bandwidth vs. lower FCLK vs. smaller part") and hand back to the human. Do not loop.
- STOP-STALLED-LONGOP: a long op (output generation, synthesis, or implementation) exceeds its poll ceiling / wall-clock budget → stop the poll loop and report it as stalled, rather than polling forever.
- Anti-thrash: if the same validation/timing/CDC/DRC error persists after 2 distinct fix attempts, STOP and present what you tried + what's left. Don't keep poking.
Safety rails (do not violate)
- Evidence before claims. "BD valid", "addresses assigned", "timing met",
"no CDC issues", "bitstream generated" each require fresh output from the
corresponding tool (
bd_validate_design,bd_get_address_map, post-implcheck_timing+report_timing_summary,report_cdc,generate_bitstream). Never infer success from a prior step or from a tool running without error. Synthesis numbers never substitute for post-implementation sign-off. - "Timing met" means setup AND hold. Always assert both setup (WNS/TNS) and
hold (WHS/THS) ≥ 0, and only after
check_timingshows no unconstrained endpoints. Setup-only is not sign-off. - CDC is its own gate. For any PS-PL or multi-FCLK design,
report_cdc(and pre-synthcheck_cdc_lint) is required;report_methodologydoes not replace it. - No fake-pass — and async exceptions need PROOF, not a verbal assumption.
Do not apply
set_false_path/set_multicycle_path/set_clock_groups/waive_lint_violationto silence a violation that could be real. A true asynchronous PS-PL crossing (different FCLKs, or PS clock vs. a separately- generated PL clock) is the only place an exception is legitimate — and you must prove it is genuinely asynchronous with freshreport_clock_interactionand/orreport_cdcevidence showing the two clocks have no timed relationship, before applyingset_clock_groups -asynchronousor insertingbd_create_axi_clock_converter. A self-declared "assume it's async" is not acceptable. If the evidence is unclear, ask first. - Don't brick the board. Never invent DDR part/timing or MIO pinout to make
validation pass on a bare part. Wrong DDR/MIO passes
bd_validate_design,bd_get_ps7_configreadback, AND synthesis — it is caught only by post-implreport_drc(UCIO/FIXED_IO/DDR no-pin). State the assumption and ask the user for the board/DDR if unknown; treat the §13report_drcgate as the decision's verification. - Confirm reset polarity before wiring. Polarity mismatch validates clean and
passes DRC but breaks silicon. Use
bd_proc_sys_reset_get_configbefore connectingaresetn:peripheral_aresetnis active-low by design;ext_reset_inpolarity is fixed at creation (recreate the block if wrong —set_polarityonly affects the aux reset). See step 7. - Confirm the wrapper is actually top. After
set_top_module, verify viaget_project_info/list_source_filesbefore synthesis (step 12). - Smallest safe change first. Prefer configuration and wiring fixes (FCLK, reset, interconnect, address) over editing or generating RTL. The PS7 is hard IP — you configure it, you do not rewrite it. For PL-side RTL issues, recommend the edit; do not silently rewrite user RTL.
- One change-class per iteration so cause→effect is attributable (clocks, then resets, then fabric, then addresses — not all at once).
- Verify connectivity before address/validate, validate before generate,
generate before build. Skipping the
bd_get_unconnected_pinscheck produces designs that validate but are functionally dead. - Right device family. PS7 tools are Zynq-7000 only. If the part is MPSoC or non-Zynq, stop — do not force it.
- Long ops use bounded async + poll. Output-product generation, synthesis, and
implementation are multi-minute: use
bd_wait_on_output_generation/bd_check_output_status/*_async+get_run_status, each with an explicit poll-count / wall-clock ceiling so the poll loop cannot hang indefinitely. Confirm completion before the next stage.
Output (report back to the user)
Report, with the tool output backing each line:
- Configuration realized — part/board, BD name, PS7 instance, FCLK(s) at
their actual realized frequency (from
bd_get_ps7_config), DDR status, reset polarity confirmed (bd_proc_sys_reset_get_config), enabled PS-PL ports, PL peripherals added. - Connectivity —
bd_get_unconnected_pinsresult (empty, or the documented exceptions). - Address map — the
bd_get_address_maptable (slave → base/range), noted as non-overlapping. - Validation —
bd_validate_designresult verbatim (clean / the errors). - Top confirmed — wrapper module set as top and verified in the fileset
(
get_project_info/list_source_files). - Sign-off evidence (fresh, post-implementation) —
check_timing(no unconstrained endpoints),report_timing_summarysetup WNS/TNS AND hold (WHS/THS) ≥ 0,report_cdc(clean / flagged crossings),report_drc(clean — explicitly note this is the DDR/FIXED_IO gate on a bare part),report_methodology,report_utilization. If any failed, say so plainly and route to the right next step (timing-closure / user decision) — do not report a partial build as a success. Never report setup-only timing as "met". - Artifacts — wrapper module set as top, bitstream (if generated), XSA path
(if
export_hardwarewas run). - Open items / trade-offs — anything that needs a human decision (DDR config to confirm, timing shortfall, bandwidth trade-off), stated explicitly.
If a STOP-ASK or STOP-TRADEOFF condition was hit, the output is the question or the options table — not a claim of completion.