Skip to content

Session 3: Schematic Design & Simulation


Session summary

In this session, we learned about schematic capture and how we can translate schematics into SPICE netlists and simulate CMOS logic using a PDK library . We looked into key netlist elements (devices, wires, labels, power references) and the netlist format. Looked into different analysis observe logic gate behaviors. Using .meas, we learned how to get propagation delays by measuring input and output crossings at 50% of VDD, and distinguished this from 10–90% rise/fall time. We also covered common SPICE errors, saving results for plotting, and how output capacitance affects waveform shape and timing. We got introduced to process corners (TT, FF, SS, etc.) to account for manufacturing variation and discussed verifying logic functionality and delay. Finally, we looked into digital design where we looked at verilog for voltage controlled switch.


Homework Given

  • Reuse and.sp netlist, which has a 2-input AND gate to make a 2-input NAND gate (e.g., remove the output inverter) and change the models to refer to the PDK models
  • Simulate it in SPICE, verify truth table (it will look something like the right table), and measure propagation delays (low-to-high and high-to-low)
  • Write an initial analog block that you can use in your chip project (e.g., an adder, counter, etc.)

Run docker locally on computer

Before working on the homework for the session, I decided to run the docker locally. I was experiencing some lag from tiger vnc and wanted to see if it was better locally.

Based on the instruction from the first session, I downloaded the docker desktop and started on the setup of the container.

Through wsl, I put in the following command

git clone https://github.com/iic-jku/IIC-OSIC-TOOLS.git

Then run this command

./start_vnc.sh 


Understanding NAND Gate

Before changing the AND netlist to NAND, I decided to make a schematic capture for nand and I decided to use LT spice, which was given as an online tool.

Just to understand how the circuit would look and how the simulation would look for the gate

LT SPICE was pretty easy to use and I was able to view the 2 input graphs and the output graph and compare it to the truth table

We are also able to view the netlist. When we press the view on the navigation bar, there is update and view spice netlist. Once netlist opens, whenyou right click on it, you can expand the netlist, to view a more expanded version.


Understanding Inverter

Before I approach with changing AND.sp to NAND, I thought it'd be best to observe and learn through the inverter example.

I copied the SPICE netlist format for CMOS Inverter from the class page to a file in my projects folder. I made the changes in the libpath as shown below and kept everything else the same and tried running the netlist

* CMOS Inverter Simulation
* For Fab Futures - Week 2

* Include the Sky130 device models
.lib "/foss/pdks/sky130A/libs.tech/ngspice/sky130.lib.spice" tt

* Power supply: 1.8V
Vdd vdd gnd 1.8

* Input: pulse from 0V to 1.8V
* PULSE(initial final delay rise fall width period)
Vin in gnd PULSE(0 1.8 1n 100p 100p 2n 4n)

* PMOS transistor (W=1u, L=150n)
* Format: Mname drain gate source body model W=... L=...
Xp out in vdd vdd sky130_fd_pr__pfet_01v8 W=1u L=150n

* NMOS transistor (W=0.5u, L=150n)
Xn out in gnd gnd sky130_fd_pr__nfet_01v8 W=0.5u L=150n

* Output load capacitor (typical gate load)
Cload out gnd 10f

* Simulation: transient analysis, 10ps step, 20ns duration
.tran 10p 20n

* Save node voltages for plotting
.save v(in) v(out)

* Control block for ngspice
.control
run
plot v(in)+2  v(out)
meas tran tpd_hl TRIG v(in) VAL=0.9 RISE=1 TARG v(out) VAL=0.9 FALL=1
meas tran tpd_lh TRIG v(in) VAL=0.9 FALL=1 TARG v(out) VAL=0.9 RISE=1
.endc

.end

First simulation run showed error!

Initially I could not understand what went wrong, it took me a while to understand the issue was in the

* PMOS transistor (W=1u, L=150n)
* Format: Mname drain gate source body model W=... L=...
Xp out in vdd vdd sky130_fd_pr__pfet_01v8 W=1u L=150n

* NMOS transistor (W=0.5u, L=150n)
Xn out in gnd gnd sky130_fd_pr__nfet_01v8 W=0.5u L=150n

where as per the error,the model name I had for PMOS and NMOS was not valid, So I looked into some document on sky130 pdk: Sky130 pdk Websource

I learned SkyWater models have an embedded scale factor, so we have to give lengths and widths in micron units. I changed the file as follows and was able to verify the output.

Changing AND.SP to NAND to refer to the PDK models

After learning the inverter, I moved on to working on NAND gate netlist file

* NAND gate with pdk

Made sure the lib was changed to the correct path

* Include the Sky130 device models
.lib "/foss/pdks/sky130A/libs.tech/ngspice/sky130.lib.spice" tt

* Power supply: 1.8V
Vdd vdd gnd 1.8

Since it was 2-input NAND gate, It had 2 input pulse voltage

* Inputs
* PULSE(initial final delay rise fall widht period)
VA inA gnd PULSE(0 1.8 0n 100p 100p 4n 8n)
VB inB gnd PULSE(0 1.8 0ns 100ps 100ps 2n 4n)
The PMOS and NMOS remains same, however the inverter was removed. Also made changes on the model name

* Two PMOS transistors in parralel for the pull-up network  (W=1u, L=150n)
* Format: Mname drain gate source body model W=... L=...
Xpa NAND inA vdd vdd sky130_fd_pr__pfet_01v8  l=0.150  w=0.99
Xpb NAND inB vdd vdd sky130_fd_pr__pfet_01v8 l=0.150  w=0.99

* Two NMOS transistors in series for the pull-down network  (W=0.5u, L=150n)
Xna NAND inA npd gnd sky130_fd_pr__nfet_01v8  l=0.150  w=0.495
Xnb npd  inB gnd gnd sky130_fd_pr__nfet_01v8  l=0.150  w=0.495

This is the load capacitance

* Output load capacitor (typical gate load)
Cload NAND gnd 10f

* Simulation: transient analysis for 20ns
.tran 10p 20n
Then the node voltages were saved for plotting
* Save node voltages for plotting
.save v(inA) v(inB) v(NAND)

This is the control block for running the netlist, plotting the grapha and the meas statement for measuring propagation delay

* Control block for ngspice
.control
run
plot v(inA)+4 v(inB)+2 v(NAND)
meas tran tpd_hl TRIG v(inA) VAL=0.9 RISE=1 TARG v(NAND) VAL=0.9 FALL=1
meas tran tpd_lh TRIG v(inA) VAL=0.9 FALL=1 TARG v(NAND) VAL=0.9 RISE=1
meas tran tpd_hl TRIG v(inB) VAL=0.9 RISE=1 TARG v(NAND) VAL=0.9 FALL=1
meas tran tpd_lh TRIG v(inB) VAL=0.9 FALL=1 TARG v(NAND) VAL=0.9 RISE=1

wrdata results.csv v(inA) v(inB) v(NAND)

.endc

.end

Simulation and Propagation delay

Once the netlist was simulated, I was able to observe the waveform and verify the truth table

Propagation delay is measured from when the input signal crosses 50 % of the supply voltage (VDD) to when the output also crosses 50 % of VDD.

The midpoint of VDD corresponds to the logic transition threshold in CMOS gates, where the logic gates is actually switching state and the transistors are most active.

Measuring at this point gives a consistent reference for both rising and falling transitions and avoids multiple ways of defining, when a signal has “changed,” making timing comparisons more reliable in simulation and design.

meas tran tpd_hl TRIG v(inA) VAL=0.9 RISE=1 TARG v(NAND) VAL=0.9 FALL=1
meas tran tpd_lh TRIG v(inA) VAL=0.9 FALL=1 TARG v(NAND) VAL=0.9 RISE=1
To measure this, it can be observed through meas statement. - ---TRIG: input crosses 0.9V which is VDD/2

-TARG when output crosses 0.9v

The time difference between the 2 is the propogation delay

We are able to observe a high to low delay (Output falling) and low to high delay (Output rising)

Since my inputs were toggling at a different time periods, I was able to notice a negative value for tpd at low to high for V(inA) and V(out). As tpd is the difference of target time and trigger time.

To measure propagation delay properly, I did one input at a time. I kept the VinB at high and toggled VinA, which looked like this

* Inputs
* PULSE(initial final delay rise fall widht period)
VA inA gnd PULSE(0 1.8 0n 100p 100p 4n 8n)
VB inB gnd DC 1.8

The output comes as follows and to observe the delay I zoom in on the graph by right clicking on it and get the x and y values by left clicking on the lines.

When zoomed in on the graph for Vina and Viout at high to low for the time at 0.9 V, I was able to observe the following value, which is not exactly accurate but the value for tpd_hl comes around 9.43818e-10 which is as per the output when simulation is run

I did the same to calculate tpd for low to high and observed the value comes around 1.1e-10.

Transition Simulation value Value from graphical observation
tp_hl 9.43818e-10 9.432538e-10
tp_lh 1.1e-10 1.048779e-10

Initial analog block

Before working on the initial analog block, I wanted to understand verilog more. I had a faint idea of what verilog was from the first session, where I did the hello world simulation.

What I know : - Verilog is used to describe and simulate circuit, using code instead of schematics. - Testbench which is a separate piece of code that is used to test other module by driving inputs and watching outputs. - How simple Verilog file looks which is:

'module myCircuit (input a, b, output y);
// The logic here
endmodule

To understand more I looked into the following websites and videos

We can do verilog coding in 3 different layer of abstraction ( ways to describe hardware ) : - Gate : Describe the actual logic gate ( For - Dataflow : Describe the way the data flows - Behavioral : Describes how the circuit behaves

The core thing to know about verliog:

  • Module: A block of hardware with inputs/outputs

  • Wire: A connection between hardware elements

  • Behavioral code: Code that behaves like logic over time

Based on the first session we had where we looked into simulation of digital circuit, we can understand the normal verilog HDL is used to describe the digital circuit.

However Verilog-A is a modeling language for analog circuits, and it is a subset of Verilog-AMS, where we have both analog and digital in one file.

Before working on the initial analog block, since I don't know how the workflow for running the .Va file was. I looked online for help and found this website - Ngspice - Ngspice manual - Semimod

I learned that to run a Verilog A code, unlike the .v code we have to first compile it using OpenVAF compiler, which generates a .osdi extension and we also need to create a ng spice netlist and refer the .osdi file under the .control section.

I wanted to work on something simple for my first initial analog block. I looked into the website given Analog Hub and looked through the Verilog- A list and decided to go with comparator verilog A model.

// Comparator model
// Author: A. Sidun
// Source: AnalogHub.ie

`include "constants.vams"
`include "disciplines.vams"

module comparator (inp, inn, out);
    input inp, inn;

    output out;

    electrical inp, inn, out;

    parameter real VDD = 3.3;           // Output voltage during high state
    parameter real t_delay = 1e-9;      // Propagation delay
    parameter real t_edge = 100e-12;        // Rise and fall times

    analog begin
        V(out) <+ VDD * transition(V(inp) > V(inn), t_delay, t_edge);
        $bound_step(1/(2*t_delay));  // comment this option if the sim is too slow
    end
endmodule