verify module#

JS3 Part 2 verification designs: prove the USB constraint binds through the pin-assigned ESD channels.

Each design wraps the shipping UsbEsdCircuit unchanged, places the USB parts and closes both legs with code Route``s that end on the ESD array's physical pads, so the routes pick one of the provider's mappings. These routes fix the mapping, which is why they live here and never in ``main.py.

  • UsbEsdProof: D+ on CH1, D- on CH2.

  • UsbEsdProofSwapped: the other channel pair with the polarity choice reversed, D+ on CH4 and D- on CH3.

  • UsbEsdProofIllegal: D+ on CH1, D- on CH3, a pairing the datasheet does not document and the provider does not offer. The runtime settles on one offered mapping and drops the routes that conflict with it.

The pass-through. Each leg also gets a route from its channel’s land to the n.c. land opposite (datasheet Fig. 15). The two lands share a net (esd.ProtectedPair), and without copper between them the report says “Unconnected Topology” at the ESD. They are separate ports of the PUSB3FR4 model on purpose: with one port mapped to both lands, the path end lands on either of them from one run to the next, and the same design passes or fails at random (jitx 4.6.0rc10, runtime 4.6.0-rc.16).

Geometry. The RP2040 has USB_DP to the left of USB_DM as the pair leaves the package, and the receptacle has D+ (A6) to the right of D- (A7) as the pair arrives, so the two legs must cross once. The D- leg crosses under D+ on the bottom layer through two THVia_L1_L20. JS1 gives its vias no SI models (see its module docstring), so the report flags a placeholder model on that leg; the measurement still appears.

Routing structure. DRS_100 keeps 0.5944 mm clearance on the outer layers, more than the gap beside a 0.4 mm pitch QFN pad or a 0.5 mm pitch DFN land, so a route under it cannot reach these parts (“Unrealizable Route: Insufficient space”). The proof routes therefore carry JS1’s Neck_SE geometry (0.15 mm line, 0.15 mm clearance) through a Route tag rule above the constraint’s structure. Neck_DIFF_100 would fit too, but it has no uncoupled region, and where the pair splits at the pads the report then says “Missing routing structure”. The neck geometry shortens the clearance, so these proofs show binding, not that a DRS_100 route fits: that is the board router’s job, with neck regions.

class ProofNeck[source]#

Bases: Tag

Proof routes, given JS1’s Neck_SE geometry.

class UsbEsdProofCircuit(p_ch, n_ch)[source]#

Bases: Circuit

UsbEsdCircuit placed and code-routed with D+ on p_ch and D- on n_ch.

Parameters:
class UsbEsdProof[source]#

Bases: Design

D+ on CH1, D- on CH2.

board: Board = HDIBoard()#
substrate: Substrate = HDISubstrate()#
class UsbEsdProofSwapped[source]#

Bases: Design

D+ on CH4, D- on CH3.

board: Board = HDIBoard()#
substrate: Substrate = HDISubstrate()#
class UsbEsdProofIllegal[source]#

Bases: Design

D+ on CH1, D- on CH3: not an offered mapping.

board: Board = HDIBoard()#
substrate: Substrate = HDISubstrate()#