<jupyter_start><jupyter_text>SPICE simulation using Python  Agenda1. Motivation 2. Comparison PySpice vs. ahkab    * Butterworth Filter in NgSpice    * Butterworth Filter in ahkab3. Handson & examples    * P2 - Advanced Butterworth Filter analysis (ahkab)    * P3 - Transient simulation of a Colpitts oscillator (ahkab)    * P4 - Small-signal transfer function of an opamp integrator (ahkab)    * P5 - Basic OpAmp AC-simulation (NgSpice)    * P6 - CMOS-Ring Oscillator (NgSpice)  Motivation * Develop in a familiar environment* Tons of Libraries for post-processing* Large community* Inexpensive* (Automatic) generation and verification of schematics          PySpice   + Frontend for ngspice   + Mature open source simulator in the background  + Easy to simulate external spice (i.e from KiCad)  + Good integration into python    + all data-types derive from numpy  - ngspice need to be compiled on each computer<jupyter_code>import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

from PySpice.Probe.Plot import plot
from PySpice.Spice.Netlist import Circuit
from PySpice.Spice.Library import SpiceLibrary
from PySpice.Spice.Parser import SpiceParser
from PySpice.Unit import *<jupyter_output><empty_output><jupyter_text>ahkab  + based on numpy  + easy to distripute to simulation to multiple machines  + Not very mature   + Not lots of device libraries available<jupyter_code>from ahkab import new_ac, new_op, new_tran, run
from ahkab.circuit import Circuit
from ahkab.plotting import plot_results # calls matplotlib for you
from ahkab import printing, time_functions<jupyter_output><empty_output><jupyter_text>Butterworth Filter (ahkab)  Schematic![Butterworth Filter](./pictures/butterworth_dp.svg)<jupyter_code>%matplotlib inline
import os

# print(os.environ['PATH'])

import numpy as np
from scipy.fftpack import fft

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

from ahkab import new_ac, new_op, new_tran, run
from ahkab.circuit import Circuit
from ahkab.plotting import plot_results # calls matplotlib for you
from ahkab import printing, time_functions
import numpy as np
# Create circuit element
cir = Circuit(title="Butterworth Low-pass filter")

gnd = cir.get_ground_node()

# Add voltage source
voltage_step = time_functions.pulse(v1=0, v2=1, td=500e-9, tr=1e-12, pw=1, tf=1e-12, per=2)
cir.add_vsource("V1", n1="n1", n2=gnd, dc_value=5, ac_value=1, function=voltage_step)

# Define circuit
cir.add_resistor("R1", n1="n1", n2="n2", value=600)
cir.add_inductor("L1", n1="n2", n2="n3", value=15.24e-3)
cir.add_capacitor("C1", n1="n3", n2=gnd, value=119.37e-9)
cir.add_inductor("L2", n1="n3", n2="n4", value=61.86e-3)
cir.add_capacitor("C2", n1="n4", n2=gnd, value=155.12e-9)
cir.add_resistor("R2", n1="n4", n2=gnd, value=1.2e3)

# Define the analysis
ac1 = new_ac(1e3, 1.0e4, 1e2, x0=None)

# run the simulation
res = run(cir, ac1)

#Print spice netlist
print(cir)

#play with results:
print(res['ac'].keys())
print(res['ac']['Vn4'][0:10])
# Plot:
figure = plt.figure(figsize=[15,8],dpi=100)
axe = plt.subplot(211)
axe.set_title('Butterworth Low-pass filter')
axe.set_xlabel('Frequency [1/s]')
axe.set_ylabel('Voltage [V]')
#plt.grid(True)
axe.semilogx(res['ac']['f'], np.abs(res['ac']['Vn4']), '-')
axe.grid(True)
axe = plt.subplot(212)
axe.semilogx(res['ac']['f'], np.angle(res['ac']['Vn4']), '-')
axe.set_xlabel('Frequency [rad/s]')
axe.set_ylabel('Angle [rad]')
axe.grid(True)
ak_dat = res['ac']['Vn4']
ak_f = res['ac']['f']<jupyter_output><empty_output><jupyter_text>Butterworth Filter (NgSpice)<jupyter_code>%matplotlib inline
import os

# print(os.environ['PATH'])

import numpy as np
from scipy.fftpack import fft

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

from PySpice.Probe.Plot import plot
from PySpice.Spice.Netlist import Circuit
from PySpice.Spice.Library import SpiceLibrary
from PySpice.Spice.Parser import SpiceParser
from PySpice.Unit import *
# Create circuit element
cir = Circuit("Butterworth Low-pass filter")

# Add voltage source
cir.Sinusoidal('V1', 'n1', cir.gnd, amplitude=1@u_V)

# Define circuit
cir.R(1, 'n1', 'n2', 600)
cir.L(1, 'n2', 'n3', 15.24e-3)
cir.C(1, 'n3', cir.gnd, nano(119.37))
cir.L(2, 'n3', 'n4', 61.86e-3)
cir.C(2, 'n4', cir.gnd, nano(155.12))
cir.R(2, 'n4', cir.gnd, kilo(1.2))

# Define the analysis and run the simulation
simulator = cir.simulator(temperature=25, nominal_temperature=25)
analysis = simulator.ac(start_frequency=1@u_kHz, stop_frequency=10@u_kHz, number_of_points=100,  variation='dec')

print(str(cir))
#print(analysis.nodes)
#x = analysis['n4']
#print(x.tolist()[0:10])
# Plot:
figure = plt.figure(figsize=[15,8],dpi=100)
axe = plt.subplot(211)
axe.set_title('Butterworth Low-pass filter')
axe.set_xlabel('Frequency [1/s]')
axe.set_ylabel('Voltage [V]')
#plt.grid(True)
axe.semilogx(analysis.frequency, np.abs(analysis['n4']), '-')
axe.grid(True)
axe = plt.subplot(212)
axe.semilogx(analysis.frequency, np.angle(analysis['n4']), '-')
axe.set_xlabel('Frequency [rad/s]')
axe.set_ylabel('Angle [rad]')
axe.grid(True)
# ak_dat = res['ac']['Vn4']
# ak_f = res['ac']['f']
prin
np.abs(analysis['n4'])/(np.abs(analysis['n4'])+np.abs(ak_dat))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14547862277714718, 'fraction_numerical': 0.03594400302686341, 'mean_word_length': 5.984147952443857, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '178834', 'license': 'MIT', 'n_tokens_mistral': 2138, 'n_tokens_neox': 2052, 'n_words': 471, 'path': 'P0-Presentation.ipynb', 'repo_name': 'm1ch/pysim', 'size': '5286'}