CoHDL
  1. Blog
  2. CoHDL 0.10.0

CoHDL 0.10.0: Supplier
Part Bindings

A library part can now name the part number its assembler stocks, and say how the assembler's footprint sits on its land. The compiler turns that into a placement file and per-supplier BOM and CPL files.

Compiler v0.10.0 was released on . It is available for all five supported platforms. It implements RFC-034, supplier part bindings, accepted on October 30.

A design names parts by manufacturer and part number. An assembly house works from its own stock numbers, and from its own idea of where each footprint's origin and pin 1 are. That gap was filled by hand after export: a spreadsheet column of stock numbers, and a rotation fix for every part the assembler's preview showed turned. CoHDL 0.10.0 lets the library record both, once, next to the part.

A binding lives on the part

An approved-vendor entry can carry a supplier clause with the supplier's part number. This chip resistor binds its Vishay alternate to an LCSC number:

passive 0.2.4, resistors_0402.cohdl
pub part R_1K58_F_0402: ChipResistor<1.58kohm, 1%>[R0402] {
    primary { mfr: "Yageo", mpn: "RC0402FR-071K58L", footprint: CHIP_0402 }
    alt { mfr: "Vishay", mpn: "CRCW04021K58FKED", supplier lcsc "C3009257" }
}

When the assembler's footprint does not sit on the library's land the same way, the binding records the difference as an offset and a turn. The compiler composes it with every placement, so the design's own place statements never change:

@st/stm32 0.3.0, f4.cohdl
primary { mfr: "STMicroelectronics", mpn: "STM32F427VGT6",
          footprint: qfp::KICAD_LQFP_100_14X14MM_P0_5MM, supplier lcsc "C117815" rotate 270 }

Supplier IDs are an open set. The compiler gives lcsc no special meaning; it checks that a part number names one manufacturer part across everything the design compiles (E813). A binding changes no connection, no geometry and no verdict.

What a build writes

Every physical build of a placed design now writes a supplier-neutral placement file, <name>-cpl.csv, using KiCad's bottom-side angle convention. An outlined .kicad_pcb carries the same origin as its auxiliary axis, so positions exported from KiCad are measured from the same point. Machine-placed parts without a placement are named (E815).

--supplier ID adds that supplier's BOM, its placement file, and a map recording which entry each instance took. For each instance the compiler takes the primary entry if it is bound, otherwise the first bound alternate on the same footprint. A design whose parts carry no binding for that supplier gets a warning (E814). Here is a two-resistor divider, with the second resistor on the bottom side:

$ cohdl build ./divider --supplier lcsc
$ cat out/divider-lcsc-bom.csv
Comment,Designator,Footprint,LCSC Part #
"CRCW04021K58FKED","R1","CHIP_0402","C3009257"
"RC0402FR-0747KL","R2","CHIP_0402","C93943"
$ cat out/divider-lcsc-cpl.csv
Designator,Mid X,Mid Y,Layer,Rotation
R1,10.0000mm,-14.0000mm,Bottom,270
R2,10.0000mm,-10.0000mm,Top,90

R1 took its bound Vishay alternate; R2 kept its bound Yageo primary. Assemblers disagree about bottom-side angles, so the convention is chosen when you export, never in source: --bottom-rotation lcsc=mirrored switches it for one supplier. The KiCad netlist also carries the part number of each bound primary entry; R2's LCSC field reads C93943.

Check bindings against the catalog

cohdl suppliers compares a design's bindings with the registry's supplier catalog: it reports whether each part number is known and whether it names the same manufacturer part. It is the only online step; check and build stay offline.

$ cohdl suppliers ./divider
lcsc passive::R_1K58_F_0402 alt[0] ok pn=C3009257 mfr="Vishay" mpn="CRCW04021K58FKED"
lcsc passive::R_47K_F_0402 primary ok pn=C93943 mfr="Yageo" mpn="RC0402FR-0747KL"

It exits 3 when a binding is unknown to the catalog or disagrees with it. cohdl search gains --supplier and --class filters for part results.

The first bound parts

Thirty-nine library parts ship with an LCSC binding. Each part number was confirmed on its supplier page, and each footprint's orientation was read on JLCPCB's placement preview of a test board. The MCUs were placed on both sides, at 0° and at 37°; the passives once each:

The registry's LCSC catalog holds 1,442 parts. Unbound parts stay usable as before; they simply have an empty part-number column in a supplier BOM.

Footprints that turned

The first preview showed some footprints a quarter turn off the assembler's models. Rather than carry a correction on every binding, the land packages moved those footprints onto the assembler's frame in new versions: soic@0.3.0, qfp@0.3.0 and transistor@0.2.0, with every dependent package bumped to match. Pad numbers and land sizes are unchanged, but pads, courtyard and silkscreen turn together.

This is a breaking change that check and build will not flag. Before running cohdl update on a design that places one of these footprints, run tools/realign_place.py from the repository, which rewrites each place by the inverse turn and keeps an undo log. Each package's README lists the footprints that moved. Earlier versions stay available unchanged.

Get the update

Compiler 0.9.0 cannot parse supplier clauses, so passive@0.2.4 and @st/stm32@0.3.0 need 0.10.0. Update the compiler first, then the packages, after migrating any placements of the footprints above:

cohdl self-update
cohdl update ./board
cohdl build ./board --supplier lcsc

For a new installation, follow the getting-started guide. The v0.10.0 release page has this version's platform archives and checksums; the full comparison records the source changes.