Component libraries are a central part of the SchematicEditor. Every placed device is a reference into a library: the library definition ties together
Without a matching library entry, a schematic can open only as graphics—pins, simulation, and layout generation have nothing to bind to.
.lel format.lel (LayoutEditor Library) is the native library format that supports the full set of options the SchematicEditor understands: parameters with formulas, multi-symbol devices, all layout backends ([cell], [macro], [oa], [tcl], [gdsFactory], …), netlist/model per format, extraction hooks, links, and more.
Foreign library/symbol formats (LTspice .asy, xschem .sym, Qucs, Eagle, KiCad, OpenAccess components, …) are converted into this internal component model when opened or imported. After that conversion, the SchematicEditor works on the same in-memory representation that .lel stores. Saving a library as .lel persists the complete native definition; other formats are import sources, not a second equally complete store.
Schematics themselves are stored in LES and reference library components by name + library. Hierarchy may embed a full component copy inside LES as SubComponent (same tag family as below); shared reusable libraries should still live in .lel.
.lel file (or other supported library sources, which are mapped into the same model)..lel on save..lel (or OA library) per team for a PDK or company kit; keep component names stable when schematics already reference them.LEL is a UTF-8 text format in XML style—not strict XML. Many tags are opening-only; field order matters. Prefer round-tripping through Edit Component when unsure.
Same entity encoding as LES for single-token fields:
| Character / value | Stored form |
|---|---|
| space | &sp; |
< |
< |
> |
> |
" |
"e; |
' |
’ |
| newline | &newline; |
| empty string | |
Raw multi-line bodies (not entity-encoded): Description, Layout, Label, Netlist, Model, extraction bodies. Graphic colors: wire or #rrggbb / named color.
A .lel file may contain any number of the following. Text outside these blocks is ignored.
<Info>
optional library-wide notes
</Info>
<Category group-name>
componentA
componentB
</Category>
<Component component-name>
…
</Component>
<Info> … </Info>Optional free-text information for the whole library (shown in library/info UI).
<Category name> … </Category>Groups component names for the Components dock / filter UI.
name.<Component name> … </Component>One complete device definition. The name is the type name used in placements (<Component … name library> in LES).
These tags appear inside <Component> (and the same payload is used inside LES <SubComponent> for embedded hierarchy).
<Description> … </Description>Free-text description (may include a URL). Raw text.
<Prefix prefix>Device-name prefix for generated instance names / netlists (opening-only). Empty linked prefixes may be written as _.
<Parameter> … </Parameter>Parameter declarations for the component type.
Declaration lines (pseudo-tags):
| Declaration | Meaning |
|---|---|
<string name [default]> |
String parameter |
<int name [default]> |
Integer (integer accepted on read; writer uses int) |
<double name [default]> |
Floating-point |
<list name v1 v2 …> |
Choice list; with pcbPackage=true values come from the PCB catalog |
Option lines until the next <…> declaration:
| Option | Meaning |
|---|---|
callback=… |
Callback / UI hook |
unit=… |
Unit label |
info=… |
Help text |
edit=… |
Edit policy |
display=… |
Display hint |
parse=true |
Value is an expression (true / True / TRUE / t) |
parseAsNum=false |
Disable numeric parse force |
multiplier=true |
Multiplier-style parameter |
pcbPackage=true |
PCB package selector |
<Label> … </Label>Instance label template ($devicename, $value, other $parameters). Raw text.
<Symbol [index]> … </Symbol>Symbol graphics for slot index (optional; default 0). Repeat for multi-symbol / multi-gate devices.
Primitives inside Symbol (one opening tag per line):
| Tag | Fields (summary) |
|---|---|
<Line x1 y1 … color> |
Polyline |
<Polygon … color> |
Filled polygon |
<Circle x1 y1 x2 y2 color> |
Bounding-box circle |
<Rect x1 y1 x2 y2 color> |
Rectangle |
<Arc … color> |
Arc |
<Text x y size [rotation] color text> |
Text |
<Port x y name [global\|local] [type] [symbolName]> |
Pin |
<Busport x y name [type] [symbolName]> |
Bus pin |
<Offsetlabel angle offsetX offsetY>Default label offset for a given placement angle (opening-only; zero offsets omitted on write).
<Layout> … </Layout>Schematic-driven layout recipe. See Layout section below—this is the link from the schematic device to a layout cell, macro, OA view, Tcl/gdsFactory generator, or package footprint.
<Netlist format> … </Netlist>Netlist line template for a named format (spice, hspice, spectre, …). Placeholders such as $devicename, $node(port), $value. Repeat per format.
<Model format> … </Model>Model / subcircuit text emitted once per component type (not once per instance), per format.
<netlistFromSchematic/>Self-closing flag: hierarchical netlist/model content is generated from the defining schematic sheet.
<Extraction method> … </Extraction>Device extraction setup.
<ExtractionParameter> … </ExtractionParameter> — raw text <ExtractionDeviceParameter> … </ExtractionDeviceParameter> — raw text <Proc formInitProc doneProc>Optional form-init and done procedure names (opening-only; written only if set).
<OaStoreLayoutOnly true|false>OpenAccess storage policy (opening-only).
<Link type [cell] [library]>Component is a link (e.g. to another component, or special link types). Opening-only. Used for linked definitions; parameters/prefix may still be present.
<Layout>)The Layout body is plain text, not XML tags. It is evaluated during schematic-driven layout when the netlist tool resolves a device to a layout cell.
[ starts a section (e.g. [cell]). Section names are case-sensitive.# is a comment (ignored).The condition is matched against a device token string built roughly as:
<componentTypeName> <param1=value1> <param2=value2> …
(instance parameters as produced for SDL). Matching rules (canUse):
| Condition | Meaning |
|---|---|
* |
Always matches (unconditional default) |
| exact string equal to the full device token string | Matches |
| one or more tokens (space-separated) | Matches if every given token appears in the device token list (case-insensitive subset match) |
Examples:
* → always
output=X1 → devices whose parameter set includes output=X1
PMOS w=0.15 → both tokens must be present
* is not a filename or cell-name wildcard—only a condition wildcard.
For [package], a row can also match when the instance’s package parameter equals the condition (usePackage), in addition to normal canUse matching.
Relative file paths in layout rows are resolved relative to the directory of the .lel file (unless absolute / drive-letter paths).
Unknown names are ignored (their data rows do nothing).
types[ignore]Skip this device for SDL (no layout cell).
[ignore]
# ignored for parameter
*
| Column | Meaning |
|---|---|
| condition | Which devices to ignore |
Typical use: simulation-only components, supplies, or variants that must not create layout.
[cell]Import or reuse a layout cell from a file (or from the currently open layout).
[cell]
#for parameter layout file cell [pins…]
* lib/AND.gds AND2 A B Y
output=X1 . AND3_X1
| Column | Meaning |
|---|---|
| condition | Match rule (see above) |
| layout file | Path to a layout file to import, or . = use/create the cell in the currently open layout database |
| cell | Cell name inside that file. . as cell name is replaced by the condition/device string used for the match |
| pins… | Optional pin names in connection order; fill empty connection names on the device |
If the cell is missing and the file is ., an empty cell with that name may be created. Otherwise the file is imported and the named cell must exist.
[package]PCB / footprint style: import a cell, clone it under a unique name, rewrite texts.
[package]
#for parameter layout-file cellname [portname pinnumber]… (nc = not connected)
* pcb/SO8N.gds SO8N in+ 3 in- 2 out 1
Package=SO8N pcb/SO8N.gds SO8N …
* . $package …
| Column | Meaning |
|---|---|
| condition | Match rule, or equals the instance package parameter |
| layout-file | Footprint file (relative to .lel, or absolute). With PCB catalog packages, the shipped pcb/ catalog may supply the file |
| cellname | Cell to import. . → take from instance parameter package. $paramName → take cell name from that instance parameter (PCB package parameters can redirect into the catalog / KiCad .kicad_mod paths) |
| port / pin pairs | Repeated: schematic port name, then footprint pin number text to replace. Use port nc to remove that pin text from the footprint |
On use, texts devicename and type in the footprint are replaced; a unique cell name is generated (component + device / package / condition).
[macro]Run a LayoutEditor .layout macro as a parametric cell generator.
[macro]
#for parameter macro-file pins
* pcb/capacitor.layout pin1 pin2
| Column | Meaning |
|---|---|
| condition | Match rule |
| macro-file | Path to the .layout macro (relative to the .lel directory unless absolute) |
| pins… | Optional pin names in order |
The macro is executed with defines such as:
| Define | Content |
|---|---|
NETLIST_PIN<n>_NAME |
Pin name for pin n (1-based) |
NETLIST_DEVICENAME |
Instance device name |
NETLIST_PARAMETER |
Device parameter/token string |
NETLIST_PATH / NETLIST_LIBRARYPATH |
Library directory |
NETLIST_MACROPATH |
Directory of the macro file |
The layout cell that is current after a successful macro run becomes the device cell. Macros may also declare their own #parameter / #parameterDouble / #parameterInt headers for interactive PCell use.
[oa]Load a cell from an OpenAccess library.
[oa]
#condition lib cell view
* pdk nmos layout
| Column | Meaning |
|---|---|
| condition | Match rule |
| lib | OA library name |
| cell | OA cell name |
| view | OA view (default layout if omitted) |
| pins… | Optional pin names |
Requires a working OpenAccess setup / plugin.
[external]Generate geometry via an external tool (ASCII geometry protocol).
[external]
#condition lib cell view tool
* mylib mycell layout mygenerator
| Column | Meaning |
|---|---|
| condition | Match rule |
| lib | Library name passed to the tool |
| cell | Cell name |
| view | View name (default layout) |
| tool | External tool / generator name |
| pins… | Optional pin names |
The tool receives library/cell/view and device parameters and returns ASCII geometry (databaseunits, box, polygon, text, …).
[tcl]Run a Tcl PCell command in the LayoutEditor Tcl environment (including Magic gencell-style openPDK flows when configured).
[tcl]
#condition TCL command
* sky130::sky130_fd_pr__nfet_01v8
| Column | Meaning |
|---|---|
| condition | Match rule |
| TCL command | Remainder of the line (may contain spaces)—executed as the PCell command |
Generated cells are typically named from the component type plus a parameter hash and reused if already present. Requires Tcl support in the build (useTCL).
[gdsFactory]Generate layout from a gdsfactory Python callable (live worker; not a GDS round-trip).
[gdsFactory]
#condition callable
* ihp.cells.nmos
| Column | Meaning |
|---|---|
| condition | Match rule |
| callable | Remainder of the line—Python callable path (e.g. ihp.cells.nmos) |
Place PDK setup (gdsfactory.pdk, etc.) next to the library as required by the gdsFactory bridge. Geometry and ports are imported from the generated component; cells are cached by parameter hash.
You may stack several sections and conditional rows. Because the first match wins, put specific conditions above a final * fallback:
<Layout>
[cell]
#condition file cell
output=X1 std/AND2_X1.gds AND2_X1
output=X2 std/AND2_X2.gds AND2_X2
[ignore]
#simulation-only variant
sim=true
[macro]
#fallback generator
* devices/and2.layout A B Y
</Layout>
In Edit Component, the simple radio modes write a single section; extended mode edits the full <Layout> text.
Common tokens in <Netlist> / labels:
| Token | Meaning |
|---|---|
$devicename |
Instance name |
$node(port) |
Net attached to symbol port port |
$value / $param |
Parameter values |
$pinlist-style patterns |
Depend on how the template was authored (also used when converting foreign formats) |
<Component rpoly>
<Description>
Poly resistor
</Description>
<Parameter>
<string value 1k>
</Parameter>
<Prefix R>
<Label>
$devicename
$value
</Label>
<Symbol>
<Line 0 0 0 -40 wire>
<Port 0 0 A>
<Port 0 -40 B>
</Symbol>
<Layout>
[macro]
#for parameter macro-file pins
* resistors/rpoly.layout A B
</Layout>
<Netlist spice>
R$devicename $node(A) $node(B) $value
</Netlist>
</Component>
| Format | Role |
|---|---|
| LEL | Full native library definition (symbol + parameters + layout recipe + netlist/model + …) |
| LES | Schematics: placements reference LEL (or embed SubComponent) |
| LTspice / xschem / Qucs / Eagle / KiCad / OA | Imported into the internal component model; save as LEL to keep all LayoutEditor options |
Hand-editing tips: keep attribute/field order from a Save/Edit Component result; validate by reopening the library; put shared PDK cells in version-controlled .lel files rather than duplicating them into every schematic.