rtl: InterChipFabric v1 — XY-routed 2D-torus + credit-based flow control #127

Merged
navigator merged 1 commit from auto/issue-124-20260618T051731Z_issue124 into main 2026-06-18 04:31:28 -03:00
Owner

Summary

Materialises the InterChipFabric body that the skeleton (#82) left empty.
Per issue #124 / SPEC rtl/src/pop/specs/InterChipFabric.SPEC.md:

  • 4-port (N/S/E/W per ADR-010) input FIFOs + dimension-ordered (XY) routing.
  • Per-(egress port, VC) credit counter, decremented on egress.fire and
    incremented on creditReturn pulse (initial budget = creditMax).
  • Per-egress round-robin arbitration via RRArbiter across the 4 input
    ports' VC-matched heads.
  • csr.fabricStop quiescence: refuses new ingress while asserted;
    csr.idle raises once every internal FIFO has drained.
  • Opaque CSR routing-table-programming latch + per-port error counters.
  • Constructor: InterChipFabric(numPorts=4, flitBits=64, numVCs=2, fifoDepth=4, creditMax=8).

Acceptance criteria

  • rtl/src/pop/InterChipFabric.scala body materialises 4-port input
    FIFOs + XY routing + per-VC credit counters + output arbitration
  • Bench extended with the 3 scenarios:
    * Single flit routed N→S (1-hop)
    * Single flit routed E→W intermediate (2-hop diameter)
    * Back-pressure on one egress does not block the other 3
  • sbt -no-colors test green — 29/29 across the tree;
    scenarios parameterised on numVCs ∈ {1, 2}
  • No fabricated flit header semantics — payload opaque,
    destChipId field sized to ADR-008's 8-chip total

Open questions (kept Open per SPEC, NOT invented)

  • Concrete flit-header layout (CRC-32K / SeqNum / VC slot / TypeFlags /
    Length per PLAN.md §3.4) — opaque payload only at v1.
  • CSR address map — single opaque latching register at v1.
  • VC-to-traffic-class binding — round-robin across VCs at egress arbiter.
  • PHY attach widths — empty PopLinkPHYAttachIO bundle until PHY-option
    selection (PLAN.md §13.2) closes.

Plan refs

PLAN.md §8.2, §12.3, §12.4, §3.4, §3.5, §3.7, §13.3; ADR-008, ADR-009,
ADR-010, ADR-011.

Closes #124

## Summary Materialises the InterChipFabric body that the skeleton (#82) left empty. Per issue #124 / SPEC `rtl/src/pop/specs/InterChipFabric.SPEC.md`: - 4-port (N/S/E/W per ADR-010) input FIFOs + dimension-ordered (XY) routing. - Per-(egress port, VC) credit counter, decremented on egress.fire and incremented on `creditReturn` pulse (initial budget = `creditMax`). - Per-egress round-robin arbitration via `RRArbiter` across the 4 input ports' VC-matched heads. - `csr.fabricStop` quiescence: refuses new ingress while asserted; `csr.idle` raises once every internal FIFO has drained. - Opaque CSR routing-table-programming latch + per-port error counters. - Constructor: `InterChipFabric(numPorts=4, flitBits=64, numVCs=2, fifoDepth=4, creditMax=8)`. ## Acceptance criteria - [x] `rtl/src/pop/InterChipFabric.scala` body materialises 4-port input FIFOs + XY routing + per-VC credit counters + output arbitration - [x] Bench extended with the 3 scenarios: * Single flit routed N→S (1-hop) * Single flit routed E→W intermediate (2-hop diameter) * Back-pressure on one egress does not block the other 3 - [x] `sbt -no-colors test` green — 29/29 across the tree; scenarios parameterised on `numVCs ∈ {1, 2}` - [x] No fabricated flit header semantics — payload opaque, `destChipId` field sized to ADR-008's 8-chip total ## Open questions (kept Open per SPEC, NOT invented) - Concrete flit-header layout (CRC-32K / SeqNum / VC slot / TypeFlags / Length per PLAN.md §3.4) — opaque payload only at v1. - CSR address map — single opaque latching register at v1. - VC-to-traffic-class binding — round-robin across VCs at egress arbiter. - PHY attach widths — empty `PopLinkPHYAttachIO` bundle until PHY-option selection (PLAN.md §13.2) closes. ## Plan refs PLAN.md §8.2, §12.3, §12.4, §3.4, §3.5, §3.7, §13.3; ADR-008, ADR-009, ADR-010, ADR-011. Closes #124
rtl: InterChipFabric v1 — XY-routed 2D-torus + credit-based flow control
All checks were successful
build / scalafmt-check (pull_request) Successful in 4s
build / sbt-compile (pull_request) Successful in 4s
build / shell-lint (pull_request) Successful in 50s
0f0001dd8b
Materialise the InterChipFabric body that the skeleton (#82) left empty:
4-port input FIFOs, dimension-ordered (XY) routing per ADR-010, per-VC
credit counters per egress port, round-robin egress arbitration, and a
fabricStop-driven quiescence FSM mirroring the cluster-stop drain pattern.

CSR surface exposes the opaque routing-table programming window
(addr/wdata/wen/rdata), per-port error counters, myChipId input, and the
fabricStop/idle quiescence handshake. PHY attach left as an empty bundle
(Open per SPEC §Interface — per-port PopLinkPHYIO wiring against
PopLinkPHY_Behavioral lands on a follow-up issue once the PHY-option
selection closes per PLAN.md §13.2).

No frame-header semantics are committed: payload is an opaque
UInt(flitBits.W) plus a destChipId field sized to ADR-008's 8 chips.
Concrete frame layout (CRC-32K, SeqNum, VC slot, TypeFlags, Length per
PLAN.md §3.4) stays Open per SPEC §Interface.

Chiseltest bench extended with three scenarios mandated by issue #124,
each parameterised on numVCs ∈ {1, 2}:
  * single flit routed N→S (1-hop)
  * single flit routed E→W as an intermediate hop (2-hop diameter per
    ADR-010)
  * sustained back-pressure on one egress port does not block the
    other 3 (no-deadlock)

All 29 tests across the rtl/ tree stay green.

Closes #124
Author
Owner

VERDICT: PASS

PR #127 lifts InterChipFabric from elaborate-only (PR #82) into a v1 with XY-routed 2D-torus topology, per-VC credit-based flow control, per-egress round-robin arbitration, and CSR-driven quiescence — exactly what Issue #124 asks for. Mechanical guardrails pass: SPDX headers preserved (CHARRUA-1.2 source, AGPL-3.0-or-later test), package pop everywhere, no AI/Anthropic attribution, no off-limits paths, scope bounded to two files. Rule 4 is handled correctly: the four SPEC §Interface categories map to sub-bundles — ports (TorusPortQuadIO with per-port Vec(numVCs, Decoupled(FabricFlit)) ingress/egress), credits (VcCreditIO with avail / creditReturn Vecs), phy (PopLinkPHYAttachIO empty, deferred to PHY-option selection per PLAN.md §13.2), csr (FabricCsrIO with myChipId, opaque routing-table latch, fabricStop/idle, per-port errCounts). The chip-side transaction-layer attach category remains Open per SPEC §Interface (the joint resolution with MultiGemminiCluster.SPEC and PCIeHostBridge.SPEC hasn't committed a shape yet); v1 handles locally-destined flits by drop-and-error-count, with the design choice explicitly documented inline as a deferral to the §3.5 5×5 crossbar local slot when the SPEC commits. Rule 7 is meticulously handled: numPorts == 4 matches ADR-010 N/S/E/W as a hard require; numVCs ∈ {1, 2} matches SPEC §Invariants commitment (ADR-010 Consequences "Deadlock-free via XY routing + 2 VCs") as a hard require; flitBits = 64 default is honestly framed as "default 64 matches the PLAN.md §3.4 PopLink frame-header width but does NOT pin the actual header layout (Open per SPEC)"; fifoDepth = 4 and creditMax = 8 defaults are annotated as Open per SPEC §Interface; ChipIdW = 3 follows from ADR-008's 8-chip total (2³=8); errCounts 16-bit width and CSR 32-bit address/data widths are documented as sizing defaults without SPEC commitments; the chip-id encoding (bits[2:1]=X, bit[0]=Y for the 2×4 torus) is a documented internal convention, not falsely attributed to any ADR/SPEC. The XY routing logic uses dimension-ordered routing per PLAN.md §3.5; the antipodal-tie handling (dxFwd==2 picks E deterministically) is documented with the rationale "so the SPEC §Behavior round-robin promise is preserved at the egress arbiter rather than smeared into the routing decision". The math checks out: chip 0 (x=0,y=0) → dest 1 (x=0,y=1) routes Y-wise to S (1 hop, Scenario 1); chip 4 (x=2,y=0) → dest 2 (x=1,y=0) routes X-wise with dxFwd=3 to W (E→W intermediate hop, Scenario 2); back-pressure on egress N keeps egresses S/E/W live for parallel injections from W, N, E respectively (Scenario 3). Each scenario is parameterised on numVCs ∈ {1, 2} matching the SPEC bound and exercises both VCs being preserved across the fabric (input VC v can only arbitrate for egress VC v). The credit counter saturates correctly and handles the fire-vs-return same-cycle nets-to-zero case. The CSR routing-table-programming surface is the right shape (opaque latching register), the fabricStop/idle quiescence pair mirrors the PopRoCCRouter/MultiGemminiCluster cluster-stop pattern, and the deferred items (concrete flit header, CSR map, VC-to-traffic-class binding, PHY attach widths) are explicitly enumerated in the file header.

Findings

None.

<!-- agent:review verdict=PASS ts=1781760965 --> **VERDICT:** PASS PR #127 lifts `InterChipFabric` from elaborate-only (PR #82) into a v1 with XY-routed 2D-torus topology, per-VC credit-based flow control, per-egress round-robin arbitration, and CSR-driven quiescence — exactly what Issue #124 asks for. Mechanical guardrails pass: SPDX headers preserved (`CHARRUA-1.2` source, `AGPL-3.0-or-later` test), `package pop` everywhere, no AI/Anthropic attribution, no off-limits paths, scope bounded to two files. Rule 4 is handled correctly: the four SPEC §Interface categories map to sub-bundles — `ports` (TorusPortQuadIO with per-port `Vec(numVCs, Decoupled(FabricFlit))` ingress/egress), `credits` (VcCreditIO with `avail` / `creditReturn` Vecs), `phy` (PopLinkPHYAttachIO empty, deferred to PHY-option selection per PLAN.md §13.2), `csr` (FabricCsrIO with `myChipId`, opaque routing-table latch, `fabricStop`/`idle`, per-port `errCounts`). The chip-side transaction-layer attach category remains Open per SPEC §Interface (the joint resolution with MultiGemminiCluster.SPEC and PCIeHostBridge.SPEC hasn't committed a shape yet); v1 handles locally-destined flits by drop-and-error-count, with the design choice explicitly documented inline as a deferral to the §3.5 5×5 crossbar `local` slot when the SPEC commits. Rule 7 is meticulously handled: `numPorts == 4` matches ADR-010 N/S/E/W as a hard `require`; `numVCs ∈ {1, 2}` matches SPEC §Invariants commitment (ADR-010 Consequences "Deadlock-free via XY routing + 2 VCs") as a hard `require`; `flitBits = 64` default is honestly framed as "default 64 matches the PLAN.md §3.4 PopLink frame-header width but does NOT pin the actual header layout (Open per SPEC)"; `fifoDepth = 4` and `creditMax = 8` defaults are annotated as Open per SPEC §Interface; `ChipIdW = 3` follows from ADR-008's 8-chip total (2³=8); `errCounts` 16-bit width and CSR 32-bit address/data widths are documented as sizing defaults without SPEC commitments; the chip-id encoding (bits[2:1]=X, bit[0]=Y for the 2×4 torus) is a documented internal convention, not falsely attributed to any ADR/SPEC. The XY routing logic uses dimension-ordered routing per PLAN.md §3.5; the antipodal-tie handling (dxFwd==2 picks E deterministically) is documented with the rationale "so the SPEC §Behavior round-robin promise is preserved at the egress arbiter rather than smeared into the routing decision". The math checks out: chip 0 (x=0,y=0) → dest 1 (x=0,y=1) routes Y-wise to S (1 hop, Scenario 1); chip 4 (x=2,y=0) → dest 2 (x=1,y=0) routes X-wise with dxFwd=3 to W (E→W intermediate hop, Scenario 2); back-pressure on egress N keeps egresses S/E/W live for parallel injections from W, N, E respectively (Scenario 3). Each scenario is parameterised on `numVCs ∈ {1, 2}` matching the SPEC bound and exercises both VCs being preserved across the fabric (input VC v can only arbitrate for egress VC v). The credit counter saturates correctly and handles the fire-vs-return same-cycle nets-to-zero case. The CSR routing-table-programming surface is the right shape (opaque latching register), the `fabricStop`/`idle` quiescence pair mirrors the `PopRoCCRouter`/`MultiGemminiCluster` cluster-stop pattern, and the deferred items (concrete flit header, CSR map, VC-to-traffic-class binding, PHY attach widths) are explicitly enumerated in the file header. ## Findings _None._
fluidpop-bot approved these changes 2026-06-18 04:28:56 -03:00
Dismissed
fluidpop-bot left a comment
Collaborator

CI green (head 0f0001dd8b), auto-approving

CI green (head 0f0001dd8b2dac2b954cf9c658a9560e62df1adb), auto-approving
fluidpop-bot approved these changes 2026-06-18 04:29:41 -03:00
Dismissed
fluidpop-bot left a comment
Collaborator

CI green (head 0f0001dd8b), auto-approving

CI green (head 0f0001dd8b2dac2b954cf9c658a9560e62df1adb), auto-approving
navigator force-pushed auto/issue-124-20260618T051731Z_issue124 from 0f0001dd8b
All checks were successful
build / scalafmt-check (pull_request) Successful in 4s
build / sbt-compile (pull_request) Successful in 4s
build / shell-lint (pull_request) Successful in 50s
to a255ee54a4
All checks were successful
build / scalafmt-check (pull_request) Successful in 10s
build / sbt-compile (pull_request) Successful in 11s
build / shell-lint (pull_request) Successful in 21s
2026-06-18 04:29:45 -03:00
Compare
fluidpop-bot left a comment
Collaborator

CI green (head a255ee54a4), auto-approving

CI green (head a255ee54a49263c77d9037f21cca95a6d5b26321), auto-approving
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Fluid/fluidpop-v1!127
No description provided.