.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. The operators in the chapters below run. 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 = layer A, orange = layer B
  • Green = kept geometry
  • Dashed outline = discarded
  • Red = violation markers (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 a - with_*(a, …) (or without_* where that short form exists).

Types

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

Nets are polygons that carry an identity after connect. They are not a fifth type.

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

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

units 1e-6
grid 0.005 um
mode flat
source TOP
include "common.ledrc"
Statement Meaning
units Metres per user unit (default 1e-6)
grid Manufacturing grid; default for ongrid(layer) without a number
mode flat Flatten into the source cell (default)
mode deep Hierarchical: intra-cell, then a flatten pass for neighbourhood
mode tiles … Tiles; border and threads belong on this line
threads N Workers for the flat scheduler (1 = serial; 0 / omitted = idealThreadCount)
source Start cell
include Insert another .ledrc file
cells Keep shapes from matching cell names
clip Clip window (AND with the rectangle)
gds name = "file" Bind a second layout; input(…, from=name)
select_checks / unselect_checks Which check IDs run
max_results Marker cap, or all
chip yes Antenna / rules on the chip top cell only

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

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; mode deep stays serial.

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: < <= > >= == !=.

Layers

layer name = expr

input(n) / input(n, d) read GDS layer/datatype. Unmerged: input(n, d).raw. A second layout: gds other = "file.gds" then input(n, d, from=other).

Boolean operators, weak to strong: | (OR), ^ (XOR), & (AND), - (difference). + is the same as |. a & b connected / 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() / bounds(a) is one bbox for the cell or the union of a. hulls / holes split outer contour and holes. snap(a, g) snaps to a grid. flatten(a) copies the layer as polygons. moved / rotated / scaled transform. rounded_corners and smoothed change vertices.

Edges (short)

edges(a) is the contour. first_edges / second_edges take the sides of an edge pair. extended turns an edge into a band. start_segments / end_segments / centers cut a piece of length d. corners / bbox_center / 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: inside, outside, not_inside, interacting, overlapping, covering, touching, cutting, abutting, and the not_* forms.

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

Filters (form)

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

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, with_distance.
without_* is a - with_*(a, …) 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: width(m1) > 20 um. Hole area: area(holes(m1)) < 0.2 um2.
Width table: layer wide = polygons(width(m1) >= 0.5 um) then space(wide).

Shape and hygiene

area, ongrid, angle, length, count / empty / not_empty, density, self_intersecting, zero_width, spikes.

Check options

Bare words after the limit (already available):

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

euclidean (default), projection, square, manhattan, shielded (default), unshielded, without_touching_corners, without_touching_edges, whole_edges, 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() / 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

Path Form
Violation list / markers Dock button, or JSON from the Text Editor
Extra layer into the result output name gds, dt
Check onto a GDS layer check … -> gds, dt
Report / result file report "file.rdb" / target "out.gds".rdb writes KLayout RDB XML, any other extension writes 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 — executed and produces markers or geometry
  • Partial — runs, with known limits. None of the operators in these chapters currently use this label.
  • Not yet available — accepted in the file but not executed. None of the operators in these chapters currently use this label.