Concepts

A short, practical glossary of the ideas faultflow works with. None of this is specific to faultflow’s internals — see the Architecture overview for how they are implemented.

Stuck-at faults

The stuck-at fault model abstracts a manufacturing defect as a single net being permanently tied to a logic value:

  • SA0 — the net is stuck at logic 0.

  • SA1 — the net is stuck at logic 1.

faultflow enumerates both polarities on every fault site. A test detects a fault if applying an input vector makes an observable output (a primary output, or a tagged test point) differ between the fault-free circuit and the faulty one.

Transition faults

A transition fault models a defect that is slow rather than stuck: a net that can eventually reach the right value but not within the clock period.

  • Slow-to-rise (STR) — a 0→1 transition is too slow.

  • Slow-to-fall (STF) — a 1→0 transition is too slow.

Detecting one needs a pair of vectors: one to set up the starting value, and one to launch the transition and capture the result. faultflow implements the two-pattern flavor two ways: combinational broadside capture, and — for scan designs — launch-on-capture (LOC) or launch-on-shift (LOS), selected with [fault_model] launch = loc | los. Transition faults are enabled with [fault_model] model = transition, and cannot be combined with fault collapsing (the stuck-at equivalence rules do not hold for transition faults).

Fault sites and the checkpoint model

Rather than placing a fault on every pin of every gate, faultflow uses the checkpoint theorem: it is sufficient to consider faults on primary inputs and on every fanout branch. The compiler materializes each fanout branch as its own net, so “a fault on a branch” becomes an ordinary net fault. This keeps the fault list small without losing coverage fidelity.

Fault collapsing

Many faults share the exact same set of detecting vectors. Collapsing removes such redundant faults from the fault list so coverage is computed over a minimal set. faultflow collapses by equivalence only (never dominance), so coverage is provably unchanged: INV/BUF, the controlling-value input polarity of AND/OR/NAND/NOR, and the Sky130 compound AOI/OAI cells (a21oi, o21ai, a22oi, …) via exhaustively-derived classes. XOR/XNOR have no equivalent faults and are left untouched. See Collapsing rules for the full table.

Note

[fault_model] collapsing defaults to true (on) when the key is omitted entirely. config.ofs.example and every shipped example config set it to false explicitly, so out-of-the-box runs have collapsing off — but if you delete that line rather than setting it, collapsing turns back on. See the Configuration reference.

ATPG

Automatic Test Pattern Generation is the search for input vectors that detect the faults a random/functional vector set missed. faultflow’s ATPG is native and SAT-based: for each target fault it builds a fault-free and a faulty CNF copy of the circuit, forces the stuck-at value, adds a constraint that some observable output must differ, and asks the CaDiCaL solver for a satisfying assignment.

  • SAT → the assignment is a test vector (re-simulated to confirm before it is trusted).

  • UNSAT → the fault is redundant (untestable) under the current model.

  • TIMEOUT / UNKNOWN → the fault is left undetected, never marked redundant.

The ATPG runs in a progressive loop: generate, fault-simulate to detect “fallout” faults the new vectors happen to cover, repeat until the coverage threshold, a round limit, or a stall is reached.

Coverage and the denominator

Coverage is only meaningful relative to a precisely defined denominator. faultflow’s rule:

denominator = faults where ALL of:
  - the net belongs to a supported (non-blackboxed) cell
  - the fault is not collapsed away
  - the net is not a clock   (unless include_clock_faults = true)
  - the net is not a reset   (unless include_reset_faults = true)

coverage = detected / denominator x 100

Every fault is still enumerated and counted; exclusions (blackbox, clock, reset) are tagged and reported separately, never silently dropped. A zero denominator is an error, never a divide-by-zero.

The report gives two coverage figures that differ only in how they treat faults the ATPG proved untestable (redundant): test coverage removes those from the denominator (detected / testable), while fault coverage keeps them in (detected / structurally-eligible), so fault coverage is always the more conservative number. See Outputs for the exact fields.

Scan

Sequential logic is hard to test directly because flip-flop state is not observable. Scan chains the flip-flops into a shift register (a scan chain) so their state can be shifted in (controlled) and shifted out (observed). This turns the flip-flops into pseudo-primary-inputs and pseudo-primary-outputs, reducing sequential ATPG to the combinational problem faultflow already solves. faultflow can insert generic scan chains, check them, map them to Sky130 scan cells, and run scan ATPG.

Test modes (IEEE 1500)

For a core wrapped with an IEEE 1500 boundary, faultflow supports three wrapper test modes: functional (wrapper transparent), intest (test the core internals), and extest (test the interconnect around the core). These are selected in the Tcl shell or via the [testmode] config section.

A few synthesis terms

faultflow sits downstream of synthesis, so a little vocabulary leaks in:

  • Liberty (.lib) — the standard-cell library file (timing, function). faultflow passes it to Yosys only; the core reads the JSON cell map instead.

  • Techmap — mapping generic cells onto a specific library’s cells. faultflow techmaps generic scan cells onto Sky130 scan flip-flops.

  • BENCH — a simple ISCAS netlist format, used by the optional Quaigh path and by the --ext sidecar to fix primary-input order.