`write_verilog -include_pwr_gnd` not working properly for buffers created by resizer
Confession: I'm not sure if this is been a long-standing problem we've been working around before or if there's an oversight on my part, but:
- OpenROAD e036ecf
OpenROAD e036ecfaca4bc0efe88a54085efcf0f562c48a6b
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.
[INFO]: Setting RC values...
[INFO RSZ-0027] Inserted 35 input buffers.
[INFO RSZ-0028] Inserted 1 output buffers.
[INFO RSZ-0058] Using max wire length 4269um.
[INFO RSZ-0039] Resized 244 instances.
Placement Analysis
---------------------------------
total displacement 1157.9 u
average displacement 2.3 u
max displacement 30.4 u
original HPWL 4786.3 u
legalized HPWL 5851.1 u
delta HPWL 22 %
[INFO DPL-0020] Mirrored 146 instances
[INFO DPL-0021] HPWL before 5851.1 u
[INFO DPL-0022] HPWL after 5637.3 u
[INFO DPL-0023] HPWL delta -3.7 %
Writing OpenROAD database to ./out.odb...
Writing powered netlist to ./out.nl.v...
Writing layout to ./out.def...
Writing timing constraints to ./tmp/placement/8-resizer.sdc...
min_report
===========================================================================
report_checks -path_delay min (Hold)
============================================================================
No paths found.
min_report_end
max_report
===========================================================================
report_checks -path_delay max (Setup)
============================================================================
No paths found.
max_report_end
check_report
===========================================================================
report_checks -unconstrained
============================================================================
Startpoint: y (input port)
Endpoint: _503_ (rising edge-triggered flip-flop)
Path Group: (none)
Path Type: max
Corner: tt
Fanout Cap Slew Delay Time Description
-----------------------------------------------------------------------------
0.00 0.00 ^ input external delay
0.00 0.00 0.00 ^ y (in)
1 0.00 y (net)
0.00 0.00 0.00 ^ input35/A (sky130_fd_sc_hd__clkbuf_1)
0.05 0.07 0.07 ^ input35/X (sky130_fd_sc_hd__clkbuf_1)
1 0.00 net35 (net)
0.05 0.00 0.07 ^ _206_/A (sky130_fd_sc_hd__clkbuf_4)
0.12 0.19 0.26 ^ _206_/X (sky130_fd_sc_hd__clkbuf_4)
10 0.04 _097_ (net)
0.12 0.00 0.27 ^ _207_/A (sky130_fd_sc_hd__clkbuf_4)
0.12 0.22 0.48 ^ _207_/X (sky130_fd_sc_hd__clkbuf_4)
10 0.04 _098_ (net)
0.12 0.00 0.48 ^ _316_/A (sky130_fd_sc_hd__clkbuf_4)
0.12 0.22 0.70 ^ _316_/X (sky130_fd_sc_hd__clkbuf_4)
10 0.04 _165_ (net)
0.12 0.00 0.70 ^ _364_/A1 (sky130_fd_sc_hd__a31o_1)
0.05 0.15 0.85 ^ _364_/X (sky130_fd_sc_hd__a31o_1)
1 0.00 _021_ (net)
0.05 0.00 0.85 ^ _503_/D (sky130_fd_sc_hd__dfrtp_1)
0.85 data arrival time
-----------------------------------------------------------------------------
(Path is unconstrained)
===========================================================================
report_checks --slack_max -0.01
============================================================================
No paths found.
check_report_end
check_slew
===========================================================================
report_check_types -max_slew -max_cap -max_fanout -violators
============================================================================
===========================================================================
max slew violation count 0
max fanout violation count 0
max cap violation count 0
============================================================================
check_slew_end
tns_report
===========================================================================
report_tns
============================================================================
tns 0.00
tns_report_end
wns_report
===========================================================================
report_wns
============================================================================
wns 0.00
wns_report_end
worst_slack
===========================================================================
report_worst_slack -max (Setup)
============================================================================
worst slack INF
===========================================================================
report_worst_slack -min (Hold)
============================================================================
worst slack INF
worst_slack_end
clock_skew
===========================================================================
report_clock_skew
============================================================================
clock_skew_end
power_report
===========================================================================
report_power
============================================================================
Group Internal Switching Leakage Total
Power Power Power Power (Watts)
----------------------------------------------------------------
Sequential 2.69e-13 1.02e-13 5.59e-10 5.60e-10 35.5%
Combinational 3.98e-13 4.19e-13 1.02e-09 1.02e-09 64.5%
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 6.67e-13 5.21e-13 1.58e-09 1.58e-09 100.0%
0.0% 0.0% 99.9%
power_report_end
area_report
===========================================================================
report_design_area
============================================================================
Design area 3625 u^2 45% utilization.
area_report_end
Writing OpenROAD database to ./out.odb...
Writing powered netlist to ./out.nl.v...
Writing layout to ./out.def...
Writing timing constraints to ./tmp/placement/8-resizer.sdc...
"Writing powered netlist" is done via write_verilog -include_pwr_gnd $::env(SAVE_POWERED_NETLIST), but the problem is the netlist generated is as follows:
sky130_fd_sc_hd__buf_12 input1 (.A(clk),
.X(net1));
sky130_fd_sc_hd__clkbuf_1 input2 (.A(rst),
.X(net2));
sky130_fd_sc_hd__buf_1 input3 (.A(x[0]),
.X(net3));
sky130_fd_sc_hd__buf_1 input4 (.A(x[10]),
.X(net4));
sky130_fd_sc_hd__buf_1 input5 (.A(x[11]),
.X(net5));
sky130_fd_sc_hd__buf_1 input6 (.A(x[12]),
.X(net6));
As you can see, while most cells are okay, these particular cells are lacking their power and ground ports. Again- I'm not sure if I'm simply missing something or if there's a bug here, but help would be appreciated regardless.
- Reproducible: https://www.dropbox.com/s/piz2ggy2yxljdry/repro.tar.gz?dl=0
Original issue follows:
write_verilog -include_pwr_gnd not working properly for buffers created by resizer
- OpenROAD 273a9ac3a
OpenROAD v2.0-4585-g273a9ac3a
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.
[INFO]: Setting RC values...
[INFO]: Configuring cts characterization...
[INFO]: Performing clock tree synthesis...
[INFO]: Looking for the following net(s): clk
[INFO]: Running Clock Tree Synthesis...
[INFO CTS-0049] Characterization buffer is: sky130_fd_sc_hd__clkbuf_8.
[INFO CTS-0038] Number of created patterns = 50000.
[INFO CTS-0038] Number of created patterns = 100000.
[INFO CTS-0039] Number of created patterns = 137808.
[INFO CTS-0084] Compiling LUT.
Min. len Max. len Min. cap Max. cap Min. slew Max. slew
2 8 1 35 1 48
[WARNING CTS-0043] 4752 wires are pure wire and no slew degradation.
TritonCTS forced slew degradation on these wires.
[INFO CTS-0046] Number of wire segments: 137808.
[INFO CTS-0047] Number of keys in characterization LUT: 1760.
[INFO CTS-0048] Actual min input cap: 1.
[WARNING CTS-0083] No clock nets have been found.
[INFO CTS-0008] TritonCTS found 0 clock nets.
[WARNING CTS-0082] No valid clock nets in the design.
[INFO]: Repairing long wires on clock nets...
[INFO RSZ-0058] Using max wire length 3048um.
Writing OpenROAD database to ./out.odb...
Writing powered netlist to ./out.nl.v...
Writing timing constraints to ./results/cts/spm.sdc...
"Writing powered netlist is done via" write_verilog -include_pwr_gnd $::env(SAVE_POWERED_NETLIST), but the problem is the netlist generated is as follows:
sky130_fd_sc_hd__buf_12 input1 (.A(clk),
.X(net1));
sky130_fd_sc_hd__clkbuf_1 input2 (.A(rst),
.X(net2));
sky130_fd_sc_hd__buf_1 input3 (.A(x[0]),
.X(net3));
sky130_fd_sc_hd__buf_1 input4 (.A(x[10]),
.X(net4));
sky130_fd_sc_hd__buf_1 input5 (.A(x[11]),
.X(net5));
sky130_fd_sc_hd__buf_1 input6 (.A(x[12]),
.X(net6));
As you can see, while most cells are okay, these particular cells are lacking their power and ground ports. Again- I'm not sure if I'm simply missing something or if there's a bug here, but help would be appreciated regardless.
Apologies-- I forgot the make install. Problem persists on OpenROAD 3342b3666.
input1 is already there in the input 11-spm.odb and is not generated by CTS. They would come from "buffer_ports -inputs" in resizer.tcl
Please provide a test case from the correct step
This looks like the new instances are not getting connected to the power rails, a call to global_connect (if set up correctly) would solve that. But we probably need to either ensure the new instances are connected correctly, we provide a mechanism to extract the power/ground connectivity, or the information in global connect is saved to the database so it can get called multiple times after the initial connections.
@arlpetergadfort for the near term we could use the kinda lame isWildConnected/setWildConnected that odb has already. Once we have UPF this will not be sufficient
@ahmadelrouby please consider this in your UPF work
Updated the issue in question- sorry it took me so long
Updated the issue in question- sorry it took me so long
What do you mean by this? Does the link now point at a different reproducer?
There's a dropbox link in the submission for the new reproducer.
Just wanna mention- I'm blocked on this for the ODB migration
I'll give it some attention
When reading DEF we would reprocess the power connections so that is why it used to work. With odb we just load the db and don't reprocess the connections. The best fix is to split scripts/openroad/pdn_cfg.tcl so that the add_global_connection section is separate. During pdn you would run both scripts (post-split) but at the end of the flow just run the add_global_connection script to reconnect any new standard cells so that they are powered in the Verilog.
Note there should be a call to 'global_connect' after the add_global_connection calls. It doesn't seem to matter here for some reason but is more correct.
Never mind about the global_connect, it only applies if you use -defer
Thank you- I'll report back after I try that
@donn Is that resolved?