PluginBench
Skill
Review
Audit score 70

spice-sim

diodeinc/pcb

Add ngspice-backed simulation testbenches to Zener PCB designs with transient analysis and waveform sources.

What is spice-sim?

Spice-sim integrates ngspice simulation into Zener `.zen` circuit designs, enabling transient analysis, pulse/PWL waveforms, and SVG plot generation. Use it to validate circuit behavior, test component models, and verify design scenarios like startup, enable/disable, or protection thresholds.

  • Create focused simulation testbenches with minimal external loads and one Simulation block
  • Define voltage sources (DC, PULSE, PWL) and transient analysis commands in raw ngspice
  • Wire SPICE models to leaf components via `spice_model=SpiceModel(...)`
  • Generate SVG hardcopy plots of voltage and current signals
  • Support `.control` blocks with `tran`, `hardcopy`, and analysis commands
  • Organize testbenches by scenario in package-local paths like `testbench/test_<scenario>.zen`

How to install spice-sim

npx skills add null --skill spice-sim
Prerequisites
  • ngspice installed and available in PATH
  • Zener design file (`.zen`) with simulation-capable components
  • SPICE model file (`.lib`) for any custom components, or vendor-provided models
Claude Code
Cursor
Windsurf
Cline

How to use spice-sim

  1. 1.Run a dummy simulation to confirm the target is simulation-capable: `pcb sim <path/to/file.zen> --setup "* empty setup check"`
  2. 2.Obtain or create a SPICE model for any leaf components missing one, then wire it via `spice_model=SpiceModel(...)`
  3. 3.Create a testbench file at `<package>/testbench/test_<scenario>.zen` with imports, module-under-test instantiation, and minimal external loads
  4. 4.Define voltage sources and analysis commands in the `Simulation.setup` string using raw ngspice syntax (DC, PULSE, PWL, .control, tran)
  5. 5.Add a `hardcopy` command to write SVG plots to `testbench/output/<scenario>.svg` with relevant signal names and labels

Use cases

Good for
  • Validate startup behavior of a power supply by simulating DC ramp and transient response
  • Test enable/disable switching with PULSE waveforms to verify timing and settling
  • Sweep input voltage across protection thresholds (OVLO/UVLO) using PWL sources
  • Verify load regulation by simulating step changes in load resistance
  • Confirm component SPICE model integration before layout by running a dummy sim
Who it's for
  • PCB design engineers validating circuit behavior before fabrication
  • Firmware developers testing power delivery and protection circuits
  • Hardware teams verifying component models and datasheets against simulation

spice-sim FAQ

What ngspice commands are supported in the setup string?

DC sources, PULSE and PWL waveforms, .control blocks, tran (transient) analysis, and hardcopy (SVG plot export). Raw ngspice syntax is passed through directly.

How do I add a SPICE model to a component?

Use the `spice_model=SpiceModel("model.lib", "SUBCKT_NAME", nets=[...], args={})` parameter on the Component definition, referencing the `.lib` file and subcircuit name.

Should I keep passive components in Zener or in the SPICE setup?

Keep passives (resistors, capacitors) in Zener as normal components; keep voltage sources and waveform definitions in the `setup` string.

How do I organize multiple test scenarios?

Create separate testbench files for each scenario (e.g., `test_startup.zen`, `test_ovlo.zen`) in `testbench/` and name output plots accordingly.

What signals should I plot?

Plot only the signals that prove the behavior being tested—typically input and output voltages, enable signals, or protection thresholds.

Full instructions (SKILL.md)

Source of truth, from diodeinc/pcb.


name: spice-sim description: Adds an ngspice-backed simulation testbench to a Zener .zen design. Use when the user asks to simulate a circuit, validate behavior in SPICE, or wire a spice_model=SpiceModel(...) into a leaf component. Covers pcb sim, Simulation property, and ngspice .control blocks with tran/PULSE/PWL sources and SVG hardcopy output.

Spice Simulation

Add a small ngspice-backed testbench to a .zen design.

Workflow

  1. Confirm the target is simulation-capable by running a dummy sim. pcb sim <path/to/file.zen> --setup "* empty setup check"

  2. If the SPICE model is missing, add it. Find a vendor model, download it, or create a simple behavioral model if needed. Wire it through the leaf component with spice_model=SpiceModel(...) before writing the testbench.

  3. Create a focused testbench file. Use a generic package-local path such as <package>/testbench/test_<scenario>.zen.

  4. Keep the structure simple:

  • top docstring
  • imports
  • nets/interfaces
  • module-under-test instantiation
  • minimal external load or pull-ups
  • one Simulation(...) block
  1. Put sources and analysis inside Simulation.setup. Use raw ngspice for:
  • DC
  • PULSE(...)
  • PWL(...)
  • .control
  • tran
  • hardcopy
  1. Write the plot to testbench/output/<scenario>.svg.

Simulation In Zener

Simulation is a Zener property loaded from @stdlib/properties.zen and attached as a normal top-level object:

load("@stdlib/properties.zen", "Simulation")

Simulation(
    name="SIM",
    setup="""
* raw ngspice goes here
.control
  tran 10u 10m
.endc
""",
)

The setup string is passed through as ngspice input. Put voltage sources, waveform definitions, analysis commands, and plot/export commands there.

Pattern

"""<Part> <scenario> simulation test."""

load("@stdlib/properties.zen", "Simulation")

Target = Module("../Target.zen")
Resistor = Module("@stdlib/generics/Resistor.zen")

VIN = Power(voltage="12V")
VOUT = Power()
GND = Ground()

Target(
    name="UUT",
    VIN=VIN,
    VOUT=VOUT,
    GND=GND,
)

Resistor(
    name="R_LOAD",
    value="10ohm",
    package="0603",
    P1=VOUT,
    P2=GND,
)

Simulation(
    name="SIM",
    setup="""
* <Part> <scenario>

V_IN VIN GND DC 12

.control
  tran 10u 10m

  set hcopydevtype = svg
  hardcopy output/<scenario>.svg v(VIN) v(VOUT) title "<Part> <scenario>" xlabel "Time" ylabel "Voltage"
.endc

""",
)

Component Pattern

If the leaf component does not already expose a SPICE model, add one like this:

VIN = io(Power())
VOUT = io(Power())
GND = io(Ground())

Component(
    name="MyPart",
    symbol=Symbol(library="MyPart.kicad_sym"),
    pins={"VIN": VIN, "VOUT": VOUT, "GND": GND},
    spice_model=SpiceModel(
        "MyPart.lib",
        "MyPart_SUBCKT",
        nets=[VIN, VOUT, GND],
        args={},
    ),
)

Example Shapes

Load switch enable test:

V_IN VIN GND DC 5.3
V_ON ON GND PULSE(0 0.9V 1ms 10us 10us 3ms 5ms)

Protection threshold sweep:

V_IN VIN GND PWL(0 12 5m 12 5.1m 22 10m 22 10.1m 12 15m 12 15.1m 2 20m 2)

Notes

  • Prefer one behavior per file: startup, enable/disable, OVLO/UVLO, current limit.
  • Keep passives in Zener and keep sources in setup.
  • Plot only the signals that prove the behavior.
  • If a SPICE model is missing, obtain or create it first, then add the testbench.