CMOS inverter using the skywater sky130 process (design with xschem and simulation with ngsice)

Design the inverter's circuit using xschem

1. start xschem
2. xschem's sky130 library provides a parameterizable inverter schematic (not.sch) and its symbol (not.sch)
3. create a new schematic (inv_sky130_a.sch)

  • instantiate and place the symbol not.sym (Tools > Insert symbol | Shift-I)
    the symbol and its schematic are available both in the library Lib406 and in the library ~/share/pdk/sky130/libs.tech/xschem/sky130_tests

 
 
  • customize the transistors’ dimensions (select the symbol, right click on it and edit its properties)

 
  • instantiate and place an input pin (ipin.sym) and an output pin (opin.sym)
    the symbols are available both in the library Lib406 and in the library ~/opt/xschem/share/xschem/xschem_library/devices

  • label the name of the input and output pins (select the pin, right click on it and edit its properties)

 
  • wire the pins to the ports of the not.sym instance (Tools > Insert wire | W)

  • save the schematic (File > Save as | Ctrl+Shift+S)

 
  • make a symbol inv_sky130_a.sym for the schematic (Symbol > Make symbol from schematic | Ctrl+L)

 

Simulate the inverter

1. use xschem to create a simulation testbench (tb_inv_sky130_a.sch) for the inverter

 


The spice directives TT_MODELS and control are code.sym instances with the following attributes:

 
 


2. create netlist (netlist button)

tb_inv_sky130_a.spice
**.subckt tb_inv_sky130_a
Vin in GND DC 0 PULSE(0 1.8 0 1ns 1ns 4ns 10ns)
VP VCC GND 1.8
VN VSS GND 0
x2 out in inv_sky130_a
**** begin user architecture code
.lib /home/utalarico/share/pdk/sky130A/libs.tech/ngspice/sky130.lib.spice tt

.param mc_mm_switch=0
.param mc_pr_switch=1

.control
* VTC analysis
DC Vin 0 1.8 1m
save all
let VP = 1.8
let vo_mid = VP/2
let dvout = deriv(v(out))
meas DC VSW find v(in) when v(out)=vo_mid
meas DC VIL find v(in) WHEN dvout=-1 CROSS=1
meas DC VIH find v(in) WHEN dvout=-1 CROSS=2
meas DC VOL find v(out) WHEN dvout=-1 CROSS=2
meas DC VOH find v(out) WHEN dvout=-1 CROSS=1
echo VTC measurements
print VSW
print VIL
print VIH
print VOH
print VOL
echo
set filetype=binary
write ./spiceout/tb_inv_sky130_a_vtc.raw v(out) v(in) dvout VSW VIL VIH VOL VOH

* Transient analysis
TRAN 0.01n 20n
save all
let VP=1.8
let per10 = Vp*0.1
let per50 = Vp*0.5
let per90 = Vp*0.9
meas TRAN t_rise  TRIG v(out) VAL=per10 rise=2  TARG v(out) VAL=per90 rise=2
meas TRAN t_fall  TRIG v(out) VAL=per90 fall=2  TARG v(out) VAL=per10 fall=2
meas TRAN t_delay  TRIG v(in) VAL=per50 rise=1 TARG v(out) VAL=per50 fall=1
echo TRAN measurements
print t_delay
print t_rise
print t_fall
echo
set filetype=binary
write ./spiceout/tb_inv_sky130_a_tran.raw

.endc

**** end user architecture code
**.ends

* expanding   symbol:  inv_sky130_a.sym # of pins=2
* sym_path: /home/utalarico/ihome/ngs406/xSchems/inv_sky130_a.sym
* sch_path: /home/utalarico/ihome/ngs406/xSchems/inv_sky130_a.sch
.subckt inv_sky130_a  out in
*.ipin in
*.opin out
x1 out in VCC VSS not W_N=1 L_N=0.15 W_P=2 L_P=0.15 m=1
.ends

* expanding   symbol:  not.sym # of pins=2
* sym_path: /home/utalarico/ihome/Lib406/not.sym
* sch_path: /home/utalarico/ihome/Lib406/not.sch
.subckt not  y a  VCCPIN  VSSPIN      W_N=1 L_N=0.15 W_P=2 L_P=0.15
*.opin y
*.ipin a
XM1 y a VSSPIN VSSPIN sky130_fd_pr__nfet_01v8 L=L_N W=W_N nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1
XM2 y a VCCPIN VCCPIN sky130_fd_pr__pfet_01v8 L=L_P W=W_P nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1
.ends

.GLOBAL GND
.GLOBAL VCC
.GLOBAL VSS
.end

3. run simulation (simulation button)

4. view results (waves button)