NELIX Silicon Lab Docs Launch Silicon Lab Launch Silicon Lab

Seeds, proof limits, equivalence and the SystemVerilog subset

Which SystemVerilog the lab's simulators run (tested), how a random test's seed is kept and replayed, what a formal check that runs out of time means, how equivalence is checked against the synthesis and the final routed netlist, and what the DFT and power checks measure.

EngineerStudent 25 min read · Updated 2026-10-31

On this page The SystemVerilog the lab runsReading SystemVerilog designs: the build's Yosys, Verilator, and the Slang readerWhere Slang and the build's Yosys read the same design differently (measured 31 October 2026)How the lab reads your design for the chip build: automatic, Slang or plain (since 31 October 2026)Import and Lint with the Slang reader (since 31 October 2026)Seeds: every Simulate run keeps its seedSeeded regression and replayFormal checks that run out of timeEquivalence: RTL against the synthesis and the final netlistDFT: undetected faults by name, patterns as STILTransition (at-speed) faultsScan chain built into the chipIR drop: the assumptions, and power from your own testsElectromigration of the power gridNot available in open source

This page says exactly what the lab's verification tools can and cannot do, measured on the lab's own server on 30 October 2026.

The SystemVerilog the lab runs#

Your design may be written in Verilog or SystemVerilog; synthesis and the chip build read it with Yosys. Your tests are cocotb (Python) by default, a plain Verilog testbench, a SystemVerilog testbench or a UVM testbench (both new, see below). For tests written in the SystemVerilog verification language (classes, randomize(), covergroups, assertions), the table below is what the simulators already on the server do. Each line was compiled and run on a small test that prints whether the feature gave the right answer.

FeatureIcarus 12.0 (Simulate)Verilator 5.020Verilator 5.044Verilator 5.044 + z3 solver
packages, enums, packed structsyes (named '{a: ..} assignment patterns: no)yesyesyes
interfaces with modportsnoyesyesyes
always_ff, always_comb, unique caseyes (unique ignored)yesyesyes
classes, objectsyesyesyesyes
class inheritance with virtual methodswrong resultyesyesyes
randomize() without constraintsnoyesyesyes
randomize() with constraintsnoconstraints silently ignoredrandomize fails (no solver)yes
randomize() with {...}, std::randomize()nonofails (no solver)yes
covergroups and coverpointsnonoparses, coverage always 0 %parses, coverage always 0 %
immediate assertyesyesyesyes
concurrent assertion, simple implication (a implies b on the same clock)nonoyesyes
concurrent assertion with a sequence (##1)nononono
queues, dynamic and associative arraysnoyesyesyes
mailbox, fork ... joinnoyesyesyes
virtual interfacesnoyesyesyes
DPI-C importsnoyesyesyes
UVM (Accellera 1800.2-2017-1.0)nonocompiles, but the run phase ends at time 0 and reports 0 errors without testing anythingsame as left; the UVM option uses Verilator 5.052 instead, where the run phase is correct

What this means:

  • SystemVerilog testbench (New project → Test with → SystemVerilog testbench, or TB_LANG = systemverilog in an existing project's Makefile). Simulate builds tb/ with your design in Verilator 5.044 with the z3 constraint solver (the right-hand column above): classes, randomize() with constraints, randomize() with {...}, immediate and simple concurrent assertions. It passes when the run reaches $finish, the simulator returns 0 and no line says FAIL, FAILED, ERROR or FATAL ($error, $fatal and a failed assertion print %Error). The log prints the random seed; SV_SEED = <number> in the Makefile repeats a run exactly. Measured (MAC-8 starter, 400 constrained-random input sets with a reference model): real design passes in about 30 s; with acc + product planted as acc - product the assertion fails at once and names the values. Not supported: covergroups (they compile but always report 0 %), sequences in assertions (##1), and dist constraints (Verilator warns CONSTRAINTIGN and ignores them: use inside and implications instead). Verilator 5.020 (the C++ testbench option) must not be used for constrained random: it accepts constraints and ignores them, so a SystemVerilog-testbench project refuses to run anywhere but this option.
  • UVM testbench (New project → Test with → UVM testbench, or TB_LANG = uvm). Simulate compiles the Accellera UVM 1800.2-2017-1.0 library with your testbench in Verilator 5.052 (image nelix-uvm:1, open source; Verilator 5.044 runs UVM but ends its run phase at once) and the z3 solver. The starter is a small UVM environment written from your design's ports: an agent (sequencer, driver, monitor), a scoreboard with a predict() for your reference model, and one constrained-random sequence. It passes when UVM's summary says UVM_ERROR : 0 and UVM_FATAL : 0, the run reaches $finish, no %Error was printed and the run phase was not cut short (UVM warning OBJTN_CLEAR). Each Simulate takes about 11 minutes and up to 1.2 GB of memory, because Verilator compiles the whole UVM library every time; only one UVM test runs on the server at a time, and it needs about 900 MB of free space in your workspace while it compiles (it tidies up to about 50 MB afterwards). UVM here is built without DPI, so name the test in run_test("my_test"). Measured on the lab (30 October 2026, MAC-8, 320 constrained-random items, reference-model scoreboard): real design 322 checks, 0 errors, PASS (Simulate TST-20261030-0051, 642 s); planted acc - product: a UVM_ERROR on the checks, FAIL (TST-20261030-0052).
  • The plain Simulate button (cocotb, Verilog testbench) still uses Icarus 12. Do not rely on SystemVerilog classes in an Icarus testbench: virtual methods give wrong results there.
  • Functional coverage: use cocotb-coverage (Simulation V&V → Functional coverage). SystemVerilog covergroups are not measured by any simulator on the server.

Reading SystemVerilog designs: the build's Yosys, Verilator, and the Slang reader#

Your design is read by three different programs in the lab, and they do not accept the same SystemVerilog. The chip build and the equivalence check read it with the flow's own Yosys (read_verilog -sv, Yosys 0.46 on SKY130 and GF180); Lint reads it with Verilator 5.044; and, since 31 October 2026 (for everyone), Lint and RTL-vs-netlist have a Reader option Slang: the full SystemVerilog elaborator (MIT) as wired into Yosys by yosys-slang, which the OpenROAD-flow-scripts image on the server already carries (Yosys 0.68). The idea of putting Slang in front of Yosys comes from LiveHD (UCSC MASC group, inou/slang). Measured on ten small design-level features on 31 October 2026:

Feature in the designYosys 0.46 read_verilog -sv (chip build, equivalence)Verilator 5.044 (Lint)Slang reader
package with typedef enum / packed struct, used in a port list via importrefusedyesyes
interface with modportsyesyesyes
unique case, $clog2, for (genvar ...)yesyesyes
parameter type T = ..., unpacked array T mem [D]refusedyesyes
streaming operator {<<{a}}, inside, $countonesrefusedyesyes
unpacked array of structs as a port, always_latchrefusedyesyes
function automatic inside a package, package localparamrefusedyesyes
assignment pattern '{x: a, y: ~a} to a structrefusedyesyes
concurrent assertion `assert property (...-> ##1 ...)`refusedrefused (unsupported)refused
priority casez with wildcardsyesyesyes

Real designs, same day: the CORE-ET minion_tlb block (OpenHW Group, SystemVerilog with packages and type-parameterised modules) is refused by Yosys 0.46 at tlb_pkg.sv:11 and elaborated by Slang (6 files, 322 word-level cells in 2 modules); CVA6's ALU elaborates through LiveHD's cva6_alu_export wrapper (11 files). In both cases the plain Verilog Slang writes out is then synthesized by Yosys 0.46 without error (1,882 and 9,053 cells).

What it does and does not do:

  • Lint with Reader = Slang: Slang elaborates the whole design; its errors and warnings are the items, and the check fails on any error. Verilator is not run. The elaborated Verilog is kept as evidence.
  • RTL vs synthesized netlist with Reader = Slang: Slang elaborates the RTL first (120 s of its own, in the OpenROAD-flow-scripts image), and the comparison uses that elaborated Verilog as the RTL side against the build's netlist. The row says so. If Slang cannot elaborate the design the row is REFUTED-unsupported with Slang's first error.
  • The chip build reads your files with the flow's own Yosys, unless the automatic check says it cannot. Every chip build starts with a short check: the flow's own Yosys reads the design (read_verilog -sv; hierarchy -check; proc) inside the flow's own image. If it takes the design, the chip is built from your own files as always. If it refuses (modern SystemVerilog), the build is prepared with Slang first (next section). With Always my own files (Chip build settings) the build reads the files directly and a design Yosys 0.46 refuses does not build; Lint and equivalence with Reader = Slang tell you exactly what Yosys will refuse.
  • Verilator's --lint-only -Wall style warnings (WIDTH, LATCH, ...) are Verilator's; Slang reports its own diagnostics, with its own names.

Where Slang and the build's Yosys read the same design differently (measured 31 October 2026)#

PicoRV32 (bench-picorv32-ol1, build BLD-20261031-0003) is PROVEN-full with the normal reader and REFUTED-cex at clock 0 with Reader = Slang (run VER-20261031-045014-577759). The night's repetition of that run, stage by stage in the same flow image, found the cause in the reading, not in the design or in Slang's logic. Three measured points, each with the design file that shows it:

  1. An incomplete case with the Yosys full_case hint. PicoRV32 writes (* full_case *) case (mem_wordsize) with values 0, 1 and 2 of a 2-bit signal. Yosys (and so the chip build) honours the attribute, and the // synopsys full_case comment, and builds plain logic. Slang follows the language: a value left unset holds, so it builds a latch. Measured on a four-module probe: Slang makes latches for the attribute, the comment and the plain incomplete case, and plain logic only for unique case; Yosys makes a latch only for the plain incomplete case. On PicoRV32 that is 68 latches (mem_la_wdata, mem_la_wstrb, mem_rdata_word), which the reference synthesis later turns back into logic with a different choice for the value that is never set.
  2. An unsized 'bx wider than 32 bits. trace_data <= 'bx on a 36-bit register: Yosys fills all 36 bits with x (IEEE 1800-2017 5.7.1: an unsized x or z literal extends to the width of the expression); Slang, as wired into Yosys 0.68, writes 36'h0xxxxxxxx, so the top four bits are 0, were not masked as undefined, and were compared against the chip. The same applies to count_cycle and count_instr (64 bits).
  3. Registers the reset does not set. mem_wordsize is not assigned during reset, so both sides start from a state the RTL never defines (the state machine is re-encoded one-hot by synthesis and the all-zero start is not one of its states). The two sides agree in that state only because the chip and the reference are synthesized from one reading by one recipe. Through Slang the structure differs and the first output compared, mem_la_wstrb, is 1111 on the chip and 0001 on the Slang side one clock after reset. Giving every unset register a power-on value of 0 before the reference synthesis removes that counterexample, but it also stops the fast register-correspondence proof of the normal reader (the comparison circuit no longer collapses), so the lab does not do it.

What this means for you: a chip built from the flow's own Yosys reading must not be judged against Slang's elaboration as if both came from one reading. With Reader = Slang on such a build the row leads with this caution and keeps LiveHD's verdict word (the two circuits do differ). To compare like with like, build the chip through the Slang reader (Chip build settings; the lab does this automatically for a design the flow's own Yosys refuses): the build is then fed Slang's elaboration, and the row compares the chip with the very file it was built from. Designs that use full_case on an incomplete case, or an unsized 'bx/'bz on a target wider than 32 bits, read differently through Slang; the Slang reader must not be trusted to reproduce the Yosys reading of them.

How the lab reads your design for the chip build: automatic, Slang or plain (since 31 October 2026)#

Chip build settings has a section How the lab reads your design with three choices, kept as one line in the project's config/project.toml ([build] reader = "auto" | "slang" | "yosys"; no line means automatic; openlane/config.json is not changed):

  • Automatic (the default). Before each chip build the lab runs the flow's own Yosys (0.46 in OpenLane, 0.62 in LibreLane, 0.68 in the ASAP7 flow) on your files in a short container of the flow's own image: read_verilog -sv, hierarchy -check -top, proc, nothing more. If it reads the design, the chip is built from your own files, exactly as a plain build, and the log says so (Yosys 0.46, the reader inside OpenLane, read your design: the chip is built from your own files). If it refuses, the log quotes Yosys' own error (file and line) and the build goes through the two Slang steps below. The decision is the flow reader's own answer, never a guess from file names or keywords. The check adds a few seconds to a build.
  • Always prepare with the standards-following reader (Slang). The two steps below on every build, with no check first.
  • Always my own files. No check; a design the flow's Yosys cannot read fails as it always did.

VHDL-only projects take the VHDL path as always; the setting does not apply to them. Mixed Verilog + VHDL projects (since 31 October, afternoon): the VHDL parts are translated first, as always, and the check then reads the whole set, your Verilog and the translated parts together; modern SystemVerilog in the Verilog half is prepared with Slang like any other design. Projects without a config/project.toml (older SKY130 projects) behave as automatic. When the Slang steps run, every chip build of that project runs in two steps, in one log:

  1. Elaboration. One container of the OpenROAD-flow-scripts image (its Yosys 0.68 carries yosys-slang) reads the files openlane/config.json names in VERILOG_FILES, in that order, elaborates the design with Slang, maps memories to flip-flops and writes plain Verilog to rtl/<top>_slang.v inside your project, next to your untouched files, with a header that says when, from which files, and how many word-level cells. The module tree is kept (since 31 October 2026, evening): every module is written on its own, a module used several times gets one copy per instance named <module>_<instance>, and the header says Module hierarchy kept: N modules; so the schematic page shows the same sub-blocks as for plain Verilog, and the chip flows flatten the design themselves as they always did. Should Yosys be unable to write a design with its hierarchy kept, the file is written as one module and the build log and the header say so. Slang's errors and warnings are printed into the build log (slang: file:line:col: ...). If Slang cannot elaborate the design the build stops there with Slang's first error as the reason; nothing is written.
  2. The chip build, which reads that one file (OpenLane and LibreLane: -c VERILOG_FILES=dir::../rtl/<top>_slang.v for this run only; ASAP7: the lab's ORFS runner is told the file name). Everything else about the build (die, clock, density, pins, antenna repair, your own constraints/clock.sdc) is as before.

Never silently: the build log shows both steps; the build keeps the elaborated file as RTL that was built: Slang elaboration beside your own files (source.rtl_slang) and records the reader in its manifest; the chip report's Build conditions row RTL read by says Slang elaboration rtl/<top>_slang.v of ... (chosen automatically ...), or, after a check that kept the plain build, your own files, read by the flow's own Yosys; the RTL vs synthesized netlist row compares the chip with the very elaborated file it was built from (like for like) and says so. The RTL fingerprint of the build stays the fingerprint of your own files, so Try this fix and the version history work as before. The clock-domain crossings check reads the same elaborated file when the project's newest build was prepared with Slang (its report says Read as the chip was built), because the check's own Yosys cannot read such designs directly.

What it is for: designs the flow's Yosys 0.46 refuses (the feature table above; CORE-ET and CVA6 blocks). What to know: Slang follows the language where Yosys is lenient (the two measured differences above: an incomplete case with the full_case hint becomes a latch; an unsized 'bx wider than 32 bits is zero-filled above bit 31). With Automatic the Slang steps run only for a design the flow's own Yosys refuses; choose Always my own files to switch the check off, and the next build reads your own files directly, exactly as before. The elaborated file stays in your project as a record; the next build through Slang overwrites it.

Measured 31 October and 1 November 2026 with the module tree kept: minion_tlb built this way PASSED on SKY130, GF180, IHP and ASAP7 (DRC, LVS and antenna clean where the process has sign-off); like-for-like equivalence was PROVEN-full on SKY130 (the CVA6 ALU, 65 signals), GF180 and IHP (MAC-8, 20 signals); minion_tlb itself stays REFUTED-unsupported on every process because it clocks flip-flops on both edges, which is the design, not the reader.

Import and Lint with the Slang reader (since 31 October 2026)#

  • Import by commit. A GitHub address of the form /tree/<commit>/<folder> is accepted (the commit is fetched on its own); a branch or tag works as before. For everyone.
  • Missing packages and modules. For a person on the switch, the import asks Slang to elaborate the picked files, reads its unknown package / unknown module / missing include messages, adds the files from elsewhere in the same repository that define them (the chosen folder first, then the shortest path), and asks again: at most six rounds or 150 seconds. The import page lists every added file with its repository path, what it defines and the round; the note says whether Slang elaborates the result. Nothing is added that Slang did not ask for.
  • Lint reads your files in the project's order. For a person on the switch, the Lint row (Verilator) feeds the files in the order openlane/config.json lists them in VERILOG_FILES, the order the chip build reads them, so a package file listed first is read first; off the switch the order is alphabetical, as before (CORE-ET minion_tlb: 6 errors before declaration alphabetically, none in the project's order).

Seeds: every Simulate run keeps its seed#

A random test draws its numbers from a seed. The same seed always gives the same numbers, so a failure found with one seed can be repeated exactly.

  • cocotb prints the seed it used at the top of every Simulate log ("Seeding Python random module with ..."). The lab now also stores that seed as data with each Simulate run, and whether it came from your Makefile or was chosen at random.
  • To fix the seed of every Simulate, add one line to your project's Makefile:

``make export COCOTB_RANDOM_SEED = 1234 ``

Remove the line to get a new seed each time. Measured: with the line, two runs produce the same random numbers.

Seeded regression and replay#

Project → Verification → More → Seeded regression runs your own tests, unchanged, once per seed (5, 10 or 20 new random seeds) in the lab's usual Simulate image, and keeps one result per seed: the seed, pass or fail, the first failure (test, simulation time, message) and the toggle coverage of that run. Replay runs one seed again and says whether it fails the same way (same test, same simulation time, same message) as the earlier run of that seed. Your files are copied, never changed. Up to 20 seeds, 2 minutes per seed, 15 minutes in all; VHDL projects not yet.

Measured on a design with a planted rare bug (an adder that is wrong only when the inputs have one rare bit pattern): 20 seeds gave 11 passes and 9 failures, each failure at its own simulation time; replaying seed 159529535 failed again at 305 ns with the same message, and a Simulate with that seed fixed in the Makefile failed the same way.

Formal checks that run out of time#

A formal check (Project → Verification → Formal checks) has a time limit of 280 seconds. If the solver has neither proved your assertions nor found a counterexample by then, the result is Not proven: time limit reached. That is never a pass. Measured: an assertion that a 32-bit * equals a 32-bit shift-and-add multiplier (true, but far too hard for the solver) stopped after 280 s and was stored as not proven.

What to do: prove a smaller version (fewer bits), use fewer clock steps, or add assumptions about the inputs.

Equivalence: RTL against the synthesis and the final netlist#

The V&V tab's RTL vs synthesized netlist check proves that the gate-level netlist of a chip build does the same as your RTL, starting from the state after reset. Measured on the MAC-8 starter on SKY130, GF180MCU and IHP SG13G2: the real design is proven equivalent; with one planted change in the RTL (acc + product changed to acc - product) the check says REFUTED-cex (NOT equivalent) and names acc as the signal that differs.

Verdict words (31 October 2026). Every result starts with one of the words of LiveHD's logic-equivalence pass (UC Santa Cruz MASC group, BSD 3-Clause), the same words the V&V summary page explains: PROVEN-full (pass), PROVEN-bounded(n) and TESTED-sampled(N) (measured, never pass), REFUTED-cex (fail, with the counterexample cycle and the signals), REFUTED-interface, REFUTED-unsupported, REFUTED-vacuous, TIMEOUT-time and TIMEOUT-memory (errors with that exact reason). "Time limit" is said only when the whole 9-minute budget was really used.

Measured on PicoRV32 (31 October 2026, build BLD-20261031-0003 of the lab's benchmark project, 9,819 cells after RTL synthesis, 25,031 after chip synthesis, 1,596 flip-flops on each side). Before this date the check reported "the comparison circuit came out empty" on this design. The cause, measured on the kept logs: two outputs the RTL never assigns (pcpi_insn, trace_data: the coprocessor and trace interfaces are off) are undefined in the synthesized RTL and 0 in the chip netlist, and the strict compare turned the whole comparison circuit into a constant. With LiveHD's power-on rule (those 68 bits are don't-cares and are masked on both sides) the comparison circuit is real (3,140 flip-flops and 34,686 AND gates handed to ABC) and the proof is PROVEN-full in 47 s on one CPU core (reference synthesis 11 s, miter 14 s, ABC register correspondence + dprove 20 s; dprove alone takes 71 s, pdr alone is still undecided after 150 s). With one planted change in the ALU (reg_op1 + reg_op2 changed to reg_op1 + reg_op2 + 1) the result is REFUTED-cex; the measured cycle and signals are in the benchmark report.

Final routed netlist. The Netlist option can also compare your RTL with the final netlist after place and route (buffers, clock tree and repair cells included). Measured on the same three processes: equivalent, and the planted change is caught there too. Physical-only cells (fill, tap and decap cells, which are connected to nothing and have no logic) are left out before the comparison and counted in the result.

DFT: undetected faults by name, patterns as STIL#

Size limit (measured 31 October 2026). The ATPG runs for at most 540 s in the test image. A block the size of the CVA6 ALU (28,494 fault sites in 6,749 gates) is stopped before its first simulation finishes; the row then says so plainly, with the measured size, and the coverage is not measured. It is a limit of the check, not a fault in the design.

The DFT check (stuck-at faults with Fault 0.9.4) now also:

  • lists every undetected fault by name (for example sa1 at _20_.B, cell sky130_fd_sc_hd__or4b_2), in the result and in undetected.txt;
  • exports the compacted test vectors as an IEEE 1450 STIL 1.0 file (patterns.stil) for the full-scan capture view, and checks the export by simulating every vector on the netlist with the kit's cell models. Measured on the MAC-8 starter: SKY130 98.9 % coverage, 51 undetected faults named, 32 vectors, 0 mismatches; GF180MCU 98.0 %, 86 named, 29 vectors, 0 mismatches; IHP SG13G2 98.8 %, 48 named, 29 vectors, 0 mismatches. The file has no scan load/unload procedures yet, so it is not a tester program.

Transition (at-speed) faults#

A chip can have every gate working and still be too slow: a wire that switches late is a transition fault (slow to rise, or slow to fall). Fault 0.9.4 models stuck-at faults only, and no other open-source tool installed here grades transition faults, so the lab has its own grader, run automatically in the same DFT check (scan on) and reported next to the stuck-at result.

How it works, so you can check a number by hand:

  • It uses the same full-scan view as the ATPG (every flop cut: its output is something the tester loads, its input something the tester reads) and each cell's logic from the kit's own liberty file.
  • A test is a launch-on-capture pair: the tester loads a vector, one clock captures the flops' new values, and that change is the launch; a second clock captures the result. The primary inputs are held between the two clocks, as a simple tester does at speed.
  • A slow-to-rise fault at a wire counts as detected when the wire goes 0 then 1 in the pair and a stuck-at-0 on it in the second step changes an output or a captured flop (slow-to-fall: 1 then 0, stuck-at-1). The fault list is Fault's own: every gate pin and every port bit.
  • The pairs are Fault's own test vectors, plus 1024 seeded random pairs (seed 20261030, in the result).

Measured on the MAC-8 starter (30 October 2026):

ProcessStuck-at (Fault)Transition, inputs heldTransition, inputs changed at launch
SKY13098.9 %64.7 % (3138 of 4852)99.8 %
GF180MCU98.0 %57.8 % (2475 of 4280)99.7 %
IHP SG13G298.8 %54.2 % (2183 of 4026)99.9 %

Why the held-input number is lower: in the MAC-8 the multiplier is fed straight from the inputs a and b. When the inputs are held, those wires never switch inside a pair, so a launch-on-capture test cannot launch a transition on them (the result counts these as never launched). A tester that can change the inputs at speed reaches the right-hand column. Every undetected transition fault is listed by name in transition_undetected.txt.

Checked against Fault. On every one of Fault's vectors the grader's outputs equal Fault's own expected outputs, bit for bit (all three processes). Every stuck-at fault Fault detects, the grader detects too; it also detects 8 (SKY130), 14 (GF180) and 9 (IHP) more, almost all at gate pins wired straight to a chip input bit, where Fault detects the same fault on the input itself but not at the pin.

Limits. This grades test pairs at logic level: there are no path delays and no timing (it cannot say how much slack a path has; that is the timing report's job), it is not a deterministic at-speed ATPG, and no launch-on-shift. It needs scan on and a design with flops; with scan off the result says not graded.

Scan chain built into the chip#

The DFT check inserts a scan chain into a copy of your netlist (Fault's fault chain: a multiplexer in front of every flop, boundary-scan cells on the ports, and the new ports sin, sout, shift, test and tck). V&V -> DFT: scan chain built into the chip puts that netlist into a real chip build:

  • What = build makes a new project <your project>-scan (your project is never changed), with your files copied, the scan netlist as rtl/top_scan.v and your own build settings, and starts Build the chip on it. OpenLane builds the netlist as it is (SYNTH_ELABORATE_ONLY); the lab first replaces each assign in Fault's netlist by a buffer cell, because OpenLane refuses assign statements.
  • What = check, on the -scan project after its build passed: the build's DRC, LVS and antenna checks; the scan ports, flops and boundary cells in the final netlist and in the layout's own extracted netlist (Magic's extraction of the GDS, the netlist LVS matched), the scan pins in the layout; and the ATPG run again on the built netlist (with the buffers, clock tree and repair cells the build added; fill, tap, decap and diode cells left out and counted).

Measured on the MAC-8 starter (30 October 2026), each through V&V → build, then V&V → check:

ProcessScan chip buildDRC / LVS / antennaScan flops in final netlist and extracted layoutATPG on the built netlist
SKY130BLD-20261030-0078pass / pass / pass57 and 57 (20 of the design + 37 boundary)97.8 %, 23 vectors
GF180MCUBLD-20261030-0079pass / pass / pass57 and 5797.0 %, 27 vectors
IHP SG13G2BLD-20261030-0080pass / pass / pass57 and 5796.8 %, 25 vectors

The scan pins are in the layout (DEF pins, and labels in the GDS). Not covered: ASAP7 (no cell models for Fault), designs with memory blocks, a JTAG/TAP controller (tck is the boundary-scan clock only), and the timing of the scan path (the shift path is not timed by a separate scan-mode constraint).

IR drop: the assumptions, and power from your own tests#

The lab's IR drop is static: one operating point, at the build's default corner. Each stored IR-drop result now carries its assumptions as data:

AssumptionWhat the lab uses
analysisstatic IR drop (OpenROAD PSM), no dynamic IR (electromigration of the power grid: see below)
cornerthe build's default STA corner, e.g. nom_tt_025C_1v80
supplythe default-corner library voltage on power nets (1.8 V SKY130, 5 V GF180, 1.2 V IHP), 0 V on ground
current sourcevectorless: each cell's current from the timing tool's power with its default switching activity
supply modelideal voltage sources on the top power-grid layer; no package, pad or bump model
parasiticsthe default corner's extracted parasitics

Project → Verification → More → IR drop and power shows them per build, and can measure power from your tests: your cocotb tests run on the final gate-level netlist, and OpenSTA reports the power with the switching it saw, next to the same report with default activity. Measured on the MAC-8 starter: SKY130 0.461 mW from the tests against 1.440 mW with the default activity; GF180MCU 4.41 mW against 18.03 mW; IHP SG13G2 0.151 mW against 1.062 mW (there the test stopped at 15 ns at gate level, so the window is short). The activity is only as representative as your tests; tests can fail at gate level because the cell models use unit delays, and the activity is still measured.

Electromigration of the power grid#

Too much current in a thin wire slowly moves the metal until the wire breaks: electromigration (EM). Each kit gives a limit for every metal layer (milliamps per micrometre of wire width) and every via (milliamps per cut). On the IR drop and power page, Check electromigration of the power grid does this for one of your passed builds:

  1. OpenROAD's power-grid analysis (the same one as the IR drop, analyze_power_grid -enable_em, in the build's own flow image) finds the current in every piece of the power and ground grid: the thin rails over each row of cells, the straps, and every via between them.
  2. The lab divides each piece's current by the drawn width of the wire it lies on (read from the build's own layout), or by the via's number of cuts, and compares it with the kit's limit from its technology LEF file.
  3. It passes when every piece is at or below its limit. The result lists the worst piece of each layer, with its place on the chip, and the margin.

Measured on the MAC-8 starter (live, 30 October 2026):

ProcessWorst piece% of its limitResult
SKY130 (limit at Tj = 90 °C, as the kit's LEF says)metal-1 rail, 0.48 µm wide: 0.115 mA/µm against 2.8 mA/µm4.1 %pass
GF180MCUMetal1 rail, 0.60 µm: 0.296 mA/µm against 0.67 mA/µm44.2 %pass
IHP SG13G2Metal1 rail, 0.44 µm: 0.128 mA/µm against 1 mA/µm12.8 %pass

The check was also tested with a planted fault: the same layouts with the rails drawn 40 times narrower. It failed on all three processes (165 %, 1770 % and 562 % of the limit).

What it assumes, shown with every result:

  • the current is the vectorless estimate (OpenSTA's default switching activity), as for the IR drop, not your tests;
  • the limits are the kits' DC average limits. SKY130 states Tj = 90 °C. GF180MCU and IHP do not state a temperature in their LEF;
  • a via's current is shared equally by its cuts;
  • the top grid layer, where the analysis places ideal voltage sources, carries no current in the analysis, so it is not represented (no pad or bump model);
  • the short links from the rails into each cell's own power pin are inside the kit's cells: they are listed with a conservative estimate but not judged;
  • ASAP7: not available, because its LEF has no current-density limits.

Not available in open source#

These are checked on purpose and are not offered, because no open-source tool on the lab's server (or that we found) does them:

  • Dynamic (time-varying) IR drop. OpenROAD's PDNSim describes itself as an open-source static IR analyzer; its analyze_power_grid (OpenROAD in OpenLane 2.3.10, LibreLane 3.0.14 and ORFS 26Q3) has no transient mode. A transient run of the grid in a circuit simulator (ngspice-47 and Xyce 7.10 are installed) would need each cell's supply current over time. The kits' libraries do not contain that: the SKY130, GF180MCU and IHP SG13G2 Liberty files have no dynamic_current (CCS power) tables. The lab will not invent a current model. What the lab offers instead: static IR drop, and power from your own tests.
  • Electromigration of signal wires (alternating, RMS and peak current). OpenROAD's -enable_em reports power-grid currents only, and no open tool on the server computes per-wire signal currents. SKY130's LEF does give RMS limits, but nothing measures signal wires against them.

Related

  • V&V summary and checksThe project's V&V tab, one row per check (lint, simulation, formal, coverage, synthesis, equivalence, DRC, LVS, antenna, timing, IR drop), what each state means, the Lint and RTL-vs-netlist checks, coverage export and exclusions, and the limits.
  • Assertions, functional coverage and test historyCheck your RTL's assertions in simulation, measure which values your tests really reached, see every test's result run by run, open a failed run's waveform at the failure, and read which requirement the last run verified.
  • Clock crossings, scan test and virtual bring-upThree deeper checks on the V&V page: clock and reset domain crossings in your RTL, a scan/ATPG fault-coverage run on your gate-level netlist, and a scripted power-on of the chip in simulation.
  • Reference checks and release gateThe known-bad designs the lab rebuilds to prove its tools still catch faults, what each must show per process, and the automated tests behind the roles, grading, learning-mode and isolation promises.

Something unclear or missing? Send feedbackSign in and use Feedback to tell us.