Thursday, July 25, 2024

using ngspice with the skywater pdk.

shout the last goodbye I have a terrible time getting ngspice-43 working with skywater 130. There's some weird stuff in the PDK models, as it definitely is still the "IBM way". Firstly, you need to comment out any includes for any devices that aren't working in the sky130.lib.spice file. For me, it was all of the nfet_05v0_nvt devices.
* .include "../cells/nfet_05v0_nvt/sky130_fd_pr__nfet_05v0_nvt__tt.corner.spice"
The next issue is that "decks" have the devices have .models as a units of 1 meter. If you take a look at the sky130_fd_pr__nfet_01v8.pm3.spice file, you see how the subcircut (subckt) is generated.
.subckt  sky130_fd_pr__nfet_01v8 d g s b
+ 
.param  l = 1 w = 1 ad = 0 as = 0 pd = 0 ps = 0 nrd = 0 nrs = 0 sa = 0 sb = 0 sd = 0 mult = 1 nf = 1.0
msky130_fd_pr__nfet_01v8 d g s b sky130_fd_pr__nfet_01v8__model l = {l} w = {w} ad = {ad} as = {as} pd = {pd} ps = {ps} nrd = {nrd} nrs = {nrs} sa = {sa} sb = {sb} sd = {sd} nf = {nf}
.model sky130_fd_pr__nfet_01v8__model.0 nmos
This means that you need to create a .spiceinit file the same directory where you run the simulation. For me, I did this:
* .spiceinit for use with Skywater PDK and ngspice KLU
set ngbehavior=hsa     ; set compatibility for reading PDK libs
set skywaterpdk        ; skip some checks for faster lib loading
set ng_nomodcheck      ; don't check the model parameters
set num_threads=8      ; CPU processor cores available
option noinit          ; don't print operating point data
option klu             ; select KLU as matrix solver
optran 0 0 0 100p 2n 0 ; don't use dc operating point, but transient op%    
If you've gotten this far, this is how I did the whole thing. You need to install git, ngspice-43 and have some time download the 45GiB that is the skywater PDK.
git clone https://github.com/google/skywater-pdk.git
cd skywater-pdk
git checkout main
git submodule init
git submodule update
In the same directory as the .spiceinit file, I made this inverter.sp file:
* Inverter simulation using SkyWater 130nm PDK
.lib "$HOME/skywater-pdk/libraries/sky130_fd_pr/latest/models/sky130.lib.spice" tt
* Power supply
VDD VDD 0 1.8
* Input voltage source
VIN IN 0 PULSE(0 1.8 0 1n 1n 10n 20n)
* NMOS transistor
X1 OUT IN 0 0 sky130_fd_pr__nfet_01v8 
* PMOS transistor
X2 OUT IN VDD VDD sky130_fd_pr__pfet_01v8 
* Load capacitor
CL OUT 0 1p

.control
* Run transient analysis
tran 0.1n 50n
* plot v(IN) v(OUT)
* Save the results
wrdata inverter_simulation.raw v(IN) v(OUT)
.endc
.end
You will get some interesting warnings. This includes that a "scale" value is set somewhere to make the models based on nanometers, instead of meters. running "ngspice -b inverter.sp" yields:
degs@kazan inverter % ngspice -b inverter.sp
Warning: can't find the initialization file spinit.
Warning: Optran step size potentially too large.

Note: Compatibility modes selected: hs a

Warning: m=xx on .subckt line will override multiplier m hierarchy!


Circuit: * inverter simulation using skywater 130nm pdk

option SCALE: Scale is set to 1e-06 for instance and model parameters
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

Using KLU as Direct Linear Solver
Note: Transient op started
Note: Transient op finished successfully
 Reference value :  0.00000e+00
No. of Data Rows : 535
Note: Simulation executed from .control section 
At this point, I used Python to read the raw file via "python plot.py inverter_simulation.raw" that is here:
import numpy as np
import matplotlib.pyplot as plt
import argparse

def read_and_plot(filename):
    # Load the data from the raw file
    data = np.loadtxt(filename)

    # Assuming the columns are:
    # Column 1: Time
    # Column 2: VIN
    # Column 3: Time again (redundant)
    # Column 4: VOUT

    time = data[:, 0]  # First column is time
    vin = data[:, 1]   # Second column is VIN
    vout = data[:, 3]  # Fourth column is VOUT

    # Plot the data
    plt.figure()
    plt.plot(time, vin, label='VIN')
    plt.plot(time, vout, label='VOUT')
    plt.xlabel('Time (s)')
    plt.ylabel('Voltage (V)')
    plt.title('Inverter Simulation')
    plt.legend()
    plt.grid(True)
    plt.show()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Plot ngspice simulation data.')
    parser.add_argument('filename', type=str, help='Path to the raw data file')
    args = parser.parse_args()

    read_and_plot(args.filename)
The results are wrong as I buggered up the netlist; however, it is actually functioning. This is a day that I will not get back. The bad graph is:

Monday, July 22, 2024

macports, building with all of the cores.

I noticed that I wasn't building on "all cores" with macports. The build.jobs addition to the command line makes it build... much faster.
port install inkscape build.jobs=8

Friday, July 19, 2024

pianobar with macports

I got stumped with default settings using pianobar (text-based Pandora client) under MacOS with macports. pianobar is highly configurable; however, something moved since I did this the last time and things did not work. it seems as if the name of the config file changed from pianobar.cfg to config.

mkdir -p ~/.config/pianobar
touch ~/.config/pianobar/config

You then can put your name and password in the file, such as

user = your@user.name
password = password

There are whole bunch of configurations for pianobar, and I sometimes tweak them.
One of the other things that you can do is remove your password explicitly from the config file. I use this:

password_command = gpg --decrypt ~/password