| src | ||
| tests | ||
| .gitignore | ||
| index.rst | ||
| ngspice.nimble | ||
| readme.org | ||
readme
Nim wrapper for ngspice library - simulation of analog circuits.
Installation
nimble install ngspice
This library is a wrapper for ngspice C library - you need to have it installed.
nim API
C api for ngspice is based on callbacks - you provide several functions and textual description of the netlist. Callback functions are used for reporting simulation progress.
ngspice provides two APis - synchronous and asynchronous. Only first one is implemented.
Netlist syntax description
For full documentation of ngspice netlist syntax see manual and glossary for list of terms. Only brief outline is presented here.
If you are familliar with spice/ngspice circuit netlist you can skip this section.
Ngspice netlist is a textual description of circuit graph. In most
cases each element (card) is put on its own line, in form of
<ElementType><Idx> <connector-1> <connector-2> <... arguments ...>.
For example 5V voltage source between terminals 0 and 1 will be
written as V1 0 1 5.
To perform actual simulation you need to add simulation command in the
netlist. For example, If I want to perform DC simulation of voltage
source V1, with voltage in range [0-5], step 1 I will need to
add .dc v1 0 5 1.
Use example
import ngspice
import strformat
ngspiceInit(
printfcn = ( # Callback for printing regular output of the simulation
proc(msg: string, a2: int): int = echo "@ ", msg
).addPtr(),
statfcn = ( # Callback for printing simulation progress
proc(msg: string, a2: int): int = echo "# ", msg
).addPtr(),
sdata = # Callback after simulation of new vector completed
proc(vdata: VecValuesAll, a2: int, a3: int, a4: pointer): int =
echo &"Processed {vdata.vecindex}/{vdata.veccount} vectors"
)
ngSpiceCirc(
@[ # terminal ~0~ is used as ground
"V1 0 1 5", # Voltage source
"V2 0 2 5",
"R1 0 1 10", # Resistor
"R2 0 2 10",
".dc v1 0 5 1" # DC simulation in range [0-5] volts
]
)
ngSpice_Command("run"); # Run execute command to run simulation
let cp: string = ngSpiceCurPlot() # Get name of current simulation
# plot (collection of
for vec in ngSpiceAllVecs(cp):
let res: NGVectorInfo = ngGetVecInfo(cp & "." & vec)
echo vec, ": ", res.realdata # voltage between group and each terminal
echo "done"
@ stdout ****** @ stdout ** ngspice-32 shared library @ stdout ** Creation Date: Tue Jun 16 21:35:13 UTC 2020 @ stdout ****** # Source Deck @ stdout Circuit: circuit simulation # Prepare Deck # Circuit2 # Circuit2: 12.5% # Circuit2: 25.0% # Circuit2: 37.5% # Circuit2: 50.0% # Circuit2: 62.5% # Circuit2: 75.0% # Circuit2: 87.5% @ stdout Doing analysis at TEMP = 27.000000 and TNOM = 27.000000 # Device Setup Processed 0/5 vectors # dc: 20.0% Processed 1/5 vectors # dc: 40.0% Processed 2/5 vectors # dc: 60.0% Processed 3/5 vectors # dc: 80.0% Processed 4/5 vectors # --ready-- Processed 5/5 vectors # --ready-- @ stdout No. of Data Rows : 6 v1#branch: @[0.0, -0.1, -0.2, -0.3, -0.4, -0.5] v2#branch: @[-0.5, -0.5, -0.5, -0.5, -0.5, -0.5] V(2): @[-5.0, -5.0, -5.0, -5.0, -5.0, -5.0] V(1): @[0.0, -1.0, -2.0, -3.0, -4.0, -5.0] v-sweep: @[0.0, 1.0, 2.0, 3.0, 4.0, 5.0] done
Contribution & development
Todo
- add documentation for static wrappers for netlist description
- Document raspberry pi simulation unit test
If you have any question about implementation or usage feel free to join my discord server.