Units
Database units, display units, the snap grid, and what circuitRF accepts when you type a value into a field.
circuitRF keeps three things apart that other tools tend to conflate: how a number is stored, how it is shown to you, and what grid new geometry lands on. Keeping them separate is what makes "change the units" an instant, lossless operation here instead of a destructive one.
The database unit (DBU)
Every layout coordinate in circuitRF is a 64-bit integer in database units. Not a floating-point millimetre — an integer count.
The reason is exactness. After a rotate, a paste, a boolean operation and a GDSII round-trip, two vertices that ought to coincide must compare exactly equal, or the geometry silently develops hairline gaps and self-intersections that only show up at the fab. Integers give that guarantee; doubles do not. It also makes "is this vertex on the grid?" a division with no remainder rather than a comparison against a tolerance.
One DBU is one nanometre by default. The layout property that sets this is DbuPerMicron, and its
default is 1000. That specific number is chosen, not inherited:
1 µm = 1000 DBU exact
1 mil = 25400 DBU exact
Both are exact integers at 1 nm resolution. A metric-authored MMIC and an imperial-authored PCB are therefore commensurable in the same database, a cell can be copied from one to the other with an exact transform, and mil↔µm conversion never produces a fractional coordinate. That single choice removes the whole family of "the imported board is 0.0003 mil off grid" problems.
At long range, ±9.2 × 1018 DBU is ±9.2 × 109 metres of addressable space. There
is no practical ceiling.
Storage versus display
The display unit is a presentation setting. Changing it moves nothing. A vertex
stored at 25400 DBU reads 25.4 when the display unit is µm and 1 when it is
mil. The stored integer is identical in both cases, and switching back and forth returns the byte-identical
file.
So changing the display unit is free: every shape stays exactly where it was, stays exactly on whatever grid it was on, and the change needs no undo entry beyond a view preference. It round-trips perfectly.
The display unit is saved in the .clay file, purely so a layout reopens in the unit it was authored
in. It carries no other meaning. The available display units are nm, µm, mm, mil and inch, and
the default comes from the technology — mil for the PCB starter technology, µm for the MMIC one.
Changing the DBU resolution is a migration
DbuPerMicron is a different matter, and circuitRF treats it as one. It is not a preference toggle:
- It may only change by an exact integer ratio. A non-integer ratio is rejected outright.
- Refining (1 nm → 0.1 nm, ratio 10) is always lossless — every coordinate is multiplied by ten and the operation proceeds, logged to the Messages pane.
- Coarsening (0.1 nm → 1 nm) is lossy the moment any coordinate is not divisible by the ratio. The whole design, including every referenced sub-cell, is pre-scanned first; if any vertex would move, the specific offenders are reported to Messages and the change requires confirmation. It is never a silent snap.
- The whole thing is one undoable operation.
In practice almost nobody touches it. The default is right for both target markets, and because refinement is always lossless, starting at 1 nm is safe even for a process that later needs finer resolution.
Layout units and the snap grid
The snap grid is a third, independent number: the pitch that new and edited vertices land on. It is stored in DBU and it is yours to change at will.
R5 in one sentence: changing the snap grid never re-snaps existing geometry. Moving from 1 µm to 0.5 µm does not move a single existing vertex. There is a separate, explicit Snap selection to grid command for when you actually want that, and it reports any shape it could not snap without self-intersecting.
This is the opposite of the schematic's rule, and it is right for layout. In a schematic an off-grid pin is a correctness bug — it breaks connectivity. In a layout an off-grid vertex is merely unusual: imported GDSII, a 45° diagonal and a flattened arc all legitimately produce vertices between grid points.
| PCB starter technology | MMIC starter technology | |
|---|---|---|
| Display unit | mil | µm |
| Snap grid | 1 mil | 5 nm |
DbuPerMicron |
1000 | 1000 |
The layout toolbar's Snap field sets this grid pitch, and offers a ladder of multiples of the technology's own default rather than a fixed list. F9 toggles it off and back to the last non-zero value.
The Snap field is the grid. Geometry snap — snapping to a pin, a corner, a midpoint — is a separate feature with its own toolbar toggle (F3 or S), and its capture radius is not a setting at all: it is a fixed 8 device pixels converted to DBU at the current zoom, so it stays the same size on screen at every zoom level. See Geometry snap in the layout editor chapter.
wBond units
Bondwire geometry is stored in nanometres — plain nanometres, not DBU. At the default 1000 DBU/µm the two happen to coincide exactly, which is why the conversion between them is one deliberate, single-place bridge rather than something spread through the code.
Everything a wire edit does quantises to one nanometre. On a 500 µm loop height that is a relative error of 2 × 10-6 — physically about a fifth of a millionth of a mil.
Inductance in the wBond panel is always read out in pH, fixed, never auto-ranged. That is deliberate: the panel exists so you can watch a number while dragging, and a unit that switches mid-drag fakes a 1000× jump.
Typing a value into a field
There are two vocabularies, because there are two different kinds of field.
Layout dimension fields
A width, a length, a coordinate, a DRC rule value. These accept a bare number — interpreted in the current display unit — or a number with one of these suffixes, case-insensitively and with any amount of whitespace:
| Suffix | Means | Example |
|---|---|---|
| (none) | the current display unit | 2.5 |
nm |
nanometre | 250nm |
u, um, µm |
micrometre | 50u |
mm |
millimetre | 2.9mm |
mil |
thousandth of an inch | 115mil |
in, inch |
inch | 0.25in |
Leading +/- and scientific notation (1.5e3) are accepted. Anything else is rejected and the field
reverts — it does not silently guess.
Component parameter fields
A resistance, a capacitance, a frequency. These are evaluated by the expression engine, and the unit is a separate column in the row, not part of the number. The unit column accepts these:
| Prefix | Multiplier | Unit family | Spellings | |
|---|---|---|---|---|
T |
1012 | Frequency | Hz kHz MHz GHz THz |
|
G |
109 | Inductance | H mH uH nH pH fH |
|
M |
106 | Capacitance | F mF uF nF pF fF |
|
k |
103 | Resistance | Ohm mOhm kOhm MOhm GOhm TOhm |
|
m |
10-3 | Length | metre nm um mm cm mil in inch |
|
u |
10-6 | Angle | deg rad |
|
n |
10-9 | Voltage / current / power | V kV mV uV nV · A mA uA nA · W mW uW kW |
|
p |
10-12 | Logarithmic | dB dBm dBc dBW |
|
f |
10-15 |
The glyphs Ω and µ are accepted and normalised — kΩ is kOhm, µF is uF. A prefix on its
own is also a valid unit, so a row whose value is 2.2 and whose unit is p resolves to 2.2 × 10-12.
A bare m is the SI prefix milli. The metre has its own spelling,
metre, and every other length (mm, um, mil, …)
reduces to it. This is a deliberate decision, not an oversight: re-pointing m at the metre
would silently multiply every hand-authored C=1m in an existing netlist by a thousand, with
nothing anywhere reporting it. The logarithmic units are measurement functions rather than scale
factors, so dBm carries no multiplier.
Units in an expression, and in the unit field
A number may carry its own unit, glued to it with no space: 10um + 1mil, 2.4GHz, 1.5nH, 50Ω,
10V + 100mV, 2u. Each is scaled to base SI as it is read, so 10V + 100mV is 10.1 V and 10um + 1mil is
35.4 µm. Any unit in the table above may be written this way, including a bare prefix and V, A and W
— except the logarithmic ones: 0dBm is refused, because a dB value is not a multiplier (use dBm(…)).
An unknown suffix is refused by name (10mils). 10j is still ten times the imaginary unit.
The row's unit column still works as it always has, and the two meet by one rule. When the value
holds a unit of its own — a unit literal, or a variable declared with a unit — the column's unit is not
applied to the result, since the value is already in base units. A plain number added to, subtracted
from or compared with such a term takes the column's unit instead: RFfreq + 100 with the column in MHz
is 100 MHz above RFfreq. A number that multiplies or divides stays a plain number: 2*RFfreq is twice
it. With nothing unit-bearing in the value, the column's unit scales the whole result, as before.
Whitespace separates: 2 GHz is not a literal. A VAR row whose unit column is empty has a trailing,
spaced unit lifted out of the expression into the unit, so RFfreq = 2 GHz in the schematic VAR editor
gives the variable you meant, and a .cnl, which has no unit column, is read the same way. The lift is
applied only when the text does not already parse, which is why 2 * f and R * m — legal
expressions ending in a name — are never torn into an expression plus femto or milli. 2GHz needs no
lift at all; it is a literal.
2m is 2 × 10-3 — in a length, two millimetres. Write 2mm to
say so, or 2metre for metres. The 3D editor refuses a bare 2m in a length box and
check warns about one inside a length expression. A name that spells a unit is still a name
where it is not glued to a number: 2*mil is twice a variable called mil.
See also: Expressions · The Layout Editor · wBond · Components · PCells.