Skip to content

zynq7, spartan7: the rest of the CLK_HROW_TOP_R left-side rows, and the CLK_HROW mask bits, copied from artix7 and verified against Vivado - #35

Merged
cavearr merged 1 commit into
openXC7:masterfrom
cavearr:fix/clk-hrow-top-active-rows
Oct 13, 2026
Merged

cavearr merged 1 commit into
openXC7:masterfrom
cavearr:fix/clk-hrow-top-active-rows

Conversation

@cavearr

@cavearr cavearr commented Oct 13, 2026 •

Copy link
Copy Markdown

Follow-up to #14. That PR copied from artix7 the cascade rows of the left-side clock wires of zynq7 CLK_HROW_TOP_R (CASCO <- CK_IN_L4..13 / CK_BUFRCLK_L0..3). It did not copy the other rows of the same wires, and I missed it:

  • CLK_HROW_CK_IN_L4..13_ACTIVE and CLK_HROW_CK_BUFRCLK_L0..3_ACTIVE (14 rows): the enable Vivado sets on each of these wires when it carries a clock;
  • CK_MUX_OUT_L0..11 / CK_MUX_OUT_R0..11 <- CK_IN_L4..13 (240 rows): the same wires into the BUFHs.

What fails today. nextpnr-xilinx writes CLK_HROW_CK_IN_L<n>_ACTIVE for every CK_IN wire it uses, and fasm2frames stops on the missing row. With the current database:

  • a blinky clocked from pad AA29 or AA30 (bank 12) of an xc7z100ffg1156, nothing else constrained: Segment DB CLK_HROW_TOP_R, key CLK_HROW_TOP_R.CLK_HROW_CK_IN_L8_ACTIVE not found;
  • a seven-output MMCM clocked from bank 12 on any of the four xc7z100 parts: nextpnr places it in the CMT next to the BUFG row, the outputs take CK_IN_L0..2 and L10..13, and it fails on CK_IN_L10..13_ACTIVE.

Without the BUFH rows, the 240 CK_IN_L4..13 -> CK_MUX_OUT_* pips have no bits, and nextpnr cannot use them.

What this PR adds. It is the output of the copy tool in fuzzers/041a-clk-hrow-casc-copy (companion prjxray PR). Every row zynq7 already had is bit-identical to artix7's (2582/2582). The diff is insertions only:

After this PR, zynq7 and spartan7 segbits_clk_hrow_*.db and mask_clk_hrow_*.db are byte-identical to artix7's.

Verified bit by bit against Vivado 2026.1. All the specimens are on xc7z100ffg900-1 and are in the tool PR:

  • pad R27 into the 24 BUFHCEs of CLK_HROW_TOP_R_X176Y234, re-routed with FIXED_ROUTE through each HCLK_CMT lane 4..13. That is 25 rows and 49 bits per lane, and all 250 rows over the ten lanes.
  • the same pad into a top BUFG through each lane: CK_IN_L<n>_ACTIVE next to the CASCO0 <- CK_IN_L<n> row that was already there.
  • four BUFRs into four BUFGs: the four BUFRCLK_L*_ACTIVE rows.

In every specimen, bit2fasm reports exactly the expected positions as unknown with the database as it stands. With the rows in place they decode to these features, and no unknown bit is left in any CLK_HROW tile. Two of the xc7z045 specimens from #14 already had the bits of CK_IN_L4/L5_ACTIVE and CK_BUFRCLK_L2_ACTIVE. The old check only followed the bits of the rows it copied, so it did not see them. They resolve now too.

Chipdb. nextpnr's generator reads segbits, not masks. For every zynq7 die, the bin changes in exactly 240 bytes: the 240 BUFH pips become expressible (xc7z100: 38163 -> 38403 of 40581). The spartan7 bins come out byte-identical.

Nothing else moves. I took our toolchain release 2026-10-13 (nextpnr f9e07df8) and changed only this database and the chipdb generated from it. Our regression suite (65 designs) and the E2E blinky on 43 parts pass, and every design's FASM is identical to the release's. The designs that failed above keep their FASM and now assemble.

checkdb gives the same result as on master: the zynq7, spartan7 and artix7 targets pass. The kintex7 and virtex7 targets fail on the same strict duplicates as master's CI, in files this PR does not touch.

Nothing is left out: all 254 rows have a specimen. kintex7 and virtex7 masks also differ from artix7's, but this PR does not touch them.

Summary by Sourcery

Complete the Zynq-7000 and Spartan-7 CLK_HROW databases so left-side clock routing is fully represented and supported designs assemble correctly.

Bug Fixes:

  • Add the missing Zynq-7000 and Spartan-7 clock-row database entries and mask bits required for nextpnr-generated CLK_HROW routes to assemble successfully.

Enhancements:

  • Complete the Zynq-7000 left-side CLK_HROW_TOP_R coverage for active clock inputs, BUFR clock inputs, and BUFH connections, bringing the affected databases into parity with Artix-7.

Tests:

  • Verify the added clock-row data bit-for-bit against Vivado and confirm existing regression, blinky, and database checks remain successful.

…he CLK_HROW mask bits, copied from artix7 and verified against Vivado specimen bitstreams

Rows produced by the copy tool of fuzzers/041a-clk-hrow-casc-copy
(companion prjxray PR).  The cascade rows of the left-side wires of
CLK_HROW_TOP_R came in earlier; their other rows did not:

  - CLK_HROW_CK_IN_L4..13_ACTIVE and CLK_HROW_CK_BUFRCLK_L0..3_ACTIVE
    (14), the enable Vivado sets on each of those wires when it carries
    a clock;
  - CK_MUX_OUT_L0..11 / CK_MUX_OUT_R0..11 <- CK_IN_L4..13 (240), the
    same wires into the BUFHs.

nextpnr-xilinx writes CLK_HROW_CK_IN_L<n>_ACTIVE for every CK_IN wire
it uses, so without the row fasm2frames stops: a blinky clocked from
pad AA29 (bank 12) of an xc7z100ffg1156, nothing else constrained,
fails on CLK_HROW_TOP_R.CLK_HROW_CK_IN_L8_ACTIVE, and a seven-output
MMCM clocked from bank 12 of any of the four xc7z100 parts on
CK_IN_L10..13_ACTIVE.

CLK_HROW_TOP_R is the same tile type on every 7-series family and every
row zynq7 already had is bit-identical to artix7's (2582/2582).  The
diff is insertions only: 254 segbits rows with their origin_info
lines, the mask bits of those rows (+38), and the mask bits the
cascade rows were added without (+32 in each of zynq7 top_r, zynq7
bot_r and spartan7 bot_r).  After it, zynq7 and spartan7
segbits_clk_hrow_*.db and mask_clk_hrow_*.db are byte-identical to
artix7's.

Verified bit-by-bit against Vivado 2026.1 specimen bitstreams on
xc7z100ffg900-1: pad R27 into the 24 BUFHCEs of
CLK_HROW_TOP_R_X176Y234, re-routed through each HCLK_CMT lane 4..13
(25 rows and 49 bits per lane, all 250 rows), the same pad into a top
BUFG through each lane, and four BUFRs into four BUFGs (the four
BUFRCLK_L*_ACTIVE).  In every specimen the expected positions are
exactly the unknown bits bit2fasm reports with the database as it
stands, they decode to these features with the rows in place, and no
unknown bit is left in any CLK_HROW tile.  Two of the xc7z045
specimens that verified the cascade rows already contained the bits
of CK_IN_L4/L5_ACTIVE and CK_BUFRCLK_L2_ACTIVE; they resolve too.
@sourcery-ai

sourcery-ai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Completes the missing Zynq-7 and Spartan-7 CLK_HROW right-side database coverage by copying the remaining Artix-7-compatible active, BUFH mux, and mask entries, enabling nextpnr/fasm2frames to represent previously unsupported clock routes while preserving validated chipdb and FASM behavior.

File-Level Changes

Change Details Files
Add the missing left-side CLK_HROW_TOP_R routing rows and corresponding bit masks for Zynq-7 and Spartan-7 clock tiles.
  • Add 14 CK_IN/BUFRCLK active-row features and 240 CK_IN-to-BUFH mux pip features.
  • Record origin metadata for all newly added segment-bit entries.
  • Extend Zynq-7 top-right masks for the new rows and complete omitted mask bits from the preceding cascade-row change.
  • Extend Zynq-7 and Spartan-7 bottom-right masks with the omitted bits from the preceding change.
zynq7/segbits_clk_hrow_top_r.db
zynq7/segbits_clk_hrow_top_r.origin_info.db
zynq7/mask_clk_hrow_top_r.db
zynq7/mask_clk_hrow_bot_r.db
spartan7/mask_clk_hrow_bot_r.db
Regenerate Zynq-7 chip databases so the newly described BUFH routing pips are expressible.
  • Update generated Zynq-7 binaries by 240 bytes per die from the segment-bit database changes.
  • Leave Spartan-7 generated binaries byte-identical.
Generated Zynq-7 chipdb artifacts (as applicable)
Validate the database additions against Vivado and existing toolchain regressions.
  • Verify all 254 new rows bit-by-bit across BUFH, BUFG, and BUFR specimens.
  • Confirm previously unknown CLK_HROW bits decode without leftovers and preserve existing FASM output.
  • Run checkdb, the 65-design regression suite, and 43-part blinky E2E coverage.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@cavearr
cavearr merged commit 86dd993 into openXC7:master Oct 13, 2026
17 of 23 checks passed
cavearr added a commit to openXC7/nextpnr that referenced this pull request Oct 14, 2026
gen/filters.py dropped the CASCO <- CASCIN pass-through pips of every
CLK_HROW_TOP tile. They are the vertical hop a clock takes from a clock
row that is not next to the BUFG tile, so a PLL, MMCM or clock-capable
pad there had no dedicated path to a BUFG: route_clocks printed "failed
to find a route using dedicated resources" and router2 carried the net
through the fabric to CLK_BUFG_IMUX, about 4 ns of delay that the timing
analysis does not count as clock skew. Vivado routes exactly these pips,
and bit2fasm reads them back with the database's bits.

The filter comes from nextpnr-xilinx fa0bbdc0 (2020-01-16, "zynq7: Make
blinky actually blink"), which added the clk pad H16 to the Arty-Z7-20
blinky in the same commit. At that time prjxray-db had no segbits row for
CLK_HROW_TOP_R CK_BUFG_CASCO <- CK_BUFG_CASCIN in zynq7 (it got them on
2020-02-09; the zynq7 and spartan7 CLK_HROW_BOT_R rows, which the filter
never touched, on 2026-09-07). Assembling the FASM of that blinky routed
with the pips, with segbits_clk_hrow_top_r.db of 2019-12-16 in place of
today's, fails: "Segment DB CLK_HROW_TOP_R, key
CLK_HROW_TOP_R.CLK_HROW_TOP_R_CK_BUFG_CASCO0.CLK_HROW_TOP_R_CK_BUFG_CASCIN0
not found". With today's database it assembles, and Vivado routes the
same tiles and writes the same CASCO0 <- CASCIN0 feature. The database
has the 32 rows in artix7, spartan7 and zynq7 now, so nothing is left for
the filter to hide.

zynq7 segbits_clk_hrow_top_r.db had the CK_IN_L0..3 "_ACTIVE" rows but
not CK_IN_L4..13 (artix7 and spartan7 have all fourteen), so a pad clock
that reaches the cascade through one of those lanes on an xc7z100 wrote a
feature fasm2frames could not look up. openXC7/prjxray-db#35 added them.

Found in a VC707 report by jrrk2 (vc707-ethmin), whose Ethernet TX clock
legs went through the fabric.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant