railRF
Power integrity on the board shape you actually drew: DC drop, Z(f) against a target, which capacitors earn their place, and what a re-layout cost.
What railRF is, and the four questions
railRF answers power-integrity questions about the board you drew, not about a rectangle standing in for it. It reads your Gerbers, drill and stackup, finds the copper belonging to one net, and solves it — at DC first, then over frequency.
It is built around four questions, in the order a board designer asks them.
- Q0 — Is this rail actually connected, and what does it cost to get there? Is the net one region or three islands joined by a neck; how much of the supply is lost between the source and the load; and which element on the path is responsible.
- Q1 — Does this rail meet its target? Z(f) at the load against a flat target or a mask, with the violations named and your own board's noise frequencies drawn on the same axis.
- Q2 — Which capacitors are actually doing anything? Every capacitor ranked by how much the worst violation would grow if you deleted it.
- Q3 — Did my form factor break it? Two designs — same schematic, same BOM, different outline — run and compared, before the second board exists.
The window opens from Tools › railRF, or by opening a .crail in the project tree. It is one
resizable, non-modal window per document, and it can sit behind the workspace while you edit the board.
Three buttons on its title bar get a board into it, and they do different things:
| Open | Points the window at something that already exists — a .crail anywhere on disk, or a bare .clay layout from any workspace. A .clay brings its own technology with it: the stackup is the one that layout references, not whichever workspace happens to be open. |
| Import a board | Creates. It runs the same Gerber/drill import File › Import runs, lands the artwork in a workspace as an ordinary cell with a layout view, mints a technology from the set's own layers, and reads the placement, BOM and netlist you point it at. |
| Help | This chapter. |
Opening a .crail resolves what the document itself names — its artwork, that artwork's stackup and
its part library — so a document opens with its board already on screen. A reference that no longer
resolves is reported and does not stop the open: the rails, the ports and the target are the
document and are still readable, and the status strip says why the board is not there.
railRF shows the artwork; it does not let you change it. Open the .clay in the
layout editor and edit it there — when both windows are open on the same board they share one
document, so what you draw appears in railRF as you draw it. Every result is cleared when the
copper moves, because the numbers were measured on the board you have just changed; press
Run again.
Everything else about the panel is the layout editor's: the same pan, the same wheel zoom, the same F, Z, Ctrl/⌘ +/− and arrow keys.
Every position, length and mesh size on this window — source and load anchors, the placement
column, the drop table, the labels over the artwork, the Mesh cell setting, and every message and
refusal — is shown in the unit picked in the board panel's toolbar, to the right of the
Layers button. A new document starts in the unit the layout is set to; after that the unit is the
.crail's own, saved with it, and changing it never changes the .clay or the
.ctech. The circuitrf rail command reports in the same unit. Positions are
stored as exact database units and only displayed in yours, so nothing is rounded by the
choice.
The Layers button in the board panel's toolbar opens a list of the board's drawing layers. Tick
or untick any of them to show or hide it on this board — including a layer the technology's
Vis box hides. The choice is saved in the .crail and nothing is written to the
.ctech. A layer you have not changed follows the technology. The button at the right of the
list's header, Follow the technology, clears your choices so every layer shows or hides as the
.ctech says.
What you provide
| The artwork | Gerbers plus the drill, a .clay layout, or a .kicad_pcb. Mandatory — it is the thing being measured. |
| The stackup | A technology whose conductors state a thickness and a conductivity. Mandatory: copper with neither has no sheet resistance, and a mesh built on it would report a perfect plane. |
| The rail and its reference layer | Which net the rail is, and which layer its current comes back on (Ref.). railRF never infers the reference layer — it proposes one, and nothing runs until you confirm it. |
| The return net | Which net on that layer is the return (Return). Usually left to the copper, which measures it; named only where the copper cannot say. See Ref. and Return. |
| The sources | Where the rail is fed, and by what: an open-circuit voltage with a series R and L, or a Touchstone file. |
| The loads and their currents | Where the rail is drawn from, and how much. Nothing in a BOM or a placement file carries a current, so this is typed. |
| The parts | The decoupling, by part number, against a part library (.crlib) holding C, the self-resonant frequency, ESR and a bias curve. |
| The target | A drop budget in millivolts, a flat Ztarget in milliohms, a per-port mask, or ΔI/ΔV/rise-time to derive one from. |
| The band and the aggressors | The frequency span to sweep, and the things on your board that actually generate energy — the crystal, the converter, the radio reference. |
Selecting a net in the pick list outlines its copper on the board, dashed, before anything is made a rail. The first net you pick after a board loads has to read the board's copper first, which can take a few seconds on a large board; the board and the pick list both say which net is being traced while it runs. Every pick after that reuses the same reading and is close to instant.
A resistor, capacitor or inductor looks the same at 0° and at 180°, so a footprint dragged onto its
lands can easily sit with its pin 1 on the copper its pin 2 belongs to. railRF reads which way round each
one really is from the copper it sits on, and names every part it read as turned under the pick list.
Turn them in the layout turns those parts 180° about their own lands, so the layout says what
the copper shows. With the layout open in its own window it is one undoable edit there; otherwise railRF
writes the .clay itself. Where the copper cannot tell which way round a part is, nothing is
turned, and picking the net says which other nets' pins are standing on its copper.
An inner plane imported from a Gerber file named after its net comes in as a drawing layer, and a conductor added to the stackup by hand does not know about it. Where one unattached drawing layer is the plausible match, the technology editor's warning names it and offers an Attach button that joins the two in one press.
Each row of the Sources card has three values, under the headings V open, R out and
L out: the voltage, and the supply's output resistance and inductance. Double-click a value to
enter it. The DC answer needs only the voltage. The |Z| plot needs R, L or
both: a source with neither (blank or zero) is ideal, shorts the rail at every frequency, and leaves
nothing to plot, so the Frequency tab says so instead of drawing a curve. Take R from the regulator's
datasheet (its output impedance at low frequency, typically tens of milliohms for a switcher or LDO) and L
where it is given (a few nH is typical); a battery's R is ohms to hundreds of ohms over its life. Inductance
needs a unit (2 nH, 2n H or just the prefix, 2n); resistance may be bare
(0.05 is 50 mΩ).
Leave a load row's current empty and it stops being a load: it contributes nothing to the DC solve and is still reported — listed as observed rather than quietly dropped — and over frequency it is a place the impedance is judged. An empty current and a stated zero are different statements, so railRF never defaults one to the other.
Ref. and Return: a layer and a net
The rail card has two rows under the rail, and they answer different questions. Ref. is a layer: the copper the rail's current comes back through, usually the ground plane under it. Return is a net: which of the copper on that layer actually is the return.
A layer alone is not enough, because a real plane layer carries more than one net. A 3.3 V island sitting in an anti-pad on the GND plane is on the reference layer and is not ground; a GND pour on the bottom layer, under a supply pad, is not on the reference layer and is ground. Knowing the return net is what lets railRF leave the island out of the return, and keep the pour out of the rail.
| Return row | What railRF does |
|---|---|
| measured from the copper (the default) | Reads which net the copper on the Ref. layer is connected to. This is right on nearly every board, and the note under the row says what it found: Return: 'GND', measured from the copper on 'GND' (layer 3/0). |
| a named net | Uses that net, and the note says named in the document. Name one when railRF refuses because the copper on the Ref. layer does not measure to a single net, or when a board carries more than one ground (GND and PGND) and you want to say which this rail returns on. |
Where the return cannot be settled and the rail has copper of its own on the Ref. layer, the rail is refused rather than solved: taking every piece of that layer as the return would count the rail as its own return, and the drop it reported would look like an ordinary number. The refusal names the Return row.
Ref. is set per rail. Return is set once for the board (the .crail's
ReferenceNet) and every rail's card shows the same choice, so changing it on one rail changes
it for all of them.
The return net is also what the mounting loops railRF computes from the via geometry are measured
against: a capacitor's power pad and its return pad are told apart by net and nothing else. A measured
return serves for that exactly as a named one does. railRF never picks a net because its name looks like
a ground — on a board with both GND and PGND, a guess would measure half
the parts against the wrong plane.
The parts table
Each row is one part on the selected rail. Selecting a row outlines that part on the board.
- Sort by any column. Click a column header to sort the rows by it, click it again to reverse
the order, and click it a third time to go back to the order in the
.crail. A ▲ or ▼ after a header shows which column is sorted and in which direction. Number columns (C, ESR, f₀, L) sort by value, not by the text, and a row with no value in the sorted column is always listed last. Sorting only changes what you see: it does not edit the document or make it unsaved. - Find a part on the board. Double-click a row's location to zoom the board to that part. If the board panel is hidden, it is shown first. A part that reads not placed has no position, so there is nothing to zoom to.
- Resize a column. Drag the thin line at the right edge of a column header. Double-click that
line to fit the column to its widest entry, counting every row, including rows scrolled out of
view. The widths last until the window is closed and are not saved in the
.crail. - A wide table scrolls sideways. The columns keep their widths and the header scrolls with the rows, so each column stays under its header in a narrow panel.
Top and bottom
On a board with copper on its bottom layer, the table has a side column: top or bottom, the side of the board the part is soldered to. railRF reads the part's pads on that side's copper, so a capacitor on the bottom connects to the bottom-layer copper under it, not to whatever top copper happens to be above it. A board with nothing on its bottom copper shows no side column.
The side starts as the artwork has it: a footprint placed mirrored is on the bottom, which is also
how the board exports read it, and the location column says bottom after its coordinates. Pick the
other side in the row's drop-down where the artwork does not say — a Gerber board whose footprints
were all placed on top, say. The choice applies to the selected rows, and to that part on every rail
of the document, since a part is soldered to one side; it is saved in the .crail and never in the part
library, because the same part number can be fitted top side on one board and bottom side on the next.
It does not change the layout.
The part library
The book button under the parts table, and the parts table's right-click menu, offer two things. Open part library opens the document's library; when it has none (or names one that has since been deleted) this is Create part library…, which creates one seeded with every part number the document names. Use existing library… reuses a library another design already built (below). One row per part number:
| Column | What goes in it |
|---|---|
| Class | The capacitor's dielectric class, from the drop-down; it sets the ESR default when no ESR is stated. Other marks a part that is not a capacitor — a ferrite bead, a resistor — which takes no bias curve. It is the model of a series part: its ESR is read as the part's DC resistance and its Model file as its measured impedance, and the other columns are ignored. |
| C, f₀ | The marked capacitance and the self-resonant frequency, each with its unit (100 nF, 28.9 MHz). A bare number is not taken: its scale would be a guess. |
| ESL (datasheet) | Optional — an inductance your table states. Where f₀ is also given it is not used: it is checked against the next column and the row is flagged where they differ by more than 5 %. Where f₀ is blank, it is the part's inductance, so C, ESL and ESR together describe a capacitor by its R-L-C values. |
| ESL from f₀ | Read-only: 1/((2πf₀)²C), the inductance railRF uses. |
| ESR | Where you know it. Blank takes the class's default, and every number computed from one is marked indicative. |
| Model file | Optional — the path, relative to the library, of the part's own Touchstone file. Type it, or pick the file with the … button beside the cell. Not a part number. It overrides the row, and it is the only route to a measured ESR. A SPICE file can be named here, but it is not simulated: the row's own C, f₀ and ESR are used and the model source column names the file. |
A bias curve can be added only to a capacitor row that states its capacitance.
A curve does not have to be typed. Under it, Import curve… reads a supplier's
capacitance-versus-DC-bias .csv (or any two columns of bias and capacitance), and Paste curve
— or pasting a multi-line table into a curve cell, or Ctrl/Cmd+V over the curve — reads
columns copied from a spreadsheet or a datasheet, separated by tabs, commas or spaces. Either one
replaces the curve as one undoable edit. The capacitance unit has to be stated, in the header
(Capacitance[F], C (µF)) or on each value (4.7uF, 470n): a bare 0.47 could be farads,
microfarads or nanofarads. Bias is read in volts unless it says otherwise. A curve whose first point is
more than ten times the row's marked value, or under a tenth of it, is refused as a unit error. A
supplier export sampled every few tens of millivolts is thinned to the points linear interpolation
needs — a 201-row export typically keeps about 14 — and no bias between two kept points reads
more than 0.2 % of the curve's largest value away from the supplier's own number. The report above the
table says how many points were read and kept, and names anything to check: a file that does not name
the part, a first point far from the marked value, a curve that stops below the part's rating.
A curve cell takes its value when you leave it or press Enter, and the point then moves to its place in bias order and stays selected.
A row classed Other has no impedance-at-one-frequency column, on purpose: a datasheet's "220 Ω at 100 MHz" does not say how much of that is resistance and how much is inductance, and any split would be a guess printed as a model. Give the row the part's own Touchstone curve — a two-port file measured series-thru, as supplier tools publish a bead's — or state an R-L on the rail's row.
Import table… on the library's toolbar reads a .csv of parts into it as one undoable edit — save a
spreadsheet as .csv first. A part-number column is required; C, the self-resonance and L are read only
where the column header states the unit (C (pF), resonance (MHz), L (nH)) or each cell does
(100nF). A row whose Value and C columns disagree imports neither, and says so. Supplier tools often
find a part only once its trailing packaging code is deleted, so a part number that is a library row's
with its end trimmed is matched to that row — when exactly one row fits — and named in the
report above the table.
Sharing one library across designs
A team that buys the same part numbers board after board can keep one .crlib — in a shared
folder, next to every project — and have every design use it:
- Use existing library… on the book button (or the parts table's right-click menu) picks a
.crliband asks what to do with it. The default, Use It Where It Is (Use It Instead where the design already has a library), names the library in place: nothing is copied, and a part added or corrected there reaches every design that uses it. The alternative is Copy Into Workspace — a new library here, seeded with this document's part numbers and filled from the one you picked, which nothing else will change — or, where the design already has a library, Merge Into it: the picked library's rows are merged in by the rules below, in the library editor, as one undoable edit that you then save. A library already inside this workspace, for a design with none, is used as it is. - Copy its rows in. Import table… also takes a
.crlib. Part numbers this library lacks arrive whole, with their bias curves; for one both libraries have, only the fields this one leaves blank are filled. Where both state a value and they differ, this library's is kept and the report names both. A row's model file is still read from where it sits, beside the other library, and the report names each one. It is one undoable edit, and the copy is saved with this workspace. - Point this design at it from the import dialog. Its Part library row names a
.crlibanywhere, exactly as Use It Where It Is does.
A shared library lives outside the workspace, so Archive Workspace… offers it as a row of its own, ticked by default, together with every model file it names — they keep their places relative to the library, so the recipient's copy resolves them unchanged, and the design is repointed at the archived copy. Untick it to send the design without the library.
Parts the rail runs through
A ferrite bead, a sense resistor or a switch standing in for its on-resistance is not decoupling: the rail runs through it. Right-click its row in the parts table and choose Make series element (Make decoupling (shunt) takes it back; each is one undo step). On a board, its two pads become its terminals, and a part that the board shows with both pads on the rail's copper is offered directly — Add refdes as series element on the same menu, or Add as series under the table.
To edit a series part's model, right-click its row and choose Edit Model Source…, or double-click its model source cell. The dialog holds its DC resistance, and either an R-L or a Touchstone file; each value is applied when you leave its box (or press Enter), the rail re-solves, and every change is one undo step in the railRF window. Every value is the row's own; a blank one takes the part library's row where that row is classed Other, and the watermark says what that is. A file picked in the dialog stays the row's own until you press Save to library: that makes it the part number's Model file in the part library — adding the part number, classed Other, if the library lacks it — so every row with that part number, on any rail and in any design using the library, uses it. The row then takes the file from the library. If the library has other unsaved edits it is left open for you to save, and the row keeps its own file until you do. The table's model source column names which won for each number, so the same bead on four rails is one library row. A part classed Other that is left as a decoupling row is refused at Run, by name.
A rail may run through several series parts. Each one cuts it, and the pieces are sections: the board's Copper view shades each section differently, every observation port reads the impedance of its own section, and each part's DC resistance is its own row of the drop breakdown, carrying the current of every load beyond it. The sections have to form a tree from the source — a chain, or one part feeding two branches. railRF refuses, naming the parts, a loop (two series paths between the same copper, whose current split a lumped model cannot answer), a part with copper around it (it is shorted out), and copper that no chain of series parts connects to the source.
A series part has to lie between the source and a load, with the rail's copper on both of its pads. One that hangs off the rail — a link between a switcher's inductor and the node the source is anchored on, say, which is upstream of the source — is refused by name, saying which end is on the rail. Either anchor the source on the part's far side, if the supply really enters through it, or take the part's row off the rail.
With no artwork, the series rows are a chain in row order, nearest the source first, and each other part and load sits at the far end unless its row names the element it sits behind.
On a series row the table's columns change meaning: the capacitance column shows the part's model (its R-L, or its file), the ESR column shows its DCR, and the self-resonance column reads —, because the part is not a capacitor. The inductance column shows the L of its R-L, or — where its model is a file. A series part has no mounting loop: it is a link between two pieces of the rail, not a branch to the reference plane.
Modelling a 0 Ω link, a jumper, a ferrite bead or an RF choke
Each of these is a series part: make it one first, as described above. Until you do, railRF treats it as a decoupling capacitor, and the parts table reads unresolved in the columns only a capacitor could fill. A series part's model is two things: its DCR and its impedance over frequency. You can state them on the rail's row, in its Edit Model Source… dialog, or once in the part library on a row classed Other, where ESR is the DCR and Model file is the impedance file. A library row cannot state an R-L. Use a Touchstone file there, or state the R-L on each rail's row.
| Part | DCR | Impedance over frequency |
|---|---|---|
| 0 Ω link | The datasheet's maximum resistance. | Leave it blank: the part is modelled as a 0 Ω link, and the result says so. For a large link at high frequency, state an R-L of 0 Ω plus the package inductance. |
| Jumper (fitted) | The same as a 0 Ω link, or the wire's own resistance. | The same as a 0 Ω link. A jumper that is not fitted is not a series part: delete the row. Clearing a series part's mounted box opens the rail, and railRF refuses the run. |
| Ferrite bead | The datasheet DCR. | A Touchstone file: the supplier's two-port S-parameters, measured series-thru. A bead's impedance falls with DC current and a datasheet curve is usually measured with none, so where the supplier offers curves at several bias currents, pick the one nearest your load current. An R-L is accepted, but it cannot follow a bead's curve, and railRF says so beside every result it produces. There is no "impedance at 100 MHz" field: that single figure does not say how much of it is R and how much is L. |
| RF choke (series inductor) | The datasheet DCR. | Below its self-resonance, an R-L works: R = its DCR, L = its inductance, with a unit (10 µH). Above its self-resonance a choke turns capacitive, and an R-L keeps rising, which reads as better filtering than the part gives. Where that band matters, use the supplier's Touchstone file. |
A blank DCR — nothing on the row and no ESR on the part's library row — is read as 0 Ω, and the DC answer notes that it was assumed. The part carries the rail's current, so enter the datasheet DCR wherever it is not negligible. Editing and saving the part library updates an open railRF window straight away.
Q0 — is this rail connected, and what does it cost to get there?
Press Run. You get, for each port, the voltage there and how far below the source it is; and, under it, where the drop went — every element on the path, ranked, in millivolts and in milliohms.
A run solves every rail at once. The bar beside the buttons shows how far through the whole run it is, and Stop abandons it and leaves the last completed answer on screen. The line at the top of the results column names the rail the numbers belong to, which reading they are, and what it cost — +3V3 · Fast · 4.1 ms. Picking another rail in the selector shows that rail's numbers without running again; only its |Z| curve is swept, which takes a moment and never enters Accuracy.
48.698 mV below the source, drawing 350 mA
22.722 mV 47% 64.919 mOhm 26.462 mm of 0.209 mm BOT copper (126.9 squares)
21 mV 43% 60 mOhm the source's own series resistance
2.023 mV 4% 5.781 mOhm 4.814 mm of 0.438 mm TOP copper (11 squares)
1.904 mV 4% 5.441 mOhm 3.927 mm of 0.387 mm TOP copper (10.1 squares)
0.61 mV 1% 1.743 mOhm the reference return
0.219 mV 0% 0.627 mOhm 2 parallel vias, 0.3 mm plated over 1.57 mm at 25 um
Expect the copper to be a large term, not a rounding error. On a compact board with thin inner copper — 0.15 to 0.5 mm traces, half-ounce copper, runs far longer than they look — a single supply trace is routinely tens or hundreds of milliohms, which is more than everything else on the board put together. In the run above it is nearly half the budget.
Three other things come out of the same solve.
- Islands. The run says how many regions the rail is, and how many the reference is. "The rail is three regions" on a net you believe is one is the answer to a question you had not asked yet.
- A drop map on the board, so the gradient has a place rather than a number.
- The via current check. Each layer transition is grouped with the barrels that share it, the worst barrel's current compared against a stated limit, and a count given that would clear the flag. The limit's basis travels with it, because the plating thickness is worth a factor of two and the drill file does not carry it: state it in the stackup's via entry or in the document's own settings, and railRF says which it used. Where nobody stated one it falls back to a drill-size table and says that, rather than pricing a barrel nobody measured.
Q1 — does this rail meet its target?
On the Frequency tab of the results column — the |Z| plot is on that tab only — railRF judges each observation port's |Z| against its target, reporting the verdict as a sentence: "Passes by 0.6 dB at its worst, 100 MHz." A violation names its frequency and its margin in decibels.
No curve at all? The card under the plot on the Frequency tab says why — most often a source with no output resistance; see What you provide.
Three things are on the plot besides the curve and the mask.
- The anti-resonances, each attributed: L(C9) against C(C7–C8). A peak you cannot attribute is a peak you cannot fix.
- Your aggressors, as vertical lines at each fundamental and its harmonics.
- The coincidences — where one of those lines lands within a stated fraction of a peak. Neither the peak nor the harmonic is alarming alone; the two together are the finding.
A plane resonance is narrow and a logarithmic grid steps straight over one, drawing a curve that looks perfectly smooth. railRF's resonance search adds points where the peaks actually are — and says which points it added, because a curve whose x-axis grew is one you cannot overlay on a measurement taken at the frequencies you asked for.
Q2 — which capacitors are actually doing anything?
You have forty decaps because the reference design had forty decaps. Some of them sit two millimetres from a lower-inductance part and contribute nothing.
railRF re-solves the whole sweep once per capacitor and reports what deleting each one would cost:
C10 100 uF bulk 12.1 dB -> -11.5 dB. Removing it fails the target outright.
C1 100 nF 0402 1.1 dB -> -0.4 dB. Removing it fails.
...
C13 100 nF 0402 0.4 dB -> 0.2 dB. Removing it still passes.
A row reading 0.0 dB is a part whose removal leaves the worst margin exactly where it was — a candidate for deletion. That is not parallelism: removing one of N equal parts in parallel moves the answer by about 8.7/N dB, so no bank of a plausible size is redundant that way. A genuine 0.0 dB row is a part that is out of band where the judging happens — shadowed by a neighbour with less mounting inductance.
Today the way to find this out is to build the board and start removing parts with a soldering iron.
Q3 — did my form factor break it?
A supplier gives you a reference design. You re-shape it to fit an enclosure: same schematic, same BOM, different outline and different placement. Compare… runs both and reports the delta.
The pairing is the part worth knowing about, because it is the part that could quietly compare the wrong things:
- Ports and parts are matched by refdes, and models by part number only where exactly one unmatched row on each side carries that number. Anything else is reported as unmatched, with the count.
- Nothing is matched by proximity. Two ports 0.2 mm apart stay unmatched however close they get; two ports at exactly the same coordinate are the port that did not move.
- Two sweeps on different frequency grids are refused, not interpolated. The resonance search adds points where each board's own peaks are, so two boards come back on two axes as a matter of course — and they differ precisely where the curve is changing fastest. Sweep both sides on one explicit grid instead.
- The delta is a ratio in decibels, not a difference in ohms: a PDN curve crosses three or four decades, so a difference in ohms is mostly a picture of where the curve is big.
- An excursion band ends where the sign changes. A resonance that moved is two findings — worse here, better there — and merging them would put the reported peak at the one frequency where nothing happened.
Fast and Accuracy: two readings of the same copper
railRF reads your copper two ways. Fast — the default, and what makes the window re-solve while you type — reduces each trace section between junctions to one resistance from its own measured length and width, and meshes only copper that is not trace-shaped. Accuracy meshes all of it.
What Accuracy buys is a bounded answer on copper the closed form cannot price. The fast reading is exact on a ribbon and optimistic wherever current spreads across a width instead of filling it — and optimistic is the direction that matters, because it is the one that turns a marginal board into a passing report. Four rules make the two safe to have together:
- Every result says which model produced it — on the plot, on each table, in the status strip and in the provenance of every export. A pass in Fast is reported as a fast-model pass, never as a pass.
- The classification is visible and correctable. The figure above is the
classtab: it draws which copper was read as a trace and which was meshed, and a region can be forced either way. A wide supply polygon mistaken for a trace is optimistic and invisible — drawing it is what makes it neither. The reference plane is drawn first and the rail's own sections over it, so a board with a plane shows both; click a region to force it either way. The return is always read as spreading, whatever its shape — current spreads under the rail rather than running along it — and it is meshed finely where the ports' current enters and leaves it, at the size Accuracy meshes a port. - Fast refuses where it cannot be honest. Where a source reaches a load only through copper
classified as spreading, the fast model produces no number rather than a smaller one, and the refusal
names both answers: run Accuracy, or force the region to
traceif you know the current follows a path across it. - The two are compared on your own board. Running Accuracy keeps the fast curve beside the accurate one, so the error is measured on this design rather than promised in a document.
Accuracy measures its own mesh. Every DC answer is solved a second time on a mesh one step coarser, and how far the drop to each load moved between the two is written on the result — that move is the discretisation error the answer is believed to carry, measured on your board rather than assumed. Where it is more than 2 % the mesh is refined until it settles; a mesh that cannot settle under the cell ceiling gives no number, and the refusal names the place on the board it could not resolve.
Accuracy is never entered automatically and never left silently: the button is the only way in.
The Settings flyout, control by control
The cog on the title bar holds the five advanced choices, and nothing else — the window is
deliberately clean by default. Every one of them is stated on the report, which is why they are
stored in the .crail rather than being per-session preferences: a number a report cannot read is a
basis nobody can check afterwards.
| Reference extent | What the reference conductor is taken to be. See below — two of the three are optimistic. |
| Via plating | The plated barrel thickness a via's current limit is computed from, in µm. Empty is not a default: railRF reads the thickness from the stackup's own via entry where one states it, takes this where it does not, and falls back to a drill-size table as a sanity band — and every flag says which of the three produced it. Clearing the field puts that behaviour back rather than leaving the last number standing. |
| Via rise | The temperature rise, in °C, a via's current limit is stated at. A budget, not a temperature: there is no thermal model in railRF and nothing else reads this number. 10 °C is the usual convention. |
| Temperature | The one temperature every resistance in the document is computed at. Copper is +0.39 %/K, so this is not a detail: the same trace at 85 °C is about 25 % worse than at 20 °C. It is on the status strip on every frame and on every report for that reason. |
| Mesh cell | How finely Accuracy meshes, as a cell size in the board's own display unit. Empty is the ordinary case — it reads automatic, and the extractor computes a cell size from the artwork itself. A number here overrides that; a unit typed explicitly (50 µm) is honoured whatever the board is set to. The fast model never reads it at all; it traces instead. |
Reference extent
railRF solves the rail's copper and its return, so what the return is taken to be changes the answer. The three choices are:
| As imported | The actual copper on that layer. Honest: a reference fragmented by anti-pads, a cut-out or a routing channel shows up as one, and the return resistance it reports is the one the board has. This is the default and it is the one to report against. |
| Filled to outline (optimistic) | That layer taken as solid within the board outline. It removes return constrictions the real board may have, so the drop it reports is lower than the truth by however much those constrictions cost. Useful for answering "how much of this is my plane?" — run both and read the difference. |
| Infinite (an upper bound) | The layer taken as unbounded at its own height. It removes the edge effects too. This is the only way to compare two different outlines on equal terms, which is what makes it worth having; as an absolute answer it is a bound, not a result. |
The status strip states the one in force on every frame, and so does every report and every export, because an optimistic reading that is not labelled as one is the thing that turns a marginal board into a passing report.
Worked example, end to end
Tools › Examples › Power Rail Integrity ships a four-layer board with one 3.3 V rail on it, set up for all four questions. Open it and follow along; its own README carries the full numbers.
- Open
Sensor board.crail. The board, the stackup and the part library are already resolved, and the window opens on Fast. Every part on it is an instance of a footprint cell with its reference designator on silkscreen, so the parts table and the board are reading the same thing. - Run. DC: 47.6 mV at
U1against a 52 mV budget — met, and only just. The breakdown names it: 26.2 mm of 0.211 mm copper on the bottom layer is 63 mΩ, and 46 % of the budget on its own, because the supply took the long way round the connector cut-out at the width a low-current net gets by default. The ferriteFB1is the third row at 20 mΩ and 7 mV, ranked with the copper rather than reported beside it. Three via transitions, none over its limit. The second load,U3, is listed as observed: it states no current and draws none. - Widen that run to 0.4 mm in the layout editor and re-run. 36.5 mV. The copper term halves and the protection FET becomes the thing worth arguing about — which is a part choice rather than a layout one.
- The sweep, over 100 kHz to 100 MHz against a flat 55 mΩ: passes by 0.8 dB at its worst, at 100 MHz — the top of the band, where every capacitor is its own mounting inductance and nothing else.
- Two anti-resonances are named: L(C9) against C(C7–C8) at 4.14 MHz, and L(C7–C8) against C(C1–C13) at 10.80 MHz. The converter's fifth harmonic at 11 MHz sits 1.8 % from the second of them — the coincidence check earning its keep.
- Open the ranking.
C10, the bulk, is holding the low band up on its own: remove it and the rail fails by 17.8 dB.C11–C13are the same part number asC1–C3and worth about half as much, because their 0.9 mm fan-out carries 1201 pH against the 555 pH of a via in the land. - Unmount
C11. Still passes, at 0.3 dB — one part and one placement saved on a board that does not exist yet. Unmount all three and the rail fails by 0.7 dB, which is the ranking's own limit said out loud: it re-solves once per part and answers what does removing THIS one cost, and three answers of 0.5 dB do not add up to a margin of 1.5 dB.
Steps 2 and 3 are the form-factor question. Step 7 is the cost question, and today it happens after tooling, with a soldering iron.
Running it headless
Everything above runs with no window:
circuitrf rail board/Panel.crail
circuitrf rail board/Panel.crail --rail +1V8 --accurate -o report.pdf
circuitrf rail board/Panel.crail --load U1.VDD=120mA --target-drop 50mV --json
Omitting --rail runs every rail in the document, in dependency order. Every number comes out of the
same solve the Run button calls, and every pixel of an .svg or .pdf report out of the same
renderer the window draws with. See rail in the CLI chapter.
What railRF will not do
Stated plainly:
- It is not a full-wave solver and does not become one. That step is very much heavier for an answer this question does not need. circuitRF's planar method-of-moments engine is a different tool for a different question — see the MoM engine.
- It is not a thermal tool. The via current flag is a rule with a stated basis, and current density is a step towards one. Neither is a temperature. Everything is computed at the copper temperature you state, and copper is +0.39 %/K: at 85 °C the same trace is about 25 % worse.
- It stops at the package. The answer is the impedance at the board-side pads. On-die capacitance and package inductance sit between that and the transistor and typically dominate above a few hundred megahertz. If your silicon vendor supplies a package model you can cascade it; railRF will not invent one.
- It does not model a regulator's forward transfer. A rail chain is solved in order and the coupling it carries is a DC one: an input-rail drop that changes a regulator's headroom. Ripple passing through a regulator needs its PSRR and its output impedance, which are frequently unpublished — so railRF does not carry it, and does not approximate it either.
- It does not do transient. The output is Z(f) and a DC operating point. Turning Z(f) into a voltage waveform for a given current profile is a different feature and is deliberately not this one.
- It does not model a split plane as if it were solid, and it does not silently bridge a split.
- It does not know your capacitors are derated unless you give it a bias curve. An MLCC at bias can be a fraction of its marked value; without a curve railRF uses the marked one and says so.
- It does not route, place or optimise your board. It measures.
What is not wired up yet
Two things are representable in a .crail and do not yet reach a solve. They are here rather than
left to be discovered:
- A port anchored by refdes does not resolve. The placement table is read on import and is not
joined into the extraction, so every port has to be anchored by coordinate, and every report row
reads a point in DBU rather than
U1.VDD. This is the same in the window and on the command line. - A rail chain is therefore unsolvable. Two rails are linked only by a refdes that is a load on one and a source on the other, and that is the one anchor shape that cannot resolve. A chain that would form a cycle is still refused, correctly, before any pad is looked up.
A fourth used to be here and no longer is: a .crail's artwork, its stackup and its part library now
resolve when the window opens it, by the same walks circuitrf rail takes. Nor is a fifth: a
series part is in the DC solve, its DC resistance a row of the breakdown.