Reference design¶
two_die_interposer is the worked example of the whole flow: two dies mounted
face down on an IntM4TM2 interposer, attached by two different interconnect
methods, with wire-bond I/O pads at the interposer edge. It ships in the
IHP-GmbH/ADK-Tools repository under examples/two_die_interposer/ and is baked into
the ADK-Tools image at /opt/adk-tools/examples/two_die_interposer. On first
container start a disposable copy is seeded at /work/example.
It is also the template adk-new-project scaffolds, so its directory layout
is the recommended one for your own designs.
Tip
Work on the seeded copy under /work/example, not on
/opt/adk-tools/examples. The seeded copy is disposable: delete
~/adk-work/example on the host and the next container start reseeds it
from the image.
What the demo assembles¶
Component |
Technology |
Description |
|---|---|---|
|
|
6492.312 x 5602.001 um, 300 um thick. Four routed metals, Cu-pillar
landing pads under each die, 35 wire-bond I/O pads of 100 x 100 um on
|
|
|
770 x 2606.339 um, 750 um thick, |
|
|
The same die layout, attached with |
Both dies are instances of the same Metal_Test layout, an SG13G2 test die
whose 58 external I/O pads sit on TopMetal2 (134/0) with their names on the
text layer 134/25.
The two connection stacks are what make the demo interesting, because they are
what forces every per-method mechanism in the flow to actually do something. The
die z values follow from them directly. The interposer’s attachment surface is
at 13.83 um; cupillar_opt1 is a 28 um Cu pillar plus a 16 um SnAg cap, so
U1 sits at 57.83 um; vendorx_microbump is 18 um plus 6 um, so U2
sits at 37.83 um. That arithmetic is not decoration: the 3Dblox exporter
verifies it exactly and refuses assemblies that do not satisfy it.
Directory tree¶
two_die_interposer/
README.md
chiplets/ gds2kicad prior-step inputs
README.md
Metal_Test.gds the full die layout, shared by U1 and U2
Metal_Test_stripped.gds curated: only the 58 I/O pads, with names
metal_test_chiplet.pins.json 58-pad pin list with reviewed side/type
metal_test_chiplet.g2kproj saved gds-to-kicad GUI session
kicad/ the human-authored source
two_die_interposer.kicad_pro
two_die_interposer.kicad_sch
two_die_interposer.kicad_pcb
two_die_interposer.kicad_sym project symbols, produced by gds2kicad
two_die_interposer.pretty/
metal_test_chiplet.kicad_mod die footprint, produced by gds2kicad
interposer_bondpad.kicad_mod wire-bond I/O pad footprint, parametric
sym-lib-table
fp-lib-table
outputs/ everything the export writes
two_die_interposer.chiplet open this in Chiplet Studio
MANIFEST.md index of the products
layout/
two_die_interposer_interposer.gds
two_die_interposer_interposer.boundaries.json
two_die_interposer_interposer.pillars.json
two_die_interposer_complete.boundaries.json
two_die_interposer_complete.pillars.json
two_die_interposer_complete.ixn_methods.json
reports/
two_die_interposer_assembly_drc.lyrdb
two_die_interposer_cupillar_drc.json
Four more paths appear once you regenerate, and are deliberately not tracked:
outputs/two_die_interposer.hyp, outputs/layout/two_die_interposer_complete.gds,
outputs/reports/assembly_drc/ (the DRC scratch directory) and
outputs/logs/. Everything else is committed on purpose, so a fresh clone
opens in Chiplet Studio and carries its DRC results without a rebuild.
Note
To open two_die_interposer_complete.gds in KLayout, or run the assembly
DRC yourself, regenerate the outputs first. The *_complete.*.json
sidecars are shipped, so the boundary and pillar manifests can be read
straight from a clone.
What each file is¶
chiplets/¶
Metal_Test.gds is the canonical die layout. Both the footprint and the
.chiplet reference it board-relative as ../chiplets/Metal_Test.gds, so
the export and Chiplet Studio read the die geometry from the example itself and
not from any external tool tree.
Metal_Test_stripped.gds is the frozen result of the pad review described in
From die GDS to KiCad: 58 external I/O pads out of about 474 shapes on
TopMetal2. Shipping the curated version makes the footprint a reproducible
conversion rather than the one hand-made artefact in the project.
metal_test_chiplet.pins.json carries each pad’s name and geometry plus the
reviewed symbol-layout fields side and type, which cannot be re-extracted
from a footprint. That is why the file exists rather than being derived.
metal_test_chiplet.g2kproj is a saved gds-to-kicad session bundling the
inputs, the layer selections and the embedded pin list. It stores
image-absolute paths, so it is meant for use inside the container.
kicad/¶
The board and its project libraries. The symbol library and the .pretty
footprint library are outputs of the prior steps below, committed so the board
opens without running them, and registered with the project through
sym-lib-table and fp-lib-table.
outputs/¶
two_die_interposer.chiplet is the assembly description and the entry point
for Chiplet Studio. It declares both technologies, all five connection stacks,
the interposer with its 35 I/O pads, and the two dies with their placement,
orientation, thickness and connection method.
Under layout/, the interposer GDS is the one the .chiplet references.
Each GDS has its own boundary manifest and pillar manifest as siblings, which is
how the assembly DRC and the viewer macro find them without being told.
two_die_interposer_complete.ixn_methods.json maps each interconnect method to
the dies that use it, so the DRC checks U1’s pads at 75/40 and U2’s at
50/15 instead of applying one number to the whole assembly.
Under reports/, the .lyrdb is the assembly DRC result database, openable
in the KLayout Marker Browser, and the _cupillar_drc.json is the Cu-pillar
DRC summary the producer wrote while generating the pillars.
Walking the flow¶
Step 0: open what is already there¶
From the host, using the launcher in the ADK-Tools checkout:
./run.sh chiplet-studio example/outputs/two_die_interposer.chiplet
./run.sh kicad example/kicad/two_die_interposer.kicad_pro
Or from a shell inside the container, where both tools are on the path. Expect Chiplet Studio to show the interposer slab with two dies standing off it on their pillars, and the wire-bond pads with their fan-out traces around the edge; switch a die to a detailed render mode to see its actual artwork as geometry. See Viewing and inspecting.
Step 1: the gds2kicad prior steps¶
These run once per die, before any board work, and produce the KiCad library the board is built on. They are reproducible from the shipped inputs, and the image build gates them against the committed library.
The die footprint, read straight out of the curated GDS:
gds_to_kicad.py Metal_Test_stripped.gds \
--layer TopMetal2.drawing --text-layer-number 134/25 \
--lyp-file $GDS_TO_KICAD_ROOT/pdks/sg13g2.lyp --flip-chip \
-o metal_test_chiplet.kicad_mod
The die symbol, from the reviewed pin list, with no GDS involved:
gds_to_kicad_symbol.py --from-pin-list metal_test_chiplet.pins.json \
-o Metal_Test.kicad_sym
The wire-bond I/O pad, generated parametrically rather than converted:
$GDS_TO_KICAD_ROOT/io_pads/generate_io_pad.py --io-class wire_bond --size 100x100
The same three steps are available from the gds-to-kicad GUI, and
metal_test_chiplet.g2kproj reopens the session at exactly the state that
produces the footprint and the symbol. See From die GDS to KiCad.
Note
--flip-chip on the footprint conversion is not cosmetic. The die is
mounted face down, so its pads are mirrored in the board frame. This is the
same mirror the assembly generator applies to the die artwork, and the same
one the pad-to-pillar check models. Getting it wrong produces an assembly
where every pad is on the wrong side and every individual check still passes.
Step 3: export and generate the GDS¶
Normally this is the Chiplet Export plugin inside pcbnew, with its output
directory pointed at the sibling outputs/. The demo’s headless equivalent,
which is exactly what the image build runs, is:
python3 /opt/adk-tools/chiplet_kicad_plugin/tests/regenerate_wirebond_demo.py \
--require-drc \
--board example/kicad/two_die_interposer.kicad_pcb \
--output-dir example/outputs
One command drives the whole chain: the HyperLynx writer produces the .hyp,
the chiplet writer produces the intermediate .chiplet, hyp_to_gds
produces both GDS files with their sidecars and finalises the .chiplet, and
the ADK assembly DRC runs on the complete GDS. --require-drc makes a DRC
failure a non-zero exit, which is what turns this into a build gate.
The script prints the resolved artefact paths as it goes, and echoes the worker
command lines it runs, so it doubles as a way to see the exact hyp_to_gds
invocation for a given board.
Step 4: the assembly DRC on its own¶
The export runs the DRC for you. To run it again by hand against the
regenerated complete GDS, with the same adapters and per-method scoping the
pipeline derives from the .chiplet:
adk-drc \
--path example/outputs/layout/two_die_interposer_complete.gds \
--interposer-adapter intm4tm2 \
--interconnect-adapter vendorx_microbump \
--interconnect-methods example/outputs/layout/two_die_interposer_complete.ixn_methods.json \
--report example/outputs/reports/two_die_interposer_assembly_drc.lyrdb \
--run_dir example/outputs/reports/assembly_drc
The boundary manifest is not on the command line because the runner
auto-discovers two_die_interposer_complete.boundaries.json next to the GDS.
The runner logs a pass or fail banner and the report path; a violation leaves
items in the .lyrdb under the rule that flagged them.
Step 5: checks the demo does not run for you¶
Only stage 3, the KLayout assembly DRC of step 4, is part of the demo pipeline.
The other three of the four verification stages are not. Two of them you can run yourself
against the shipped artefacts, and they are given below. The third, the KiCad
design-time check, cannot be run here at all: the demo kicad/ tree ships no
generated .kicad_dru, so there is nothing for pcbnew to enforce. Generate
one as KiCad DRU generation describes before using this example as the
template for a design of your own.
Pad-to-pillar alignment, which needs the .chiplet, the pillar manifest and a
pad source per die:
python3 $ADK_ROOT/checks/pads_vs_pillars.py \
--chiplet example/outputs/two_die_interposer.chiplet \
--pillars example/outputs/layout/two_die_interposer_complete.pillars.json \
--pins U1=example/chiplets/metal_test_chiplet.pins.json \
--pins U2=example/chiplets/metal_test_chiplet.pins.json \
--json pads_vs_pillars.json
The 3Dblox export, whose own consistency checks run without OpenROAD installed:
python3 $ADK_ROOT/openroad/chiplet2dbx.py \
--chiplet example/outputs/two_die_interposer.chiplet \
--out-dir build/3dblox \
--pins U1=example/chiplets/metal_test_chiplet.pins.json \
--pins U2=example/chiplets/metal_test_chiplet.pins.json
Running check_3dblox on the result additionally needs an OpenROAD image
carrying the 3Dblox commands. See Verification stages.
Step 6: the one-command self test¶
adk-smoke
adk-smoke verifies that the intm4tm2 KLayout technology is registered
and its layer properties resolve, then exports the demo end to end into a
throwaway directory with --require-drc and asserts the DRC passed. It is the
fastest way to tell whether a container, or a hand-assembled toolchain, is
wired correctly. On success it ends with the line
adk-smoke: PASS (export + assembly DRC green); any failure exits non-zero
before that.
What the committed reports say¶
Two result files are tracked, so you can read the demo’s verification outcome without running anything.
reports/two_die_interposer_cupillar_drc.json records the producer-side
Cu-pillar checks: version 2 of the report format, the per-die method assignment
(U1 to cupillar_opt1, U2 to vendorx_microbump), the parameter set
each method was checked with, and a summary of zero errors, zero warnings and
ten informational results across ten checks over two devices, with passed
true.
reports/two_die_interposer_assembly_drc.lyrdb records the assembly DRC. It
carries eleven rule categories and no violation items:
ASM.a ASM.b ASM.e ASM.f
IXN.b.cupillar_opt1 IXN.e.cupillar_opt1
IXN.b.vendorx_microbump IXN.e.vendorx_microbump
IXN.x.cupillar_opt1.vendorx_microbump
IXN.b.unclaimed IXN.e.unclaimed
That list is the interesting part. The per-method categories show the two dies
being checked at their own numbers; IXN.x is the conservative cross-method
spacing between the two bump fields, at the larger of the two spacings; and the
unclaimed categories cover any attachment pad that falls under no die’s
boundary, checked with the assembly-level adapter’s numbers.
Reproducibility¶
The demo outputs are not decorative. The image build regenerates them headless
from the board and then compares the fresh regeneration against the committed
tree, failing the build on any semantic difference: a committed deliverable a
fresh run no longer produces, a new sidecar a fresh run emits that is not
committed, or a change in the .chiplet, the manifests, the reports or the
GDS geometry.
The comparison is not a naive byte diff. GDS files are hashed with the
BGNLIB and BGNSTR timestamps zeroed, so a real geometry, layer or cell
change is caught while KLayout’s per-run header timestamp is not. Boundary
manifests are compared with assembly_gds_sha256 dropped, for the same
reason. Per-run artefacts, the logs, the DRC scratch directory, the .lyrdb,
the complete GDS and the .hyp, are ignored.
The gate exists because the runtime image bakes the tracked deliverables rather
than the regeneration, so a tracked set that had drifted from what the current
board and toolchain produce could ship on a green build. A stale .chiplet and
a missing pillar manifest reached a release candidate that way.
What the demo demonstrates¶
A die layout becoming a KiCad symbol and footprint, reproducibly, from shipped inputs.
An interposer authored in KiCad on process-named copper layers, exported to a
.chipletassembly and a HyperLynx netlist.Routing becoming fabrication geometry: paths on real process layers, vias from the base PDK’s
via_stackPCells, the board outline onprBoundary.Cu-pillar generation from per-die pin lists, with two different interconnect methods in one assembly, each checked against its own rules.
Flip-chip placement of both dies, mirrored per layer in the assembly GDS.
Wire-bond I/O pads placed on the interposer and recorded in the
.chiplet.The manifest sidecars, and both consumers of them: the assembly DRC and the boundary viewer.
A per-method assembly DRC run that passes, including cross-method spacing.
3D inspection of the finished assembly, with drill-down into the real layouts.
What it does not demonstrate¶
Two different dies.
U1andU2are two instances of the same layout. Nothing in the flow requires that, but the demo does not exercise a genuinely heterogeneous die set.A stacked or multi-tier assembly. Everything sits on one tier. The assembly rules assume that, and
ASM.awould flag legally stacked dies as overlapping.Automated 2.5D place and route. That work is a proof of concept and is not part of this example. See Roadmap.
The interposer’s or the dies’ own fabrication rules. The example runs the assembly checks only. The interposer PDK and the die PDK own their decks, and running them is a separate step.
Thermal, power-integrity or timing analysis. Those ADK domains are reserved names with no implementation.
A fabricated assembly. The interposer process has been fabricated several times at IHP, which is a statement about process maturity. This example is a design flow demonstration, and no complete assembly built from it has been manufactured.
A vendor-qualified fine-pitch method.
vendorx_microbumpis a deliberately synthetic, non-IHP method, present so that the per-method machinery has two methods to distinguish. Its numbers are demonstration values.
Starting your own design¶
adk-new-project my_design
This scaffolds /work/heterogenic-designs/my_design with the same
kicad/ plus chiplets/ plus outputs/ split, and a .gitignore
already keeping the heavy and scratch files out of version control while
tracking the light deliverables. Author the board under kicad/, run the
Chiplet Export plugin with its output directory set to the sibling
outputs/, and open the result with chiplet-studio.