The Tcl shell¶
faultflow’s primary interface is an interactive, Tcl-based command shell that holds a live project session. Load a netlist, synthesize, insert scan, run ATPG, insert test points, and publish netlists step by step — or drive the whole flow from a script. A batch CLI covering the same core operations also exists, for scripted, one-shot runs where a live session isn’t needed; see Running without the shell.
Starting the shell¶
python3 ff.py shell # interactive REPL
python3 ff.py shell -c config.ofs # preload a project config
python3 ff.py shell -f flow.tcl # run a script, then exit
Flag |
Default |
Meaning |
|---|---|---|
|
— |
Execute a Tcl script non-interactively, then exit |
|
— |
Preload a project config (requires |
|
|
Output root directory |
|
off |
DEBUG logging with timestamps; expands result rendering to show Details/Artifacts/Metrics/Warnings |
The REPL¶
The prompt starts bare (
faultflow>) and grows to show the loaded design and PDK profile as session state accumulates:faultflow[c17]>once a design is loaded,faultflow[c17:sky130]>once a PDK is also selected.Multi-line input is supported (continuation lines show
...); exit withquit,exit, or EOF (Ctrl-D).Tab-completes command names; arrow-key history persists to
~/.faultflow_history(1000 lines).The shell is a full Tcl interpreter —
set,proc,foreach,if,catch,dict get,source,puts, and namespaces all work. Every faultflow command returns a Tcl dict (status/command/message/artifacts/metrics/warnings), so scripts can do[dict get $result message].set_option’s worker count is also mirrored to the Tcl global$WORKERS.Any line that isn’t a known faultflow command is passed through to the underlying OS shell — so
ls,cat, oryosyswork directly at the prompt.Errors render with actionable
Next:hints keyed off the specific error.
Session lifecycle¶
flowchart LR
A["read_netlist / load_json"] --> B[use_lib_cells]
B --> C[synth]
C --> D{scan design?}
D -- yes --> E[add_scan] --> F[check_scan] --> G[run_atpg]
D -- no --> G
G --> H["status / report"]
H --> I[write_netlist]
Command reference¶
Commands use Tcl single-dash flags (-chains 4) and are grouped by category, as
shown by help. Run help <command> for the live version of this reference, or
help <glob> (e.g. help re*) to list matching commands.
Project¶
Command |
Summary |
|---|---|
|
Load Verilog or Yosys JSON (Verilog is synthesized later by |
|
Load an already-synthesized Yosys JSON directly, skipping |
|
Select the PDK profile: |
|
Synthesize loaded Verilog with Yosys. On already-synthesized JSON, validates and returns |
|
Declare a clock domain; |
|
List declared clock domains (port + off-state) |
|
Model an instance as a test boundary: its inputs become observable (pseudo-PO), its outputs controllable (pseudo-PI). The instance itself is not simulated. Repeat calls accumulate; a duplicate is ignored. |
|
List blackboxed instances |
|
Audit every netlist cell type against the selected PDK cell map; report total/uncovered/memory-like types. Report-only — never aborts the session. |
Test mode¶
Command |
Summary |
|---|---|
|
Inject IEEE 1500 WBR cells on every non-clock boundary port. |
|
Select the wrapper test mode. |
|
Show the current wrapper test mode |
|
Read a block’s exported INTEST scan patterns (from |
Test point¶
Command |
Summary |
|---|---|
|
Insert test points via OpenTestability, re-run ATPG on the resulting netlist, and print a Baseline / +TP / Δ comparison table. The TPI netlist becomes the active version. Defaults: metric |
|
Revert the last test-point iteration (restore the previous netlist). Cannot go past the original baseline. |
See Test-point insertion for the full workflow.
Scan¶
Command |
Summary |
|---|---|
|
Insert and stitch generic |
|
Structural + normal-mode equivalence checks on the current scan insertion. |
Run¶
Command |
Summary |
|---|---|
|
Run native SAT ATPG. Combinational stuck-at by default; |
|
Show coverage, classification, terminal reason, and timing. |
|
Regenerate the unified report ( |
Output¶
Command |
Summary |
|---|---|
|
Publish a functional or scanned netlist. |
|
Reserved for future scan-aware STIL/WGL export. Not implemented — raises a clear error today. |
Options¶
Command |
Summary |
|---|---|
|
Get (no argument) or set the parallel SAT-ATPG worker count. Default |
|
Set a persistent flow option — see the full key table below |
|
Remove an option override |
|
Show project state and current option overrides |
set_option keys (validated; an unrecognized key is rejected):
Key |
Meaning |
|---|---|
|
Maximum progressive ATPG rounds (positive integer) |
|
Per-fault CaDiCaL conflict limit (positive integer) |
|
Fixed per-fault SAT timeout in seconds (positive integer); the fallback used when |
|
Comma list of escalating per-fault timeouts, e.g. |
|
Random-fill vector budget per round (non-negative integer; |
|
Stop random fill and switch to SAT once coverage reaches this percent ( |
|
Parallel SAT worker processes (positive integer); prefer the |
|
Easy/hard worker split, only applied when |
|
Enable incremental-SAT (IFC) solving (bool) |
|
Enable OpenTestability structural reconvergence pre-ordering and pre-certification (bool) |
|
Enable/disable fault collapsing for this session (bool) |
|
Count clock-net faults in the denominator (bool) |
|
Grade async reset/set-tree faults via implication instead of excluding them (bool); fingerprinted, so toggling it forces a fresh campaign |
|
Target coverage percent |
|
Fault-grading worker threads (non-negative integer; |
|
|
|
|
Session¶
Command |
Summary |
|---|---|
|
Validate and checkpoint the session to |
|
Restore project identity and options only — not derived run state |
|
Reload full validated state (synth / scan / check / campaign) |
|
Remove campaign database state; keeps manifests, session, logs, and netlists |
|
Clear the in-memory project |
Shell¶
Command |
Summary |
|---|---|
|
Overview (no argument), single-command detail, or glob-matched list |
|
Exit the shell |
A scripted flow¶
Because shell -f executes a script non-interactively, a complete campaign can be
captured as a Tcl file. For example, flow.tcl:
# flow.tcl — synthesize, scan-insert, and run scan ATPG for serial_adder
read_netlist examples/serial_adder.v -top serial_adder
use_lib_cells sky130
synth
add_scan -chains 4 -SI scan_in -SO scan_out -SE scan_en
check_scan
run_atpg -sa -scan -max 20 -target 95
status -scan
report
write_netlist -scan -techmap -o output/serial_adder/serial_adder_scan.v
Run it with:
python3 ff.py shell -f flow.tcl
The flowscripts/ directory¶
The repository ships runnable .tcl recipes under flowscripts/, each driven by a
proc that takes key value arguments — edit the CONFIGURATION block at the
bottom of the file, or source it and call the proc directly:
Script |
Flow |
|---|---|
|
Flat-netlist stuck-at ATPG — no scan or wrapper. Leaf blocks, or characterizing a design before adding scan. |
|
Scan insertion and scan-protocol stuck-at ATPG. |
|
Core-level ATPG on a wrapped design. |
|
IEEE 1500 INTEST — scan-integrated core coverage. |
|
IEEE 1500 EXTEST — wrapper-boundary / interconnect coverage. |
|
Hierarchical block-to-SoC flow: per-block INTEST plus assembly EXTEST. |
See Flow recipes for a walkthrough of the two most common flows.
The Yosys synthesis script¶
faultflow’s other “scripting” surface is the locked Yosys synthesis template,
faultflow/templates/yosys_synth.tcl.j2.
It is a Jinja2 template rendered per run into
output/<top>/.faultflow/generated_scripts/yosys_synth.tcl and executed with
yosys -s:
read_verilog -sv {{ verilog }}
hierarchy -check -top {{ top }}
proc
flatten
opt_expr
opt_clean
synth -top {{ top }}
dfflibmap -liberty {{ liberty }}
abc -liberty {{ liberty }}
clean
write_json {{ output_json }}
write_verilog {{ output_verilog }}
One synthesis run emits both write_json (consumed by the C++ core) and
write_verilog (used by the optional iverilog verification gate). The script is
intentionally fixed so the same netlist is used everywhere, with no drift between
the graded netlist and the verified one.