Faults

A fault is a list of primitive changes to the netlist, with a record of what it is. There are three primitives, and nothing else changes a netlist:

Primitive Effect
SetParameter Change a value or an instance parameter: set it, or move it relative to the value the component has
InsertSeries Reconnect one terminal to its node through a resistance
InsertParallel Add a resistance between the nodes of two terminals

Fault types

Type Physical interpretation What it does to the netlist
OpenCircuit Broken connection A large resistance in series with one terminal
ShortCircuit Bridge or breakdown across a component A small resistance between two terminals
LeakageFault Finite parasitic conduction A graded resistance between two terminals
ParametricFault A parameter outside its tolerance band The parameter is moved relative to its realised value, or set to a value
CompositeFault One mechanism with several electrical consequences The changes of its parts, in order

Every fault has an identifier, a record (fault.metadata()) from which it can be rebuilt, and optionally a severity on a declared scale. A FaultSet is the ordered fault list of an experiment; it can be saved to JSON and filtered.

from spicefault.faults import (
    CompositeFault, LeakageFault, OpenCircuit, ParametricFault, ShortCircuit,
)

OpenCircuit("R1")                              # 1 GOhm in series with its second terminal
ShortCircuit("C1", r_short=0.1)                # 0.1 Ohm across it
LeakageFault("C1", 1e6, r_min=1e4, r_max=1e8)  # graded, severity on a log scale
ParametricFault("R2", deviation=-0.2)          # 20 % below the value it was drawn with
ParametricFault("XU1", "vos", fault_value=0.02, nominal_value=0.0, reference=0.5e-3)
CompositeFault("capacitor_ageing", [
    ParametricFault("C1", factor=0.7),         # less capacitance ...
    OpenCircuit("C1", r_open=50.0),            # ... and more series resistance
])

Opens and shorts are finite resistances: an ideal open leaves a node floating and the operating point has no solution. r_open and r_short belong to the model, are recorded with the fault, and should be checked against the impedances around the component.

Magnitude and severity

The magnitude of a fault is its physical size, with a unit: a deviation, a resistance, an offset. Its severity is an optional dimensionless number on a scale that is recorded with it. There is no universal formula, and severities on different scales cannot be compared.

Fault universe and coverage

The faults of a campaign can be generated from rules instead of listed by hand, so that what was simulated and what was left out are both on record:

from spicefault.faults import FaultUniverse, open_rule, parametric_rule, short_rule

universe = FaultUniverse(
    circuit,
    [open_rule("R"), short_rule("R"), parametric_rule([-0.2, -0.05, 0.05, 0.2], "R")],
)
universe.exclude("R2:short", reason="ties the output to ground: outside the study")

universe.coverage_matrix()   # components x fault types: conditions to simulate
universe.exclusions()        # every fault left out, with its reason
universe.coverage()          # 11 of 12 conditions

faults = universe.selected()
faults.tolerance_overlap(experiment.variations)   # parametric faults inside the tolerance band

A rule selects components by element letter (kinds), by name (components) and by the subcircuit of an instance or the model of a device (models, compared with Component.model). It can tag its faults, with a dictionary or a function of the component, and a parametric rule takes relative deviations, factors or absolute values, reported under the fault type given:

rules = [
    parametric_rule(kinds="X", models=("opamp",), parameter="vos", fault_values=(20e-3,),
                    fault_type="offset", tags=lambda c: {"part": c.name, "origin": "amplifier"}),
    parametric_rule(kinds="X", models=("opamp",), parameter="aol", factors=(0.01,),
                    fault_type="gain_loss"),
    open_rule("R", tags={"origin": "assembly"}),
]

With tag_columns=("part", "origin"), a campaign writes these tags as columns of the dataset.

The definitions behind this page are in the fault model.