KrIO carrier
Architecture
What is fixed on the module, where the experiment-specific boundary falls, and what each data path out has actually demonstrated.
KrIO exists to make one division of labor explicit. The K26 does the computing, KrIO does transport and control, and the experiment’s own board does the analog front end. This page is the interface list that division implies, with the evidence for each claim attached to it.
The processing element
The module accepts a Kria K26 system-on-module through J1, a Samtec ADM6-60 socket
(241 pads, all on F.Cu — the SOM mounts on KrIO rather than the other way round). The
K26 carries a Zynq UltraScale+ device, which matters here because it puts two fairly
different resources on one part:
- Programmable logic for the work that has to be deterministic — digitizing, timestamping, triggering, and any counting that cannot tolerate an operating system between it and the signal.
- A processor system running Linux, for configuration, monitoring, slow control, and moving data off the board.
Front ends that would otherwise need a microcontroller for housekeeping and an FPGA for timing get both from the same module, sharing memory between them.
The front-end boundary
J3 is where the experiment begins. It is a Samtec HSEC8 edge connector, 2 × 60 positions at 0.8 mm pitch, carrying 68 signals to the K26’s high-density I/O banks in three groups — HDA, HDB and HDC.
J3’s gold fingers are part of KrIO’s own board outline. Verified from the PCB: the
footprint is Samtec_HSEC8-160-X-X-DV-BL_2x60_P0.8mm_Edge, it contributes 19
Edge.Cuts segments, and its pads sit on both faces (61 on F.Cu, 60 on B.Cu).
KrIO is the card; the socket belongs to the front-end board.
Consequence: a new front end is a board with an HSEC8 socket and whatever analog it needs, and nothing else — no processor, no network interface, no boot media, no host connector.
| Connector | Samtec HSEC8, 2 × 60 positions, 0.8 mm pitch, edge-mounted |
| Signals | 68 single-ended across banks HDA / HDB / HDC, plus 6 differential pairs |
| Direction | Set per pin in the K26’s I/O banks, not fixed by the carrier |
| Pin map | KrIO Connector Specification — all 120 pins |
The full contract — every pin, both power rails, the present-detect line and the I²C bus — is on the connector specification page, generated from the KiCad project rather than transcribed.
Data paths out
Data leaves over PCI Express or Ethernet. They are independent, and an experiment picks whichever suits its host arrangement — a directly attached machine, or a network drop.
Gigabit Ethernet — Proven on hardware
Two Texas Instruments DP83867CRRGZR physical-layer devices, both on RGMII, sharing one
management bus on GEM1 (MIO76/MIO77). U15 straps to address 0x0 and U9 to
0x5.
Throughput: the two ports bond into a single logical interface for up to 2 Gb/s aggregate, which is the higher-bandwidth option when no PCIe slot is available.
Evidence: the tx-delay sweep passes for 10 of 16 settings, spanning 1.25–3.75 ns.
A window that wide means the RGMII layout has real timing margin rather than working by
luck, and that is what makes the path reusable for a front end I have not designed yet.
The historical “Ethernet doesn’t work” turned out to be entirely device-tree — a missing
ti,*-internal-delay, then compatible-string ordering — and not hardware.
Ethernet A’s PHY answers at MDIO address 0x0 and Ethernet B’s at 0x5, both on
GEM1’s MDIO bus. Firmware needs those two addresses; the DP83867’s four-level straps
mean they are not what a single divider per address bit would suggest.
PCI Express x4 — Designed, not yet linking
Four PS-GTR lanes plus a reference clock to J4, a PCI Express x4 card edge. As with
J3, the fingers are KrIO’s own outline (BUS_PCIexpress_x4, 11 Edge.Cuts segments,
pads on both faces), so the module is an add-in card and the slot belongs to the host.
What is right: M2C→PET, C2M→PER and REFCLK→A13/A14 are all correct per the
card electromechanical specification, and refclk placement is textbook. Every firmware
precondition has been verified on the running board — clocked, out of reset, endpoint
attributes programmed, ICM_CFG0/1 = 0x11/0x11, LTSSM not held.
What is wrong: the link reaches Polling.Active and falls back, cycling at roughly
a 3% duty cycle rather than training. Leading explanation is that the transmit pairs are
missing their coupling capacitors, which the specification assigns to the add-in card.
Fix: a rework, not a redesign — 100 nF (0402) in series on the lane-0 pair at J4 B14/B15 for x1, or on all four pairs for x4. Detail in E1.
Confidence: I would not advertise this path as working until the rework runs.
Boot, storage and control
Fixed on the module, and the part a front end benefits most from not having to build:
| Flash | Micron mt25qu512 QSPI | boots the board |
| eMMC | 14.8 GB | partitioned and booting |
| Debug | JTAG header | verified against Vivado’s hardware manager |
| Management | GEM1 MDIO, MIO76/MIO77 | both PHYs on one bus, as designed |
Cold boot is reliable and repeatable. Warm reset is not supported on this revision —
the boot-time flash driver leaves the mt25qu512 in a volatile non-power-on state, so
the BootROM reads garbage after a warm reset and only a power cycle recovers. Mechanism
and candidate fix in O2.
Signal integrity
Six layers with controlled impedance, and the differential classes a front end depends
on are already defined in Krio.kicad_dru:
| class | used by |
|---|---|
100ohm_diff | LVDS, PCI Express reference clock |
90ohm_diff | — |
85ohm_diff | PCI Express lanes |
50ohm | single-ended controlled-impedance nets |
Both outer layers sit over ground at the same height (0.0993 mm, εr 3.23), so F.Cu and
B.Cu reach the same geometry and a pair can change layer without changing impedance.
The stackup, and the caveat that its inner heights are not yet locked to a
fabricator, are on the fabrication page.
What is deliberately not here
KrIO does not condition, amplify, discriminate or digitize anything. It has no analog front end of its own, and no connectors for detector signals other than J3. That is the whole point of the split: the module stays the same across experiments precisely because none of the experiment-specific analog lives on it.