Skip to content

Session 2: Analog Basics

ngspice

Class page | Class recording

Assignments

First run Ngspice

Ngspice is the spice tool in the container. I have not used it before so I started by making it run the example net-list files. To run the program I did it using ngspice and.sp and two scope windows appeared.

firstrun_ngspice.jpeg

I looked at the net-list code and it looks like I'm looking at the input on the and gate marked a and b. And it's running wave form to test the truth table. This was the end of spiral 0. Next things to figure out:

  • how can I see the output

  • Read-up on Ngspice

Second run

I found a video that went trough a simple series resistor circuit it was just what I needed to understand how Ngspice worked. I then browsed over the manual chapter 14 covers the UI. To get a better overview I looked for cheat sheet for the commands and found this quick reference guide from Tom W wolf

This was just what I needed to understand what was happening looking back at the netlist code I noted there was a plot v(AND)command but it seems like it did not run automatically so I typed plot v(AND) in Ngspice and the output window popped up.

second_run_ngspice.jpeg

Change the AND gate to OR gate

Now there was time to see if I could change change the netlist code and turn it into a or gate. I already knew how to do this with the schematic since I have studied this before but I have not had experience with netlist so that was new.

In Falstad there is various samples circuits for each logical families: d

---
config:
  look: handDrawn
  theme: neutral
---
flowchart LR
  A[Logic Families] --> U[Unipolar]
  A --> B[Bipolar]
  A --> T[Ternary Logic]

  %% Unipolar
  U --> PMOS[PMOS]
  U --> NMOS[NMOS]
  U --> CMOS[CMOS]

  %% Bipolar
  B --> S[Saturated]
  B --> NS[Non Saturated]

  %% Saturated
  S --> TTL[TTL - Transistor Transistor Logic]
  S --> RTL[RTL - Resistor Transistor Logic]
  S --> DTL[DTL - Diode Transistor Logic]

  %% Non Saturated
  NS --> ECL[ECL - Emitter Coupled Logic]
  NS --> STTL[Schottky TTL]

  %% Ternary note
  T --> T1[Three Valued Logic]

  • PMOS and NMOS are early MOS logic families that use only one type of transistor. They consume static power and are generally slower.
  • CMOS (Complementary MOS) pairs N- and P-channel transistors, resulting in low static power consumption and higher efficiency. It is the dominant digital logic technology today.

fallstad_nand.jpeg

I took the CMOS NAND circuit and added a inverter on the end I then took a look at the circuit and code to analyze it. Jennifer Volk had shown us blocks of codes and where they where in the scematic so I made a illustration of the connection points and blocks in the code. Since I found out you can export .svg from falstad I used Inkscape for that.

Here is a link to the CMOS AND gate on Falstad

cmos_and.svg

Doing this work, I now understood the netlist a lot better. From studying logic before, I knew that changing the PMOS network to series and the NMOS network to parallel would give me the OR behavior. The schematic logic was familiar, but implementing it directly in the netlist format was a new step for me. I quickly changed the wiring in Falstad, not in the most elegant way or using best practices but I just wanted to confirm it worked and it did. It was now an OR gate.

falstad_or.jpeg

I then cleaned up the circuit and you can try it here

I was now confident I could modify the code and see if it would work. I first exported the design from Falstad to .svg to draw up the plan.

cmos_or.svg

I made the schematic into a colored diagram with the connections needed and like the AND code I divided it into 3 blocks with a pair of Mosfets.

I realized I only had to change the connections on Mp1, Mp2, Mn1 and Mn2. I could leave Mp3 and Mn3 as they were.

device syntax

Mosfet has order of drain, gate and source and the symbols for P and N are flipped.

cmos_symb.svg

Here is the code based on that:

* OR gate ngspice example

* NGSPICE transistor models
.model mosn NMOS level=49 version=3.3.0 tox=10n nch=1e17 nsub=5e16 
.model mosp PMOS level=49 version=3.3.0 tox=10n nch=1e17 nsub=5e16

* 1 V power supply
vsup VDD 0 1 


* OR pull-up network -- two pmos in series changed to npu for up network // (1)!
Mp1 npu A VDD VDD mosp L=0.35u W=2u 
Mp2 nOUT B npu VDD mosp L=0.35u W=2u


* Pull-down network -- two nmos in parallel
Mn1 nOUT A 0 0 mosn L=0.35u W=2u 
Mn2 nOUT B 0 0 mosn L=0.35u W=2u

* Inverter, or a logical NOT stays the same when changing from AND to OR
Mp3 D nOUT VDD VDD mosp L=0.35u W=2u
Mn3 D nOUT 0 0 mosn L=0.35u W=2u

* Input voltage source, ramps up to VDD then back down
vin1 A 0 PWL(0 0 2mS 0 2.001mS 1V 3mS 1V 3.001mS 0) 
vin2 B 0 PWL(0 0 1mS 0 1.001mS 1V 2.5mS 1V 2.5001mS 0) 

.control 
* transient simulation using vin sweep
  tran 100n 4m 

* plot vout against vin 
  plot v(A) v(B) v(D)+0.2

.endc
  1. :man_raising_hand: These are the lines I changed.

  2. :man_raising_hand: I'm a code annotation! I can contain code, formatted text, images, ... basically anything that can be written in Markdown.

I ran the code and got a plot confirming it was working as OR gate. Having the plot showing up in tree windows was not very convenient. I read up on the Plot feature and I learned doing plot v(A) v(B) v(AND) on one line would plot it in one window.

Troubleshooting

The node name AND caused parsing issues in Ngspice because and is also a reserved logical operator. Renaming the output node to D resolved the issue. I also shifted the signal up by +0.2 so I could see it in the same window.

There was an option to save the plot as .svg meaning I could clean it up a bit in Inkscape, you can see the outcome below.

plot_or_ink.svg

Comparing the time signals I could see the expected AND outcome from earlier with the OR outcome now.

Time A B Expected OR Expected AND
0–1 ms 0 0 0 0
1–2 ms 0 1 1 0
2–2.5 ms 1 1 1 1
2.5–3 ms 1 0 1 0
>3 ms 0 0 0 0

Thinker Spice

We encourege to try to hook up the circuit on a breadboard in the class to gain a better understanding it was pointed out we could use ThinkerCAD. So I tought it would be fun to try that. I liked the idea of going from Ngspice to Falstad to ThinkerCAD simulation. I wanted to take time and make the breadboard layout clean and neat so I used more connection that needed so I could keep all wires at 90° and have no overlap. breadboard circuit

beadboard spice

Point to point SPICE

After that I found out there was other types of connections like alagator clips. It was at this point I tought why bother with the breadboard at all. The breadboard has become a contiversal mater when it comes to the Fab Academany. So I hit dealeate on the breadboard and it was gone. Then I made a point to point Cmos and gate circuit. Here is a link to the circuit thinker spice

Schmitt trigger analysis

A Schmitt trigger is a very useful circuit in digital electronics. It is commonly used to clean up noisy signals, for example after long-distance transmission where interference may distort the waveform. Unlike a normal inverter with a single switching threshold, a Schmitt trigger has two different threshold voltages:

  • an upper threshold

  • a lower threshold

This threshold range called hysteresis ensures that small fluctuations or noise around the switching point do not cause unwanted oscillations. As a result, a slow or noisy input signal becomes a clean and stable square wave at the output. A Schmitt trigger can also be used for level shifting and for converting analog signals (like sine or triangle waves) into digital signals.

Because of how common and useful it is, the Schmitt trigger even has its own schematic symbol.

symbol

Schmitt triggers can be implemented in several ways, for example using op-amps, BJTs, or CMOS transistors. In this assignment, we will analyze a CMOS Schmitt trigger and identify which transistors determine the upper and lower switching thresholds.

CMOS Schmitt trigger

In Falstad there there are Schmitt trigger op-amp and BJT sample circuits but no CMOS exsaple so I strated out by making one to analize. The CMOS Schmitt trigger consists of six transistors: - PMOS: Mp1, Mp2, Mp3 - NMOS: Mn1, Mn2, Mn3

cmos

CMOS Schmitt trigger Falstad

Inverter determine the basic switching point and is formed by:

  • The main inverter action is primarily determined by Mp1 (pull-up) and Mn1 (pull-down).
  • Mp2 and Mn2 are series devices that modify the effective pull-up and pull-down strength and enable hysteresis behavior.

Feedback

  • Mp3 and Mn3 provide output-controlled positive feedback.
  • Mn3 determines the upper threshold (VT+) when the output is high, and Mp3 determines the lower threshold (VT−) when the output is low.

Hysteresis curve

In the Falstad simulation, I observed the input and output signals using the scope. The input signal is a sine wave and 1 kHz sine wave simulating a noisy, deformed signal. In the bottom right, I generated an X–Y plot where the X-axis represents the input voltage and the Y-axis represents the output voltage. The X–Y plot shows the hysteresis curve.

A CMOS Schmitt trigger exhibits hysteresis in its voltage transfer characteristic (VTC). Unlike a standard inverter, which has a single switching threshold, the Schmitt trigger has two distinct switching points depending on the direction of the input transition.

curve

I measured the upper threshold at 3.3 V and the lower threshold at 1.7 V. The hysteresis width is therefore: $$ \Delta V = V_{T+} - V_{T-} = 3,3V-1,7V=1,6V $$ When the input voltage is between 1.7 V and 3.3 V, the output depends on its previous state, demonstrating the memory effect created by positive feedback. The circuit does not switch until the input crosses the corresponding threshold for the current transition direction.

range

The hysteresis curve clearly demonstrates the positive feedback behavior introduced by Mp3 and Mn3.

Changing the hysteresis range

Next, I looked at how to change the hysteresis range. In real CMOS technology, this is done by adjusting the transistor sizing \( W/L \) of Mp3 and/or Mn3. In Falstad, this corresponds to modifying the Beta parameter, which by default is set to 20m. The definition of Beta can be found here:

\[ I_D = \frac{\beta}{2}(V_{GS} - V_T)^2 \]
\[ \beta = \mu C_{ox} \frac{W}{L} \]

This shows that increasing Beta increases the effective strength of the transistor.

Effect of modifying the feedback transistors

  • Increasing Beta of Mn3 increases the pull-down strength when the output is high. This raises the upper threshold \( V_{T+} \).
  • Increasing Beta of Mp3 increases the pull-up strength when the output is low. This lowers the lower threshold \( V_{T-} \).

hys range

When I increased the Beta value to 120m for both Mp3 and Mn3, I measured switching thresholds of approximately:

  • \( V_{T-} \approx 1.4\,V \)
  • \( V_{T+} \approx 3.5\,V \)

This increased the hysteresis width to approximately 2.1 V.

low beta

When I reduced the Beta value to 6m, the thresholds shifted to approximately: - \( V_{T-} \approx 2.1\,V \)
- \( V_{T+} \approx 2.8\,V \)

This reduced the hysteresis width to approximately 0.7 V.

These results demonstrate that hysteresis in a CMOS Schmitt trigger is controlled by transistor sizing. The switching midpoint can also be adjusted by modifying the sizing of Mp1 and Mn1.

Side quest if there time

  • Hook it up on a RL breadboard
  • Look at other Spice software
    • Qspice
    • LT spice
  • Try creating netlist using KiCad

Look at other SPICE software

After working with Ngspice I did't realy have a urge to look at other other software like I had in the beging. LTspice only had instalation for win and mac so that did't lead anywhere. I had also heard of Qspice and when I pressed download I was greating by a form to fill out to resive it in email so I think I'm good just using Ngspice. I was also glad to see that Ngspice seams to work well with KiCAD. Looking at this list I could see that Ngspice seams to be the real deal since it's the back end for a lot of EDA softwares.

Running the container locally

I ran out of time last week to try Docker. Since I have heard so much about it, but never really had a reason to get into it, I decided to take the time and set it up locally. On the curriculum page there is a great setup guide.

Local Docker VNC

Step 1: Install Docker

First step was to get Docker Desktop. It turns out that on Linux it requires running a virtual machine. That was not so appealing. Who needs a GUI anyway, our home is the terminal. I figured I just needed Docker Engine, so I ran: sudo apt install docker.io and verified it with docker --version

docker

Step 2: Clone the Repository

Next I made a microelectronics directory to clone into and ran: git clone https://github.com/iic-jku/IIC-OSIC-TOOLS.git

Navigated to the cloned repo cd IIC-OSIC-TOOLS

Step 3: Start the Container

I then ran ./start_vnc.sh This script creates the container, pulls the image, sets everything up and starts it. I watched a hypnotizing installation list scroll by for about 10 to 20 minutes while everthing was being setup.

install iic

done

After it finished I ran: docker ps and saw the container was running. I opened it in the browser at: http://localhost:80 ](http://localhost:80) Everything looked good. I also tried connecting with TigerVNC and Remmina. It was noticeably faster that way, and Remmina has a slightly more modern touch, so I might switch to that.

Usefull comands for Docker are:

  • docker ps to see what is running
  • docker ps -a to see everything, even stopped containers
  • docker stop <container name> to stop the container
  • docker start <container name> to start it again
  • sudo systemctl status docker check Docker status

It is good to be able to run everything locally. I still need to figure out how to properly mount a local directory so the course examples and my own designs live outside the container, but that will be the next step.

vnc

In the help session I also leaned a local directory had been made with my design files ~eda/designs

Docker in local terminal

I later learned that I could attach to the running container directly from my local terminal instead of using the browser or VNC.

docker exec -it iic-osic-tools_xvnc_uid_1000 bash

This opens an interactive shell inside the running container.

docker local term

This already felt much better than working through the VNC interface but I still needed VNC for GUI apps. Could we go deeper?

Docker X11

In one of the help sessions Julian mentioned that it was possible to run the container using the local X server. That means GUI applications inside the container can open directly on my Linux desktop, making everything feel like one unified system. The IIC tools repository already includes a helper script for this:

IIC-OSIC-TOOLS - using-a-local-x-server

When I did that, an xterm window appeared. That confirmed that X11 forwarding was working correctly. If I want to reconnect later, I can again use:

docker exec -it iic-osic-tools_xvnc_uid_1000 bash

It also opens the container in my local terminal and I can just minimize Xterm.

docker x11

  • Now I can:

  • Use ~eda/designs for my local work

  • Edit files with my own Neovim setup
  • Use my Kitty terminal emulator
  • Keep Xterm minimized while still running GUI tools otherwise the connection closes

This setup feels much more natural compared to working inside the browser. Docker is no longer some mysterious thing people talk about, it’s just part of my work flow now.

Troubleshooting

During testing and after rebooting the computer I ran into a few issues that are worth documenting.

X11 container failed to start

After rebooting I got this error:

error mounting "/tmp/.iic-osic-tools_xserver_uid_1000_xauthority"
not a directory
Are you trying to mount a directory onto a file?

The problem was that the path:

/tmp/.iic-osic-tools_xserver_uid_1000_xauthority

was created as a directory instead of a file. The container expects this to be a file for Xauthority.

To fix it I removed the broken path:

sudo rm -rf /tmp/.iic-osic-tools_xserver_uid_1000_xauthority
X11 permission reset after reboot

After reboot, GUI apps would not open because X permissions were reset.

I fixed that by running:

xhost +local:docker

This allows local Docker containers to connect to the X server.

KiCad netlist

I made a very simple circuit of two resistors connected in series to understand netlists in KiCad. There is an export under: file > export > netlist. A window shows up with some options there were two SPICE option and I tried both. I also tried the KiCad netlist but that produced a lot of lines. The one that looked most promesing were SPICE and SPICE Model.

kicad spice

* SPICE Model from KiCad

.subckt ngspice_test


R1 Net-_R1-Pad1_ +10V 440
R2 Net-_R1-Pad1_ GND 440

.ends
.title KiCad schematic
R1 Net-_R1-Pad1_ +10V 440
R2 Net-_R1-Pad1_ GND 440
.end   

Looking at the code SPICE Model looks more like the Ngspice code it did't export with any format so I tried adding .sp. I started my local container and tried the code but it looked like it did not work I didn't get any list from Ngspice and running the plot command just gave an error.

first try

I decided to try the .cir format and when I ran that I actually got the list I then ran op that should to a DC operating point analysis. Then I did print v(Net-_R1-Pad1_) expecting to see the 5V but it just showed 0V. At this point it might be clever to look at a tutorial how to work with Kicad and Ngspice.

second try

In KiCad there is a built in simulation that uses Ngspice so I decided to try that next. What was interesting is that it also just showed zero every where. So I knew at this point it was somewhat working I just had to take a closer look at KiCad. I also realized I didn't think to much when I had put in the values in KiCad.

kicad sim

Note

This is as far as I got I will come back to this when there's time.

Nice finds

I use MathJax every now and then but's it's hard to remeber the syntax so this mathjax online editor was a good dicovery.