Description
CTS-0105 ("Net already has clock buffer... Skipping") still fires on OpenROAD 26Q1-2966-g29d97c45b3 despite the fix in PR #7134 (commit 25acd37).
The fix correctly checks inst->getSourceType() == dbSourceType::TIMING before skipping, but all Yosys SYNTH_HIERARCHICAL output port buffers arrive in the ODB with source type TIMING instead of NETLIST. So the check passes and CTS still skips the clock net.
Root cause
When a clock input is forwarded to an output port (e.g., AXI m_aclk = clk), Yosys hierarchical synthesis inserts a buffer (output####) on the passthrough path. By the time CTS runs, these buffers have dbSourceType::TIMING in the ODB — even though no CTS or timing repair step inserted them. This causes the PR #7134 fix to incorrectly classify them as CTS-inserted buffers and skip the clock net.
Verified with OpenROAD Tcl on the post-placement ODB (before CTS runs):
output10: master=BUFx2_ASAP7_75t_R source=TIMING
output11: master=BUFx2_ASAP7_75t_R source=TIMING
...
All output* instances from Yosys have TIMING source — not just the one on the clock net.
Reproducer
Minimal 40-line design — a counter with assign clk_out = clk:
clk_passthrough.v
module counter (
input wire clk,
input wire reset,
input wire [7:0] d,
output reg [7:0] q
);
always @(posedge clk) begin
if (reset)
q <= 8'b0;
else
q <= q + d;
end
endmodule
module clk_passthrough_top (
input wire clk,
input wire reset,
input wire [7:0] din,
output wire [7:0] dout,
output wire clk_out
);
assign clk_out = clk;
counter u_counter (
.clk (clk),
.reset (reset),
.d (din),
.q (dout)
);
endmodule
constraint.sdc
current_design clk_passthrough_top
set clk_period 500
create_clock -name clk -period $clk_period [get_ports clk]
set_input_delay [expr $clk_period * 0.2] -clock clk [all_inputs -no_clocks]
set_output_delay [expr $clk_period * 0.2] -clock clk [all_outputs]
set_false_path -from [get_ports reset]
Build with ORFS on asap7 with SYNTH_HIERARCHICAL=1, CORE_UTILIZATION=50.
CTS log output:
[INFO CTS-0007] Net "clk" found for clock "clk".
[WARNING CTS-0105] Net "clk" already has clock buffer output10. Skipping...
[WARNING CTS-0105] Net "clk_out" already has clock buffer output10. Skipping...
[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.
Impact
The NyuziProcessor design (352k cells, 55 SRAM macros, 41,040 clock sinks) forwards clk to output m_aclk for AXI. CTS inserts 0 buffers, leaving all flops on a raw unbuffered clock net. Post-global-route extraction yields ~388 ns of clock insertion delay on a 1.6 ns target period, making the design unroutable.
Suggested fix
The source type issue is upstream of CTS — the output* buffers from Yosys synthesis should have dbSourceType::NETLIST, not TIMING. Either:
- Fix whatever ORFS flow step is setting
TIMING source on synthesis-inserted buffers, or
- Have CTS use a more robust heuristic than source type alone (e.g., check instance naming convention, or check if the buffer was present before any CTS/resizer pass)
Related
Version
- OpenROAD:
26Q1-2966-g29d97c45b3
- ORFS image:
docker.io/openroad/orfs:26Q2-32-gca75a11e2
Description
CTS-0105 ("Net already has clock buffer... Skipping") still fires on OpenROAD
26Q1-2966-g29d97c45b3despite the fix in PR #7134 (commit 25acd37).The fix correctly checks
inst->getSourceType() == dbSourceType::TIMINGbefore skipping, but all YosysSYNTH_HIERARCHICALoutput port buffers arrive in the ODB with source typeTIMINGinstead ofNETLIST. So the check passes and CTS still skips the clock net.Root cause
When a clock input is forwarded to an output port (e.g., AXI
m_aclk = clk), Yosys hierarchical synthesis inserts a buffer (output####) on the passthrough path. By the time CTS runs, these buffers havedbSourceType::TIMINGin the ODB — even though no CTS or timing repair step inserted them. This causes the PR #7134 fix to incorrectly classify them as CTS-inserted buffers and skip the clock net.Verified with OpenROAD Tcl on the post-placement ODB (before CTS runs):
All
output*instances from Yosys haveTIMINGsource — not just the one on the clock net.Reproducer
Minimal 40-line design — a counter with
assign clk_out = clk:clk_passthrough.v
constraint.sdc
Build with ORFS on asap7 with
SYNTH_HIERARCHICAL=1,CORE_UTILIZATION=50.CTS log output:
Impact
The NyuziProcessor design (352k cells, 55 SRAM macros, 41,040 clock sinks) forwards
clkto outputm_aclkfor AXI. CTS inserts 0 buffers, leaving all flops on a raw unbuffered clock net. Post-global-route extraction yields ~388 ns of clock insertion delay on a 1.6 ns target period, making the design unroutable.Suggested fix
The source type issue is upstream of CTS — the
output*buffers from Yosys synthesis should havedbSourceType::NETLIST, notTIMING. Either:TIMINGsource on synthesis-inserted buffers, orRelated
Version
26Q1-2966-g29d97c45b3docker.io/openroad/orfs:26Q2-32-gca75a11e2