Session 6 - Synthesis & Physical Design

Synthesis
I started off by researching and analyzing some synthesis models. I learned the most by reading the chapter A Primer on Digital Circuit Synthesis in the Yosys documentation. I also browsed through a few of the other chapters on the site.
Yosys provides a capable and well-established synthesis engine. In the previous session, when I wanted to see if I could convert my behavioral Verilog into structural Verilog, I had actually already used Yosys for that task.
To better understand how the synthesis process works, I mapped out the core blocks that make up the engine.
Synthesize your design
The class page already had a good step-by-step guide on how to run Yosys. I also found a good demo on the Yosys website. I started the container and opened my UART ALU project from the last session with:
An interactive shell started with the Yosys header and a parsing message.
/----------------------------------------------------------------------------\
| yosys -- Yosys Open SYnthesis Suite |
| Copyright (C) 2012 - 2026 Claire Xenia Wolf <claire@yosyshq.com> |
| Distributed under an ISC-like license, type "license" to see terms |
\----------------------------------------------------------------------------/
Yosys 0.62 (git sha1 7326bb7d6, g++ 13.3.0-6ubuntu2~24.04 -fPIC -O3)
-- Parsing `up_dw_alu_uart.v' using frontend ` -vlog2k' --
1. Executing Verilog-2005 frontend: up_dw_alu_uart.v
Parsing Verilog input from `up_dw_alu_uart.v' to AST representation.
Storing AST representation for module `$abstract\alu_top'.
Storing AST representation for module `$abstract\ctr_up'.
Storing AST representation for module `$abstract\ctr_down'.
Storing AST representation for module `$abstract\alu'.
Successfully finished Verilog frontend.
yosys>
I could see my four modules, so that looked good. Next I ran help just to see the available commands. It displayed 308 lines. One of the commands is ls, which lists the modules currently loaded.
I then ran:
-check
also check the design hierarchy. this generates an error when
an unknown module is used as cell type.
-top <module>
use the specified top module to build the design hierarchy. Modules
outside this tree (unused modules) are removed.
yosys> hierarchy -check -top alu_top
3. Executing HIERARCHY pass (managing design hierarchy).
4. Executing AST frontend in derive mode using pre-parsed AST for module `\alu_top'.
Generating RTLIL representation for module `\alu_top'.
4.1. Analyzing design hierarchy..
Top module: \alu_top
ERROR: Module `\uart_tx' referenced in module `\alu_top' in cell `\u_uart' is not part of the design.
I got an error because of the UART library. At first I wasn't sure if I should ignore it this time or investigate it further. I was also curious if I could modify the Verilog code while Yosys was already running.
I found out that I can, but I would have to re-read the file afterwards.
I also realized that I had to read the uart_tx.v library as well.
I copied the library into the directory, opened Yosys again and ran:
This time the UART module also appeared.
2. Executing Verilog-2005 frontend: lib/uart_tx.v
Parsing Verilog input from `lib/uart_tx.v' to AST representation.
Generating RTLIL representation for module `\uart_tx'.
Successfully finished Verilog frontend.
I then ran the hierarchy command again and got messages like this:
3.4. Analyzing design hierarchy..
Top module: \alu_top
Used module: $paramod$f6ca900275f16cbf280bd6b10c3f9b8b97db50c1\uart_tx
Used module: \alu
Used module: \ctr_down
Used module: \ctr_up
Removing unused module `\uart_tx'.
Removed 1 unused modules.
Nothing looked wrong. It looked like it was generating RTLIL, removing unused modules, and renaming some modules.
I also noticed the $paramod$ prefix and looked it up:
-naming_attr <attr>
once a specialization is derived, use the value of the module attribute
<attr> for a name which should be used for the derived module (this
replaces the internal Yosys naming scheme in which the names of derived
modules start with '$paramod$')
Running synthesis
Next step was the actual synthesis.
After the hierarchy step I expected to see some gates, so I ran:
This produced a report of about 1540 lines.
The design hierarchy looked good. Here are some of the things I found:
-
174 cells
-
29 flip-flops
-
49 ANDNOT and 7 NAND gates (At first I thought they were the same, but I found out:)
-
ANDNOT =
A & ~B -
NAND =
~(A & B)
Other notes from the report:
- No latches detected
- Async reset detected
- Final result:
Found and reported 0 problems.
Full report here: synth_report.txt
In Yosys
statreprints the whole report whilecheckonly shows the last section.

Technology mapping
Next I ran two commands:
dfflibmap -liberty /foss/pdks/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib
abc -liberty /foss/pdks/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib
I got some warnings at this stage, but after checking them it looked normal and safe to continue.
From the ABC output I could see that it was selecting cells such as:
The purpose of these steps is:
dfflibmapmaps sequential logic (flip-flops)abcmaps combinational logic (logic gates)
This stage takes generic Yosys primitives like:
and maps them to real technology cells like:
from the Sky130 standard cell library.
This was quite a fascinating stage and I was satisfied that the mapping had worked.

Cleaning and writing the netlist
Next I ran:
This step basically tidies up the netlist and removes wires or cells that are no longer used.
Finally I wrote out the synthesized design:
Yosys printed the following messages:
10. Executing Verilog backend.
10.1. Executing BMUXMAP pass.
10.2. Executing DEMUXMAP pass.
Dumping module `$paramod$f6ca900275f16cbf280bd6b10c3f9b8b97db50c1\uart_tx'.
Dumping module `\alu'.
Dumping module `\alu_top'.
Dumping module `\ctr_down'.
Dumping module `\ctr_up'.
Using ls I could see that a new file had been created:
The file contains about 1357 lines and represents the final gate-level netlist of the design.
You can find the file here: synth.v
It's also possible to run Yosis with one line:
Or run it with a TLC script:
Before closing Yosys I ran the check command. The tool reported several warnings about wires that were used but had no driver. Looking closer at it, these were related to unused or partially connected signals in the example modules and did not prevent the synthesis from completing.
It seems like this could likely be cleaned up by running stat again and then using clean. There is also a related command opt_clean.
Since I'm not actually taping anything out and just practicing the synthesis flow, I did not investigate this further.

Pipeline diagram
To wrap this up I added a diagram of the synthesis pipeline. Seeing the steps visually helped me understand what Yosys is actually doing under the hood, from reading the RTL all the way to producing the final Sky130 gate-level netlist.
Place and route flow - OpenROAD
I began by looking at the OpenROAD documentation and the class example. The OpenROAD workflow looks similar to Yosys in the sense that it also runs in an interactive shell. There also seems to be some GUI functionality available, but at this stage I did not explore that yet. I made a quick diagram similar to the one I did for the Yosys flow to get an overview.
There is also an option to run the flow using a .tcl script, but I decided to execute each step interactively to better understand what happens at each stage. I typed openroad in the terminal to open the shell and it printed a rather minimal output:
/foss/designs/s6/uart > openroad
OpenROAD 26Q1-990-g15af3a5c0
Features included (+) or not (-): +GPU +GUI +Python
This program is licensed under the BSD-3 license. See the LICENSE file for details.
Components of this program may be licensed under more restrictive licenses which must be honored.
openroad>
The first step was to read the technology files from the Sky130 PDK. This is done with two commands:
read_lef $::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lef/sky130_fd_sc_hd.lef
read_liberty $::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib
The .lef file (Library Exchange Format) describes the physical layout information of the standard cells.
The .lib (Liberty) file describes the timing and electrical behavior of the cells.
When I ran this command I got a long list of warnings about undefined layers such as li1, met1, pwell, and nwell, as well as warnings about an unknown site called unithd. At first glance the messages looked confusing because they repeatedly contained the word error inside the warning lines.

However, OpenROAD also printed the following message at the end:
[INFO ODB-0227] LEF file: /foss/pdks/sky130A/libs.ref/sky130_fd_sc_hd/lef/sky130_fd_sc_hd.lef, created 437 library cells
At this point I decided to pause and check whether this behavior was expected before continuing with the flow. While looking through the documentation and other student examples I noticed that a more complete flow was described in Luis documentation. He encountered the same errors and had worked out a slightly different flow. He had also added the .tlef file in the technology setup.

I looked inside the sky130_fd_sc_hd__nom.tlef file and could see some information for li1, met1, pwell, and nwell. I didn't find too much information explaining the .tlef itself, but I did find this paper by Jui-Hsin Hung and Jaijeet Roychowdhury. On page 18 it explains:
"Technology Library Exchange Format (.tlef) file: Contains physical properties of all layers/vias and design rules related to their geometry."
Second Route and Flow Attempt
With a new flow reference I began by running these commands:
set design_name alu_top
set top_module alu_top
set netlist "synth.v"
set sdc_file "constraints.sdc"
set out_dir "openroad_out"
file mkdir $out_dir
set pdk_root $::env(PDK_ROOT)
set is used to create a variable and assign a value to it. These variables can then be reused later in the script so paths and file names only need to be defined once.
When running these commands OpenROAD did not print any additional output, which suggested the variables were created successfully.
Next I ran the technology setup:
read_lef $pdk_root/sky130A/libs.ref/sky130_fd_sc_hd/techlef/sky130_fd_sc_hd__nom.tlef
read_lef $pdk_root/sky130A/libs.ref/sky130_fd_sc_hd/lef/sky130_fd_sc_hd.lef
read_liberty $pdk_root/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib
This time the commands executed cleanly and the long list of layer warnings from the earlier attempt did not appear. OpenROAD reported that it created 14 routing layers, 25 vias, and 437 standard cells, which confirmed that the technology and library data had been loaded correctly.
After that I loaded the synthesized netlist and linked the top module:
These commands also produced no additional output, which indicated that the design was read and linked successfully.
I had not created the constraints file yet, so I created a minimal constraints.sdc file before continuing. The constraints file only needs to define the clock for the design:
This defines a clock with a period of 20 ns, corresponding to a 50 MHz clock frequency. Then I ran:
Again there was no output. Next was initializing the floorplan, which defines the space that the design can take.
-
die_area - total chip size
-
core_area - region where standard cells are placed
-
site unithd - the row type used for Sky130 standard cells
to run that I used:
I did get a output this time reading this:
[WARNING IFP-0028] Core area lower left (20.000, 20.000) snapped to (20.240, 21.760).
[INFO IFP-0001] Added 58 rows of 347 site unithd.
[INFO IFP-0100] Die BBox: ( 0.000 0.000 ) ( 200.000 200.000 ) um
[INFO IFP-0101] Core BBox: ( 20.240 21.760 ) ( 179.860 179.520 ) um
[INFO IFP-0102] Core area: 25181.651 um^2
[INFO IFP-0103] Total instances area: 1451.392 um^2
[INFO IFP-0104] Effective utilization: 0.058
[INFO IFP-0105] Number of instances: 145
openroad>
The warning told me it had adjusted the size. Looking into it, I learned that this has to do with the placement grid snapping correctly. The rest of the output gave a summary of the die area, core area, and utilization. My design only used a small fraction of the available core area:
- Core area: 25181.651 um^2
- Total instances area: 1451.392 um^2
- Effective utilization: 0.058
I then ran:
Make tracks gave no feedback and place pins reported this:
Found 0 macro blocks.
Using 2 tracks default min distance between IO pins.
[INFO PPL-0001] Number of available slots 718
[INFO PPL-0002] Number of I/O 9
[INFO PPL-0003] Number of I/O w/sink 9
[INFO PPL-0004] Number of I/O w/o sink 0
[INFO PPL-0005] Slots per section 200
[INFO PPL-0008] Successfully assigned pins to sections.
[INFO PPL-0012] I/O nets HPWL: 927.58 um.
This showed that OpenROAD found 9 top-level I/O pins in the design and placed them successfully around the die boundary. I then ran the next comands:
Global placement outputed a long list with some interesting information in the end:
[INFO GPL-1001] Global placement finished at iteration 409
[INFO GPL-1002] Placed Cell Area 1578.8683
[INFO GPL-1003] Available Free Area 25181.6512
[INFO GPL-1004] Minimum Feasible Density 0.0700 (cell_area / free_area)
[INFO GPL-1006] Suggested Target Densities:
[INFO GPL-1007] - For 90% usage of free space: 0.0697
[INFO GPL-1008] - For 80% usage of free space: 0.0784
[INFO GPL-1009] - For 50% usage of free space: 0.1254
[INFO GPL-1014] Final placement area: 1578.87 (+0.00%)
Detailed placement also gave a nice summary:
Placement Analysis
---------------------------------
total displacement 275.1 u
average displacement 1.9 u
max displacement 5.3 u
original HPWL 1759.0 u
legalized HPWL 2064.1 u
delta HPWL 17 %
-
global_placement finds rough positions for the cells
-
detailed_placement snaps them into legal rows and sites
Next was the routing, which is done with:
global_route took almost no time and gave no feedback, while detailed_route took about 12 seconds to run.
- global_route: The router decides the rough paths that connections should take across the chip.
- detailed_route: The wires are placed exactly on the metal tracks and vias according to the technology rules.
[INFO DRT-0267] cpu time = 00:00:12, elapsed time = 00:00:12, memory = 567.96 (MB), peak = 567.40 (MB)
The next and final step was to write the outputs. For that I ran:
That gave no feedback, but I now had two new files in the directory: alu_top.def and alu_top_pnr.v.
I could now run the reports, which summarized some of the results from going through these steps.
Here are the commands for the reports:
I got this output from that:
openroad> report_checks
Startpoint: u_uart/_226_ (rising edge-triggered flip-flop clocked by clk)
Endpoint: u_uart/_227_ (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
---------------------------------------------------------
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 ^ u_uart/_226_/CLK (sky130_fd_sc_hd__dfrtp_1)
0.38 0.38 v u_uart/_226_/Q (sky130_fd_sc_hd__dfrtp_1)
0.79 1.17 ^ u_uart/_173_/Y (sky130_fd_sc_hd__nor4bb_1)
0.37 1.55 v u_uart/_193_/Y (sky130_fd_sc_hd__a2111oi_0)
0.26 1.81 v u_uart/_197_/X (sky130_fd_sc_hd__and2_0)
0.22 2.03 ^ u_uart/_203_/Y (sky130_fd_sc_hd__a221oi_1)
0.00 2.03 ^ u_uart/_227_/D (sky130_fd_sc_hd__dfrtp_1)
2.03 data arrival time
20.00 20.00 clock clk (rise edge)
0.00 20.00 clock network delay (ideal)
0.00 20.00 clock reconvergence pessimism
20.00 ^ u_uart/_227_/CLK (sky130_fd_sc_hd__dfrtp_1)
-0.10 19.90 library setup time
19.90 data required time
---------------------------------------------------------
19.90 data required time
-2.03 data arrival time
---------------------------------------------------------
17.87 slack (MET)
openroad>
Doing this step by step took longer than running Yosys, but I'm glad I did it. It gave me a better understanding and will make it easier to use a script in the future.
Layout in KLayout
At this point I wanted to take a look at the layout in Klayout. I imported the alu_top.def and .lef and .tlef. What I saw was not what I expected and I was not sure if I should be impressed or not. I could see some of the routing but no cells.

I found some information on how to make GDS with klayout but that looked a bit complex and I was unable to get it to work. I ended up fiding something called strm2gds that is part of Klayout and works in terminal. I typed it in the terminal and it was there I ran it with help to how it worked since there was not any documentation I could find on-line.
/foss/designs > strm2gds -h
Usage:
strm2gds [options] <input> <output>
This program will convert the given file to a GDS2 file
Input options - LEF/DEF specific:
--lefdef-lef-layouts Layout files for resolving FOREIGN LEF cells from
This option applies when reading DEF files.
Use a comma-separated list of file names here to specify which layout
files to use for resolving LEF macros. This applies when LEF macros
are specified with FOREIGN. By using '--lefdef-macro-resolution-mode'
you can force external resolution (assume FOREIGN always) or turn it
off (ignore FOREIGN).
I ran it a couple of times getting errors but eventually got it to work using this command:
strm2gds alu_top.def alu_top.gds \
--lefdef-lef-layouts /foss/pdks/sky130A/libs.ref/sky130_fd_sc_hd/lef/sky130_fd_sc_hd.merged.lef,/foss/pdks/sky130A/libs.ref/sky130_fd_sc_hd/gds/sky130_fd_sc_hd.gds
I now had a GDS file that I opened in Klayout. It was nice to see the cells and they were organized into a grid.


I did notes that even tough this had somewhat worked there was no power grid. So I went to look at the flow and saw that I probably missed that step and also the clock step.
Layout second attempt
Looking back at the script on the class page and what I had been running I notes that I had not ran the clock or power command. This time I made a script and ran it with Openroad. I discovered that open-road has a GUI that you can open with gui::show opening the GUI I could get a clear picture of the layout. I saw the power-rail was still missing and it looked like three cells were overlapping. I used the Tcl interface to rerun the command that was very useful allowing me to see visually what was happening.

Power Grid
The power grid sems like a critical part to have in the layout so I looked at that first. There were two things that cauth my atention it looked like the global route was not doing any thing and also the pdngen did not seam to work. I was able to find documentaion on the Power Distribution Network Generator and found out it might be missing some arguments and definition. I also notes that the might be a problem with the naming of "VSS and VDD" in sky130 it uses "VPWR and VGND". Was able to find I needed to run this:
This ties the cells to the power grid runnig this made blocks on the floor plan. next I had to define the VDD and VSS naming I did that useing these commands:
set_voltage_domain -power VDD -ground VSS
define_pdn_grid -name "stdcell_grid" -starts_with POWER
add_pdn_stripe -grid "stdcell_grid" -layer "met1" -width 0.48 -pitch 5.44 -offset 0 -extend_to_core_ring
add_pdn_stripe -grid "stdcell_grid" -layer "met4" -width 1.6 -pitch 27.0 -offset 13.5 -extend_to_core_ring
add_pdn_connect -grid "stdcell_grid" -layers {met1 met4}
pdngen
This made the power grid on the floor plan next I made a power ring around the design at this point I was trying to connect the grid to the outside world. I ran these command to make the ring:
add_pdn_stripe -grid "stdcell_grid" -layer "met4" -width 1.6 -pitch 27.0 -offset 13.5 -extend_to_core_ring
add_pdn_ring -grid "stdcell_grid" -layers {met4 met5} \
-widths {2.0 2.0} \
-spacings {1.7 1.7} \
-core_offsets {2.0 2.0} \
-add_connect
add_pdn_connect -grid "stdcell_grid" -layers {met1 met4}
add_pdn_connect -grid "stdcell_grid" -layers {met4 met5}
pdngen
Now I had a much more complete layout I had outside connection for the I/O pins but not for the power but at least the cells were connected to the power grid.


At this point I paused a bit I was not sure if I should downscale the Verilog code and run it trough Yosys and OpenROAD again, if I should look into the make file or continue on this design and make a script and change some things like the floor plan size since I was only using a fraction of the space.
I was impressed with the OpenROAD GUI it was a game changer when it comes to debugging and understanding the flow.
Third attempt - Synthesis, route and place
After a bit of thinking I decided to look closer at the class examples there was a make file there that basically just did the whole run in on take. I tried the fortune-tell example and ran make build-fortune this just ran the whole Yosis and open road in a only about 2 minutes. I could then open Klayout with make view-fortune and in Klayout I could open the GDS file and see the cell layout, very impressive work behind this.

I looked at the make file and what is was actually doing I though about just renaming my code and put replace it but then I saw the makefile was running two scripts one for Yosys and another one for OpenROAD. I then figured I could just try to use that in my project directory. I decided to start fresh so I made a new project directory with only my Verilog code. I then took the library and flow directories and place them with in my project. The flow scrip had nice comments how to run this so I adapted it to my project. I had to modify the scrip a little just taking the paths with ../ and remove one dot ./
I started by running the synthesis again with:
That ran smoothly and took under a minute I now had a new synth.v file that I could feed into the next step witch was OpenROAD that I ran with:
It took a little longer but just a few minutes I kept OpenROAD open this time so I could open the GUI and inspect it after it was done I typed gui::show in the shell and it opened the GUI I was impressed to see a nicely laid out cells with power and every thing needed to make it work.
Layout view
I took time to inspect and view various things in OpenROAD it gives you alot of information. You can look at just the net and from there you can isolate the types of signals. I verified that the clock signal was there. then I looked at the cells I could see some filler cells and then I could see the module cells that were nicely color coded by there role the UART modules took up most of the space.

the net layout

cell layout with color code and without the filler cells

The I/O connections
Generate GDS
I looked at how the MAKE file made the GDS. It did't look mutch diffrent from what I had seen earlier so I ran the same command again:
strm2gds alu_top.def alu_top.gds \ --lefdef-lef-layouts /foss/pdks/sky130A/libs.ref/sky130_fd_sc_hd/lef/sky130_fd_sc_hd.merged.lef,/foss/pdks/sky130A/libs.ref/sky130_fd_sc_hd/gds/sky130_fd_sc_hd.gds
I opend the GDS file in Klayout and this time it looked a lot better. I could see the power rails, the filler cells and the instance cells. I also looked at the I/O and all the signals were there. I'm not sure how the power rails are connected out side from the chip, it looked like that can just be done by putting a wire on the rails.

3D render
After hours in the terminal and 2D land. I took a break to look at some 3D options Tiny Tape out have a drag and drop version that is pretty intuitive and nice. I did how ever want to try this GDS to .stl that I came across from session 3. It's pretty simple to run I cloned the repo made a virtual environment .venv and ran my files with no problems. It produced 7 .stl files that had one layer. I imported to blender I had to do a little bit of assembly and scale the Z axis. It's not by any means in scale but it was a nice way to visualize how things are routed and placed.


Analyze timing reports - identify and fix any violations
I had actually closed OpenROAD, but I had saved a .db file so I could open it again. I realized I had the fortune-tell constraints loaded, so I changed them to this:
To get the reports working again I ran this in the Tcl interface:
read_db /foss/designs/s6/alut/alu.db
read_liberty /foss/pdks/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib
read_sdc /foss/designs/s6/alut/lib/constraints.sdc
Timing report
To get the timing report I ran report_checks and got these numbers:
-
Data arrival time: 2.03 ns
-
Data required time: 19.40 ns
-
Slack: 17.37 ns (MET)
The slack is the most important number. It should be above zero. If it goes below zero, that means there is a timing violation. I found some good information from the MICRO 2022 by OpenROAD:
"Slack" is the difference between the constraint (0.46ns) and the actual signal propagation time. Positive slack means the constraint is met ("there is extra slack"). Negative slack means the constraint is violated.
So for example, if I had set the constraint to 1 ns, or if the data arrival time had been 20 ns, that would have caused a violation and the slack would have been negative. (MET) means the timing constraint was met. If not, the report would say (VIOLATED).
| Slack | Meaning |
|---|---|
| positive | timing OK |
| zero | exactly on limit |
| negative | timing violation |
Here is the full timing report:
Startpoint: u_uart/_110_ (rising edge-triggered flip-flop clocked by clk)
Endpoint: u_uart/_111_ (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
---------------------------------------------------------
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 ^ u_uart/_110_/CLK (sky130_fd_sc_hd__dfrtp_1)
0.38 0.38 v u_uart/_110_/Q (sky130_fd_sc_hd__dfrtp_1)
0.79 1.17 ^ u_uart/_057_/Y (sky130_fd_sc_hd__nor4bb_1)
0.37 1.55 v u_uart/_077_/Y (sky130_fd_sc_hd__a2111oi_0)
0.26 1.81 v u_uart/_081_/X (sky130_fd_sc_hd__and2_0)
0.22 2.03 ^ u_uart/_087_/Y (sky130_fd_sc_hd__a221oi_1)
0.00 2.03 ^ u_uart/_111_/D (sky130_fd_sc_hd__dfrtp_1)
2.03 data arrival time
20.00 20.00 clock clk (rise edge)
0.00 20.00 clock network delay (ideal)
-0.50 19.50 clock uncertainty
0.00 19.50 clock reconvergence pessimism
19.50 ^ u_uart/_111_/CLK (sky130_fd_sc_hd__dfrtp_1)
-0.10 19.40 library setup time
19.40 data required time
---------------------------------------------------------
19.40 data required time
-2.03 data arrival time
---------------------------------------------------------
17.37 slack (MET)
Power Report
After analyzing the timing I also generated a power report in OpenROAD using report_power
The report divides the power into three main categories:
- Internal power – power consumed inside logic gates
- Switching power – power used when charging and discharging wires
- Leakage power – static transistor leakage when idle
From the report I got these numbers:
- Internal power: 1.15e-04 W
- Switching power: 1.92e-05 W
- Leakage power: 6.86e-10 W
Total power consumption:
1.35e-04 W (≈ 135 µW)
Group Internal Switching Leakage Total
Power Power Power Power (Watts)
----------------------------------------------------------------
Sequential 6.03e-05 8.25e-07 3.23e-10 6.11e-05 45.4%
Combinational 2.73e-06 2.25e-06 2.83e-10 4.98e-06 3.7%
Clock 5.25e-05 1.62e-05 7.99e-11 6.86e-05 50.9%
Macro 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0%
Pad 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0%
----------------------------------------------------------------
Total 1.15e-04 1.92e-05 6.86e-10 1.35e-04 100.0%
85.7% 14.3% 0.0%
Other useful reports
I saw there were several other commands available in the Tcl (~30) and I tried a few.
| Command | Purpose |
|---|---|
report_worst_slack |
Quickly prints the worst slack value |
report_design_area |
Reports total cell area and utilization |
report_clock_latency |
Reports clock network latency |
report_cell_usage |
Shows which standard cells are used . |
report_pulse_width_checks |
Shows required and actual pulse widths |
report_dont_touch |
Lists objects marked as "dont_touch" |
report_floating_nets did give me this warning: [WARNING RSZ-0020] found 2 floating nets.
I learned that reports are definitely a powerful tool for debugging and can give useful information about the design before tape-out.
Reflection
This session left me feeling like I had mapped out a whole cave full of random corners to get lost in. After every assignment I kept thinking: how much deeper does this actually go?
In the end I was glad that the report part was relatively error free and actually much more satisfying than I expected. Seeing something go from an ASCII text Verilog file to silicon n-wells and polysilicon gates, and somewhat understanding how that transformation happens, really makes you appreciate the technology we have around us.
It is also truly amazing to witness more open-source tools like Yosys and OpenROAD becoming established for the future. Seeing this ecosystem grow makes it feel like chip design is slowly becoming more accessible, much like what happened earlier with open-source software and digital fabrication tools.