Run SPICE circuits as blocks inside your existing Verilog simulation.
SpiceBind embeds ngspice into a VPI-capable HDL simulator. Replace only the blocks that need circuit-level simulation. RTL, testbench, cocotb, and the digital verification flow stay in the HDL simulator.
It is useful for mixed-signal simulation in general, and especially when the digital part is large.
SpiceBind is an early project. It is tested with Icarus Verilog, Verilator, and ngspice. The plugin uses VPI, so it is not tied to those two HDL simulators, but others have not been qualified.
The spi_adc example above crosses the HDL/SPICE boundary in both directions. vin is passed from HDL into ngspice, the ADC code is calculated by the SPICE model, and HDL logic shifts the result out over SPI.
- RTL, testbenches, cocotb, and digital simulation stay in the HDL simulator you already use. You do not have to move the design into a mixed-signal environment.
- The plugin uses standard VPI, so it can attach to open-source or commercial HDL simulators. It is tested with Icarus Verilog and Verilator. Other VPI-capable simulators still need qualification. You can change the simulator without changing the RTL, testbench, or how SpiceBind maps instances.
- Selected HDL instances can be backed by transistor-level or analog SPICE models. The rest of the design stays RTL.
- HDL events stay in lock-step with ngspice adaptive timesteps, including events that fall inside an analog step.
A mixed-signal design is often mostly RTL with a few analog blocks. Putting the whole system under SPICE can mean rewriting the testbench and how the digital part is simulated.
%%{init: {
'theme': 'base',
'themeVariables': {
'lineColor': '#22808f',
'textColor': '#1c3d42',
'fontSize': '14px'
}
}}%%
flowchart LR
TB["Testbench / cocotb\n{test.v} / {test.py}"]:::tb
subgraph DUT["Design Under Test\n {dut.v}"]
direction LR
ADC["ADC (stub)\n{adc.v}"]:::hdl
FE["Sensor (stub)\n{sensor.v}"]:::hdl
DD["\n\nDigital Design\n{core.v}\n\n\n"]:::hdl
DD <--> ADC
DD <--> FE
end
SB["SpiceBind<br/>time synchronization<br/>D/A + A/D"]:::bridge
subgraph NG["ngspice"]
direction LR
ADCSP["ADC (SPICE)\n{adc.cir}"]:::analog
FESP["Sensor (SPICE)\n{sensor.cir}"]:::analog
end
TB <--> DUT
DUT <-->|VPI| SB
SB <-->|libngspice| NG
%% Custom Class Definitions based on SVG Palette
classDef hdl fill:#eef7f8,stroke:#22808f,stroke-width:2.5px,color:#1c3d42,font-weight:bold;
classDef analog fill:#fff5eb,stroke:#d9772b,stroke-width:2.5px,color:#b8540a,font-weight:bold;
classDef bridge fill:#e07a2d,stroke:#e07a2d,color:#ffffff,stroke-width:2px,font-weight:bold;
classDef tb fill:#fcfbb4,stroke:#d1ce00,stroke-width:2.5px,color:#1c3d42,font-weight:bold;
%% Subgraph Styles
style DUT fill:#ffffff,stroke:#22808f,stroke-width:2.5px,color:#22808f
style NG fill:#ffffff,stroke:#d9772b,stroke-width:2.5px,color:#d9772b
style DD fill:#ffffff,stroke:#22808f,stroke-width:2.5px,color:#22808f
The HDL side sees a normal module instance. The module body can be empty. SpiceBind finds the selected instance through VPI and connects its ports to sources and nodes in the SPICE circuit.
Digital-to-analog values go to ngspice through external voltage sources. Analog results are read back and driven onto the corresponding HDL outputs.
The two simulators have independent event and timestep mechanisms, so exchanging values is not enough. SpiceBind also keeps simulation time in lock-step. VPI callbacks detect HDL events, ngspice callbacks report analog progress, and a time barrier stops either engine from running ahead. If an HDL event lands inside an ngspice step, ngspice repeats that step at the event time.
See the timing synchronization documentation.
- C++17 compiler (needed to build the VPI plugin)
- ngspice shared library and development headers
- Verilog VPI compatible simulator (tested with Icarus Verilog and Verilator 5)
- Python 3.10+
On Debian/Ubuntu:
sudo apt install build-essential cmake iverilog ngspice libngspice0-dev python3-venvIcarus Verilog from that package set is enough to run the examples. Verilator needs a recent 5.x build with --timing and --vpi (CI compiles it from git; distro packages are often too old).
Install the released package:
pip install spicebindIf ngspice is not on PATH, point CMake at its install prefix (include/ and lib/):
NGSPICE_ROOT=/path/to/ngspice pip install spicebindRun the SPI ADC example (Icarus Verilog by default; SIM=verilator selects Verilator):
python examples/spi_adc/test_spi_adc.py
SIM=verilator python examples/spi_adc/test_spi_adc.pyFor development:
git clone https://github.com/themperek/spicebind.git
cd spicebind
pip install -e ".[dev]"Standalone VPI build (no Python package):
cmake -S . -B build # optional: -DNGSPICE_ROOT=/path/to/ngspice
cmake --build build
cmake --build build --target debug # Optional: debug VPIThe HDL contains a module with the interface that the rest of the design expects:
module adc_core(
input real vin,
output [7:0] code,
input range0,
input range1
);
// implemented in SPICE
endmoduleThe corresponding SPICE netlist provides external sources for HDL inputs and nodes for HDL outputs:
Vvin vin 0 0 external
Vrange0 range0 0 0 external
Vrange1 range1 0 0 external
* Analog implementation
Xadc vin ref vcc code[7] code[6] code[5] code[4] code[3] code[2] code[1] code[0] adc_ideal_8bit
.tran 1ns 100us
.end
At runtime, select the netlist and HDL instance:
export SPICE_NETLIST=examples/spi_adc/spi_adc.cir
export HDL_INSTANCE=spi_adc.adc_inst
export VCC=3.3The VPI module can then be loaded by the HDL simulator.
Icarus Verilog:
vvp -M "$(spicebind-vpi-path)" -m spicebind_vpi simulation.vvpVerilator (--vpi --timing); pass the plugin as a plusarg:
./Vtop +verilator+vpi+"$(spicebind-vpi-path)/spicebind_vpi.vpi"The examples use the cocotb runner or small shell scripts to set this up automatically. $SIM selects the HDL simulator (icarus default, or verilator). The full suite is nox -s test (see CONTRIBUTING.md).
| Variable | Meaning |
|---|---|
SPICE_NETLIST |
Path to the ngspice netlist |
HDL_INSTANCE |
HDL instance path, or a comma-separated list of instance paths |
VCC |
Voltage used for digital-to-analog conversion. Default: 1.0 |
SPICE_DUMP_RAW |
Write ngspice transient data to dump.raw at shutdown |
| Example | What it shows |
|---|---|
examples/adc |
8-bit ADC with Verilog and cocotb testbenches |
examples/adder_mos |
Four-bit CMOS adder derived from the ngspice MOS adder example |
examples/spi_adc |
HDL SPI interface connected to an ADC implemented in SPICE |
examples/serv_dco_calibration |
SERV firmware calibrates a transistor-level DCO through SpiceBind |
There are several ways to combine HDL and SPICE. They differ mainly in which simulator owns the top level and how the digital part is executed.
| Approach | Top-level environment | Digital execution | Analog engine | What it does |
|---|---|---|---|---|
| SpiceBind | HDL simulator | Normal HDL simulation | ngspice shared library | Selected HDL instances are replaced by SPICE while the HDL flow stays in place |
ngspice d_cosim |
ngspice / XSPICE | HDL compiled with Verilator, Icarus Verilog, or GHDL and loaded as an XSPICE model | ngspice | SPICE-first flow with HDL blocks inside the ngspice netlist |
| Yosys to XSPICE | ngspice / XSPICE | Synthesizable RTL mapped to XSPICE gates and storage elements | ngspice | One simulator at runtime, but the RTL is reduced to synthesized logic |
cocotbext-ams |
cocotb / Python | Normal HDL simulator through cocotb | ngspice or Xyce | Python coordinates the HDL and analog simulators |
A SPICE-first flow fits when the analog netlist is already the top level. Synthesizing RTL into XSPICE avoids synchronizing two simulators at runtime. SpiceBind is for the other case: a digital simulation already exists and only selected blocks need SPICE.
Commercial Verilog-AMS and real-number-modeling flows are not compared here.
SpiceBind currently focuses on:
- ngspice as the analog engine
- Verilog through VPI
- Icarus Verilog and Verilator as the tested HDL simulators
- binding selected HDL instances to SPICE
- event and timestep synchronization between HDL and ngspice
- cocotb compatibility, without requiring cocotb
The VPI plugin is not tied to those two HDL simulators, but others have not been tested.
Tutorials, configuration, API notes, and timing:
https://themperek.github.io/spicebind/
OrConf 2026: SpiceBind: Bringing SPICE into RTL Verification. Slides (PDF).
Bug reports, examples, and pull requests are welcome. Use the GitHub issue tracker for bugs, questions, and feature proposals.
SpiceBind is distributed under the BSD 3-Clause License. See LICENSE.
SpiceBind is developed with assistance from generative AI tools. All generated or modified code is reviewed, tested, and maintained like any other contribution.
