This document is for the FaultFlow session — it describes the machine interface OT exposes so FaultFlow can obtain structural reconvergence data before ATPG without inserting test points.
Overview
OT exposes an internal CLI subcommand _preflight (underscore prefix = not for end users).
FaultFlow calls it as a subprocess, parses the stdout JSON line, and reads two output files:
opentest --yosys _preflight \
-i /path/to/netlist.json \
--scoap \
-r \
--reconv-algorithm advanced \
-o /path/to/workspace
Recommended flags:
--scoap— run SCOAP metrics (faster; required to build the circuit DAG)-r/--reconvergence— run reconvergence analysis--reconv-algorithm advanced— default; recommended — providesstemfields needed for Phase B fault certification-o <dir>— output directory; defaults to<netlist_dir>/_preflight/--tech sky130|osu035|ihp|nangate|auto— PDK (default:sky130)
Stdout Contract
OT prints exactly one JSON object on stdout as the last output line:
{
"status": "ok",
"manifest": "/abs/path/to/tpi_manifest.json",
"reconv_ids": "/abs/path/to/fanout_design_reconv_ids.json",
"tech": "sky130"
}
On error:
{"status": "error", "message": "...reason..."}
FaultFlow should:
- Run the command, capture stdout
- Find the last line starting with
{ - Parse JSON, check
status == "ok" - Use the returned
manifestandreconv_idspaths
Output Files
tpi_manifest.json
Written at <output_dir>/tpi_manifest.json. Schema version "1.0".
Key fields for FaultFlow:
{
"schema_version": "1.0",
"session_id": "ot_1234567890_abcd1234",
"iteration": 1,
"top_module": "fanout_design",
"netlist_path": "/abs/path/to/netlist.json",
"inserted_test_points": [],
"structural_hints": {
"fanout_points": [
{"name": "net_foo", "yosys_net_id": 42},
{"name": "net_bar", "yosys_net_id": 107},
{"name": "internal_ot_name", "yosys_net_id": null}
],
"reconvergences": [...],
"enabled": true,
"algorithm": "advanced"
},
"awaiting_oracle": true,
"response_path": "/abs/path/to/oracle_response.json"
}
structural_hints.fanout_points
list[dict] — each entry is:
| Field | Type | Notes |
|---|---|---|
name |
string |
OT signal name (from circuit graph) |
yosys_net_id |
integer \| null |
netnames[name]["bits"][0] — first integer in Yosys bits list. null if signal not in Yosys netnames or if all bits are string constants ("0", "1") |
Mapping: FaultFlow maps yosys_net_id → its internal compiled net index via the existing
Yosys net-ID lookup it already uses for other purposes. Signals with null net_id are OT
internal synthesis names — skip or ignore them.
FaultFlow Phase A action: before the ATPG round loop, push any fault whose net_id is in
this set to the back of the ordering queue and skip the short-timeout tier (reconvergent-site
faults are likely hard/redundant; don’t burn short attempts on them).
<design>_reconv_ids.json
Written at <output_dir>/<design>_reconv_ids.json. This is the algorithm output enriched
with Yosys net IDs on every reconvergence record.
Each record in reconvergences has the following additional fields (any can be null):
Basic / Simple algorithm format
{
"site": "gate_Y",
"site_net_id": 42,
"branch1": "sig_A",
"branch1_net_id": 55,
"branch2": "sig_B",
"branch2_net_id": 56,
"path1": ["sig_A", "mid_1", "gate_Y"],
"path2": ["sig_B", "mid_2", "gate_Y"]
}
Advanced algorithm format (recommended — use --reconv-algorithm advanced)
{
"site": "gate_Y",
"site_net_id": 42,
"pairs": [
{
"branch1": "sig_A_br0",
"branch1_net_id": 55,
"branch2": "sig_A_br1",
"branch2_net_id": 56,
"stem": "sig_A",
"stem_net_id": 50
}
]
}
stem_net_id identifies the fanout source — the net that diverges into two paths and
reconverges at site. This is the field needed for Phase B SAT pre-certification:
two paths from stem → site with no common intermediate nodes means any single stuck-at
fault on stem propagates through both paths and cancels at the XOR-equivalent merge site.
FaultFlow Phase B action: for each record where stem_net_id is non-null and the two
paths are structurally disjoint, structurally certify any sa0/sa1 fault on stem as
UNSAT (canceling paths) without running SAT at all.
Net ID Semantics
OT derives yosys_net_id as:
bits = netnames[signal_name]["bits"]
net_id = next((b for b in bits if isinstance(b, int)), None)
This matches Yosys’s internal bit numbering. String entries like "0" and "1" represent
constant tie-offs and are skipped. The returned integer is directly usable as a Yosys net index.
Full Example Invocation
# Phase A + B preflight before ATPG
opentest --yosys _preflight \
-i /workspace/design.json \
--scoap \
-r \
--reconv-algorithm advanced \
-o /workspace/preflight_out \
--tech sky130
# Parse stdout to get paths
RESULT=$(opentest --yosys _preflight ... 2>/dev/null | tail -1 | python3 -c "
import sys, json
d = json.load(sys.stdin)
if d['status'] != 'ok':
raise SystemExit(d['message'])
print(d['manifest'])
print(d['reconv_ids'])
")
Or in FaultFlow’s Rust/C++ subprocess handler:
- Spawn
opentest --yosys _preflight ... - Collect stdout lines
- Find last line matching
/^\{/ - Parse JSON
- On
status == "ok": readmanifestandreconv_idspaths
Backward Compatibility
tpi_manifest.json → structural_hints.fanout_pointschanged fromlist[str]→list[dict]. If FaultFlow reads the oldlist[str]format, add a version guard:if isinstance(fp[0], str): fanout_names = fp # old format else: fanout_names = [d["name"] for d in fp] # new format with net IDs- The
_reconv_ids.jsonfile is new — the original_reconv.jsonfrom the algorithm is unchanged alongside it. FaultFlow reads_reconv_ids.json; other tooling reads the original. fanout_point_count(integer count) is now the field name in algorithm output where it was previouslyfanout_points(integer) — this was a bug fix. FaultFlow should read signal names fromstructural_hints.fanout_points(list of dicts), not from the raw algorithm count field.
Files Written (summary)
| File | Content |
|---|---|
<output_dir>/tpi_manifest.json |
Session manifest with enriched fanout_points |
<output_dir>/<design>_reconv_ids.json |
Reconvergence records with *_net_id fields |
<output_dir>/<design>_scoap.json |
SCOAP metrics (side-effect of DAG build) |
<output_dir>/<design>_yosys_dag_advanced.json |
DAG with reconvergence data |