Vyges Loom · Physical construction

vyges-ppl

Put the IO pins where they cost the least wire.

Optimal matching within each section — with excluded regions, region constraints, pin groups and mirrored pairs all honoured, not approximated.

View source on GitHub →

What it does

Used by: anyone placing pins on a block boundary, where a bad assignment costs wirelength on every net that crosses it.

Every pin on a block boundary is a decision that the router then has to live with. Placed badly, pins add wire to every net that reaches them — and unlike most placement problems, this one has a clean optimum within a section.

vyges-ppl generates the legal slots from each layer’s routing tracks, cuts them into sections, and solves the assignment optimally inside each one — cost being half-perimeter wirelength over the net bounding box.

.odb + layer choice + constraints  ──►  vyges-ppl  ──►  pin positions, total wirelength, unplaced pins named

A constrained pin that does not fit is reported unplaced, not relocated

If you constrain a pin to a region and it does not fit, this says so. It does not put the pin somewhere else and call the job done — the design asked for a region, and somewhere else is not a smaller version of that answer.

The same principle runs through the ordering. Constrained pins are placed before free ones, and their slots are withdrawn, because the reverse order lets a pin with alternatives take the only position a constrained pin had. Groups go before individual pins, since one pin dropped into the only long-enough run destroys it irrecoverably. Mirrored pairs go first of all — they need two positions open at once, so they have the least room to manoeuvre.

A mirrored pair is one decision, not two: if the reflection is unavailable, both halves are reported unplaced. Half a pair is a broken symmetry, not a partial success.

Score your current placement against it

The optimal assignment cost is unique, but the optimal pairing is not: two placements can swap a pair of pins and both be exactly right. So a placement that looks different from yours is not necessarily a worse one — and you should not have to guess which.

That is what --evaluate is for: hand it the placement you are using today and it scores that under the identical cost model. One number, one run, and you know whether changing anything is worth your time — before you rebuild a flow around it. So far it has matched or beaten every placement scored this way, and never come out worse.

Scope, stated plainly: it reports the chosen positions rather than writing pin rectangles into the database, which depends on pin-length handling that is not built. Slot availability accounts for excluded regions and fixed ports’ metal, but not yet for macros or routing obstructions — so where a macro abuts the boundary, availability stays optimistic. Both are in the engine’s own --describe, so neither is a surprise you find later.

Try it

$ vyges install physical   # one-time: fetch the construction engines into ~/.vyges/bin
$ vyges physical ppl slots design.odb --hor-layers met3 --ver-layers met2   # what slots exist, and why
$ vyges physical ppl place-pins design.odb --hor-layers met3 --ver-layers met2   # assign the pins optimally
$ vyges physical ppl place-pins design.odb ... --min-distance 2 --corner-avoidance 5   # spacing and corner keep-out
$ vyges physical ppl place-pins design.odb ... --evaluate reference.json   # score someone else’s placement the same way

Reports the assignment and its total wirelength as JSON, and names every pin it could not place — a clean run never hides an unplaced pin.

Where it sits in the flow

After the die and core exist (vyges-ifp) and before routing, since the router needs to know where the boundary pins are. Constraints are read back from the database, where the flow stores them — not passed on the command line — so a constraint set by an earlier step is honoured without being restated.

Open core · Apache-2.0

A clean-room Rust engine writing the shared design database through vyges-opendb, so the block you check is the block you built. See all the engines & the data spine →