DC Sweep Analysis#
Compute the DC operating point while sweeping an independent source.
import os
import sys
from pathlib import Path
# Set working directory to the PDK root if running from scripts/
if Path.cwd().name == "scripts":
os.chdir(Path.cwd().parent)
# Ensure ngspice shared library can be found (macOS homebrew)
if sys.platform == "darwin" and "/opt/homebrew/lib" not in os.environ.get(
"DYLD_LIBRARY_PATH", ""
):
os.environ["DYLD_LIBRARY_PATH"] = "/opt/homebrew/lib:" + os.environ.get(
"DYLD_LIBRARY_PATH", ""
)
import numpy as np
import pandas as pd
import holoviews as hv
from nyancad.watch import watch_project_dir, file_schematic
from nyancad.netlist import inspice_netlist
from nyancad.plot import sweepplot
from InSpice import Simulator
hv.extension("bokeh")
Parameters#
SCHEMATIC = "inverter" # stem of the .nyancir file
CORNER = "mos_tt"
# -- DC sweep parameters --
SOURCE = "VV2" # name of the source to sweep
START = 0 # start value (V or A)
STOP = 5 # stop value (V or A)
STEP = 0.1 # step size
# -- Vectors to plot --
# Leave empty to auto-select all node voltages after simulation.
VECTORS = []
Load schematic and build netlist#
project = watch_project_dir(".")
schem_data = await file_schematic(project, SCHEMATIC)
spice = await inspice_netlist(SCHEMATIC, schem_data, corner=CORNER)
print(spice)
Duplicated lib ('ihp/models/ngspice/models/cornerMOSlv.lib', 'mos_tt')
.title schematic
.lib /Users/pepijndevos/code/IHP/ihp/models/ngspice/models/cornerMOSlv.lib mos_tt
VV1 W2 GND DC 1.8
VV2 W3 GND DC 0.9 AC 1 sin(0.9 0.5 1k)
XM1 W6 W3 GND GND sg13_lv_nmos l={0.13 * 1e-6} m=1 ng=1 w={0.15 * 1e-6}
XM2 W2 W3 W6 W2 sg13_lv_pmos l={0.13 * 1e-6} m=1 ng=1 w={0.15 * 1e-6}
CC1 W6 GND 1u
print("Netlist nodes:", list(spice.node_names))
print("Netlist elements:", list(spice.element_names))
Netlist nodes: ['0', 'W2', 'GND', 'W3', 'W6']
Netlist elements: ['VV1', 'VV2', 'XM1', 'XM2', 'CC1']
Run DC sweep#
simulator = Simulator.factory(simulator="ngspice-shared")
for osdi in [
"ihp/models/ngspice/osdi/psp103.osdi",
"ihp/models/ngspice/osdi/psp103_nqs.osdi",
"ihp/models/ngspice/osdi/r3_cmc.osdi",
"ihp/models/ngspice/osdi/mosvar.osdi",
]:
simulator._ngspice_shared.exec_command(f"osdi {osdi}")
simulation = simulator.simulation(spice)
analysis = simulation.dc(**{SOURCE: slice(START, STOP, STEP)})
print("DC sweep complete.")
Warning: can't find the initialization file spinit.
Newer Ngspice version that could be unsupported 46
DC sweep complete.
Results#
available = [*analysis.nodes.keys(), *analysis.branches.keys()]
print("Available vectors:", available)
if not VECTORS:
VECTORS = list(analysis.nodes.keys())
print("Auto-selected:", VECTORS)
df = pd.DataFrame(index=np.array(analysis.sweep))
for vec in VECTORS:
df[vec] = np.array(analysis[vec])
df
Available vectors: ['n.xm1.nsg13_lv_nmos#SI', 'n.xm1.nsg13_lv_nmos#GP', 'n.xm1.nsg13_lv_nmos#NOI', 'n.xm2.nsg13_lv_pmos#SI', 'n.xm2.nsg13_lv_pmos#GP', 'n.xm2.nsg13_lv_pmos#NOI', 'w6', 'w3', 'w2', 'v-sweep', 'vv1', 'vv2']
Auto-selected: ['n.xm1.nsg13_lv_nmos#SI', 'n.xm1.nsg13_lv_nmos#GP', 'n.xm1.nsg13_lv_nmos#NOI', 'n.xm2.nsg13_lv_pmos#SI', 'n.xm2.nsg13_lv_pmos#GP', 'n.xm2.nsg13_lv_pmos#NOI', 'w6', 'w3', 'w2', 'v-sweep']
| n.xm1.nsg13_lv_nmos#SI | n.xm1.nsg13_lv_nmos#GP | n.xm1.nsg13_lv_nmos#NOI | n.xm2.nsg13_lv_pmos#SI | n.xm2.nsg13_lv_pmos#GP | n.xm2.nsg13_lv_pmos#NOI | w6 | w3 | w2 | v-sweep | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0.0 | 0.0 | 6.965056e-10 | 0.0 | 0.0 | 1.376240e-10 | 0.0 | 1.800000e+00 | 0.0 | 1.8 | 0.0 |
| 0.1 | 0.0 | 1.000000e-01 | 0.0 | 0.0 | 1.000000e-01 | 0.0 | 1.800000e+00 | 0.1 | 1.8 | 0.1 |
| 0.2 | 0.0 | 2.000000e-01 | 0.0 | 0.0 | 2.000000e-01 | 0.0 | 1.799994e+00 | 0.2 | 1.8 | 0.2 |
| 0.3 | 0.0 | 3.000000e-01 | 0.0 | 0.0 | 3.000000e-01 | 0.0 | 1.799899e+00 | 0.3 | 1.8 | 0.3 |
| 0.4 | 0.0 | 4.000000e-01 | 0.0 | 0.0 | 4.000000e-01 | 0.0 | 1.798347e+00 | 0.4 | 1.8 | 0.4 |
| 0.5 | 0.0 | 5.000000e-01 | 0.0 | 0.0 | 5.000000e-01 | 0.0 | 1.785391e+00 | 0.5 | 1.8 | 0.5 |
| 0.6 | 0.0 | 6.000000e-01 | 0.0 | 0.0 | 6.000000e-01 | 0.0 | 1.739928e+00 | 0.6 | 1.8 | 0.6 |
| 0.7 | 0.0 | 7.000000e-01 | 0.0 | 0.0 | 7.000000e-01 | 0.0 | 1.629709e+00 | 0.7 | 1.8 | 0.7 |
| 0.8 | 0.0 | 8.000000e-01 | 0.0 | 0.0 | 8.000000e-01 | 0.0 | 1.084613e+00 | 0.8 | 1.8 | 0.8 |
| 0.9 | 0.0 | 9.000000e-01 | 0.0 | 0.0 | 9.000000e-01 | 0.0 | 1.621298e-01 | 0.9 | 1.8 | 0.9 |
| 1.0 | 0.0 | 1.000000e+00 | 0.0 | 0.0 | 1.000000e+00 | 0.0 | 6.295796e-02 | 1.0 | 1.8 | 1.0 |
| 1.1 | 0.0 | 1.100000e+00 | 0.0 | 0.0 | 1.100000e+00 | 0.0 | 2.906256e-02 | 1.1 | 1.8 | 1.1 |
| 1.2 | 0.0 | 1.200000e+00 | 0.0 | 0.0 | 1.200000e+00 | 0.0 | 1.207761e-02 | 1.2 | 1.8 | 1.2 |
| 1.3 | 0.0 | 1.300000e+00 | 0.0 | 0.0 | 1.300000e+00 | 0.0 | 3.685119e-03 | 1.3 | 1.8 | 1.3 |
| 1.4 | 0.0 | 1.400000e+00 | 0.0 | 0.0 | 1.400000e+00 | 0.0 | 5.700681e-04 | 1.4 | 1.8 | 1.4 |
| 1.5 | 0.0 | 1.500000e+00 | 0.0 | 0.0 | 1.500000e+00 | 0.0 | 3.810609e-05 | 1.5 | 1.8 | 1.5 |
| 1.6 | 0.0 | 1.600000e+00 | 0.0 | 0.0 | 1.600000e+00 | 0.0 | 2.139360e-06 | 1.6 | 1.8 | 1.6 |
| 1.7 | 0.0 | 1.700000e+00 | 0.0 | 0.0 | 1.700000e+00 | 0.0 | 1.429718e-07 | 1.7 | 1.8 | 1.7 |
| 1.8 | 0.0 | 1.800000e+00 | 0.0 | 0.0 | 1.800000e+00 | 0.0 | 4.057214e-08 | 1.8 | 1.8 | 1.8 |
| 1.9 | 0.0 | 1.900000e+00 | 0.0 | 0.0 | 1.900000e+00 | 0.0 | 5.167813e-08 | 1.9 | 1.8 | 1.9 |
| 2.0 | 0.0 | 2.000000e+00 | 0.0 | 0.0 | 2.000000e+00 | 0.0 | 7.708216e-08 | 2.0 | 1.8 | 2.0 |
| 2.1 | 0.0 | 2.100000e+00 | 0.0 | 0.0 | 2.100000e+00 | 0.0 | 1.130805e-07 | 2.1 | 1.8 | 2.1 |
| 2.2 | 0.0 | 2.200000e+00 | 0.0 | 0.0 | 2.200000e+00 | 0.0 | 1.619090e-07 | 2.2 | 1.8 | 2.2 |
| 2.3 | 0.0 | 2.300000e+00 | 0.0 | 0.0 | 2.300000e+00 | 0.0 | 2.263713e-07 | 2.3 | 1.8 | 2.3 |
| 2.4 | 0.0 | 2.400000e+00 | 0.0 | 0.0 | 2.400000e+00 | 0.0 | 3.094189e-07 | 2.4 | 1.8 | 2.4 |
| 2.5 | 0.0 | 2.500000e+00 | 0.0 | 0.0 | 2.500000e+00 | 0.0 | 4.140394e-07 | 2.5 | 1.8 | 2.5 |
| 2.6 | 0.0 | 2.600000e+00 | 0.0 | 0.0 | 2.600000e+00 | 0.0 | 5.431828e-07 | 2.6 | 1.8 | 2.6 |
| 2.7 | 0.0 | 2.700000e+00 | 0.0 | 0.0 | 2.700000e+00 | 0.0 | 6.997208e-07 | 2.7 | 1.8 | 2.7 |
| 2.8 | 0.0 | 2.800000e+00 | 0.0 | 0.0 | 2.800000e+00 | 0.0 | 8.864527e-07 | 2.8 | 1.8 | 2.8 |
| 2.9 | 0.0 | 2.900000e+00 | 0.0 | 0.0 | 2.900000e+00 | 0.0 | 1.106181e-06 | 2.9 | 1.8 | 2.9 |
| 3.0 | 0.0 | 3.000000e+00 | 0.0 | 0.0 | 3.000000e+00 | 0.0 | 1.362042e-06 | 3.0 | 1.8 | 3.0 |
| 3.1 | 0.0 | 3.100000e+00 | 0.0 | 0.0 | 3.100000e+00 | 0.0 | 1.657197e-06 | 3.1 | 1.8 | 3.1 |
| 3.2 | 0.0 | 3.200000e+00 | 0.0 | 0.0 | 3.200000e+00 | 0.0 | 1.995189e-06 | 3.2 | 1.8 | 3.2 |
| 3.3 | 0.0 | 3.300000e+00 | 0.0 | 0.0 | 3.300000e+00 | 0.0 | 2.379896e-06 | 3.3 | 1.8 | 3.3 |
| 3.4 | 0.0 | 3.400000e+00 | 0.0 | 0.0 | 3.400000e+00 | 0.0 | 2.819709e-06 | 3.4 | 1.8 | 3.4 |
| 3.5 | 0.0 | 3.500000e+00 | 0.0 | 0.0 | 3.500000e+00 | 0.0 | 3.327254e-06 | 3.5 | 1.8 | 3.5 |
| 3.6 | 0.0 | 3.600000e+00 | 0.0 | 0.0 | 3.600000e+00 | 0.0 | 3.908957e-06 | 3.6 | 1.8 | 3.6 |
| 3.7 | 0.0 | 3.700000e+00 | 0.0 | 0.0 | 3.700000e+00 | 0.0 | 4.571385e-06 | 3.7 | 1.8 | 3.7 |
| 3.8 | 0.0 | 3.800000e+00 | 0.0 | 0.0 | 3.800000e+00 | 0.0 | 5.321231e-06 | 3.8 | 1.8 | 3.8 |
| 3.9 | 0.0 | 3.900000e+00 | 0.0 | 0.0 | 3.900000e+00 | 0.0 | 6.165291e-06 | 3.9 | 1.8 | 3.9 |
| 4.0 | 0.0 | 4.000000e+00 | 0.0 | 0.0 | 4.000000e+00 | 0.0 | 7.110448e-06 | 4.0 | 1.8 | 4.0 |
| 4.1 | 0.0 | 4.100000e+00 | 0.0 | 0.0 | 4.100000e+00 | 0.0 | 8.163651e-06 | 4.1 | 1.8 | 4.1 |
| 4.2 | 0.0 | 4.200000e+00 | 0.0 | 0.0 | 4.200000e+00 | 0.0 | 9.331901e-06 | 4.2 | 1.8 | 4.2 |
| 4.3 | 0.0 | 4.300000e+00 | 0.0 | 0.0 | 4.300000e+00 | 0.0 | 1.062224e-05 | 4.3 | 1.8 | 4.3 |
| 4.4 | 0.0 | 4.400000e+00 | 0.0 | 0.0 | 4.400000e+00 | 0.0 | 1.204171e-05 | 4.4 | 1.8 | 4.4 |
| 4.5 | 0.0 | 4.500000e+00 | 0.0 | 0.0 | 4.500000e+00 | 0.0 | 1.359740e-05 | 4.5 | 1.8 | 4.5 |
| 4.6 | 0.0 | 4.600000e+00 | 0.0 | 0.0 | 4.600000e+00 | 0.0 | 1.529636e-05 | 4.6 | 1.8 | 4.6 |
| 4.7 | 0.0 | 4.700000e+00 | 0.0 | 0.0 | 4.700000e+00 | 0.0 | 1.714565e-05 | 4.7 | 1.8 | 4.7 |
| 4.8 | 0.0 | 4.800000e+00 | 0.0 | 0.0 | 4.800000e+00 | 0.0 | 1.915229e-05 | 4.8 | 1.8 | 4.8 |
| 4.9 | 0.0 | 4.900000e+00 | 0.0 | 0.0 | 4.900000e+00 | 0.0 | 2.132329e-05 | 4.9 | 1.8 | 4.9 |
| 5.0 | 0.0 | 4.999999e+00 | 0.0 | 0.0 | 5.000000e+00 | 0.0 | 2.366559e-05 | 5.0 | 1.8 | 5.0 |
sweepplot(df).opts(responsive=True, height=500)