Technology
The technology (PDK) of a project lives in tech.json in the project folder. It defines
the layers, their GDS numbers and display style, simple width / spacing rules, vias,
electrical coefficients for parasitic extraction, and the DRC rule deck. A project without
tech.json uses the built-in generic180 technology.
generic180
A generic 180 nm-class technology, used by new projects and the demo. 1 dbu = 1 nm, grid 10 nm.
| Layer | GDS | Layer | GDS |
|---|---|---|---|
| nwell | 1 | via1 | 8 |
| active | 2 | metal2 | 9 |
| nplus | 3 | via2 | 10 |
| pplus | 4 | metal3 | 11 |
| poly | 5 | boundary | 62 |
| contact | 6 | text | 63 |
| metal1 | 7 |
Routing layers are poly and metal1 to metal3. Vias: contact (active to metal1),
polycon (poly to metal1), via1, via2.
tech.json
Top level:
| Field | Meaning |
|---|---|
name | Technology name |
dbu_per_um | Database units per µm (1000 means 1 dbu = 1 nm) |
grid | Snap grid in dbu |
layers | Array of layers |
vias | Array of via definitions |
drc_deck | DRC deck text (optional; derived from the layer rules when absent) |
caps | Per-layer parasitic coefficients (optional) |
roles | Which layers and vias are the diffusion, poly, well, implants and contacts (optional; generic180 names by default) |
rules | Device rules used by the PCells, in dbu (optional) |
devices | PDK MOS devices (optional; generic nmos / pmos when absent) |
models | PDK SPICE model library (optional; built-in level-1 models when absent) |
signoff | External DRC / LVS runsets (optional; see Verification) |
pcell_layers, pin_labels, drc_extra | Extra PCell layers, net label layers and deck lines, as [[pcell_layer]], [[pin_label]] and drc_extra of a PDK file (optional) |
stream_map | GDSII / OASIS layer map for import and export: rows of layer, stream_layer, datatype (optional; see Stream Layer Map) |
Layer:
{
"name": "metal1", "gds_layer": 7, "gds_datatype": 0,
"color": [80, 140, 255, 160], "fill": "hatch",
"min_width": 230, "min_spacing": 230, "routing": true
}
fill:solid,hatch,backhatch,cross,dotsoroutline.min_width,min_spacing: in dbu; 0 means not checked.min_area(optional): in dbu²; PCell contact plates and router via pads grow to reach it.routing: a routing layer carries net labels and is used by extraction and the router.
Via: name, bottom, cut, top (layer names), cut_size, cut_spacing,
enc_bottom, enc_top (dbu) and resistance (Ω per cut).
Parasitic coefficients (caps), one entry per layer: layer, area (aF/µm²),
fringe (aF/µm of edge), coupling (aF; adds coupling * length / spacing for a
parallel neighbour) and resistance (Ω per square).
DRC rule deck
The deck is plain text, one statement per line. # starts a comment. Lengths are in µm,
areas in µm². Keywords and layer names are not case sensitive. Every rule can have an
optional NAME: prefix; otherwise a name such as metal1.W or contact.EN.metal1 is
generated. A #@ text line gives the next rule its description, reported with its
violations instead of the generated one.
Rules
| Statement | Checks |
|---|---|
width LAYER MIN | Minimum width |
space LAYER MIN | Minimum spacing between shapes of one layer |
separation A B MIN | Minimum spacing between A and B (B pieces that do not overlap A) |
enclosure INNER OUTER MIN | OUTER must enclose INNER by MIN (INNER pieces that overlap OUTER) |
extension A B MIN | A must extend past B by MIN (e.g. poly endcap over active) |
area LAYER MIN | Minimum area |
antenna METAL RATIO | Maximum ratio of metal area to connected gate area (needs poly and active layers) |
density LAYER MIN MAX WINDOW [STEP] | Density between MIN and MAX percent (plain numbers, 0 to 100) in a sliding WINDOW x WINDOW µm window (STEP defaults to WINDOW/2) |
flag LAYER | Every piece of LAYER is a violation (use it with a derived layer) |
Derived layers
NAME = A and B
NAME = A or B
NAME = A not B # A minus B
NAME = A xor B
NAME = A size DIST # grow (negative DIST shrinks)
NAME = A wide MIN # the parts of A at least MIN wide
NAME = A interact B # pieces of A that overlap or touch B
NAME = A inside B # pieces of A entirely inside B
NAME = A outside B # pieces of A that do not overlap B
NAME = A enclose B # pieces of A that contain a whole piece of B
NAME = A touch B # pieces of A that touch B without overlapping it
NAME = A not interact B # (also not inside, not outside, not enclose, not touch)
NAME = A area MIN MAX # pieces with MIN <= area < MAX (µm²; MAX may be inf)
NAME = holes A # the enclosed empty areas of each piece of A
NAME = extents A # the bounding box of each piece of A
A piece is an edge-connected part of a layer. Derived layers can use technology layers and
derived layers defined earlier, and can be used in any rule. With flag, any derived layer
becomes a check, for example floating poly:
floating = poly not interact active
PO.FLOAT: flag floating
SVRF decks
A deck written in SVRF (the Calibre rule language) is recognised and translated to these
rules, so a foundry-style deck runs on the built-in engine. It works everywhere a deck is
used: the Rule deck editor, drc_deck in tech.json or a PDK file,
ics drc --deck rules.svrf, and runsets with tool = "builtin". From a file, INCLUDEs are
resolved relative to it.
Translated:
- Comments,
#DEFINE/#UNDEFINE/#IFDEF/#IFNDEF/#ELSE/#ENDIF, numericVARIABLEs. LAYER MAP g DATATYPE d nandLAYER name n .... A layer number maps to the technology layers with that GDS layer and datatype (any datatype without aLAYER MAP).- Layer operations
AND,OR,NOT,XOR,[NOT] INTERACT / INSIDE / OUTSIDE / ENCLOSE / TOUCH,SIZE a BY d [OVERUNDER | UNDEROVER],HOLES,EXTENTS,COPY,AREA, and parentheses. - Rule checks
NAME { @ comment ... }withINT a < d(width),EXT a < d(space),EXT a b < d(separation),ENC a b < d(enclosure),AREA a < x,DENSITY a < x | > x WINDOW w STEP s, or any layer expression (all of its geometry is reported). The@comment becomes the violation’s description.
Specification and LVS statements (LAYOUT, DRC, PRECISION, CONNECT, DEVICE, …)
are skipped. Check modifiers that change the measurement (OPPOSITE, PROJECTING,
PARALLEL, …) are ignored with a note; those that only shape the output (REGION,
SINGULAR, ABUT) silently. Anything else, such as edge operations, WITH WIDTH or
two-layer INT, leaves its rule check out. Every such case is listed with its line number:
in the SVRF notes under the rule deck, as note: lines from ics drc, and as
deck_notes from MCP. The built-in measurements are Manhattan and Euclidean at corners, so
for sign-off run the same deck in Calibre (see
Verification).
Example
# poly and gates
width poly 0.18
space poly 0.24
gate = poly and active
GATE.EX: extension poly active 0.22
width gate 0.18
# metal1, with a larger spacing next to wide metal
width metal1 0.23
space metal1 0.23
m1w = metal1 wide 10
M1.WIDE.S: separation m1w metal1 0.6
area metal1 0.2
# contacts and vias
enclosure contact active 0.1
enclosure contact metal1 0.06
enclosure via1 metal1 0.06
antenna metal1 400
density metal1 20 80 100
When a technology has no drc_deck, IC Studio derives one from the layers’ min_width,
min_spacing and min_area, the via cut sizes, spacings and enclosures, a poly-over-active
extension, antenna rules and the PDK’s drc_extra lines.
Open Rule deck in the Layout workspace to see it, edit it, and Save to technology.
The DRC Rule Designer edits the same deck as forms.
The command line can use a separate file: ics drc <project> <cell> --deck rules.drc.
PDK files
A PDK file is one TOML file that describes a whole process: layers with their rules, vias,
the layer roles, the MOS devices and the SPICE model library. The repository includes
pdks/sky130A.toml (SkyWater SKY130) and pdks/ihp-sg13g2.toml (IHP SG13G2, 1.2 V and
3.3 V MOS devices, Metal1 to TopMetal2). Both read the models and sign-off decks from an
installed PDK through $PDK_ROOT.
- GUI: File > Import > PDK… (or Load PDK… in the command palette)
- CLI:
ics load-pdk myproj pdks/sky130A.toml - MCP: the
load_pdktool
Lengths in the file are in µm. Relative paths are relative to the PDK file, and ${VAR}
expands an environment variable, so the model library can point into an installed PDK:
[models]
path = "${PDK_ROOT}/sky130A/libs.tech/ngspice/sky130.lib.spice"
corners = ["tt", "ff", "ss", "sf", "fs"]
default = "tt"
length_unit = "um" # the models take W / L in µm
The main sections:
| Section | Content |
|---|---|
name, dbu_per_um, grid | Technology name, database unit, snap grid (µm) |
lyp, lyt | Optional KLayout files supplying layers and colours |
[[layer]] | name, gds, datatype, width, space, area (µm²), routing, color (#rrggbb), fill. Adds a layer, or sets rules on a layer from the .lyp |
[roles] | diffusion (list), tap, poly, nwell, nimplant (empty when the process draws no n+ implant: n+ is diffusion outside pimplant), pimplant, diff_contact, poly_contact (via names), label |
[rules] | gate_contact_space, poly_endcap, implant_enc, nwell_enc, marker_enc (device marker layers around the diffusion) |
[[pin_label]] | Net label layer of a conducting layer: layer, label (e.g. Metal1 and Metal1.text). Routing labels named nets there, extraction reads labels there as names of that layer’s nets |
[[pcell_layer]] | Extra layer the PCells draw: layer, around (poly_contact, diff_contact, gate, diffusion, poly or a layer name), enc, optional kinds (nmos, pmos, poly_res, mom_cap, ntap, ptap) |
drc_extra | Deck lines appended to the deck derived from the layer rules (top-level key, before the tables) |
[[via]] | name, bottom, cut, top, size, space, enc_bottom, enc_top, resistance |
[[device]] | name, type (nmos / pmos), layers, exclude, subckt |
[models] | path, extra (more model files loaded at the same corner), corners, default, length_unit (m or um) |
drc_deck | Optional DRC deck file |
[[signoff]] | External DRC / LVS runsets: name, tool (klayout, calibre, netgen, builtin), check (drc, lvs), deck, vars, klayout, skip, ground (see Verification) |
[[cap]] | Parasitic coefficients, as in tech.json |
What changes with a PDK:
- Extraction finds gates on the role layers and names each transistor after the first
[[device]]of its polarity whoselayersall cover the gate and whoseexcludelayers do not (for examplelvtnfor low-Vt devices). - Netlists map the schematic models
nmos/pmosto the first device of each polarity, writeXelements forsubcktdevices, and load the model library with.libat the corner chosen in the Simulation workspace. PDK models need ngspice. - LVS also compares device models.
- PCells, schematic-driven layout and routing use the role layers, vias and rules. PCell variants already in the project are regenerated.
- MOS PCells can be any
[[device]]of the PDK and then draw its markerlayers(e.g.lvtnaround a low-Vt device,marker_encbeyond the diffusion). Schematic-driven layout picks the device from the schematic model, so a low-Vt transistor in the schematic is placed, extracted and compared as that device.[[pcell_layer]]adds layers such as SKY130’snpcover poly contacts:
drc_extra = [
"pcon = licon1 and poly",
"pcon_npc = npc size -0.1",
"pcon_bad = pcon not inside pcon_npc",
"NPC.EN: flag pcon_bad",
]
[[pcell_layer]]
layer = "npc"
around = "poly_contact"
enc = 0.1
The contact to gate spacing grows when needed so that neighbouring source / drain contacts keep the first metal’s spacing at short gate lengths.
Importing a real PDK layer set
IC Studio reads KLayout layer properties (.lyp) and, optionally, the KLayout technology
file (.lyt):
- GUI: File > Import > KLayout layer properties…
- CLI:
ics import-tech myproj sky130A.lyp --lyt sky130A.lyt
What is imported:
- Every layer entry with a concrete
layer/datatypesource becomes a layer. Its name comes from the entry’s name (spaces become_, duplicates get_2,_3, …). - Colours come from the fill or frame colour; KLayout dither patterns map to the nearest fill style.
- Layers named like
poly,li,met1,metal2,m3are marked as routing layers. - From the
.lyt: the technology name, the database unit and the default grid.
Not imported: width / spacing rules, vias, parasitic coefficients and a DRC deck. Add them
to tech.json (and the deck in the Rule deck editor) to use DRC, extraction and
routing with that technology.
Existing layouts are kept: shapes move to the new layer with the same GDS layer / datatype (or the same name), layers in use that the file lacks are kept, and coordinates are rescaled if the database unit changes.