Signoff Campaigns¶
Documentation Home | CLI Reference | Circuit JSON Format | 中文版
circuit-opt signoff runs multiple circuit testbenches over one explicit
process/voltage/temperature grid. It is intended for checks that cannot be
represented honestly by one netlist, such as open-loop gain, differential and
common-mode loop stability, closed-loop noise, and large-signal settling.
circuit-opt signoff examples/tsmc28hpcp_mdac_ota_signoff.json \
--workers 4 --output results/tsmc28_mdac_signoff.json
The example contains 11 testbench cases over
tt/ss/ff/sf/fs x -40/27/125 degC x 0.85/0.90/0.95 V, for 45 PVT points and
495 case runs. It covers open-loop gain, the differential loop, both CMFB
loops, closed-loop input/output noise, five residue levels, and the 0111 to
1000 major-carry transition.
Manifest¶
Campaign paths are relative to the manifest file. Absolute paths and paths that escape the manifest directory are rejected, so a repository can be moved without editing machine-specific locations.
{
"name": "ota_signoff",
"pvt": {
"corners": ["tt", "ss", "ff", "sf", "fs"],
"temperatures_c": [-40, 27, 125],
"supplies_v": [0.85, 0.9, 0.95],
"nominal_supply_v": 0.9,
"supply_bias_key": "VDD"
},
"cases": [
{
"name": "open_loop",
"circuit": "ota_ac.json",
"overrides": {
"ac_drives": {"VINP": 0.5, "VINN": -0.5},
"signoff": {
"measurements": {},
"constraints": {"gain": {"min": 80}}
}
}
}
]
}
Each case deep-merges overrides into its base circuit. Objects merge
recursively and arrays replace the base array. A numeric PVT expression is an
explicit affine expression:
This evaluates to 0.5 * VDD + 0.0 * temperature_c + 0.225. At each point the
runner also binds section, MOS temperature in kelvin, the named supply bias,
PMOS bulk voltage, numeric voltage-source levels, and DC seeds.
Margin Table¶
--margins prints one row per constraint instead of the single tightest
measurement that worst_case names. A spec sitting at +0.02 of its limit is a
design constraint even when another spec is at -0.5, and a worst-case view hides
it entirely.
Each row carries the constraint's worst normalized margin and the PVT point that
produced it, the observed minimum and maximum with their unit, the number of
points evaluated, and every failing point. Rows are sorted tightest first.
The same data is available programmatically from
circuitopt.signoff_campaign.summarize_margins(result).
Passive Tolerance Sweep¶
A signoff that passes only at nominal component values is not a signoff. Poly resistors carry roughly 20% absolute tolerance and MOM capacitors roughly 10%, so a compensation network tuned on a knife edge will not survive fabrication.
Values are percentages. A key of R or C perturbs that whole element class; any
other key names a single element, for example --tolerance CC1=10. The sweep runs
1 + 2N campaigns for N entries — nominal, then each entry at 1 - tolerance
and 1 + tolerance — and reports which constraints break in which direction. The
result is robust only when every run passes.
Per-element perturbation answers a different question from class-wide perturbation: scaling one nulling resistor alone isolates the compensation network, while scaling every resistor together also moves the bias network that sets its target.
Result Contract¶
Every case must contain a circuit-level signoff block. The campaign stores
that unit-bearing signoff envelope, not the raw waveform arrays. A model error,
non-convergence, non-finite result, or invalid signoff configuration produces
an invalid case; it is never converted to a passing fallback value.
Each point reports its case results and worst_case. The campaign-level
worst_case includes case, corner, temperature_c, supply_v,
measurement, and normalized margin. invalid dominates fail, and fail
dominates pass. Point ordering is deterministic for every worker count.
The manifest schema is
schemas/signoff_campaign.schema.json.
The referenced testbenches continue to use
schemas/circuit.schema.json.