feat(hw): split intercard_link into upstream/downstream variants (closes #13)#15
Merged
marcos-mendez merged 1 commit intoMay 6, 2026
Conversation
#13) PR #11 declared `clk_p`/`clk_n` as unconditionally `output` on the single `intercard_link` module. Per docs/hw/intercard-connector-pinout.md §2.1 §6, the forwarded source-synchronous clock is driven by the upstream card and consumed by the downstream card — so the original single-module surface only modeled the upstream role. A downstream-card instantiation could not compile against it without a wrapper. Apply Option C from issue #13 (least disruptive): - git-rename src/intercard_link.sv → src/intercard_link_upstream.sv (preserves blame; clk_p/clk_n stay output, prsnt_n stays input) - add src/intercard_link_downstream.sv with clk_p/clk_n declared as input and prsnt_n as output (downstream pulls low so upstream sees logic-0 = neighbour present) - update verif/intercard_link/test_widths.sv to instantiate BOTH role variants in the same elaboration unit - add verif/intercard_link/test_two_card_pair.sv: cross-wires upstream → downstream over the connector signal names. Verilator's multi-driver / undriven-output checks catch any future regression that flips CLK direction. Local sanity check confirmed: forcing downstream clk_p/clk_n back to output yields `%Warning-UNDRIVEN: 'clk_p'`, exit 1. - run_lint.sh now performs two Verilator passes (widths + 2-card pair) - docs/hw/intercard-connector-pinout.md §2.1 §4 §6: CLK and PRSNT_N direction explicitly tied to card role, with cross-references to ADR-003 from the per-pin table - docs/adr/0003-intercard-link-role-split.md: rationale, alternatives A/B/C/no-op, consequences, and a downstream-caller table Verilator 5.048 evidence (local): $ bash verif/intercard_link/run_lint.sh [run_lint] verilator Verilator 5.048 2026-04-26 rev v5.048 [run_lint] (1/2) widths: ...test_widths.sv → exit 0 [run_lint] (2/2) two-card pair: ...two_card_pair.sv → exit 0 [run_lint] PASS — intercard_link_upstream + intercard_link_downstream elaborate with INTERCARD_BUS_WIDTH = 128 (CLK direction split per ADR-003) and the two-card pair wires up cleanly. closes #13 refs #11, #14 Authored by Agent 2 (FPGA Hardware). Signed-off-by: Marcos <m@pop.coop>
Member
Author
Review by Agent RVerdict: APPROVE Pre-review gates (
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #13. Splits the single
intercard_linkmodule (PR #11, hardened by PR #14) into two role-specific stubs so the receiver-side card can compile cleanly without a wrapper.src/intercard_link_upstream.sv—git mvfromintercard_link.sv. CLK pair isoutput;prsnt_nisinput.src/intercard_link_downstream.sv— new. CLK pair isinput;prsnt_nisoutput(downstream pulls low).verif/intercard_link/test_widths.sv— instantiates both role variants in the same elaboration unit.verif/intercard_link/test_two_card_pair.sv— new. Cross-wires upstream's TX/CLK outputs into downstream's RX/CLK inputs over a single shared net per signal. Verilator's multi-driver / undriven-output checks turn the CLK direction contract into a structural elaboration assertion.verif/intercard_link/run_lint.sh— two Verilator passes (widths + two-card pair), exits 0 only on combined success.Design choice
Option C from issue #13 (least disruptive). Rationale and the full Options A / B / no-op discussion live in docs/adr/0003-intercard-link-role-split.md.
Quick summary:
CARD_ROLEparameter): SV 2012 forbids parameter-driven port direction; would require a wrapper module per role anyway → equivalent to C with extra indirection._core): premature factoring while bodies are stubs. Defer to the transceiver-body PR. C does not foreclose this future move.Documentation updates
docs/adr/0003-intercard-link-role-split.md— new ADR.docs/hw/intercard-connector-pinout.md§2.1, §4 (CLK and PRSNT_N rows), §6 — CLK and PRSNT_N direction explicitly tied to card role; cross-references to ADR-003.Test evidence
Verilator 5.048 (local):
Sanity check (manually flipping downstream
clk_p/clk_nfrominputback tooutputto simulate the regression mode):→ regression caught by elaboration. State restored before commit.
Out of scope
Test plan
verif/intercard_link/run_lint.shexits 0 (both Verilator passes).test_widths.svinstantiates bothintercard_link_upstreamandintercard_link_downstream;INTERCARD_BUS_WIDTH = 128confirmed.test_two_card_pair.svelaborates with upstream→downstream CLK on a single shared net.References
Authored by Agent 2 (FPGA Hardware).