I've started investigating some CTS issues - clock...
# openroad
a
I've started investigating some CTS issues - clock tree skew and clock delay are quite high
Baseline:
Copy code
Clock user_clock2
Latency      CRPR       Skew
_127845_/CLK ^
   8.21
_122164_/CLK ^
   5.77     -0.13       2.31
That's using
Copy code
set ::env(ROOT_CLK_BUFFER) sky130_fd_sc_hd__clkbuf_16
set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_2 sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
Seems a bit strange we'd need a
clkbuf_16
on the root, considering with are only driving 2 gates. Also strange, is we seem to be using a
clkbuf_16
for the leaf nodes, so I guess
-root_clk_buf
is for both root and leaf
I also wonder if CTS is making intelligent decisions with the choice of buffers. As an experiment I just gave it clkbuf_4:
Copy code
set ::env(CTS_CLK_BUFFER_LIST) {sky130_fd_sc_hd__clkbuf_4}
set ::env(CTS_ROOT_BUFFER) {sky130_fd_sc_hd__clkbuf_4}
A slight improvement:
Copy code
Clock user_clock2
Latency      CRPR       Skew
_123645_/CLK ^
   7.90
_127643_/CLK ^
   5.74     -0.13       2.03
Apart from that, I notice we are added a large number of buffers along wires. Seems like too many to me. I tried modifying that behaviour:
Copy code
unsigned maxWirelength = (_charBuf->getHeight() * 10)
                            * wirelengthIterations;  // Hard-coded limit
   if (_options->getWireSegmentUnit() == 0) {
-    unsigned charaunit = _charBuf->getHeight() * 10;
+    unsigned charaunit = _charBuf->getHeight() * 200;
     _options->setWireSegmentUnit(charaunit);
   } else {
That helped quite significantly:
Copy code
Clock user_clock2
Latency      CRPR       Skew
_124062_/CLK ^
   5.48
_130501_/CLK ^
   3.61     -0.24       1.63
I was thinking about the over buffering and realise the change above isn't what we want. Would it make sense instead to call
findMaxWireLength()
against all the buffer cells and pick the shortest length and set
maxWirelength
to that?