Verification
The Python functions for writing DRC and extraction decks: layer processing, DRC checks, connectivity and device extraction. Decks are run from the Verify menu; see Verification commands.
DRC checking
Glade supports design rule checking and connectivity extraction using the Python scripting language to write DRC/extraction decks. The advantage of this is that you are using the same procedural language as the rest of the database and UI functionality. An example python DRC script looks like:
from ui import *
# Get the open cellView
cv = getEditCellView()
# Initialise the geometry engine
geomBegin(cv)
# Get layers
active = geomGetShapes("active", "drawing")
poly = geomGetShapes("poly", "drawing")
# Form derived layer
gate = geomAnd(active, poly)
# Run width check
geomWidth(gate, 0.18 "gate width < 0.18um")
# Finish with the geometry engine
geomEnd()
In this example we first initialise the geometry package and tell it we want to check the current editing cellview with the geomBegin(cv) command. We then get shapes on different layers and perform boolean operations on them. Finally we check the derived layer using the geomWidth function. By default this writes DRC violations shapes to the TECH_DRCMARKER_LAYER (drcMarker layer in the LSW).
After completing DRC operations we call geomEnd() to free memory.
In the above example, 'active' and 'poly' are original layers. 'gate' is a derived layer that does not exist in the original cellView.
Boolean processing functions
Before using DRC or LPE (extraction) commands, we normally need to perform some layer processing using boolean operations or select operations. For example in order to extract a MOS transistor, we need to identify the gate area by using the geomAnd() of the poly and diffusion layers, and we need to use the geomAndNot() of the diffusion and poly layers to split the diffusion between the source and the drain of the device, else we end up with all devices S/D terminals shorted.
The following layer processing functions are supported. Note that these don't have to be used just for DRC or LPE - you can use them in any python script for layer processing. The 'layers' that the commands produce are in fact temporary binary edge files. These files are called geom<pid>_<thread>_0000.dat, geom<pid>_<thread>_0001.dat etc. and are automatically deleted during geomEnd(). A run that stops before geomEnd (a script error, a crash or os._exit()) leaves its files behind; the next geomBegin, in any Glade, deletes the files of processes that are no longer running. By default the layer files are written in the directory that Glade is invoked in. However if the environment variable GLADE_DRC_WORK_DIR is set to a valid directory, then they will be written to that directory instead.
Checks can run multithreaded. A check on a layer of 20,000 edges or more (GLADE_DRC_STRIP_MIN_EDGES changes this) is split into vertical strips, about four for each thread, and the strips are checked at the same time; the markers are the same as when the check runs as one scan. Boolean and sizing operations on layers of 100,000 edges or more (GLADE_DRC_MERGE_MIN_EDGES) are split the same way. This is off unless Multithreaded is checked in the Run DRC or Run Extraction dialog, which sets the number of threads for that run, or a rule deck calls geomSetThreads(). Otherwise the environment variable GLADE_THREADED_DRC gives the number of threads to use, e.g. for a deck run from a -script file (e.g. GLADE_THREADED_DRC=8; 'no' means one thread). Layers that are not Manhattan, and geomEolSpace() and geomNeighbours(), always run as one scan. For testing, GLADE_DRC_STRIPS=n splits every check into n strips, and GLADE_DRC_STRIP_CUTS=x1,x2,... (in database units) puts the cuts between strips at the given x values.
geomSetThreads(num = machine's thread count)
Sets the number of threads that checks run on (see above). With no argument, checks use all the machine's threads. 0 goes back to using GLADE_THREADED_DRC; 1 runs checks on one thread.
Optional arguments are shown as e.g. hier=True, indicating that the default value of True is used if the argument is not specified.
geomBegin( cellView cv)
Initialise the DRC package. A valid cellView must be passed to initialise the package. The cellView cvwill be the one that subsequent processing operates on. Note the former equivalent function drcInit(cv) is still supported, but deprecated.
geomEnd()
Uninitialise the DRC package. Working memory is freed. Temporary layer files are deleted. Note the former equivalent function drcUnInit(cv) is still supported, but deprecated.
A layer passed to a geom, extract or save function must not be None (as a function that fails can return): the call raises a ValueError naming the function and argument, e.g. "geomSpace: layer argument 2 is None". Only the optional layers can be None: an extract function's bulk and isolation layers, and geomSetShieldLayer's layer.
out_layer = geomGetShapes('layerName', purpose = 'drawing', hier=True)
Initialises out_layer with all shapes on the layer layerName, with purpose purpose. purpose defaults to 'drawing' if not ven. The resulting derived out_layer contains merged shapes. The default is to get all shapes through the hierarchy; if the optional parameter hier is False, then only top level shapes are processed.
out_layer = geomStartPoly(vertices)
Creates a polygon from the given vertices list and saves to the layer out_layer, which will be overwritten if it exists. The resulting output layer is not merged. The vertex list must be in counterclockwise order and not self-intersecting. For example:
y4 = geomAddShape([ [0,0], [1000, 0], [1000, 2000], [0, 2000] ])
out_layer = geomAddPoly(layer, vertices)
Adds a polygon from the given vertices to the edge layer layer, and saves to the layer out_layer. The resulting output layer is merged with existing shapes on the layer. The vertex list must be in counterclockwise order and not self-intersecting. For example:
y3 = geomAddShapes(y3, [1000, 0], [1000, 2000], [0, 2000] ])
out_layer = geomAddShape(layer, shape)
Adds a shape shape to the edge layer layer. The resulting output layer is merged. For example:
y4 = geomEmpty()
cutshape = cv.dbCreateRect(cut, y4_lyr)
y4 = geomAddShape(y4, cutshape)
out_layer = geomAddShape(layer, shapes)
Adds a python list of shapes to the edge layer layer. The resulting output layer is merged. For example:
y3 = geomEmpty()
shapes = []
for i in range(0,4) :
shape = cv.dbCreateRect(box, y3_lyr)
box.offset(2000, 0)
shapes.append(shape)
y3 = geomAddShapes(y3, shapes)
num = geomNumShapes(layer)
Returns the number of shapes in a layer. This can be used as a test, e.g.
if geomNumShapes(diff) != 0 :
gate = geomAnd(poly, diff)
out_layer = geomEmpty()
Creates a dummy empty out_layer .
out_layer = geomBkgnd(size = 0.0)
Creates out_layer with an extent the size of the cellView's bounding box, plus size (which defaults to 0.0um). This is useful for example to create a pwell layer when the original mask data just has nwell information:
nwell = geomGetShapes('nwell', 'drawing') bkgnd = geomBkgnd() psub = geomAndNot(bkgnd, nwell)
geomErase('layerName', purpose='drawing')
Erases any design data on layer layerName in the current cellView. purpose defaults to 'drawing' if not given. Beware: there is no way of undoing this operation.
out_layer = geomMerge(layer)
Returns the merged shapes on layer. This is equivalent to a single layer OR. Note that geomGetShapes() always merges raw input data, so there is normally no need to separately merge layers.
out_layer = geomOr(layer1, layer2)
Returns the OR (union) of the two layers.
out_layer = geomAnd(layer1, layer2)
Returns the AND (intersection) of the two layers.
out_layer = geomNot(layer)
Returns the inverse of the layer. Effectively it runs geomAndNot(), with the first 'layer' being a rectangle the size of the cellView's bounding box, and the second the specified layer.
out_layer = geomAndNot(layer1, layer2)
Returns the AND NOT of layer1 with layer2. This is equivalent to subtracting all shapes on layer2 from layer1.
out_layer = geomXor(layer1, layer2)
Returns the XOR of the two layers.
out_layer = geomSize(layer, size, flag = 0)
Sizes the layer by size microns. A positive size grows the layer, while a negative size shrinks the layer. If a shape should shrink so its width becomes zero, it will no longer be present in the sized_layer . The third argument, flag, if not specified sizes all edges by size. If flag is set to 'vertical' then sizing is only done in the vertical direction, if flag is set to 'horizontal' then sizing is only done in the horizontal direction.
Allowable flags are:
- vertical
- horizontal
out_layer = geomTrapezoid(layer)
Converts layer to trapezoids. If layer has connectivity established via geomConnect(), the connectivity will be maintained in the trapezoids generated.
Selection functions
Each selection function also takes an optional count, after flag, which selects shapes by how many shapes on the other layer meet the criteria: add equals, not_equal, greaterthan, greaterorequal, lessorequal or lessthan to flag and give the count. For example:
geomTouching(m1, via, figA | greaterthan, 1)
outputs the m1 shapes touched by more than one via. lessthan and none are both 0, and with a count of 0 (the default) mean every selected shape; lessthan, 2 outputs the shapes that meet exactly one shape on the other layer. Each shape on the other layer counts once, however many of its edges meet.
The allowable flags of every selection function are figA or figB (fig is the same as figA), and one of equals, not_equal, greaterthan, greaterorequal, lessorequal or lessthan for the count. geomAvoiding, geomInteracts and geomNotInteracts also take not_singular: shapes that meet only at a single point (corner to corner) then don't interact.
select_layer = geomTouching(layer1, layer2, flag=figB)
Select all shapes on layer2 that touch layer1. Touching is defined as any edge of layer2 polygons that touch an edge from a layer1 polygon. flag can be figA (layer1's shapes) or figB (layer2's, the default), and controls which of the two layers that meet the criteria are output to touching_layer.
select_layer = geomOverlapping(layer1, layer2, flag=figB)
Select all shapes on layer2 that touch layer1. Overlapping is defined as any edge of layer2 polygons that intersects an edge from a layer1 polygon, i.e. the layer2 polygon is part inside, part outside layer1, or is inside layer1. geomIntersecting selects only the shapes that are part inside, part outside. flag can be figA (layer1's shapes) or figB (layer2's, the default), and controls which of the two layers that meet the criteria are output to overlapping_layer.
select_layer = geomInside(layer1, layer2, flag=figB)
Select all shapes on layer2 that are inside (enclosed by) layer1. Shapes are considered as 'inside' if the shapes have common area. The layer2 edges may be coincident with layer1 edges. flag can be figA (layer1's shapes) or figB (layer2's, the default), and controls which of the two layers that meet the criteria are output to inside_layer.
select_layer = geomContains(layer1, layer2, flag=figB)
Select all shapes on layer2 that are contained by shapes on layer1. Shapes are considered as 'contained' if all of their vertices are inside layer1 and do not touch layer1. flag can be figA (layer1's shapes) or figB (layer2's, the default), and controls which of the two layers that meet the criteria are output to contains_layer.
select_layer = geomOutside(layer1, layer2, flag=figB)
Select all shapes on layer2 that are outside layer1. The shapes may touch or abut layer1. To make sure that shapes on layer2 are completely 'outside' layer1, and get considered, the 'enclosing' shape should be layer1. flag can be figA (layer1's shapes) or figB (layer2's, the default), and controls which of the two layers that meet the criteria are output to outside_layer.
select_layer = geomAvoiding(layer1, layer2, flag=figB)
Select all shapes on layer2 that avoid layer1 and do not touch or overlap. flag can be figA (layer1's shapes) or figB (layer2's, the default), and controls which of the two layers that meet the criteria are output to avoiding_layer.
select_layer = geomButting(layer1, layer2, flag=figB)
Select all shapes on layer2 that have outside edges that abut layer1 outside edges. flag can be figA (layer1's shapes) or figB (layer2's, the default), and controls which of the two layers that meet the criteria are output to butting_layer.
select_layer = geomCoincident(layer1, layer2, flag=figB)
Select all shapes on layer2 that have edges coincident with inside edges of layer1. flag can be figA (layer1's shapes) or figB (layer2's, the default), and controls which of the two layers that meet the criteria are output to coincident_layer.
select_layer = geomInteracts(layer1, layer2, flag=figB)
Select shapes on layer2 that interact with shapes on layer1. An interaction is defined as overlapping, abutting, coincident, or inside. flag can be figA (layer1's shapes) or figB (layer2's, the default), and controls which of the two layers that meet the criteria are output to interacting_layer.
select_layer = geomIntersecting(layer1, layer2, flag=figB, count=0)
Select shapes on layer2 whose edges cross edges of layer1 shapes, i.e. that are part inside, part outside layer1. Unlike geomOverlapping, shapes wholly inside layer1 aren't selected.
select_layer = geomButtOrCoin(layer1, layer2, flag=figB, count=0)
Select shapes on layer2 that butt or are coincident with shapes on layer1: the shapes geomButting or geomCoincident would select.
select_layer = geomNotTouching(layer1, layer2, flag=figB, count=0)
select_layer = geomNotOverlapping(layer1, layer2, flag=figB, count=0)
select_layer = geomNotIntersecting(layer1, layer2, flag=figB, count=0)
select_layer = geomNotInside(layer1, layer2, flag=figB, count=0)
select_layer = geomNotOutside(layer1, layer2, flag=figB, count=0)
select_layer = geomNotButting(layer1, layer2, flag=figB, count=0)
select_layer = geomNotCoincident(layer1, layer2, flag=figB, count=0)
select_layer = geomNotButtOrCoin(layer1, layer2, flag=figB, count=0)
select_layer = geomNotInteracts(layer1, layer2, flag=figB, count=0)
Each outputs the shapes of the output layer (layer2, or layer1 with figA) that the function without Not doesn't select, given the same flag and count. For example:
geomNotTouching(m1, via, figA | greaterthan, 1)
outputs the m1 shapes touched by at most one via, including those no via touches. geomNotInteracts is the same as geomAvoiding. geomNotOutside selects the same shapes as geomOverlapping, and geomNotOverlapping the same as geomOutside.
out_layer = geomGetTexted(layer,'layerName', purpose = 'drawing', name=None)
Gets all shapes on layer that have text labels on the layer/purpose pair given by layerName / purpose. purpose defaults to drawing if not given. Optionally a name can be supplied e.g. 'vdd', and then only shapes with text labels with that name are output to out_layer .
out_layer = geomGetNet(layer1, ‘netName’)
Gets all shapes on layer1’s layer (which must be an input or derived layer specified in geomConnect) that are assigned to net with name ‘netName’.
out_layer = geomHoles(layer, flag=greaterthan, count=0)
Gets the holes in polygons on layer and outputs them to out_layer. flag and count select the polygons by their number of holes, as for geomGetHoles; the defaults output every hole.
out_layer = geomNoHoles(layer)
Gets the polygons on layer and outputs them, minus any holes, to out_layer.
out_layer = geomGetHoles(layer, flag=greaterthan, count=0)
Gets the holes on layer polygons and outputs them, to out_layer. flag and count set the criteria; for example greaterthan, 1 will only output holes for polygons which have more than 1 hole.
out_layer = geomGetHoled(layer, flag=greaterthan, count=0)
Gets the polygons on layer whose number of holes meets the criteria and outputs them, less their holes, to out_layer. flag and count set the criteria; for example equals, 2 will output original polygons (less their holes) for polygons with exactly 2 holes. The defaults output every polygon that has a hole.
For geomHoles, geomGetHoles and geomGetHoled, flag is one of greaterthan (the default), greaterorequal, lessthan, lessorequal, equals or not_equal, and the polygon's number of holes is compared with count. As for the selection functions, lessthan (or none, also 0) considers only polygons that have holes, and with a count of 0 means all of them: lessthan, 2 selects polygons with exactly 1 hole. Use equals, 0 for polygons with no holes. Leave flag out to get greaterthan. geomHoles also takes inner, which outputs only the holes of the polygon whose holes have the smallest total area (count is then not used). geomNoHoles takes no flags.
out_layer = geomGetNon90(layer)
Gets the polygons on layer and outputs ones that have one or more edges that are non 90 degrees to out_layer.
out_layer = geomGetNon45(layer)
Gets the polygons on layer and outputs ones that have one or more edges that are non 90 and non 45 degrees to out_layer
out_layer = geomGetRectangles(layer)
Gets the shapes on layer and outputs ones that are rectangular, i.e. have 4 edges parallel to the X or Y axes.
out_layer = geomGetPolygons(layer)
Gets the shapes on layer and outputs ones that are not rectangular, i.e. have at least one edge not parallel to the X or Y axes.
out_layer = geomGetVertices(layer1, num, flags = equals)
Get shapes on layer1’s layer that have num vertices. Optionally flags can be set to equals (the default), not_equal, greaterthan, greaterorequal, lessthan or lessorequal.
DRC
DRC functions, like boolean operations, are edge-based, using a Bentley-Ottman scanline algorithm. Distances are measured as the Euclidean distance between edges. A check measures a pair of edges that project onto each other (share a run along their length). Spacing and enclosure checks also measure perpendicular edges, when each lies wholly on the outer side of the other: corners that face each other diagonally (corner to corner) are measured by the perpendicular edges that meet at them. Parallel edges that don't project onto each other are not measured. Width checks, and checks with the project flag, don't measure perpendicular edges unless given with_perp (see Check modifiers below). The resulting error marker shapes are constructed from the four vertices of the error edges, and are copied to the output layer where they may be used for subsequent boolean operations.
A spacing check (geomSpace) reports, for each edge, only the nearest edge that fails with it, so it doesn't look past that edge to shapes behind it. A two layer spacing check doesn't stop at shapes of the edge's own layer, though, and width, notch, enclosure, overlap and extension checks report every pair of edges that fails, whatever is between them. The shielded flags (see Check modifiers below) report only what isn't hidden behind other edges.
Flags
Many commands take a flags parameter. Flags can be bitwise OR's together using the '|' operator, although some flags are mutually independent: samenet/diffnet; equals/not_equal/greaterthan, greaterorequal, lessthan, lessorequal; horizontal/vertical/diagonal; figA/figB/fig; edges/wholeEdges (with their A and B forms, and the figure flags); butting/coincident/inside/outside/over/not_over; with_perp/only_perp; parallel/notParallel; opposite/oppositeA/oppositeB; shielded/shieldedA/shieldedB; and the corner modifiers, of which only one may be given. A check given more than one flag of any of these last five groups reports an error and checks nothing, as does one given appLimit or lengthLimit with no range set (see Check modifiers below).
The six edge relationships (butting, coincident, outside, inside, over, not_over) select parts of edges in geomGetEdge, and which edges are checked in geomEdgeLength. geomGetEdge takes exactly one of them, optionally with whole_edge.
The flags are:
- none - No flag bits set.
- samenet - Used for geomSpace checks, check only carried out if shapes are on the same net.
- diffnet - Used for geomSpace checks, check only carried out if shapes are on different nets.
- vertical - Only vertical edges are checked.
- horizontal - Only horizontal edges are checked.
- diagonal - Only diagonal (45 degree) edges are checked.
- project - The checked edges must project, i.e. be parallel and share a common parallel runlength.
- parallel - The checked edges must be parallel.
- abut - Used for geomSpace and geomEnclose checks. If set, abutting edges will flag the spacing check, else abutting is allowed.
- equals - If set, violations are created where the test result is equal to the rule, e.g. geomWidth(M1, 0.030, equals) will result in shapes with width equal to 30nm selected for error/output.
- not_equal - If set, violations are created where the test result is not equal to the rule, e.g. geomWidth(M1, 0.030, not_equal) will result in shapes with width not equal to 30nm selected for error/output.
- greaterthan - If set, violations are created where the test result is greater than the rule, e.g. geomWidth(M1, 0.030, greaterthan) will result in shapes with width greater than 30nm selected for error/output.
- greaterorequal - If set, violations are created where the test result is greater than or equal to the rule, e.g. geomWidth(M1, 0.030, greaterorequal) will result in shapes with width greater than or equal to 30nm selected for error/output.
- lessthan - the default. Violations are created when the test result is less than the rule.
- lessorequal - Violations are created when the test result is less than or equal to the rule.
- output_only - Do not flag a violation on the marker, used when a DRC check generates edge data to be further processed.
- opposite - Report violations with opposite lengths of the edges only. Else the full length of the edges are reported.
- oppositeA, oppositeB - in a two layer check, report only the part of the first (A) or second (B) layer's edge that projects onto the other edge, with that projection. In a single layer check they are opposite.
- figA - output the shapes of the first layer: in a selection, layer1's shapes; in a check, the shapes of the first layer that violations lie on (see Figure output below).
- figB - output the shapes of the second layer: in a selection, layer2's shapes (the default); in a two layer check, the second layer's shapes that violations lie on.
- fig - in a check, output the shapes of both layers that violations lie on, or of the one layer in a single layer check. In a selection it is the same as figA.
- layer1, layer2 - the former names of figA and figB, still accepted.
- edges - in a check, output the parts of the edges in error that form each error region (see Edge output below). edgesA, edgesB: in a two layer check, only the first (A) or second (B) layer's.
- wholeEdges - in a check, output the whole edges in error. wholeEdgesA, wholeEdgesB: in a two layer check, only the first (A) or second (B) layer's.
- butting - edges of layer1 on an edge of layer2 where the shapes don't overlap: layer2 is on the edge's outside only.
- coincident - edges of layer1 on an edge of layer2 where the shapes overlap: layer2 is on the edge's inside only.
- outside - edges of layer1 outside layer2 shapes: layer2 is on neither side, and the edges don't butt.
- inside - edges of layer1 inside layer2 shapes: layer2 is on both sides, and the edges aren't coincident.
- over - edges of layer1 that are inside or coincident: layer2 is on the edge's inside.
- not_over - edges of layer1 that are outside or butting: layer2 is not on the edge's inside.
- whole_edge - used with geomGetEdge: output each selected edge whole, and join edges that follow on from one another into one edge (such as the side of a bent gate), which geomGetLength measures whole.
- with_perp - also measure perpendicular edges in width checks and with project (spacing and enclosure checks already do).
- only_perp - measure only perpendicular edges.
- corner - check only edges in a corner to corner or corner to edge relationship. cornerA, cornerB: in a two layer check, a corner to edge relationship must have the edge on the first (A) or second (B) layer.
- cornerToCorner - check only edges in a corner to corner relationship. cornerToCorner45, cornerToCornerNot45: only where the line between the corners is (or isn't) at 45 degrees.
- cornerToEdge - check only edges in a corner to edge relationship. cornerToEdgeA, cornerToEdgeB: in a two layer check, with the edge on the first (A) or second (B) layer.
- notCorner - check only edges in neither corner relationship.
- shielded - report only the parts of a violation that aren't hidden behind other edges of the checked layers, or of the layer set by geomSetShieldLayer. shieldedA, shieldedB: only the first or second layer's edges shield.
- shieldCoin - edges along the line of a violation's edges shield too. On its own it implies shielded.
- notParallel - check only edges that aren't parallel.
- appLimit - check only edges whose apposition is in the range set by geomSetAppLimit.
- lengthLimit - check only edges whose lengths are in the range set by geomSetLengthLimit. lengthLimitA, lengthLimitB: in a two layer check, only the first (A) or second (B) layer's edge's length.
- not_singular - used with geomAvoiding, geomInteracts and geomNotInteracts: shapes that meet only at a single point don't interact.
- inner - used with geomHoles: output only the holes of the polygon whose holes have the smallest total area.
Two groups of flags are named in the lists of allowable flags below:
- The output flags, which every check that takes flags accepts: output_only; opposite, and in a two layer check oppositeA and oppositeB; the figure flags figA, figB and fig; the edge output flags edges, edgesA, edgesB, wholeEdges, wholeEdgesA and wholeEdgesB; and shielded, shieldedA, shieldedB and shieldCoin.
- The check modifiers: with_perp, only_perp, the corner modifiers (corner, cornerA, cornerB, cornerToCorner, cornerToCorner45, cornerToCornerNot45, cornerToEdge, cornerToEdgeA, cornerToEdgeB, notCorner), notParallel, appLimit, lengthLimit, lengthLimitA and lengthLimitB (see Check modifiers below).
A flag that isn't in a command's list is ignored by it, except by geomGetVertices, which takes one flag only and selects nothing if given any other.
Figure output
A check normally outputs its error regions: the shapes between the edges in violation, which are also written as markers. With figA, figB or fig in its flags, the check outputs instead the whole shapes, with their holes, that the edges in violation lie on. Each shape is output once, however many violations it has. The markers are written as usual (unless output_only is given), so only the output layer changes. For example, to get the metal1 shapes that are too close to poly:
bad_m1 = geomSpace(m1, poly, 0.3, figA, "M1 to poly space < 0.3")
In a two layer check, figA outputs the first layer's shapes, figB the second layer's and fig both; in a single layer check all three output the layer's shapes. A shape is output if a violation's edge, or part of an edge, lies on one of its edges, so a shape of the other layer with an edge exactly on that edge would be output too. When a check runs on an edge layer from geomGetEdge, its source polygons' shapes are output.
The figure flags apply to the checks that take flags: geomWidth, geomAllowedWidths, geomLength, geomEdgeLength, geomSpace, geomSpace2, geomAllowedSpaces, geom2DSpace, geomNotch, geomLineEnd, geomEolSpace, geomPitch, geomOverlap, geomEnclose, geomExtension and geomAdjLength. The area and density checks already output whole shapes.
Edge output
With edges, a check outputs instead of its error regions the edges in error, as an edge layer (as geomGetEdge gives): the parts of the two edges each error region lies between, which with opposite are the parts that face each other. With wholeEdges it outputs the whole edges of the shapes that have a part in error. In a two layer check edgesA and wholeEdgesA output only the first layer's edges, edgesB and wholeEdgesB only the second's; in a single layer check they are the same as edges and wholeEdges. Each edge is output once, directed as its shape's edge (the shape's inside on its left). The markers are written as usual.
The edge layer can be used as geomGetEdge's output can: with geomGetEdge and geomGetLength, the booleans on edge layers, saveDerived, and in the checks that accept edge layers (see Edge layers in checks), which then check only those edges. A layer of one layer's edges (one layer's check, or edgesA, edgesB, wholeEdgesA or wholeEdgesB) has that layer as its source polygons; a layer of both layers' edges has none, so can't be checked again. The edge and figure flags can't be given together. For example, the parts of metal1 edges too close to poly, then their lengths:
m1edges = geomSpace(m1, poly, 0.3, edgesA | opposite, "M1 to poly space < 0.3") long = geomGetLength(m1edges, 1.0, greaterthan)
Check modifiers
The modifier flags choose which pairs of edges a check measures, and how much of a violation it reports. The perpendicular, corner, notParallel, appLimit and lengthLimit modifiers apply to geomWidth, geomSpace (one or two layers, with a rule and flags, and the width dependent form), geomSpace2, geomNotch, geomOverlap, geomEnclose and geomExtension. The shielded flags apply to every check that takes flags.
Perpendicular edges. Spacing and enclosure checks measure perpendicular edges whenever each lies wholly on the outer side of the other, so with_perp changes nothing for them. It makes width checks measure perpendicular edges too, where each lies wholly on the other's inner side and they don't meet at a vertex, and makes checks with project measure them. only_perp measures perpendicular edges only, as with_perp does, and no others. For example, a width across a cut corner:
geomWidth(m1, 0.35, with_perp, "M1 width < 0.35, including across corners")
Corners. The corner relationships are decided by where the two edges are closest, whichever edges the check measures them by. Since corners facing each other diagonally are measured by perpendicular edges (see above), the corner modifiers look at the points the distance is measured between, not at whether the edges are parallel:
- Corner to corner: the closest points are an end of each edge, each end is a right angle of its shape, each edge leads away from the other's corner, and parallel edges don't overlap along their length. With cornerToCorner45 the line between the corners must be at 45 degrees, with cornerToCornerNot45 it mustn't.
- Corner to edge: the edges are neither parallel nor perpendicular, and a right angle at an end of one of them has its exterior bisector (the line from the corner at 135 degrees to both its edges) meet the other edge. A corner facing a Manhattan edge is measured as edge to edge, by the edge it projects onto.
On an edge layer from geomGetEdge, the corners are those of its source shapes. For example, a larger spacing between corners on a 45 degree line than elsewhere:
geomSpace(m1, 0.12, cornerToCorner45, "M1 corner to corner space < 0.12") geomSpace(m1, 0.10, notCorner, "M1 space < 0.10")
Shielding. With shielded, a violation is reported only where its two edges can see each other. For parallel edges that project onto each other, each edge of a shielding layer between them hides the part of their common run in front of it, and the parts left are reported as separate violations, so with opposite each has its own length. For other pairs, the violation is reported only if no shielding edge crosses the line between the edges' closest points. By default the edges of the checked layers shield; with shieldedA or shieldedB only the first or second layer's do. Edges along the line of a violation's own edges don't shield unless shieldCoin is given, and the violation's own edges never do. As a spacing check already stops at the nearest failing edge, shielding matters most for two layer spacing, enclosure and width checks, which see through other shapes. For example, poly to diffusion spacing that isn't hidden behind other diffusion:
geomSpace(poly, diff, 0.2, shielded | opposite, "Poly to diff space < 0.2")
geomSetShieldLayer(layer)
Sets the layer whose edges shield, for the checks after it with shielded or shieldCoin, in place of the checked layers. geomSetShieldLayer(None) goes back to the checked layers, as do geomBegin and geomEnd. shieldedA and shieldedB always use the checked layers. For example, metal spacing not hidden by poly:
geomSetShieldLayer(poly) geomSpace(m1, 0.2, shielded, "M1 space < 0.2 not shielded by poly") geomSetShieldLayer(None)
Apposition and edge length. With appLimit, a check measures a pair of edges only if their apposition is in the range set by geomSetAppLimit. Apposition is how much of one edge's projection onto the other's line overlaps the other edge: the length of their common run for parallel edges, and negative, minus the gap, where the projection falls short of the edge, as for corners facing each other diagonally. For edges that aren't parallel, it is the larger of the two ways round. With lengthLimit, a check measures a pair only if both edges' lengths are in the range set by geomSetLengthLimit (whole edges of the shapes); with lengthLimitA or lengthLimitB, only the first or second layer's edge's length, in a two layer check.
geomSetAppLimit(range), geomSetLengthLimit(range)
Set the range, in microns, for the checks after them with appLimit, or lengthLimit, lengthLimitA or lengthLimitB. The range is a string: a name (any word) with a limit on one side or both, using <, <=, >, >= or ==, e.g. "app > 0.5", "0.1 < length <= 2.0" or "length == 1.0". None clears it. They return False, and set nothing, if the range can't be read. Call them after geomBegin, which clears them. For example, metal spacing where the lines run alongside each other for more than 2um, and short metal edges facing poly:
geomSetAppLimit("app > 2.0")
geomSpace(m1, 0.25, appLimit, "M1 space < 0.25 for runs over 2um")
geomSetLengthLimit("length < 0.5")
geomSpace(m1, poly, 0.1, lengthLimitA, "Short M1 edge to poly space < 0.1")
Opposite parts. With opposite, a violation's error region covers only the parts of its two edges facing each other. In a two layer check, oppositeA reports instead the part of the first layer's edge that projects perpendicularly onto the second layer's edge, and that projection; oppositeB the same for the second layer's edge. For parallel edges all three are the same. For edges at an angle they differ, and a violation is reported only if the chosen edge projects onto the other at all: a square corner facing a 45 degree edge projects onto it, but the 45 degree edge doesn't project onto the square's edges.
geomSetErrorLimit(limit, abort = False)
Limits the markers each check after it writes to limit (0, the default, is no limit). A check's output layer has every violation whatever the limit, and geomGetCount() still counts them all; a message says how many weren't marked. With abort True, a check that reaches the limit stops the run with an error, so later checks aren't run. geomBegin clears the limit. For example:
geomSetErrorLimit(100) geomSpace(m1, 0.2, "M1 space < 0.2")
Error regions output by a check can overlap one another (a corner, for example, is measured by two pairs of edges), as can shapes from geomGetRawShapes and the windows from geomDensity. Each region stays a shape of its own, so geomNumShapes() counts them, and the boolean operations (geomOr, geomAnd, geomAndNot, geomXor, geomNot) and geomSize and geomTrapezoid merge them first.
out_layer = geomWidth(layer, rule, message=None)
Single layer width check. Checks layer for minimum width violations i.e. widths less than rule. Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns.
An optional message will be written as a property 'drcWhy' on the marker shape if specified.
out_layer = geomWidth(layer, rule, int flags, message=None)
Checks layer for minimum width violations i.e. widths less than rule. Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns.
Allowable flags are:
- horizontal
- vertical
- diagonal
- project
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- the output flags (see Flags above)
- the check modifiers (see Flags above)
An optional message will be written as a property 'drcWhy' on the marker shape if specified.
out_layer = geomAllowedWidths(layer, rules, flags, message=None)
Checks layer for width violations. The widths must be discrete values specified in rules, which is a python sequence. Error polygons are created on the drcMarker layer in the current cellView. The rules must be specified in microns.
Allowable flags are:
- horizontal
- vertical
- diagonal
- the output flags (see Flags above)
An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Example:
geomAllowedWidths(poly, [0.020, 0.022, 0.024], horizontal)
out_layer = geomLength(layer, rule, message=None)
out_layer = geomLength(layer, rule, int flags, message=None)
Checks the length of each shape on layer: the largest distance across the shape between two of its edges that face each other, which for a rectangle is its longer side. Shapes with a length less than rule, in microns, are violations. An error region is reported between each pair of facing edges of the shape. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags are:
- horizontal
- vertical
- diagonal
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- the output flags (see Flags above)
The angle flags choose which edges of the shape are measured. For the length of edges themselves, use geomGetLength.
out_layer = geomEdgeLength(layer1, layer2, rule, int flags, message=None)
Checks layer1 for edge length violations i.e. lengths less than rule, where edges of layer1 related to shapes on layer2 are checked. The relation of layer1 edges to layer2 edges can be specified by flags. Possible checks are:
- butting - outside edges of layer1 that abut layer2 outside edges are checked.
- coincident - inside edges of layer1 that are coincident with outside edges of layer2 are checked.
- inside - edges of layer1 that are inside layer2 shapes are checked.
- outside - edges of layer1 that are outside layer2 shapes are checked.
- over - edges of layer1 that are coincident or inside layer2 shapes are checked.
- not_over - edges of layer1 that abut or are outside layer2 shapes are checked.
- the output flags (see Flags above)
Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns.
Allowable flags are:
- horizontal
- vertical
- diagonal
- butting
- coincident
- inside
- outside
- over
- not_over
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- output_only
- opposite
An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Example:
geomEdgeLength(gate, active, 0.13, coincident, "Gate length < 0.13um")
geomEdgeLength compares nearby edges whole. For an exact selection of the parts of edges in a relationship, use geomGetEdge and geomGetLength, e.g.:
saveDerived(geomGetLength(geomGetEdge(gate, active, coincident), 0.13), "Gate length < 0.13um")
out_layer = geomGetEdge(layer1, layer2, int flags)
Selects the parts of the edges of layer1 that are in a relationship to the shapes of layer2. layer1 is a polygon layer, or an edge layer from geomGetEdge or geomGetLength. layer2 is a polygon layer. The result is an edge layer: each edge keeps its direction, with the inside of the layer1 shape it came from on its left. It can be written with saveDerived, combined with other edge layers by geomAnd, geomOr, geomAndNot and geomXor, and passed to geomGetEdge and geomGetLength again.
Exactly one relationship flag must be given:
- inside - parts of edges inside layer2 shapes, which cover both sides of the edge.
- outside - parts of edges outside layer2 shapes, which cover neither side.
- coincident - parts of edges on a layer2 edge, where the shapes overlap.
- butting - parts of edges on a layer2 edge, where the shapes do not overlap.
- over - inside or coincident.
- not_over - outside or butting.
Other allowable flags are:
- whole_edge - output each edge of layer1 whole if any part of it is selected, and join edges that follow on from one another (the end of one is the start of the next, diagonal or not) into one edge: a run of segments, such as the side of a bent gate. geomGetLength measures a run's length as the sum of its segments.
- horizontal, vertical, diagonal - only output edges at these angles.
Several relationships, such as the parts of diff edges outside poly and over pwell, are nested calls. Example:
gate = geomAnd(poly, active) gatel = geomGetEdge(gate, poly, inside) # gate ends: their length is the gate length gatew = geomGetEdge(gate, poly, coincident | whole_edge) # gate sides, whole even if the gate bends saveDerived(geomGetLength(gatew, 5.0), "Gate width < 5.0") diffside = geomGetEdge(geomGetEdge(diff, poly, outside), pwell, over)
Edge layers in checks
geomWidth, geomSpace (one layer or two, with a rule and flags), geomEnclose and geomExtension accept an edge layer from geomGetEdge or geomGetLength wherever they take a layer. The check runs on the polygons the edges came from, and reports only the parts of their edges in the edge layer: a pair of edges is measured as usual, and each pair of their parts in the edge layers that fails is reported. Without opposite a marker covers both edges of a pair; with it, only where they face each other. For example, gate rules:
gate = geomAnd(poly, active) ends = geomGetEdge(gate, poly, inside) # across the poly sides = geomGetEdge(gate, poly, coincident | whole_edge) # along the poly sides geomEnclose(poly, ends, 3.0, opposite, "Poly gate overlap onto field < 3.0") geomEnclose(active, sides, 3.0, opposite, "Source/Drain enclosure of gate < 3.0")
The other checks (geomNotch, geomSpace2, geomEnclose2, the geomAllowed checks, geomEolSpace, geom2DSpace and the width or run length dependent forms of geomSpace) don't take edge layers, and give an error if given one.
out_layer = geomGetLength(layer, rule, int flags=lessthan)
Selects the edges of layer (a polygon layer, or an edge layer) whose length compares with rule. An edge from geomGetEdge with whole_edge may be a run of segments; its length is their sum, and with an angle flag every segment must have that angle. The length is compared with rule, in microns, as the flags say: lessthan (the default), lessorequal, equals, not_equal, greaterthan or greaterorequal. horizontal, vertical and diagonal select edges by angle. The result is an edge layer, as for geomGetEdge, and no markers are written. A diagonal edge is rarely a whole number of database units long, so test it with lessorequal or greaterorequal rather than equals.
out_layer = geomGetLengthRange(layer, min, max, int flags=0)
Selects the edges of layer with min < length < max. With greaterorequal the min end is included, with lessorequal the max end. horizontal, vertical and diagonal select edges by angle, as for geomGetLength. Example:
legs = geomGetLength(geomGetEdge(m1, fleb, inside), 0.19, greaterorequal) ends = geomGetLengthRange(geomGetEdge(m1, poly, outside), 0.05, 0.1, greaterorequal | lessorequal)
out_layer = geomSpace(layer, rule, message=None)
out_layer = geomSpace(layer, rule, int flags, message=None)
Checks layer for minimum spacing violations i.e. single layer spacings less than rule. Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns. Note that spacing violations between edges of the same polygon are not reported; to detect these perform a geomNotch check. An optional message will be written to the error marker flag if specified. flags can be used to control the spacing check. A flag of samenet applies the check only if the two shapes are on the same physical net. flags can be used to control the spacing check.
Allowable flags are:
- samenet
- diffnet
- vertical
- horizontal
- diagonal
- project
- parallel
- abut
- not_equal
- equals
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- the output flags (see Flags above)
- the check modifiers (see Flags above)
Example:
geomSpace(active, 0.2, samenet, "active space < 0.2 for same net")geomSpace(active, 0.3, diffnet, "active space < 0.3 for different nets")
out_layer = geomSpace(layer, rule, width, length, int flags, message=None)
Checks layer for minimum spacing violations i.e. single layer spacing less than rule, where one of the shapes has a width > width and a parallel run length > length. The width is the shape's width at the edge, as for geom2DSpace, and the length is the side along the edge of the rectangle that width comes from. Error polygons are created on the drcMarker layer in the current cellView. The rule and width dimensions must be specified in microns. Note that spacing violations between edges of the same polygon are not reported; to detect these perform a geomNotch check. An optional message will be written to the error marker flag if specified. flags can be used to control the spacing check.
Allowable flags are:
- samenet
- diffnet
- vertical
- horizontal
- diagonal
- project
- parallel
- abut
- not_equal
- equals
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- the output flags (see Flags above)
- the check modifiers (see Flags above)
Example:
geomSpace(active, 0.2, 10.0, samenet, "active space < 0.2 for same net with width > 10.0")
geomSpace(active, 0.3, 10.0, diffnet, "active space < 0.3 for different nets with width > 10.0")
out_layer = geomSpace2(layer, rule, width, length, int flags=0, message = None)
Checks layer for minimum spacing violations i.e. single layer spacing less than rule, where both of the shapes has a width > width and a parallel run length > length. Error polygons are created on the drcMarker layer in the current cellView. The rule and width dimensions must be specified in microns. Note that spacing violations between edges of the same polygon are not reported; to detect these perform a geomNotch check. An optional message will be written to the error marker flag if specified. flags can be used to control the spacing check.
Allowable flags are:
- samenet
- diffnet
- vertical
- horizontal
- diagonal
- project
- parallel
- abut
- not_equal
- equals
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- the output flags (see Flags above)
- the check modifiers (see Flags above)
Example:
geomSpace2(active, 0.2, 10.0, samenet, "active space < 0.2 for same net with width > 10.0")geomSpace2(active, 0.3, 10.0, diffnet, "active space < 0.3 for different nets with width > 10.0")
out_layer = geomSpace2(layer1, layer2, rule, width, length, int flags=0, message = None)
Checks for spacing less than rule between shapes on layer1 and shapes on layer2, where both shapes have a width > width along a length > length. As with the two layer form of geomSpace, shapes that touch, overlap or contain one another are not checked. Each shape's width is measured on its own layer. flags are as for the single layer form above.
Example:
geomSpace2(metal1, wide, 0.3, 0.1, 0.001, 0, "Metal1 space < 0.3 to wide metal, both wider than 0.1")
out_layer = geomSpace(layer1, layer2, rule, message=None)
out_layer = geomSpace(layer1, layer2, rule, int flags, message=None)
Checks layer1 to layer2 for minimum spacing violations i.e. two layer spacings less than rule. Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns. An optional message will be written to the error marker flag if specified. flags can be used to control the spacing check.
Allowable flags are:
- samenet
- diffnet
- vertical
- horizontal
- diagonal
- project
- parallel
- abut
- not_equal
- equals
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- the output flags (see Flags above)
- the check modifiers (see Flags above)
Example:
geomSpace(nwell, ndiff, 0.2, samenet, "nwell to n+ diff space < 0.2 for same net")
geomSpace(nwell, ndiff, 0.3, diffnet, "nwell to n+ diff space < 0.3 for different nets")
out_layer = geomSpace(layer1, rule, length, flags=0, message = None)
Single layer length dependent spacing check. Checks layer1 for minimum spacing violations i.e. single layer spacing less than rule, where the shapes have a parallel run length that can be lessthan, greaterthan, equals not not_equal to length, according to flags. Error polygons are created on the drcMarker layer in the current cellView. The rule and length dimensions must be specified in microns as a float. Note that spacing violations between edges of the same polygon are not reported; to detect these perform a geomNotch check. An optional message will be written to the error marker flag if specified. flags can be used to control the runlength check.
Allowable flags are:
- vertical
- horizontal
- diagonal
- not_equal
- equals
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- samenet
- diffnet
- the output flags (see Flags above)
Example:
geomSpace(active, 0.2, 10.0, lessthan, "active space < 0.2 with runlength < 10.0")
out_layer = geomAllowedSpaces(layer, rules, flags, message=None)
Checks layer for space violations. The spaces must be discrete values specified in rules, which is a python sequence. Spacing greater or equal to the last rule is allowed. Error polygons are created on the drcMarker layer in the current cellView. The rules must be specified in microns.
Allowable flags are:
- vertical
- horizontal
- diagonal
- project
- abut
- the output flags (see Flags above)
An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Example:
geomAllowedSpaces(active, [0.020, 0.022, 0.024], horizontal)
In the above, the layer 'active' must have spacing of either 20nm, 22nm or >= 24nm.
out_layer = geom2DSpace(layer, rules, flags, message=None)
Checks layer for spacing that is both length and width dependent. The rules consist of a 2D python array, of which row 0 defines the widths of the rules, and column 0 defines the lengths of the rules. The other entries are the rule values. A shape's width along an edge is measured as LEF does, stretch by stretch: the smaller side of the widest rectangle of the shape's metal that has that stretch of the edge on one of its sides. So where a wide block's edge runs on into a thin wire's edge, the block's stretch is wide and the wire's is thin, and each stretch is checked at its own spacing. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags are:
- samenet
- diffnet
- vertical
- horizontal
- diagonal
- project
- abut
- the output flags (see Flags above)
Example:
geom2DSpace(m1, [ [0.000, 0.028, 0.032, 0.040, 0.064, 0.120, 0.240, 0.320, 0.600], [0.028, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036], [0.240, 0.036, 0.068, 0.076, 0.076, 0.076, 0.076, 0.076, 0.076], [0.480, 0.036, 0.068, 0.076, 0.092, 0.092, 0.092, 0.092, 0.092], [1.200, 0.036, 0.068, 0.076, 0.092, 0.120, 0.120, 0.120, 0.120], [1.800, 0.036, 0.068, 0.076, 0.092, 0.120, 0.240, 0.240, 0.240], [2.400, 0.036, 0.068, 0.076, 0.092, 0.120, 0.240, 0.320, 0.600] ], 0, "M1 Minimum spacing")
The above defines a minimum rule of 28nm for normal metal. For metal wider than 240nm then if the width is wider than 32nm the rule is 68nm, if the width is wider than 40nm the rule is 76nm etc.
out_layer = geomNeighbours(layer1, dist, rule, num = 3, message= None)
Single layer nearest neighbour check. Checks layer1 shapes for neighbouring shapes within dist. If there are more than num shapes within rule, then an error is generated. This check is for contacts/vias in e.g. 40nm or below processes; only rectangular shapes can be checked. geomNeighbours takes no flags.
Example:
geomNeighbours(CO, 0.11, 0.10, 3, "CO Space to 3 neighbours < 0.10 (CO.S.2)") The above checks if there are 3 neighbouring CO shapes within 0.11um of a CO shape. If so they have to be spaced by 0.10um.
out_layer = geomNotch(layer1, rule, message=None)
out_layer = geomNotch(layer1, rule, flags, message=None)
Checks layer1 polygons for notch violations. Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns. Note that notches are effectively spacing violations between edges of the same polygon. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags are:
- the output flags (see Flags above)
- the check modifiers (see Flags above)
out_layer = geomNotch(layer1, rule, width, length, message=None)
Width dependent notch check. Checks layer1 polygons for notches less than rule where one of the two edges has a width > width along a length > length. The width is measured as for the width dependent form of geomSpace, stretch by stretch along each edge. rule, width and length are in microns, and width and length must be greater than 0. This form takes no flags. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Example:
geomNotch(metal1, 0.3, 1.0, 0.5, "M1 notch < 0.3 with width > 1.0")
out_layer = geomLineEnd(layer1, rule, num_ends, min_adj_edge_length=0.0, flags=0, message=None)
Checks layer1 for minimum line end spacings. The spacing is from the line end edge to another edge which is either a normal edge (if num_ends=1) or another line end edge (if num_ends = 2). A line end edge is a horizontal edge with two adjacent vertical edges, or a vertical edge with two adjacent horizontal edges. The adjacent edge length must be greater than the line end edge length, or min_adj_edge_length, whichever is the greater. The rule dimension and the min_adj_edge must be specified in microns.
Allowable flags are:
- vertical
- horizontal
- diagonal
- not_equal
- equals
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- the output flags (see Flags above)

In the above example, the rules are as follows:
geomSpace(metal1, 0.06) geomLineEnd(metal1, 0.08, 1) geomLineEnd(metal1, 0.07, 2)
out_layer = geomLineEnd(layer1, layer2, rule, num_ends, min_adj_edge_length=0.0, flags = 0, message=None)
As above but for two layer checking.
out_layer = geomPitch(layer1, rule, flags = 0, message=None)
Checks that layer1 is on a pitch greater than or equal to the rule specified. flags can be vertical or horizontal. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags are:
- vertical
- horizontal
- diagonal
- equals
- not_equal
- the output flags (see Flags above)
out_layer = geomOverlap(layer1, layer2, rule, message=None)
out_layer = geomOverlap(layer1, layer2, rule, flags, message=None)
Checks layer1 to layer2 for minimum overlap violations i.e. layer1 overlaps layer2 by less than rule. Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags are:
- vertical
- horizontal
- diagonal
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- the output flags (see Flags above)
- the check modifiers (see Flags above)
out_layer = geomEolSpace(layer1, space, width, within, flags=0, message=None)
Checks layer1 for end of line spacing, as the LEF rule SPACING space ENDOFLINE width WITHIN within
and the techfile MINEOLSPACE rule. layer1 is merged first, so shapes that abut or overlap make no line ends.
A line end is a Manhattan edge shorter than width whose two corners are both convex. The zone in front of it,
space deep and within wider than the line end on each side, must have no metal in it; metal that only
touches the zone's boundary is clear. Metal of other shapes counts, and so does the line end's own shape where it comes
round in front. Each failing line end is reported once, as the box from the line end out to the nearest metal in its zone.
space and width must be greater than 0 and within 0 or more, all in microns.
Allowable flags are:
- the output flags (see Flags above)
For example, for a metal1 rule of SPACING 0.08 ENDOFLINE 0.10 WITHIN 0.025:
geomEolSpace(metal1, 0.08, 0.10, 0.025)
out_layer = geomEnclose(layer1, layer2, rule, message=None)
out_layer = geomEnclose(layer1, layer2, rule, flags, message=None)
Checks layer1 to layer2 for minimum enclosure violations i.e. layer1 encloses layer2 by less than rule. Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns. The optional flags can have the 'abut' flag set which considers abutting edges an error; otherwise abutting edges are allowed. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags are:
- vertical
- horizontal
- diagonal
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- abut
- the output flags (see Flags above)
- the check modifiers (see Flags above)
Either layer may be an edge layer from geomGetEdge, to check only those edges (see Edge layers in checks). Example, gate rules:
gate = geomAnd(poly, active) ends = geomGetEdge(gate, poly, inside) sides = geomGetEdge(gate, poly, coincident | whole_edge) geomEnclose(poly, ends, 3.0, opposite, "Poly gate overlap onto field < 3.0") geomEnclose(active, sides, 3.0, opposite, "Source/Drain enclosure of gate < 3.0")
out_layer = geomEnclose2(layer1, layer2, rule1, rule2, rule3, edges, message=None)
Checks layer1 to layer2 for minimum enclosure violations. layer1 should enclose layer2 by rule1 normally. However if there 1 or more edges of layer2 with enclosure greater than or equal to rule2, but less than rule1, and edges (e.g. 2) perpendicular edges of layer1 enclose layer2 by greater than or equal to rule3, then no violation occurs. The rule* dimensions must be specified in microns. An optional message will be written to the error marker flag if specified. Any edge enclosure less than rule2 will give an error. The parameter edges must be 1 or 2.
Example:
geomEnclose2(nwell, active, 0.18, 0.08, 0.23, 2)
Enclosure of active by nwell should be >= 0.18um, however if 2 parallel edges of active have a nwell enclosure of 0.08um then the other two perpendicular edges should have a minimum enclosure of 0.23um.
geomEnclose2(cont, metal, 0.15, 0.05, 0.30, 1)
Enclosure of cont by metal should be 0.15um, however an edge can be enclosed by 0.05um if one perpendicular edge is greater than or equal to 0.3um.
out_layer = geomAllowedEncs(layer1, layer2, rules, message=None)
Checks layer1 to layer2 for minimum enclosure violations. layer1 must enclose layer2 according to rules, which is a list of triplets e.g. [ [0.010, 0.010, 4], [0.0, 0.032, 2], [0.002, 0.028, 2] ]. For each triplet, the first two numbers are allowed enclosures, and the third number is the number of sides that must obey the second rule. For example, in the first case [0.010, 0.010, 4] all 4 sides of layer2 can be enclosed by 10nm. In the second case [0.0, 0.032, 2] there can be 2 opposite sides with enclosure of 0nm, and the other two sides must have an enclosure of 32nm. Finally in the third case [0.002, 0.028, 2] there can be 2 opposite sides with enclosure of 2nm and the other two sides must have enclosure of 28nm. These are the only allowed enclosure values; anything else will give a violation. The rule dimensions must be specified in microns. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
out_layer = geomExtension(layer1, layer2, rule, message=None)
out_layer = geomExtension(layer1, layer2, rule, flags, message=None)
Checks layer1 to layer2 for minimum extension violations i.e. layer1 extends beyond layer2 by less than rule. Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags are:
- vertical
- horizontal
- diagonal
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- abut
- the output flags (see Flags above)
- the check modifiers (see Flags above)
out_layer = geomArea(layer1, minrule, maxrule=9e99, message=None)
Checks layer1 shapes for minimum area violations that meet the condition (minrule < area) || (area < maxrule). Error polygons are created on the drcMarker layer in the current cellView. The minrule and optional maxrule dimensions must be specified in microns. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Pass maxrule as a float, e.g.:
geomArea(m1, 0.1, 10.0)
A whole number such as 10 is taken as flags by the form below, not as a maximum area. The same applies to geomAreaIn, geomHoleArea and geomHoleAreaIn.
out_layer = geomArea(layer1, minrule, flags=0, message= None)
Single layer area check. Checks layer1 shapes for minimum area violations that meet the condition minrule op area. Error polygons are created on the drcMarker layer in the current cellView. The minrule dimension must be specified in microns as a float. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags to control op are:
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
out_layer = geomAreaIn(layer1, minrule, maxrule=9e99, message=None)
Checks layer1 shapes and flags shapes that meet the condition (area > minrule) && (area < maxrule). Error polygons are created on the drcMarker layer in the current cellView. The minrule and optional maxrule dimensions must be specified in microns. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
out_layer = geomAreaIn(layer1, minrule, flags=0, message= None)
Single layer internal (hole) area check. Checks layer1 shapes and flags shapes that meet the condition area op minrule. Error polygons are created on the drcMarker layer in the current cellView. The minrule and optional maxrule dimensions must be specified in microns as a float. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags to control op are:
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
out_layer = geomHoleArea(layer1, minrule, maxrule=0.0, message=None)
Checks the holes in layer1 shapes for area violations: a hole with area less than minrule, or greater than maxrule, is an error. A maxrule of 0.0 (the default), or one less than minrule, means no maximum. The areas are in square microns. Each failing hole is output, as a shape, and marked. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
out_layer = geomHoleArea(layer1, minrule, flags=0, message=None)
Checks the holes in layer1 shapes: a hole whose area compares with minrule as flags say is an error.
Allowable flags are:
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
out_layer = geomHoleAreaIn(layer1, minrule, maxrule=0.0, message=None)
Checks the holes in layer1 shapes and flags the holes that meet the condition (area > minrule) && (area < maxrule), as geomAreaIn does for shapes. A maxrule of 0.0 (the default), or one less than minrule, means no maximum.
out_layer = geomHoleAreaIn(layer1, minrule, flags=0, message=None)
As geomHoleArea with flags. Allowable flags are the same: equals, not_equal, lessthan, lessorequal, greaterthan and greaterorequal.
As for geomArea, pass maxrule as a float: a whole number is taken as flags.
area = geomMinDensity(layer1, rule, message= None)
Checks layer1 for minimum density of the layer, where rule is the percentage of the layer area of the design bounding box. An optional message will be written as a property 'drcWhy' on the marker shape if specified. This function returns the area in square dbu of the layer.
area = geomMaxDensity(layer1, rule, message= None)
Checks layer1 for maximum density of the layer, where rule is the percentage of the layer area of the design bounding box. An optional message will be written as a property 'drcWhy' on the marker shape if specified. This function returns the area in square dbu of the layer.
geomDensity(layer1, window_x, window_y, step_x, step_y, rule, flags, message= None)
Checks layer1 for density locally in a rectangle of size given by window_x and window_y. The window is stepped in increments of step_x and step_y over the design bounding box. Flags will determine how the area rule is applied (rule is a percentage). An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags are one of:
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
out_layer = geomMargin(layer1, rule, message=None)
Checks layer1 shapes for minimum margin violations. A margin violation is the distance (typically greater than the normal minimum spacing), from the vertex common to two adjacent concave edges of a polygon, to edge(s) of a nearby polygon. Error polygons are created on the drcMarker layer in the current cellView. The rule dimension must be specified in microns. An optional message will be written as a property 'drcWhy' on the marker shape if specified.
In the above example, the distance of the inner (concave) edge of the L shaped polygon vertex is less than the specified rule to the nearest vertex of the rectangle. Two error flags are created because there are two edges of the rectangle containing the vertex in violation.
num = geomOffGrid(layer1, grid, marker_size=0.1, message=None)
Checks all layer1 vertices of edges to see if they are on a multiple of the grid specified in microns by grid. marker_size is the size of the marker in microns (shown as a '+' centered on the offgrid vertex) on the drcMarker layer. An optional message will be written to the error marker flag if specified. The return value is the number of off-grid vertices found.
out_layer = geomAdjLength(layer1, rule, length, flags, message=None)
Checks vertices for adjacent edge length, If one edge has length less than length, the other edge must have length greater than rule.An optional message will be written as a property 'drcWhy' on the marker shape if specified.
Allowable flags are:
- equals
- not_equal
- lessthan
- lessorequal
- greaterthan
- greaterorequal
- the output flags (see Flags above)
out_layer = geomAllowedSize(layer1, rule, message=None)
Checks the size of rectangular shapes e.g. contacts or vias. rule specifies the permissible edge lengths as length/width pairs.An optional message will be written as a property 'drcWhy' on the marker shape if specified.
For example:
geomAllowedSize(via, [[0.028, 0.028],[0.028,0.056]], "Via is rectangular 28x28 or 28x56nm")
Checks shapes on the layer via which must be rectangles with either sides of 28nm or 2 sides of 28nm and 2 sides of 56nm.
num = geomGetCount()
Returns the number of errors detected in the most recent DRC check.
num = geomGetTotalCount()
Returns the total number of DRC errors since the start of the run.
Extraction
Glade can trace connectivity in a layout and identify devices such as resistors, capacitors, diodes, mos and bipolar transistors plus parasitic capacitors. To extract a layout, a python script is used to form derived layers, run connectivity tracing and extract devices. The results are saved to a cellView with the viewName of ‘extracted’ but this can be changed using the setExtViewName command.
Extraction rules consist of 4 steps:
- Reading layer data and merging it
- Forming derived layers
- Extracting connectivity
- Extracting devices
- Saving interconnect layers
Derived layers are used to identify devices and break connecting layers such as poly or diffusion where they touch active devices.
A MOS device is formed by diffusion and poly layers. Two derived layers are generated; the recognition region, formed by using geomAnd() to produce the intersection of the tow layers, and the S/D terminals, produced by using geomAndNot() to subtract the poly area from the diffusion. This is necessary, else connectivity tracing on the diffusion would see a short between the S and D terminals. Connectivity tracing is performed using the geomConnect command. This traces connectivity through specified layer-layer overlaps, for example metal1 connectivity to poly though a contact layer. Device extraction is performed using the extract… commands. When devices are extracted, an extraction PCell (e.g. nch_ex.py in the example data) is used to form an instance in the extracted view which is connected via the layers traced in geomConnect. The PCell is passed the coordinates of the recognition region used to identify the device, along with any properties for the particular type of device. Saving interconnect is done using the saveInterconnect() function. This takes a derived layer and maps it back to a technology file layer/purpose. The layers being saved should have been present in a geomConnect() command previously. Parasitic extraction determines capacitance between connect layers either using a simple area/perimeter calculation, or a more accurate (but much slower) 3D field solver ‘Fastcap’.
The extracted view can be netlisted to a CDL/Spice file; there are two methods by which the netlister will format the lines for each instance in the file. If a string property named ‘NLPDeviceFormat’ is present on the PCell master, this property allows user defined netlisting. See ‘NLP expressions’ for more details of the NLPDeviceFormat syntax. If this property is not present, the netlister will look for hardcoded property names on devices:
- MOS/TFT : ‘w’, ‘l’, ‘m’, ‘as’, ‘ad’, ‘ps’, ‘pd’
- Resistors : ‘r’, ‘w’, ‘l’
- Capacitors : ‘c’, ‘w’, ‘l’
- Inductors : ‘l’
- Diodes : ‘area’, ‘pj’ or ‘perim’
- Bipolars : ‘area’, ‘pj’ or ‘perim’
The hardcoded netlister expects specific pin names on the extraction PCell devices:
- MOS : D, G, S, B
- FET : D, G, S
- Resistors : A, B
- Capacitors : A, B
- Inductors : A, B
- Diodes : A, C
- Bipolars : C, B, E
setExtViewName(name)
Sets the name of the extracted view. The default is "extracted", but for e.g. abstract generation you can set this to "abstract". Note this command should be given before any saveDerived / saveInterconnect commands.
geomConnect( [ [viaLayer, bottomLayer, topLayer], [...] ])
Trace connectivity through layers. This function takes a list of lists of layers, where the layers are a via or contact layer and the layers that are connected by it. For example:
geomConnect( [
[cont, active, poly, metal1],
[via1, metal1, metal2]
] )
The above will connect active and metal1 by the cont layer, poly and metal1 also by the cont layer, and metal1 and metal2 by the via1 layer. There is no limit to the number of lists of layers, or to the number of layers connected by a contact layer. However the list of connected layers must have only one contact/via layer, and that layer must be the first layer in the list. If shapes already have net information (e.g. through the use of the geomLabel() command) then these shapes are used as initial tracing points, and net names are propagated to connected shapes. Other shapes are assigned automatically generated names (n0, n1, n2 etc). Shorts between shapes with assigned or traced net names that are different are reported.
The geomConnect() command is multithreaded. It runs on the number of threads set in the Run Extraction dialog (one if Multithreaded is not checked), or on all the machine's threads for a rules file run some other way. The environment variable GLADE_THREADED_EXTRACTION sets the most threads it runs on, e.g. GLADE_THREADED_EXTRACTION=8; no or 0 runs it on one thread.
out_layer = geomStamp(layer, stampLayer, flags = 0, message = None)
Copies the shapes of layer to out_layer, giving each the net of the shapes of stampLayer it overlaps. stampLayer must have been connected by geomConnect() (or named by geomLabel()), so its shapes have nets. Use it to give a layer that isn't connected through a contact, such as a well, the net of the ties in it, without connecting the well to the ties in geomConnect(). Shapes that only abut or touch a stamping shape at a corner aren't stamped by it; they must share area.
- A shape overlapped by stamping shapes of one net gets that net.
- A shape overlapped by stamping shapes of several nets gets the net with the most of those shapes (of nets with as many, the first by name). With floatMultiStamp it gets a new net of its own instead.
- A shape overlapped by no stamping shape gets a new net of its own (named n0, n1 etc, as geomConnect names nets).
The flags also write markers, with the message (if given) before their text:
- floating - each shape of layer no stamping shape overlaps: "No stamped connections."
- multStamp - each shape of layer overlapped by stamping shapes of several nets: "Has multiple stamped connections."
- multConnect - each stamping shape whose net wasn't the one chosen for a shape it overlaps: "Causes multiple stamped connections."
- stampErrors - all three.
geomGetCount() returns the number of markers written. out_layer can be used wherever a connected layer can, e.g. with geomGetNet(), or in spacing checks with samenet and diffnet. For example, nwell given the nets of its tap diffusion, with markers for wells with no tap or taps of different nets:
geomConnect( [
[cont, ntap, metal1]
] )
nwellnet = geomStamp(nwell, ntap, stampErrors, "nwell/ntap")
geomSpace(nwellnet, 1.2, diffnet, "NW space < 1.2 (different nets)")
out_layer = geomAntenna(gate, antenna, rule, flags = 0, diode = None, diodeRule = 0.0, cumulative = None, message = None)
Checks antenna ratios. For each net, the antenna ratio is the area of its shapes on the antenna layers over the area of its shapes on the gate layers. A net fails if its ratio is greater than rule. The check measures the nets as connected when it runs, so a deck connects only the layers made so far with geomConnect() before each check (see the example below). gate, antenna and diode can each be a layer or a list of layers. The gate shapes need nets: give them their poly's net with geomStamp().
- gate: the gate shapes, e.g. poly AND diffusion stamped from poly. A net's gate area is the sum of its gates' areas, or with gateMin or gateMax in flags its smallest or largest gate's.
- antenna: the layers whose area on the net is the antenna area, e.g. the metal just made, or a list such as [metal2, via1] to count the cut area too.
- rule: the largest ratio allowed. With greaterorequal in flags, a ratio equal to it fails too.
- diode, diodeRule: a net with a shape on a diode layer (e.g. source/drain diffusion, connected through contacts) is checked against diodeRule instead; 0, the default, means such nets never fail.
- cumulative: a name. Each gate's ratio is added to a running total kept under this name, and the total is checked instead of the ratio. Calls with the same name add up, e.g. one per metal layer for a cumulative rule. Gates are matched between calls by their geometry, so use the same gate layer (stamped again) in each call. geomBegin() clears the totals. A gate on a net exempted by its diode adds nothing.
- message: the markers' text, followed by the net's name and ratio.
Allowable flags are gateMin or gateMax, greaterorequal and figB (see below).
out_layer has the gate shapes of the failing nets (with a cumulative total, the failing gates), or with figB in flags their shapes on the antenna layers. Each has a marker. geomGetCount() returns the number of failing nets. Nets with no gate area or no antenna area never fail. For example, a cumulative check over three metal layers, where a net connected to source/drain diffusion is safe:
gate = geomAnd(poly, diff)
sd = geomAndNot(diff, poly)
metal = [metal1, metal2, metal3]
via = [via1, via2]
for step in range(3):
# As connected when this metal is made
geomConnect([[cont, sd, poly, metal1]] + [[via[i], metal[i], metal[i + 1]] for i in range(step)])
g = geomStamp(gate, poly)
geomAntenna(g, metal[step], 400.0, 0, sd, 0.0, "car", "Metal%d cumulative antenna > 400" % (step + 1))
geomLabel(layer, 'layerName', purpose = 'drawing', createPin = True)
Label a layer with existing text labels. If a text label with layer layerName and purpose purpose has its origin contained in a shape on layer, then the shape will have its net name set to the text label name. Note that labelling layers should be performed prior to connectivity extraction for net name propagation. Logical nets/pins will be created in the extracted view for all text labels that attach to shapes on layer. If not specified, labelPurpose defaults to "drawing" . Note that labels are only used for the top level of the design; in other words labels at lower levels of the layout hierarchy are ignored. For LVS purposes, labelling power, ground, clock and primary IOs is all that is usually necessary. createPin can be set to False (default is True) to disable creating a pin - only a net will be created.
ok = geomSetText(layer, xcoord, ycoord, 'labelName', createPin = True)
Labels layer with text label labelName at the coordinates given by xcoord and ycoord (in microns). Returns True if a shape on the layer was found at the given xy coordinates; False if no shape was found (i.e. the command failed). This is useful if you cannot modify the original layout and want to try and resolve LVS errors by forcing a shape to be a specified net name. createPin can be set to False (default is True) to disable creating a pin - only a net will be created.
saveDerived(layer, 'why', outLayer = TECH_DRCMARKER_LAYER)
Outputs layer geometries as polygons to the current cellView. The layer they are output to can be set by outLayer, which defaults to the drcMarker layer. Each polygon has a string property drcWhy with value set to the string why.
saveDerived(layer, 'layerName', 'purpose', viewType='ext_view')
Outputs layer geometries as polygons to the current cellView. The layer they are output to can be set by layerName and purpose. If viewType is specified, the layer geometries are output to this view name rather than the default view name 'extracted'.
saveInterconnect( [layer1, layer2, ...] )
Creates a new cellview with the same cell name as the current cell, and a view name of 'extracted'. Shapes on layers specified are created in the extracted cellview. Shapes will have net information if they are on layers present in geomLabel and/or geomConnect() commands. Optionally instead of a layer name, a list of derived layer name, a techfile layer name and optionally a purpose can be specified, for example:
saveInterconnect( [
poly,
active,
[ metal1, 'M1' ],
[ metal2, 'M2', 'pin']
] )
Original layers that are generated from geomGetShapes() do not need the techfile layer name/purpose specified, but derived layers MUST specify the target layer name, else they will be assigned a fake layer number which the LSW will not show. It is often desirable to add dummy layers to the techfile and use these for saveInterconnect(). For example, when extracting a lateral PNP, derived layers for emitter, base and collector need to be generated for the extractBjt() terminals. In this case it's desirable to have dummy layers 'emitter', 'base' and 'collector' so that devices get extracted correctly.
If an existing layer name is specified without a purpose name, the purpose name defaults to 'drawing'. There is no limit on the number of layers in the list. Note that any terminal layer used in subsequent 'extract...' commands should be saved.
Extraction PCells
If the device model cellview is a PCell, each device is measured first and the PCell is then evaluated with the recognition region point list ptlist and the measured parameters listed for each command below (e.g. w, l, nsquares and nbends for a resistor). A PCell receives a measured parameter as an argument of the same name, if it has one, so it can calculate further parameters from the measured ones and save them with dbAddProp, for example a resistance from the number of squares and bends:
def rppolywo_ex(cv, ptlist=[[0,0],[1000,0],[1000,1000],[0,1000]], w=1.0e-6, l=1.0e-6, nsquares=1.0, nbends=0) :
rsh = 1000.0 # ohms/square
bendFactor = 0.56 # squares added per bend
cv.dbAddProp('r', rsh * (nsquares + nbends * bendFactor))
...
The measured parameters are also saved as properties of the PCell submaster. They keep their measured values even if the PCell sets them, so save calculated values under other names, such as r above. Devices with the same point list and measured parameters share a submaster. Properties that can differ between devices of the same geometry, such as a MOS device's as, ad, ps, pd, sa and sb, are set on the instance and are not passed to the PCell; use extractCalc (below) to calculate from them. The generic extractDevice command can measure further parameters.
Each device type has two extract commands. The extractXXXDevice forms (extractMOSDevice, extractResDevice etc.) name the device terminals and take extra measurements with measure and instMeasure; use them, or the generic extractDevice, for new rule decks. The plain forms (extractMOS, extractRes, extractMosCap, extractMimCap, extractDio, extractBjt and extractTFT) have fixed terminal names and are deprecated; they are kept so existing decks still run.
extractMOS('modelName', recLayer, gateLayer, diffLayer, bulkLayer=None)
Deprecated: this form has fixed terminal names and cannot take extra measurements. Use extractMOSDevice instead.
Extracts MOS devices and creates instances of a cellView 'modelName layout' in the extracted view. recLayer is the recognition layer of the gate region. gateLayer is the poly layer and diffLayer is the source/drain diffusion layer. bulkLayer is the optional well layer; if present the extracted instances have terminals D G S B, otherwise 3 terminal devices with terminals D G S are extracted. The layers gateLayer, diffLayer and bulkLayer must have previously been saved using the saveInterconnect command.
The extracted instances have the property 'w' set to the recLayer shape width (length of gate recognition shape edge coincident with diffLayer) and 'l' set to the distance between the coincident diffLayer/gateLayer edges. Both manhattan and any-angle gates are supported. The recLayer shapes should be a simple polygon without holes.
The instances also have the source and drain area and perimeter properties as, ps, ad and pd (in square metres and metres), nrs and nrd (the area over the width squared), and the sa/sb diffusion lengths. as/ps are those of the shape on the S terminal. A source/drain shape shared by several gates (e.g. the diffusion between the fingers of a multi-finger device) is split between them in proportion to the length of the edge each gate shares with it, i.e. each gate's width: a device gets that share of the shape's area, and that share of its perimeter less all the gate edges. For a shape that only one gate touches, this is the whole area and the perimeter less the device width.
The cellview 'modelName layout' will be created if it does not already exist. If it does exist, it is assumed to be a PCell, and its ptlist property is set to the point list of the recognition region. Example nmos/pmos cells with parameterised point lists are nmos_ex.py and pmos_ex.py.
extractMOSDevice(modelName, recLayer, [[gateLayer, termName],[S/DLayer, termName,termName],[bulkLayer, bulkTermName], measure=None, instMeasure=None)
As above but allows the terminal names of the gate, source, drain and bulk terminals to be specified.
measure and instMeasure are optional lists of extra measurements, as for extractDevice below: measure results are device (PCell) parameters and instMeasure results instance properties. A measurement with the name of a built-in parameter, e.g. w, replaces it.
extractRes('modelName', recLayer, termLayer, bulkLayer=None)
Deprecated: this form has fixed terminal names and cannot take extra measurements. Use extractResDevice instead.
Extracts a 2 terminal resistor and creates instances of a cellView 'modelName layout' in the extracted view. recLayer is the recognition layer for the resistor. termLayer is the layer of the resistor terminals e.g. poly, and shapes on this layer should overlap or touch the recognition layer shape. The layer termLayer must have previously been saved using the saveInterconnect command. If the optional layer bulkLayer is specified, an additional bulk node is generated for the resistor model.
The extracted instances will have the properties w set the the recLayer width (length of recLayer edge coincident with termLayer edge) and l set to the recLayer length (total length of all recLayer edges minus twice the width, then divided by two), nsquares set to l/w, nbends to the number of bends. These properties can be accessed via an extraction PCell - see the example 'pres_ex.py' in the distribution.
The cellview 'modelName layout' will be created if it does not already exist. If it does exist, it is assumed to be a PCell, and its ptlist property is set to the point list of the recognition region. If a PCell is used, its terminals are expected to be "A" and "B".
extractResDevice(modelName, recLayer, [[termLayer, termName, termName],[bulkLayer, termName]], measure=None, instMeasure=None)
As above but allows the terminal names of the term layer and bulk layer(if used) to be specified.
measure and instMeasure are optional lists of extra measurements, as for extractDevice below: measure results are device (PCell) parameters and instMeasure results instance properties. A measurement with the name of a built-in parameter, e.g. w, replaces it.
extractMosCap('modelName', recLayer, gateLayer, diffLayer, bulkLayer=None)
Deprecated: this form has fixed terminal names and cannot take extra measurements. Use extractMosCapDevice instead.
Extracts a 2 terminal capacitor and creates instances of a cellView 'modelName layout' in the extracted view. recLayer is the recognition layer for the capacitor. gateLayer and diffLayer form the terminal layers of the capacitor, and these layers must have previously been saved using the saveInterconnect command.
The extracted instances will have the properties area set the the recLayer area and perim set to the recLayer perimeter.
The cellview 'modelName layout' will be created if it does not already exist. If it does exist, it is assumed to be a PCell, and its ptlist property is set to the point list of the recognition region. If a PCell is used, its terminals are expected to be "G" for the gate layer and "S" for the diff layer.
extractMosCapDevice(modelName, recLayer, [[gateLayer, termName],[S/DLayer, termName],[bulkLayer,termName]], measure=None, instMeasure=None)
As above but allows the terminal names of the gate, S/D and optional bulk layer to be specified.
measure and instMeasure are optional lists of extra measurements, as for extractDevice below: measure results are device (PCell) parameters and instMeasure results instance properties. A measurement with the name of a built-in parameter, e.g. w, replaces it.
extractDio('modelName', recLayer, anodeLayer, cathodeLayer, bulkLayer=None)
Deprecated: this form has fixed terminal names and cannot take extra measurements. Use extractDioDevice instead.
Extracts a 2 terminal diode and creates instances of a cellView 'modelName' layout in the extracted view. recLayer is the recognition layer for the capacitor. anodeLayer and cathodeLayer form the terminal layers of the diode, and shapes on these layers should overlap or touch the recognition layer shape, and these layers must have previously been saved using the saveInterconnect command. .
The extracted instances will have the properties area set the the recLayer area and pj set to the recLayer perimeter.
The cellview 'modelName layout' will be created if it does not already exist. If it does exist, it is assumed to be a PCell, and its ptlist property is set to the point list of the recognition region. If a PCell is used, its terminals are expected to be "A" for the anode and "C" for the cathode.
extractDioDevice(modelName, recLayer, [[anodeLayer, termName],[cathodeLayer,termName], bulkLayer,termName]], measure=None, instMeasure=None)
As above but allows the terminal names of the anode, cathode and optional bulk layer to be specified.
measure and instMeasure are optional lists of extra measurements, as for extractDevice below: measure results are device (PCell) parameters and instMeasure results instance properties. A measurement with the name of a built-in parameter, e.g. w, replaces it.
extractBjt('modelName', recLayer, emitLayer, baseLayer, collLayer, bulkLayer=None)
Deprecated: this form has fixed terminal names and cannot take extra measurements. Use extractBjtDevice instead.
Extracts a 3 terminal bjt and creates instances of a cellView 'modelName layout in the extracted view. recLayer is the recognition layer for the bjt. emitLayer, baseLayer and collLayer form the terminal layers of the bjt, and shapes on these layers should overlap or touch the recognition layer shape, and these layers must have previously been saved using the saveInterconnect command. If bulkLayer is given, the bulk (substrate) shape that contains the recognition region becomes a fourth terminal, S (B is the base).
The extracted instances will have the properties area set the the emitter recLayer area and perim set to the recLayer perimeter.
The cellview 'modelName layout' will be created if it does not already exist. If it does exist, it is assumed to be a PCell, and its ptlist property is set to the point list of the recognition region. If a PCell is used, its terminals are expected to be "C" for the collector, "B" for the base and "E" for the emitter.
extractBjtDevice(modelName, recLayer, [[emitLayer, termName],[baseLayer, termName],[collLayer, termName],[bulkLayer, termName]], measure=None, instMeasure=None)
As above but allows the terminal names of the emitter, base, collector and optional bulk layer to be specified.
measure and instMeasure are optional lists of extra measurements, as for extractDevice below: measure results are device (PCell) parameters and instMeasure results instance properties. A measurement with the name of a built-in parameter, e.g. w, replaces it.
extractTFT('modelName', recLayer, gateLayer, diffLayer)
Deprecated: this form has fixed terminal names and cannot take extra measurements. Use extractTFTDevice instead.
Extracts TFT (thin film) MOS devices and creates instances of a cellView 'modelName layout' in the extracted view. recLayer is the recognition layer of the gate region. gateLayer is the poly layer and diffLayer is the source/drain diffusion layer. The layers gateLayer and diffLayer must have previously been saved using the saveInterconnect command. The gateLayer is normally the bottom metal1 plate and the diffLayer the top metal2 fingers.
The extracted instances have the property w set to the recLayer shape width (length of gate recognition shape coincident with diffLayer) and l set to the distance between the coincident edges. Both manhattan and any-angle gates are supported. The recLayer shapes should be simple polygons without holes.
The cellview 'modelName layout' will be created if it does not already exist. If it does exist, it is assumed to be a PCell, and its ptlist property is set to the point list of the recognition region. If a PCell is used, its terminals are expected to be "D" for the drain, "S" for the source and "G" for the gate.
extractTFTDevice(modelName, recLayer, [[gateLayer, termName],[S/DLayer, termName, termName]], measure=None, instMeasure=None)
As extractTFT but allows the terminal names of the gate, source and drain to be specified.
measure and instMeasure are optional lists of extra measurements, as for extractDevice below: measure results are device (PCell) parameters and instMeasure results instance properties. A measurement with the name of a built-in parameter, e.g. w, replaces it.
extractMimCapDevice(modelName, recLayer, [[plusLayer, termName],[minusLayer, termName]], measure=None, instMeasure=None)
Extracts metal finger (MIM) capacitors formed by interleaved fingers on plusLayer and minusLayer, which must have been saved by saveInterconnect, and creates instances of a cellView 'modelName layout' in the extracted view. The instances have the properties w (finger width), sp (finger spacing) and lr (finger length), in microns, and nr (number of fingers), from which an extraction PCell can calculate the capacitance. The deprecated extractMimCap('modelName', recLayer, plusLayer, minusLayer) does the same with the fixed terminal names PLUS and MINUS.
measure and instMeasure are optional lists of extra measurements, as for extractDevice below: measure results are device (PCell) parameters and instMeasure results instance properties. A measurement with the name of a built-in parameter, e.g. w, replaces it.
extractDevice('modelName', recLayer, [[termLayer1, 'term1', ...] [termLayer2, 'term2', ...]], measure=None, instMeasure=None)
Extracts a generic deviceand creates instances of a cellView 'modelName layout' in the extracted view. The first letter of the modelName should correspond to the Spice device type e.g. R for a resistor, C for a capacitor (case insensitive) etc. recLayer is the device recognition layer. The termLayer(s) should be connection layers previously saved by the saveInterconnect command. Each terminal layer can have one of more terminal names. Shapes on the terminal layer(s) that touch or overlap the recognition layer will be created as terminals of the device. The recLayer shapes should be a simple polygon without holes.
The cellview 'modelName layout' will be created if it does not already exist. If it does exist, it is assumed to be a PCell, and its ptlist property is set to the point list of the recognition region.
measure is an optional list of device parameters to measure. Each item is [name, kind], [name, kind, layer] or [name, kind, layer, value], and the result is a device parameter called name: a PCell model gets it as the argument of that name, so it can calculate further parameters from it (see Extraction PCells above), and other models get it as an instance property. Lengths are in metres and areas in square metres. A layer can be any layer, raw or derived, saved by saveInterconnect or not; its shapes are merged first, so touching shapes count as one and holes are allowed. The kinds are:
| kind | layer | result |
|---|---|---|
| area | none | Area of the recognition region |
| area | layer | Total area of the layer shapes that touch or overlap the recognition region, less their holes |
| perimeter | none | Perimeter of the recognition region |
| perimeter | layer | Total perimeter of the layer shapes that touch or overlap the recognition region, including their holes' edges |
| inside | layer | Area of the layer inside the recognition region (the AND of the two), less the layer's holes |
| bends | none | Number of bends in the recognition region (vertices / 2 - 2, so 0 for a rectangle) |
| corners | none | Number of vertices of the recognition region, not counting collinear ones (an integer) |
| concave | none | Number of concave vertices of the recognition region, e.g. one per 90 degree bend of a resistor (an integer) |
| count | layer | Number of layer shapes that touch or overlap the recognition region (an integer). A region inside a shape's hole does not touch it. |
| coincident | layer | Total length of the recognition region edges that lie along edges of layer shapes, e.g. a resistor's width at both ends |
| butting | layer | Length of the recognition region edges with the layer just outside them and not inside, e.g. the terminals at a resistor's ends |
| edgeinside | layer | Length of the recognition region edges that run within the layer (layer on both sides) |
| edgeoutside | layer | Length of the recognition region edges clear of the layer on both sides |
| distance | layer, value | Least edge to edge distance from the recognition region to layer shapes, looking up to value microns away; value (in metres) if there are none. 0 if the edges touch or cross. For a region inside a layer shape, it is the distance to that shape's edge, e.g. well proximity. |
For example, a resistor whose PCell calculates r from the measured width and area:
extractDevice('Rpoly_ex', pres, [[polyg, 'A', 'B']], measure=[
['wc', 'coincident', polyg], # width at both ends
['area', 'area'],
['nbends', 'bends'],
['dwell', 'distance', nwell, 20.0]])
instMeasure is a list of measurements in the same form, whose results are set as instance properties instead of device parameters. The PCell does not see them, so devices whose geometry is the same but whose surroundings differ, e.g. their distance to a well edge, still share a submaster. extractCalc functions do see them:
extractCalc('Rpoly_ex', lambda d: {'wpe': 1.0 + 1.0e-7 / d['dwell']})
extractDevice('Rpoly_ex', pres, [[polyg, 'A', 'B']],
measure=[['wc', 'coincident', polyg], ['area', 'area']],
instMeasure=[['dwell', 'distance', nwell, 20.0]])
extractCalc('modelName', function)
Sets a Python function to calculate instance properties of the devices extracted with model modelName by any of the extract commands. For each device the function is called with a dict of the device's parameters (e.g. w, l or the measure results), its instance properties (e.g. as, ad, sa, sb) and instName. It returns a dict of properties (numbers, strings or booleans) to set on the instance, or None. Unlike PCell parameters, these can differ between devices that share a submaster. Call extractCalc after geomBegin and before the extract command; geomBegin clears the functions, and extractCalc('modelName', None) removes one. If the function raises an error, the error is reported and the function is not called again.
def nchCalc(d):
return {'nrs': 0.5 * d['as'] / (d['w'] * d['w'])}
extractCalc('nch_ex', nchCalc)
extractMOS('nch_ex', ngate, polyg, active, psub)
extractParasitic(metLayer, areaCap, perimCap, 'gndNetName')
Extracts the parasitic capacitance of net shapes on layer metLayer. metLayer can be any layer in the geomConnect() set of layers; for each (merged) shape on metLayer its area (in microns^2) and perimeter (in microns) are calculated and multiplied by the values of areaCap and perimCap. An instance of a capacitor is created (of size 100x100 database units so not normally visible) on one of the vertices of the shape, with property 'c' set to the area * areaCap + perimeter * perimCap. The capacitance will be connected to the shape's net and to the ground net specified by gndNetName.
extractParasitic2(metLayer1, met2Layer, areaCap, perimCap)
Extracts the parasitic capacitance of net shapes between layers met1Layer and met2Layer. The two layers can be any layer in the geomConnect() set of layers; for each intersection of met1Layer and met2Layer the area (in microns^2) and perimeter (in microns) are calculated and multiplied by the values of areaCap and perimCap. An instance of a capacitor is created (of size 100x100 database units so not normally visible) on one of the vertices of the shape, with property 'c' set to the area * areaCap + perimeter * perimCap. The capacitance will be connected between the nets of the shapes of each metal layer.
extractParasitic3(metLayer1, met2Layer, areaCap, perimCap, [layer1,...layerN])
Only extracts capacitance between metal1Layer and metal2Layer if shield layer(s) layer1... layerN are not present between them. Note no checkinig is done for valid layers (yet). The two layers can be any layer in the geomConnect() set of layers; for each intersection of met1Layer and met2Layer the area (in microns^2) and perimeter (in microns) are calculated and multiplied by the values of areaCap and perimCap. An instance of a capacitor is created (of size 100x100 database units so not normally visible) on one of the vertices of the shape, with property 'c' set to the area * areaCap + perimeter * perimCap. The capacitance will be connected between the nets of the shapes of each metal layer.
extractParasitic3D('subsNetName', 'refNetName', tol=0.01, order=-1, depth=-1)
Perform parasitic capacitance extraction using the Fastcap 3D field solver. subsNetName is the name of the silicon substrate net; capacitances from conductor layers to the substrate plane will have this net as one of their terminals. tol is an optional tolerance (fastcap -t option) and defaults to 0.01 i.e. 1%. order is an optional parameter and corresponds to the fastcap option -o. By default (-1) fastcap automatically sets this. A higher number e.g. 3 may be used e.g. if accuracy of net-net capacitance is small and fastcap gives warning about non-negative values of the capacitance matrix. depth is the partitioning depth and corresponds to the fastcap option -d. It defaults to fastcap automatically setting the value.
In order to extract parasitics for layers, they must be defined in the techfile with non-zero thickness. An example:
In the above, HEIGHT specifies the conductor height above the silicon surface and THICKNESS the layer thickness. Dielectric constants are assumed to be 3.9 currently; the ability to set dielectric layer thickness/permittivity may be added in future. Automatic meshing is performed to generate fastcap compatible format input files: conductor faces are divided into panels no bigger than the smallest conductor shape width, and at least two each way, and the substrate plane, which extends beyond the conductors by three times the highest conductor top, into panels up to 1.5 conductor panels wide under the conductors, growing away from them (at most 20000; beyond that a warning is given and the panels under the conductors are made bigger). Layout with very narrow shapes over a large area therefore gives many panels and a long run. Each layer shape has conductors with a net name resulting from a geomConnect() connectivity extraction. Capacitances are calculated by Fastcap as a matrix in which the diagonal elements are the total capacitance for the conductor, and off-diagonal elements are the capacitances between conductors. Capacitances are backannotated to the extracted view as instances of a parasitic cap 'pcap'; netlisting the extracted view using File->Export CDL will allow a spice compatible netlist to be generated.
METLYR metal1 drawing HEIGHT 0.890 THICKNESS 0.280 ;
VIALYR via1 drawing HEIGHT 1.170 THICKNES 0.450 ;
METLYR metal2 drawing HEIGHT 1.620 THICKNESS 0.370 ;
In addition to the substrate net, a reference net refNetName is also created. Capacitances to this net represent field lines from a conductor to infinity. For most usage this can be lumped to the substrate net by a zero volt source connecting the two in your simulation testbench.
The temporary files produced by Glade are in Fastcap2 format, so another extractor could be used that can read this format. Temp files are created in the current working directory, or in the directory specified by the env var GLADE_FASTCAP_WORK_DIR. Temp files are normally deleted after extraction is completed; the env var GLADE_NO_DELETE_TMPFILES can be set to keep them. Glade expects is to find an executable called 'fastcap.exe' (windows) or 'fastcap' (Linux) in the same directory as the glade executable.
Note that Fastcap is a field solver - and as such is not designed to handle large problems. Typically cells with up to about 50 nets will extract in a resonable amount of time and memory .
Parasitic resistance extraction
Glade extracts the parasitic resistance of interconnect from the layout: each net becomes a network of resistors between its terminals (pins, device terminals and contacts), which can be measured in the rule deck, viewed in the extracted view and written as DSPF. The method follows Horowitz and Dutton [1] for the resistance of each piece of a conductor, and the REX extractor of Hwang [2] for the subnodes, ladder networks and network reduction. Run it after geomConnect(); the commands are:
resReset()
resConductor(metal1, 0.08, 'm1txt', 'drawing', 1e-4, 5e-5) # ohms/square, pin labels, pF/um^2, pF/um
resConductor(metal2, 0.06, 'm2txt', 'drawing') # capacitance from the techfile
resConductor(sd, 50.0)
resConductor(poly, 8.0)
resVia(cont, sd, metal1, 10.0) # a cut layer joining two layers; ohms per cut
resVia(cont, poly, metal1, 10.0)
resVia(via12, metal1, metal2, 2.0)
resDevice(sd, gate) # device shapes whose abutments are terminals
resDevice(poly, gate)
resInstPins(metal1) # LEF macro pins of placed cells are terminals
resExtract(None, True) # all nets, saving the results
r = resPointResistance('net1', 0.5, 20.5, 29.5, 20.5) # ohms between two points of net1
The method. Each conductor layer is merged into polygons, one net each, and every polygon is given subnodes, the places where current enters or leaves it [2]:
- via: a group of cuts to the layer above or below (cuts on the same two polygons no more than a cut size apart), with its number of cuts
- device edge: a stretch of boundary a device shape butts, for example source/drain against a gate; this is an equipotential
- device area: a device shape inside the polygon, for example a gate under poly
- pin: a text label on the polygon, or a pin shape of the cell itself (such as a DEF IO pin) over it, with resInstPins
- instance pin: with resInstPins, a pin shape of a placed cell's master (a LEF macro pin), transformed to the cell, over the polygon; it is named instance:pin
Instance pins let a routed LEF/DEF design, which has no extracted devices, be written as DSPF: DEF routing is read on purpose 'net', whose shapes keep their DEF net names, and the macro pins (purpose 'pin') are terminals where the routing overlaps them. If a pin covers several places on its net they are one node. An instance pin on the layer that no routing overlaps is put on its net from the layout as a node of its own, unconnected, and a polygon with no net takes the net of an instance pin on it.
If devices have been extracted (extractMOS and the other extract commands, after saveInterconnect), each device subnode is matched to a pin of the device instance holding its device shape: the pin on the polygon's net. A polygon with no net, such as a drain connected to nothing else, takes the net of the pin whose net covers it, so it gets the same name as in the extracted view.
The polygon is then broken into convex pieces by break lines at its concave corners [1]. At each corner the break line is perpendicular to the dominant direction of current flow, which is the direction along one of the corner's edges that runs furthest before meeting a wall that is not parallel to it; a device edge at the corner is continued instead, as it is an equipotential [2]. Break lines stop at the first wall or break line they meet, so every piece is convex. Edges may be at 0, 45 or 90 degrees.
The resistance of each piece between its ports (its subnodes and break lines) follows Horowitz and Dutton [1]: the current direction is set from the ports, and each port at an end of the piece is replaced by an equivalent contact perpendicular to the current. A contact along the side of the piece counts from half its width back from its end (the half square of the bend), a diagonal one from a quarter back, and a via by its face towards the other ports, lengthened to allow for current crowding. Ports between the ends make a ladder of resistors [2], and each step of the ladder is the integral of ds / w(s) along the current, with the width narrowed at the end contacts by current spreading from them at 45 degrees. Ohms are squares times the sheet resistance.
The heuristics suit wire-like shapes. A polygon they model poorly, typically a fat one where a break line along the side of a piece is not an equipotential, or one with small contacts set side by side, is instead solved by a 2D finite volume field solver on a grid through its vertices, graded finer next to small contacts; its subnodes are the terminals, and a resistor is placed between each pair that conducts. The solver works once per terminal, so a long polygon with many terminals, such as a power rail, is too much work: then only the pieces the heuristics model poorly (typically the via pads along it) are field solved, each on its own with its ports as the terminals, and the rest keep the heuristics. Only Manhattan polygons and pieces are field solved.
Each piece's capacitance to ground, its area times the layer's area capacitance plus the length of its walls (its edges that are not break lines or device edges) times the edge capacitance, is shared among its nodes [2]: each node gets the slice of the piece nearer to it than to its neighbours along the current.
Each net's polygons are then joined by their via resistors (ohms per cut divided by the number of cuts) into one network, which is reduced to its terminals: parallel resistors are combined and other nodes with one or two neighbours removed [2]. A removed node's capacitance goes to its neighbours, more to the one with less resistance to it.
Accuracy. Against a fine grid solution of Laplace's equation, random routed wires with bends are within about 2% (median 1.2%), and random fat shapes, which are field solved, within about 7% (median 1.2%). Shapes like the test shapes of [1] (bends, steps in width, T junctions, a 45 degree jog) are within 5%.
resReset()
Forgets the layers given to resConductor, resVia, resDevice and resInstPins, and restores the resFieldSolve defaults.
resConductor(layer, sheetRes = -1.0, textLayer = None, textPurpose = 'drawing', areaCap = -1.0, edgeCap = -1.0)
A layer to extract, which must have been in geomConnect(). sheetRes is in ohms per square; if negative, the layer's resistance in the techfile is used (LEF RPERSQ, or techfile sheetResistance). Text labels on textLayer/textPurpose over the layer become pins. areaCap (pF per square micron) and edgeCap (pF per micron of edge) give the layer's capacitance to ground; if negative, the layer's values in the techfile are used (LEF CPERSQDIST and EDGECAPACITANCE).
resVia(cutLayer, lowerLayer, upperLayer, ohmsPerCut = -1.0)
A cut layer joining two layers, at least one of which is a resConductor; contacts to a layer that is not (for example diffusion, if it is not extracted) are terminals of the network. ohmsPerCut is the resistance of one cut; if negative, the cut layer's resistance in the techfile is used (LEF cut layer RESISTANCE). A cut layer may be given in several resVia commands, for example contacts to diffusion and to poly.
resDevice(conductorLayer, deviceLayer)
Shapes of deviceLayer (for example a gate recognition layer) that butt or lie inside shapes of conductorLayer are terminals: device edges and device areas.
resInstPins(conductorLayer, pinPurpose = 'pin')
Pin shapes on the conductor's layer name with purpose pinPurpose are terminals where they overlap the conductor: those of the cell's own pins are pins, named as the pin, and those of each instance's master (LEF macro pins, which LEF import puts on purpose 'pin') are instance pins named instance:pin. Give it for each conductor layer that has pins, before or after its resConductor; resExtract stops with an error naming the layer if a resInstPins layer has no resConductor. With resExtract's save the instances are copied to the extracted view, each pin on its extracted net (pins not on a resInstPins layer, such as power pins, on their layout nets), so that Export DSPF writes each instance pin as an *|I node and each instance as an X line connected through those nodes. The log reports how many cell and instance pins were placed and how many instance pins no routing overlaps.
geomConnect([[via12, m1, m2], [via23, m2, m3], [via34, m3, m4]]) # each read on purpose 'net'
resReset()
for m in (m1, m2, m3, m4):
resConductor(m, -1.0)
resInstPins(m)
resVia(via12, m1, m2)
resVia(via23, m2, m3)
resVia(via34, m3, m4)
resExtract(None, True)
r = resPinResistance('net1', 'u1:A', 'u2:Z') # between two instance pins
resFieldSolve(maxCells = 200000, cellsPerWidth = 8.0)
Polygons the fracture heuristics model poorly are field solved, with cellsPerWidth cells across their narrowest piece, when the grid's cells times the number of terminals less one (one solve per terminal but one) is at most maxCells; otherwise the poorly modelled pieces are field solved one by one within the same limit. 0 turns field solving off. The log reports how many polygons were too fat for the heuristics, how many of them were field solved whole, and how many had pieces field solved.
n = resExtract(netName = None, save = False, reduce = True, verbose = False)
Extracts the networks of net netName, or of all nets, and returns the number of subnodes (-1 on error). With reduce each net's network is reduced to its terminals. With save the extracted view gets the pieces on layer resElement, the subnodes on layer resNode, each piece's resistors (with their values) on layer resResistor, and each named net's network as subnets net:1, net:2... (the node of its first pin named as the net, and a node at a device or instance pin named instance:pin) resistors and capacitors to ground, which File->Export DSPF writes: the net's capacitance on its *|NET line, pins as *|P, device pins as *|I, other nodes as *|S, then the resistors and capacitors (in farads), and the device instances as the CDL netlist writes them, each device pin written as its node; with resInstPins, the layout's instances the same way. With verbose and a net name, the net's resistors (each polygon's, then the reduced network's) are also listed in the log; for a large net that is many lines. While it runs, a progress bar and a stop button are shown in the status bar; stopping returns -1 and keeps no results.
resPinResistance, resPointResistance and resNetCapacitance query the networks of the last resExtract; they do not extract. When one returns a negative value it warns why: no resExtract has been run (or resReset has been since), the net was not extracted (the last resExtract was of another net only, or found no such net), a pin was not found, or the two nodes are not connected.
r = resPinResistance(netName, pinA, pinB)
After resExtract, the resistance in ohms through the whole network of netName between the nodes holding pins pinA and pinB (labels, cell pins, or instance pins as instance:pin); negative if either is not found or they are not connected.
r = resPointResistance(netName, x1, y1, x2, y2)
The same between the network nodes nearest two points, in microns. After a reduced resExtract the nodes are the net's terminals.
c = resNetCapacitance(netName)
After resExtract, the capacitance to ground of netName in farads; negative if it was not extracted.
Limitations. Capacitance is to ground only, from area and edge values: there is no coupling capacitance between nets (extractParasitic3D can give that). Two device or instance pins at one node are stored as one: on power rails, where the pins of abutting cells cover the rail, many instance pins can share nodes, so power nets are not yet written completely. Nets with no name and no device are not stored. Fat polygons with 45 degree edges keep the heuristic networks, which can read low; in a polygon too large to field solve whole, the break lines of the field solved pieces are still taken as equipotentials.
References
- M. Horowitz and R. W. Dutton, “Resistance Extraction from Mask Layout Data,” IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems, vol. CAD-2, no. 3, pp. 145–150, July 1983.
- J. P. Hwang, “REX – A VLSI Parasitic Extraction Tool for Electromigration and Signal Analysis,” in Proceedings of the 28th ACM/IEEE Design Automation Conference, paper 41.1, pp. 717–722, 1991.