.ledrc Reference

.ledrc — Rule File Language

.ledrc is the LayoutEditor rule-file language. The Rule File DRC button and Execute on a .ledrc tab in the Text Editor both run this language.

The engine is beta and ships from LayoutEditor 20260823. Every operator in the chapters below runs. There is no remaining Partial item in this reference.

This page is the language overview. Each operator — with a figure — is listed in the chapters below.

Chapters

How to read the figures

Each operator page shows input on the left and result on the right. Blue is layer A, orange is layer B, green is kept geometry, a dashed outline is discarded, and red marks violations (usually an edge pair). Coordinates in the sketches are schematic, not to scale. Y points up, as in the layout.

A check is an expression. width(m1) < 0.14 um already produces markers. check "id" "text" : only attaches a name and a report line.

A filter keeps shapes; it does not create markers. The complement is the layer minus the matching with_ filter, or without_ where that short form exists.

Types

The engine has four value kinds. Nets are polygons that carry an identity after connect; they are not a fifth type.

Type What it is Typical origin
polygons Closed rings, optionally with holes input, boolean, sized, selection, filters
edges Open contour segments edges(a), inside_part, with_length
edge_pairs Two edges plus a measured distance Spacing checks, ongrid as a layer, with_angle on polygons
texts Anchor + string texts

Mini deck

units 1e-6
grid 0.005 um
mode flat
source TOP

layer m1 = input(68, 20)
layer via = input(70, 20)
layer gate = input(66, 20)

connect m1, via
connect gate, via

check "M1.W" "min width" : width(m1) < 0.14 um
check "M1.S" "min space" : space(m1) < 0.14 um
check "VIA.E" "enclosure" : enc(m1, via) < 0.05 um
check "M1.A" "min area" : area(m1) < 0.09 um2
check "M1.G" "off grid" : ongrid(m1) != 0.005 um
check "ANT.1" "antenna" : antenna(gate, m1) > 200
check "DEN.1" "density" : density(m1, window=50 um, step=25 um) < 0.20

layer dummy = fill(bounds(), exclude=m1 | via, shape=rect(0.5 um, 0.5 um), step=1.0 um)
output dummy 99, 0

inside(a, b) and a.inside(b) are the same.

File and setup

A deck is UTF-8, one statement per line. # starts a comment outside "…".

units 1e-6
grid 0.005 um
mode flat
source TOP
include "common.ledrc"

units is metres per user unit (default 1e-6). grid is the manufacturing grid and the default for ongrid(layer) when no number is given. source names the start cell. include inserts another .ledrc file. cells keeps shapes from matching cell names. clip is a clip window (AND with the rectangle). gds name = "file" binds a second layout for input(…, from=name). select_checks and unselect_checks choose which check IDs run. max_results is a marker cap, or all. chip yes applies antenna and related rules on the chip top cell only.

mode flat flattens into the source cell (the default). mode deep is hierarchical: intra-cell, then a flatten pass for neighbourhood. mode tiles … tiles the layout; border and threads belong on that line. mode deep and mode tiles exclude each other. If border is omitted for tiles, the engine uses the largest check limit in the file. mode tiles … threads N parallelises the statement DAG inside each tile (tiles themselves stay sequential). The setup line threads N drives the flat pass (1 is serial; 0 or omitted is idealThreadCount); mode deep stays serial.

The GDS database unit comes from the layout, not from the deck.

Numbers

0.18
0.18 um
180 nm
180 dbu
0.2 um + 1 dbu
inf

Bare numbers are user units. Area uses um2. Comparisons are < <= > >= == !=.

Layers

layer name = expr

input(n) and input(n, d) read a GDS layer and datatype. Unmerged input is input(n, d).raw. A second layout is bound with gds other = "file.gds", then input(n, d, from=other).

Boolean operators, weak to strong, are | (OR), ^ (XOR), & (AND), and - (difference). + is the same as |. a & b connected or not_connected keeps only result pieces whose A- and B-shapes sit on the same (connected) or a different (not_connected) geometric net of a|b.

Geometry (short)

sized(a, d) grows or shrinks. merged(a) unions overlapping shapes; merged(a, n) keeps n-fold overlap. extents(a) is the bbox of each shape; bounds() and bounds(a) are one bbox for the cell or the union of a. hulls and holes split outer contour and holes. snap(a, g) snaps to a grid. flatten(a) copies the layer as polygons. moved, rotated and scaled transform. rounded_corners and smoothed change vertices.

Edges (short)

edges(a) is the contour. first_edges and second_edges take the sides of an edge pair. extended turns an edge into a band. start_segments, end_segments and centers cut a piece of length d. corners, bbox_center and intersections yield small boxes. with_edge(a, b) keeps A-shapes that share a collinear edge piece with B. polygons(x) turns pairs back into area.

Selection (whole shape)

Keep whole shapes of A when the relation holds to at least one shape of B, using inside, outside, not_inside, interacting, overlapping, covering, touching, cutting, abutting, and the corresponding not_ forms.

Clipping (cut edges, do not keep whole polygons) is inside_part / outside_part. edges(a) & b is inside_part.

Filters (form)

One number is an exact value (tolerance 0.5 dbu² for area). Two numbers are [min, max]. inf is an open end.

The filters are with_area, with_perimeter, with_holes, with_angle, with_length, with_width, rectangles, squares, rectilinear, with_bbox, with_area_ratio, with_vertex_count, path_length, and with_distance. A without_ form is the layer minus the matching with_ filter, except the existing short form without_length.

ongrid(a) as a layer yields off-grid vertices as degenerate edge pairs, not the whole polygons. The check ongrid(a) != g marks the same vertices.

inside(a, b) keeps A when all vertices of A lie in some polygon of B — not a full edge-inside test on concave B.

Checks

check "M1.S.1" "min space" : space(m1) < 0.18 um
check "M1.S.1" "min space" severity warn : space(m1) < 0.18 um -> 200, 0
layer nar = width(m1) < 0.14 um

severity is error (default), warn or info. The level is stored on every violation, appears as a column in .drc.rpt, and is counted as warnings / infos. The error count and exit code stay the total number of markers.

Spacing

Check Meaning
width(a) Inside
space(a) Outside, all pairs
notch(a) Outside, same shape
isolated(a) Outside, different shapes
sep(a, b) Outside, two layers
enc(a, b) a encloses b
enclosed(a, b) The reverse
overlap(a, b) Overlap width
width(a, b) Inside width of the overlap (AND, then RelWidth)

Maximum width is width(m1) > 20 um. Hole area is area(holes(m1)) < 0.2 um2. A width table is layer wide = polygons(width(m1) >= 0.5 um) then space(wide).

Shape and hygiene

Shape and hygiene checks are area, ongrid, angle, length, count / empty / not_empty, density, self_intersecting, zero_width, and spikes.

Check options

Bare words after the limit are already available:

check "S.1" : space(m1) < 0.18 um projection whole_edges angle_limit(90)

The metric words are euclidean (default), projection, square, and manhattan. Shielding is shielded (default) or unshielded. Further bare words are without_touching_corners, without_touching_edges, whole_edges, and angle_limit(α) (default 90).

New options use name=value: nets=same / nets=different, projecting=min.. max, relation=parallel|acute|perpendicular|obtuse, opposite=only|waive, rect_sides=…, eol=yes, coincident=yes. Example: enc(m1, via) < 0.05 um eol=yes.

Nets, antenna, fill

connect m1, via
connect gate, via
label m1, txt

check "S.U" : space(m1) < 0.18 um nets=different
check "ANT.M1" : antenna(gate, m1) > 200

connect is transitive. connect reset starts a new block. soft_connect counts for connected() / floating(), but is not conducting for nets= / antenna. Without connect, nets= on a spacing check uses geometric components of a|b; connected(), floating() and antenna have no graph.

layer dummy = fill(bounds(), exclude=m1 | via, shape=rect(0.5 um, 0.5 um), step=1.0 um)
check "D.1" : density(m1, window=50 um, step=25 um) < 0.20

The first argument of fill is always the fill region, not the keep-out. exclude= is the keep-out.

texts(n, d) reads text anchors; expand_text(t, d) makes a mini-box around each anchor. label m1, txt copies a text string onto the net.

Output

The dock button, or JSON from the Text Editor, writes the violation list and markers. output name gds, dt adds an extra layer into the result. check … -> gds, dt writes that check onto a GDS layer. report "file.rdb" and target "out.gds" write a report or result file: .rdb is KLayout RDB XML, any other extension is marker GDS.

Fill and DFM layers are geometry, not violations, unless a check runs on them.

Aliases

The file may use these; new decks should write the canonical name.

Canonical Alias
isolated iso
sep separation
enc enclosing
euclidean euclidian
| +
unshielded transparent
nets=same / nets=different connected / not_connected
extended(e, out=d, in=0) extended_out(e, d)
empty(a) count(a) == 0
self_intersecting odd_polygons

Availability (beta)

On each operator page Available means the operator is executed and produces markers or geometry. Partial would mean it runs with known limits, and Not yet available would mean it is accepted in the file but not executed. None of the operators in these chapters currently use those last two labels.