diff-pair-naming

A differential-pair positive net (_P / _DP / trailing +) has no complementary negative net, and the board declares no pair for it.

Remedy

Add the missing complementary net, or rename the net if it was never half of a pair. Left as it is, the layout tool routes the two as ordinary signals and the link is not a differential pair at all.

What it means

A net named as the positive half of a differential pair (a “_P”, “_DP”, or trailing “+” suffix) must have a matching negative half ("_N", “_DN”, or trailing “-”).

Why engineers want it

High-speed signals travel as complementary pairs. The naming convention declares the pair to every downstream tool that must route the two nets together with matched length. The two halves are authored separately, and nothing but the name ties them, so a typo or a deleted net silently breaks the pair.

Impact

The layout tool never couples the two nets, so they get routed like ordinary signals and the link fails signal integrity.

A positive net with no matching negative half is flagged; a complete P/N pair is fine

A declared pair passes on the declaration

Some boards declare their pairs. An Allegro board records each pair in its constraint manager, so USB1_DP and USB1_DM pair because the designer paired them, and DDR1_CLK0 pairs with DDR1_CLK0N though no suffix says so. The rule reads those pairs first (net.group, agni issue 1360). A declared pair passes, and the witness names both nets and the pair. A pair is one verdict, on the member whose name reads as the positive half.

A net the board declares in no pair is still judged by its name, as below. A design that declares any pair uses differential pairs, so the gate in the next section is open on it.

Positive-anchored on purpose

Detection anchors on the positive member. A lone “_N” suffix is ambiguous with active-low signals (RESET_N, WE_N), so treating every “_N” as an orphaned pair half would fire on the most common real naming convention. A positive suffix does not carry that ambiguity. The cost is that a stray negative with no positive is not reported, and the positive anchor accepts that cost.

Only when the design uses the convention

The rule fires only on a design that shows it uses differential pairs at all. That means it declares a pair, or at least one complete pair by name (some X_P with a matching X_N) exists somewhere. A suffix like _P is weak evidence on its own. Combinational netlists (the LGSynth benchmark family, for example) carry hundreds of _P-suffixed signal names that are not differential, and without this gate every one of them is a finding. Requiring pair-population evidence takes those designs to zero. A real board does declare complete pairs, so it still surfaces its broken ones.

The cost falls on a design with one differential pair that is itself broken (one X_P, no X_N, and nothing else paired). That design reports not-considered rather than a finding. That is the same weak-signal case, so the trade is deliberate. An operator who wants a stricter policy can add a naming convention via --conventions.

For a software reader, this is the difference between “the string ends in _P” and “this codebase uses a _P/_N pairing convention that this one member violates.” The second is only a bug if the convention is in use.

Query structure

Gate on pair-population evidence, then select the positive-suffix nets the design declares in no pair and whose expected complement is absent.

diff_convention_present(design)
  and select N in nets where is_pos_diff(N) and not declared_pair(N)
    and not has_net(expected_negative(N))

Reads: net.names, net.group. Primitives: pattern (the suffix), pair (the P-to-N lookup and the convention-present check). Tier R.