Alembic Language Guide
Alembic is a Scala-inspired DSL for describing wafer pipelines, packaging flows, and the metadata that travels with them. This book is the canonical place for tutorials, patterns, and the language reference.
What this book covers
- Orientation and quick-start examples.
- A tour of core syntax and idioms.
- Reference conventions for types, verbs, and lifecycle hooks.
- Tooling tips for building, testing, and publishing Alembic packages.
Writing style
- Favor runnable snippets and keep inputs/outputs explicit.
- Tag stability levels (experimental, stable, deprecated) alongside language levels (L1, L2, …).
- Cross-link recipes back to the reference entries that define them.
Getting Started
Alembic scripts are small, composable descriptions of wafers and packages. A minimal file looks like this:
pipeline wafer_map {
define die "sensor" {
size 6.5 mm by 7.2 mm
process "28nm-fdsoi"
}
route metal[1..3] {
width 40 um
spacing 40 um
via "v1" every 120 um
}
validate with drc_profile "foundry-a"
export gds "build/sensor-top.gds"
}
Key ideas:
- Everything starts at a
pipelineroot; nested blocks describe dies, routes, checks, and exports. - Types stay close to verbs (e.g.,
routeintroducesmetalandviabindings). - Profiles (like
drc_profile) keep fab- and package-specific rules separate.
Next: expand the syntax and learn how to structure larger flows in the Language Tour.
Language Tour
Alembic borrows expression clarity from Scala while keeping domain verbs first. This tour sketches common constructs before you dive into the full reference.
Pipelines and profiles
Use profiles to scope capabilities to fabs, packaging flows, or bring-up teams.
pipeline pkg_profile(profile = "packaging") {
define package "fcBGA-900" {
layers 12
ball_map "maps/fcbga-900.csv"
}
publish manifest "artifacts/pkg-manifest.yaml" with {
stability = stable
level = 2
}
}
Data shapes
- Scalars:
length,layer,material,via,temp. - Collections:
stack,array,bundle,grid. - Qualifiers: tolerances, confidentiality scope, revision tags.
Composition patterns
- Keep verbs narrow:
definefor naming artifacts,routefor geometry,simulatefor analysis,publishfor outputs. - Store fixtures per language level (
examples/L2/route-basic.alembic) so behavior stays reproducible. - Prefer pipelines that return explicit artifacts so CI can diff and cache them.
Reference Style
Reference entries follow a consistent shape so they are easy to scan and automate against.
Definition block template
verb: route
intent: describe metal and via steps for a stack
inputs:
- stack: layer[]
- constraints: drc_profile
outputs:
- map: wafer_map
notes:
- profiles: fab, packaging
- stability: stable (L2)
- examples: /examples/route-basic, /examples/route-high-density
Conventions
- Every verb states stability and the language level that introduced it.
- Inputs and outputs are typed; optional fields are called out explicitly.
- Cross-link recipes and longer walkthroughs back to the verb that powers them.
- Keep changelog snippets near the entry so upgrades are obvious.
Indexing and IDs
- Assign a stable slug per symbol (e.g.,
verb.route,type.layer) so generated references can cross-link reliably. - Emit a machine-readable index (JSON) from the compiler to keep
SUMMARY.mdand link targets in sync. - Favor relative links; mdBook is served at
/alembic, so assets resolve without additional configuration.
Tooling & Workflow
Build the book
mdbook build docs/alembic
This writes the rendered site to docs/alembic/book/, which the server serves at /alembic.
Keep examples runnable
- Tag code fences with
alembicand add a small runner in CI to execute them against the compiler. - Store fixtures alongside chapters (e.g.,
src/examples/route-basic.alembic) so updates stay local. - Capture outputs and wire them back into the docs to prevent drift.
Versioning and compatibility
- Track language levels in the docs; prefer adding
since = "L2"frontmatter fields. - For breaking changes, add a short migration section and point to the previous level’s examples.
- Use
site-url = "/alembic/"inbook.tomlto keep links stable when the book moves.
Appendix
- Profiles: fab, packaging, bringup. Add new profiles by defining capability flags and default fixtures.
- Stability tags:
experimental,stable,deprecated. Surface them in the reference and changelog. - Artifacts: prefer structured outputs (
manifest.yaml,wafer_map.json,package.drc) so CI can diff. - Style: keep sentences short, show inputs/outputs together, and link to runnable examples.
Analog CHISEL-style Example
A short Alembic snippet in Scala style for an analog front-end block. Think of it like a Chisel module, but geared toward analog constraints and packaging details.
package alembic.examples.afe
import alembic.core._
import alembic.analog._
object DiffSenseAmp extends AlembicModule {
val clk = Clock("clk_100mhz")
val diffIn = Analog("diff_in", MilliVolts(10))
val ref = Analog("vref", Volts(1.0))
val out = Analog("out", Volts(1.8))
// Geometry + routing hints live with the block.
route stack("metal1" to "metal3") {
width = Microns(0.6)
spacing = Microns(0.6)
shield = Some("ground-ring")
matchLength(diffIn.p, diffIn.n, tolerance = Microns(5))
}
// Device-level intent alongside package hooks.
define differentialPair("input") {
gmTarget = MilliSiemens(2.5)
vcm = Volts(0.8)
maxOffset = MilliVolts(3)
packagePin = Ball("A12")
}
validate with drcProfile("foundry-a-28nm")
simulate transient {
sources = List(Pulse(diffIn, amplitude = MilliVolts(6), rise = PicoSeconds(30)))
stop = NanoSeconds(20)
}
export gds "build/diff-sense-amp.gds"
export lef "build/diff-sense-amp.lef"
export json "build/diff-sense-amp.manifest.json"
}
Highlights:
- Verbs stay narrow (
route,define,validate,simulate,export) and colocate physical and simulation intent. - Analog-aware types (volts, millivolts, microns, pico/nanoseconds) keep units explicit.
- Package-facing details (like
packagePin) live with the design, so package teams and fab teams share the same source.