This repository contains the documentation of the work done during a five-day physical verification workshop carried out by VSD.
The workshop describes the physical verification process that takes place during an RTL to GDSII flow using Skywater 130nm Technology, including DRC and LVS tests. This helps the participants get ready for the tape out and is particularly helpful for chip fabrication. The workshop assists in locating and fixing violations made during the physical verification stage.
More information about the workshop can be found at https://www.vlsisystemdesign.com/physical-verification-using-sky130/
A special thanks to Tim, Kunal, and Sumanto for creating and helping out during this fantastic workshop
- Chapter 0 - Getting the tools
- Chapter 1 - Understanding the design flow
- Chapter 2 - DRC and LVS Fundamentals
- Chapter 3 - DRC Issues
- Chapter 4 - LVS
- Additional Content - OpenLANE Design Flow
- Workshop Certificate
To adequately utilize the open source skywater130 pdk and understand the design flow, we first require to install all the tools, which are
Note: open_pdk has to be installed last so it can correctly associate the xschem and magic directories. Note: if the configure step fails during any process, its most likely due to missing additional packages, and they need to be installed (preferably from source) to complete the installation
Magic is an open-source VLSI layout tool.
Install steps:
$ git clone git://opencircuitdesign.com/magic
$ cd magic
$ ./configure
$ make
$ sudo make install
More info can be found at http://opencircuitdesign.com/magic/index.html
Netgen is a tool for comparing netlists, a process known as LVS, which stands for "Layout vs. Schematic"
Install steps:
$ git clone git://opencircuitdesign.com/netgen
$ cd netgen
$ ./configure
$ make
$ sudo make install
More info can be found at http://opencircuitdesign.com/netgen/index.html
Xschem is a schematic capture program
Install steps:
$ git clone https://github.com/StefanSchippers/xschem.git xschem_git
$ ./configure
$ make
$ sudo make install
More info can be found at http://repo.hu/projects/xschem/index.html
ngspice is the open-source spice simulator for electric and electronic circuits.
Install steps:
After downloading the tarball from https://sourceforge.net/projects/ngspice/files/ to a local directory, unpack it using:
$ tar -zxvf ngspice-37.tar.gz
$ cd ngspice-37
$ mkdir release
$ cd release
$ ../configure --with-x --with-readline=yes --disable-debug
$ make
$ sudo make install
More info can be found at https://ngspice.sourceforge.io/index.html
Please note that to view the simulation graphs of ngspice, xterm is required and can be installed using.
$ sudo apt-get update
$ sudo apt-get install xterm
Open_PDKs is distributed with files that support the Google/SkyWater sky130 open process description https://github.com/google/skywater-pdk. Open_PDKs will set up an environment for using the SkyWater sky130 process with open-source EDA tools and tool flows such as magic, qflow, openlane, netgen, klayout, etc.
Install steps:
$ git clone git://opencircuitdesign.com/open_pdks
$ open_pdks
$ ./configure --enable-sky130-pdk
$ make
$ sudo make install
Now that we have all the necessary tools installed let's understand the design flow!
An initial working directory can be made by copying the required files as follows:
$ mkdir Lab1_and
$ cd Lab1_and
$ mkdir mag
$ mkdir netgen
$ mkdir xschem
$ cd xschem
$ cp /usr/local/share/pdk/sky130A/libs.tech/xschem/xschemrc .
$ cp /usr/local/share/pdk/sky130A/libs.tech/ngspice/spinit .spiceinit
$ cd ../mag
$ cp /usr/local/share/pdk/sky130A/libs.tech/magic/sky130A.magicrc .magicrc
$ cd ../netgen
$ cp /usr/local/share/pdk/sky130A/libs.tech/netgen//sky130A_setup.tcl .
Checking if magic works
Checking if xschem works
Checking if netgen works
Checking if ngspice works
An initial schematic is made by placing components from the open_pdk library
The required changes to the properties of the device can be made here and will automatically reflect in the layout
Convert the schematic to a symbol
Using the symbol, we can create an independent test bench to simulate the circuit
The circuit can be simulated in ngspice. make sure to disable .subckt in the simulation tab for the netlist generated for the sim
The original schematic can be used to export a netlist, which can be imported into magic to create the layout.
Set the appropriate device properties and route the layout.
The netlist of the layout can be extracted using
% extract do local
% extract all
% ext2spice lvs
% ext2spice
ext files are intermidiate files and can be cleaned using
rm *.ext
/usr/local/share/pdk/scripts/cleanup_unref.py -remove
The schematic netlist and layout netlist can be compared using LVS by netgen
$ netgen -batch lvs "../mag/inverter.spice inverter" "../xschem/inverter.spice inverter"
Make sure the design layout meets all silicon foundry rules for masks.
Make sure the design layout matches a simulatable netlist by electrical connectivity and devices.
$ cp /usr/local/share/pdk/sky130A/libs.tech/magic/sky130A.magicrc ./.magicrc
% gds read /usr/local/share/pdk/sky130A/libs.ref/sky130_fd_sc_hd/gds/sky130_fd_sc_hd.gds
% load sky130_fd_sc_hd__and2_1
% cif istyle sky130(vendor)
% gds read /usr/local/share/pdk/sky130A/libs.ref/sky130_fd_sc_hd/gds/sky130_fd_sc_hd.gds
% port first
% port 1 name
% port 1 class
% port 1 use
% lef read /usr/local/share/pdk/sky130A/libs.ref/sky130_fd_sc_hd/lef/sky130_fd_sc_hd.lef
% readspice /usr/local/share/pdk/sky130A/libs.ref/sky130_fd_sc_hd/spice/sky130_fd_sc_hd.spice
% load sky130_fd_sc_hd__and2_1
Note: the difference between load and getcell
The difference is between a cell and an instance of that cell. If you do load inverter, then you will be editing the cell called inverter. If you do getcell inverter, then you will place an instance of the cell inverter inside the cell you're currently editing.
% lef read /usr/local/share/pdk/sky130A/libs.ref/sky130_fd_sc_hd/lef/sky130_fd_sc_hd.lef
% load sky130_fd_sc_hd__and2_1
% readspice /usr/local/share/pdk/sky130A/libs.ref/sky130_fd_sc_hd/spice/sky130_fd_sc_hd.spice
% load test
% getcell sky130_fd_sc_hd__and2_1
% gds write test
Restart magic and the cell fails to be adequately loaded because the changes were not saved.
%gds read test
%save test
When the test is reloaded after saving, we get the original layout.
% load test
% gds write test
We can edit the cell by making it editable.
% property
% cellname writeable sky130_fd_sc_hd__and2_1 true
% gds write test
And after restarting magic and reloading it, we still get an unchanged cell
% gds read test
% extract all
% ext2spice lvs
% ext2spice
% ext2spice cthresh 0.01
% ext2spice
% ext2sim labels on
% ext2sim
% extresist tolerance 10
% extresist
% ext2spice lvs
% ext2spice cthresh 0.01
% ext2spice extresist on
% ext2spice
$ /usr/local/share/pdk/sky130A/libs.tech/magic/run_standard_drc.py /usr/local/share/pdk sky130A/libs.ref/sky130_fd_sc_hd/mag/sky130_fd_sc_hd__and2_1.mag
% drc liastall style
% drc style drc(full)
% drc check
% drc why
% drc find
% getcell sky130_fd_sc_hd__tapvpwrvgnd_1
netgen -batch lvs "../mag/sky130_fd_sc_hd__and2_1.spice sky130_fd_sc_hd__and2_1" "/usr/local/share/pdk/sky130A/libs.ref/sky130_fd_sc_hd/spice/sky130_fd_sc_hd.spice sky130_fd_sc_hd__and2_1"
XOR is the process of comparing to GDS files by highlighting any differences between the two.
% flatten -nolabels xor_test
edit the cell
% xor -nolables xor_test
% load xor_test
Each foundry has its own manufacturing rules and we have to make sure that the layout abides by these. The stackup for the skywater130 process is as folows:
The detailed explaination of all the rules can be found at: https://skywater-pdk.readthedocs.io/en/main/rules.html
- b
- s
- ?
- : box width 0.14um
- : stret u 0.14um
- : move e 0.14um
- : box grow c 0.01um
- : paint m1
- drc find
- see no *
- see m1
% extract all
% antennacheck debug
% antennacheck
The density of the fill pattern can be checked in magic by
% cif cover MET2
After writing the gds file, scripts can be used to generate the fill patterns
$/usr/local/share/pdk/sky130A/libs.tech/magic/check_density.py exercise_11.gds
$/usr/local/share/pdk/sky130A/libs.tech/magic/generate_fill.py exercise_11.mag
The fill patterns can be accurately loaded by
load excercise_11
box values 0 0 0 0
getcell excercise_11_fill_pattern child 0 0
Netgen will compare 2 netlists even if the cells are not contained in subckts. netgen can be launched with a GUI using
$ netgen
And then the 2 spice files can be compared using
% lvs netA.spice netB.spice
The actual information can be better analyzed in the comp.out file. By editing a netlist to mismatch and analyzing it we see
netgen does not compare net names but matches them as closely as possible, putting them in the same partition. Here the format cell2/1 = 1 => pin 1 on cell 2 appears once
In the device mismatch the Instance: cell3:3 1 = 3 represents pin 1 of the cell3 instance has a fanout of 3
Note: It is usually easier to debug from the net mismatch than the device mismatch
Unlike magic, Netgen has to be reinitialized between runs this can be done by
reinitialize
we can see despite having a subckt definition the devices are not checked A subckt definition is not an active component. It is only a device definition. Only subckt lines starting with x in a spice netlist are considered as active components. Both the spice netlists are considered as empty lists here by netgen
It is better to compare the netlists at a subckt level rather than the top level. we can give the subckt name to netgen by:
% lvs "netA.spice test" "netB.spice test"
Netgen does not care about the order of the pin names. It cares whether all the pin names are the same.
By changing the pin name order in netA.spice and rerunning lvs
We see the circuits are matched. By swapping pin names at the top level inside the circuit and rechecking, we get the mismatch error.
this indicates that it is okay to have port order in an netlist in a differnt order, but since netgen cannot make any assumptions about the top level the pin names should match.
Instead of always running the GUI, a batch script can be made to run netgen in batch mode and output the files in a json file with a custom name
$ netgen -batch lvs "netA.spice test" "netB.spice test" \
/usr/local/share/pdk/sky130A/libs.tech/netgen/sky130A_setup.tcl \
exercise_3_comp.out -json | tee lvs.log
The json file gives a more machine readable file and can be viewed Using
../count_lvs.py | tee -a lvs.log
subckts that are defined and are completely empty are considered as blackbox entries. Ie the definition is a stand in for the circuit with the correct pin names and order. We can see how these pin names are reflected in the comp.out file.
By changing the pin name order of subckt cell1 we do get a mismatch and this shows that the cell names are meaningful
By changing the port names in cell1 from A B C to A B D and re running we get proxypins. Since these are blackbox circuits netgen assumes that port c is missing in circuitA and D is missing in circuitB
Netgen assumes that the cell has all pin A B C D and adds the proxy pin to show the missing pin
By changing the cell1 to cell 4 in both the definition and the instantiation.
We see that cells match and the cells are being flattened. This highlights an issue with blackcells. It cannot recognize when it is a blackbox cell and when it is an empty circuit
This can be solved by using the -blackbox flag which tells netgen to treat any empty cells as blackbox entries
$ netgen -batch lvs "netA.spice test" "netB.spice test" \
/usr/local/share/pdk/sky130A/libs.tech/netgen/sky130A_setup.tcl \
exercise_3_comp.out -json -blackbox | tee lvs.log
We see how this results in a device count mismatch
both the cells show up in the same partition This highlights how even though components in the comp.out file may be aligned but are a complete mismatch
Devices have been added to subckts and as they do not begin with X they are not subckts themselves but low level components.
Low level circuits such as resistors can have their pin swapped ie they are permuteable. We can tell netgen to consider this by:
first copying the tech file to the same directory
$ cp /usr/local/share/pdk/sky130A/libs.tech/netgen//sky130A_setup.tcl .
Editing the run_lvs.sh script
$ netgen -batch lvs "netA.spice test" "netB.spice test" \
sky130A_setup.tcl \
exercise_4_comp.out -json | tee lvs.log
Apending the following lines to the bottom of sky130A_setup.tcl
permute "-circuit1 cell1" A C
permute "-circuit2 cell1" A C
pn running lvs we see the circuits match
For the diode subckt when pins A and C are swapped both at the port name and low level cells, after running lvs we get no error but the comp.out file highlights how pins A and C have been swapped.
Extract the Schematic netlist in xschem
Note: 1.change the extraction directory for the spice netlists 2.make sure the simulation top lvl is a subckt is selected 3.recopy the xcshemrc and .spiceinit files
Extract the netlist from magic
Note: 1.copy the magicrc file 2.run using magic -d XR
On comparing the netlists using netgen we can see that the issue is with the defination of standard cells, as they are missing in the netlist they are treated as blackbox cells.
Extract the xschem netlist for the analog wrapper test bench Compare this with the previously extracted layout netlist, and we see that since the subckts are defined only pin matching errors are shown
By analysing the example_por we realise that the layout contains top_level_circuits -> Parameterized_devices -> low_level_device as a hirarchy whereas the schematic netlist is top level circuits -> low_level_device.
Netgen automatically flattens these circuits to perform a comparision
We also see that using netgen we can compare any cells in a netlist.
Parameterized devices are extracted as individual devices strung together not as one parameterized devices. netgen flattens these automatically
Analysing the output for the wrapper again we can see the following errors in the comp.out files
Lets fic the i0_analog[4] error, In the .mag file for the circuit we can see the 2 nets are shorted, that can be fixed by adding a resistor (resmet3) on the layer and re exporting the netlists make a not of the resistor size.
Now edit the schematic bt=y adding the resistor and giving the appropriate values. Make sure to export the tb netlist and not only the subckt.
On comparing the netlists again we can see a the mismatch error is resolved
The design contains a fill cells that are avoided by Magic during extraction as they do not really contain anything inside them but are accurately placed by the router. So we ignore comparing these cells in netgen by changing the corresponding environment variable.
We can do this in the run_lvs file by adding
export MAGIC_EXT_USE_GDS=1
on rerunning netgen we get no errors.
If the veilog code is not of stuctural level and has any behavorial assignment netgen treats it as a black box and doesnot evaluate it.
Another issue arising in cells are when different power rails are in the layout connected to the same substrate but magic fails to extract this. The different power layers can be tied together in the verilog code to fix this error.
Generating the netlists and running netgen we first get a similar issue to ex6 and can be fixed by adding the following line to the run_lvs.sh script
export MAGIC_EXT_USE_GDS=1
Next we have a diode mismatch error and we can see that the diode is missing in the verilog file. The possible reason for this is that the diode was generated in an antennacheck. We can locate the diode in the layout using its instance name from the netgen output.
% select cell sky130_fd_sc_hd__diode_2_0
We can check which node the diode is connected to
% getnode
note : by pressing 's' three times we can select the net in the entire layout
The verilog file can be edited to add the diode circuit
Rerunning netgen shows that the diode is available in the verilog netlist
Moving on to the nect error we see there is a huge nimber of unconnected devices to the VPWR rail especially in the cell instance_249_
finding this in the layout we see it is missing via3 connections to VPWR
This can be resolved by painting in the via3
This fixes all the mismatch issues and now we can move on to the final issue.
Seeing the digital_pll circuit it looks like there is a broken net on instance_364_
Elements like resistors,capcitors can have property mismatches like width , lenght etc. These can be corrected in the schematic or layout.
Example of property errors. Errors corrected
OpenLANE is an automated RTL to GDSII flow based on several components including OpenROAD, Yosys, Magic, Netgen, Fault, OpenPhySyn, CVC, SPEF-Extractor and custom methodology scripts for design exploration and optimization. The flow performs full ASIC implementation steps from RTL all the way down to GDSII.
- Synthesis
yosys/abc
- Perform RTL synthesis and technology mapping.OpenSTA
- Performs static timing analysis on the resulting netlist to generate timing reports
- Floorplanning
init_fp
- Defines the core area for the macro as well as the rows (used for placement) and the tracks (used for routing)ioplacer
- Places the macro input and output portspdngen
- Generates the power distribution networktapcell
- Inserts welltap and decap cells in the floorplan
- Placement
RePLace
- Performs global placementResizer
- Performs optional optimizations on the designOpenDP
- Performs detailed placement to legalize the globally placed components
- CTS
TritonCTS
- Synthesizes the clock distribution network (the clock tree)
- Routing
FastRoute
- Performs global routing to generate a guide file for the detailed routerTritonRoute
- Performs detailed routingOpenRCX
- Performs SPEF extraction
- Tapeout
Magic
- Streams out the final GDSII layout file from the routed defKLayout
- Streams out the final GDSII layout file from the routed def as a back-up
- Signoff
Magic
- Performs DRC Checks & Antenna ChecksKLayout
- Performs DRC ChecksNetgen
- Performs LVS ChecksCVC
- Performs Circuit Validity Checks
All the information about the project can be found in the openlANE documentation: https://openlane.readthedocs.io/en/latest/index.html
this file is necessary for running the openLANE flow and its documentation can be found at: https://openlane.readthedocs.io/en/latest/reference/configuration.html
run the following in the openLANE directory
export PDK_ROOT=/usr/local/share/pdk
make mount
./flow.tcl -design spm -tag run1
This runs the entire openLANE flow and generates the required GDSII and .mag files which can be viewed in magic
The interactive flow allows to run each step of the design flow. It can be launched using
export PDK_ROOT=/usr/local/share/pdk
make mount
./flow.tcl -interactive
Start the Design flow and synthesis with the following
package require openlane
prep -design spm -tag run1
run_synthesis
Run the Floorplanning using
run_floorplan
Run the placement using
run_placement
Run the clock tree generation and STA using
run_cts
The clock tree can be optimized using
run_resizer_timing
Run the routing using
run_routing
After all the changes that have taken place a new verilog file can be obtained using
write_powered_verilog
set_netlist $::env(lvs_result_file_tag).powered.v
Generate GDSII file using
run_magic
An alternate GDSII file is generated using klayout for XOR verification
run_klayout
Run the XOR test using
run_klayout_gds_xor
Export spice netlist using
run_magic_spice_export
Run LVS on exported spice netlist and verilog file
run_lvs
DRC checks
run_magic_drc
Antenna Checks
run_antenna_check
LEF checks DRC_checks
run_lef_cvc
Final summary report can be generated using DRC_checks
generate_final_summary_report
- Local Interconnect rules : Avoid routing large traces on the local interconnect
- Density Planning : The utilization ratio can be reduced to form more spaced circuits with lesser errors The FP_CORE_UTIL variable in the .config file
- Dont use cells : Avoid using cells that are known to cause errors
- Manual verification : For designs with lower number of DRC errors, the can be corrected with the methods discussed in chapter 3