Project 5, Part 1: The Broken Design and the Evidence
Every other project in this module gave you working RTL and asked you to carry it forward. This one does the opposite. The design has already been through synthesis, floorplan, placement, CTS and routing, and its signoff run produced three failing reports. Nobody is going to tell you what is wrong yet. That is the exercise. It is the physical design version of the bug-hunting capstone the Verilog course ended with: the evidence is real and in front of you, and the reasoning is yours.
The design is Project 2’s UART, uart_top, run through the flow a second time, with some things planted before this run started. In this article I just present the evidence. Read it slowly.
Report one: DRC
Magic’s DRC on the final GDS, with the script from Module 8.1:
Metal2 spacing < 0.14um (met2.2)
----------------------------------------
212.400 88.600 214.100 89.000
COUNT: 1
One violation, one layer. The report gives a location but, like every DRC report, no net names; DRC knows nothing about nets. To find out what is there, open the layout at that box in the OpenROAD GUI (which knows the nets) or in KLayout, as in Section 9.2. Doing that shows:
- Two met2 shapes 0.11 µm apart, against a 0.14 µm rule.
- One belongs to a net called
rx_valid_fix_net. It is a single, perfectly straight met2 segment, 6.2 µm long, at minimum width, with no jogs and no vias along its length. - The other is an ordinary routed segment of the
tx_busynet.
Note the description of the first shape carefully. It will matter.
Report two: LVS
Netgen, comparing the extracted layout with the final netlist OpenLane wrote for this run. The relevant parts, trimmed and simplified:
Number of devices: 432 **Mismatch** |Number of devices: 431 **Mismatch**
Number of nets: 590 **Mismatch** |Number of nets: 589 **Mismatch**
...
Instance: _eco_buf_9 (sky130_fd_sc_hd__buf_4)|(no matching instance)
...
Net: rx_valid |Net: rx_valid
sky130_fd_sc_hd__dfxtp_1/Q = 1 | sky130_fd_sc_hd__dfxtp_1/Q = 1
sky130_fd_sc_hd__buf_4/A = 1 | sky130_fd_sc_hd__buf_2/A = 1
sky130_fd_sc_hd__buf_2/A = 1 |
...
Netlists do not match.
(Device counts here are the logic cells only, for readability; the real report also counts taps, decaps and fillers.) One extra instance in the layout that the netlist has never heard of, _eco_buf_9. One extra net. And the net rx_valid has one more pin in the layout than in the netlist: the input of that same buffer. Everything is off by exactly one, in the same direction.
Report three: signoff timing
The flow’s multi-corner STA passes at tt (worst setup slack +2.10 ns) and at ff (+2.94 ns). At ss it fails:
Corner: ss_100C_1v60
Startpoint: baud_tick_reg Endpoint: tx_shift_reg[0] Path Type: max
Delay Time Fanout Description
0.31 0.31 clock latency at baud_tick_reg
5.61 5.92 42 baud_tick_reg/Q (sky130_fd_sc_hd__dfxtp_1)
0.46 6.38 wire to the farthest load
4.63 11.01 mux2, a21oi, mux2 to tx_shift_reg[0]/D
11.01 data arrival time
10.00 10.34 clock period + capture clock latency (0.34)
-0.25 10.09 clock uncertainty and setup
10.09 data required time
-0.92 slack (VIOLATED)
Only the slow corner fails. And this report has a column the others did not need: a fanout of 42 on the output of baud_tick_reg, a single small flop whose clock-to-Q delay, 5.61 ns, is more than half of the clock period.
Notice what none of the three reports tells you. None names a cause, a mistake or a fix. No tool report ever does. A DRC report says some geometry breaks a rule. An LVS report says two netlists disagree. An STA report says a path is too slow at a corner. Getting from those facts to “this is what went wrong, and why” is a skill, not something the tools do for you, and it is the skill this project is for.
Practice Exercise
Before the next article walks through the reasoning, form your own hypotheses. Look at the description of rx_valid_fix_net (a single straight segment, minimum width, no jogs or vias) and at the name of the extra instance, _eco_buf_9. What do those details suggest about how the first two problems came about, even before you think about the timing violation?
Solution
Neither detail proves anything on its own, but both point the same way. The detailed router rarely produces a perfectly straight, minimum-width run with no vias that stops 0.11 µm from a neighbour: its routes follow the track grid, jog and change layer as needed, and above all keep clearance, since that is its whole job. A straight wire that ignores its neighbour looks like one drawn by hand or by a small script, outside the router.
The instance name is a second clue. Yosys and OpenROAD name their instances systematically (_1532_, hold12, rebuffer3 and the like). A name with “eco” in it, and a net name ending in “fix_net”, look like things a person typed during a manual edit. Neither tells us the full story yet, but they are the small, specific tells the next article builds into a diagnosis.
Three reports, three real problems, and deliberately no explanation. In the next article we work through each one in turn, using the diagnostic habits of Modules 6, 7 and 8, and arrive at a specific cause for each.