Skip to content

rsz: detect cross-clock-domain hold violations on clock-as-data endpoints (#8075) - #12091

Merged
maliberty merged 3 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:fix/8075
Nov 1, 2026
Merged

maliberty merged 3 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:fix/8075

Conversation

@maliberty

Copy link
Copy Markdown
Member

Takes over #10718 to resolve the merge conflict

saurav-fermions and others added 3 commits June 21, 2026 04:18
…ints (The-OpenROAD-Project#8075)

findHoldViolations excluded every endpoint for which Sta::isClock() is
true. isClock() reports any pin in a clock network's combinational
fanout, which also includes register data (D) pins that sample a signal
sourced from a clock -- e.g. a clock used as data that crosses into a
different sampling-clock domain. Those D pins are legitimate hold
endpoints, so repair_timing -hold silently reported "No hold violations
found" while a real hold violation remained (issue The-OpenROAD-Project#8075).

Refine the exclusion to skip only true clock-tree pins: pins that are on
the clock network AND carry no timing check (!Vertex::hasChecks()).
Register data pins that hold a setup/hold check are kept, so cross-clock
-domain hold violations are detected and repaired. Clock-tree pins are
still excluded as before.

Add regression test repair_hold_clock_as_data where clk1 is used both as
a clock (for r1) and as data into r2/D (r2 clocked by clk2). On the
unfixed code RSZ reports "No hold violations found" and r2/D stays at
-0.59; with the fix the endpoint is detected and repaired to >= 0.
Registered in both CMake and Bazel.

Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
…paths

With clock-as-data endpoints now visible to repair_timing -hold, the
worst hold path to such an endpoint starts at the clock source rather
than at a register clk->Q arc, so repairEndHold walks drivers that are
part of the clock tree.  A driver whose net also feeds clock sinks with
negative (propagated) hold slack would get a hold buffer in front of
those clock sinks, changing their clock latency.

Compute the set of clock-network pins that transitively drive a clock
sink (register/check clock pins, clock output ports) and skip those
drivers when choosing a hold-buffer insertion point.  Clock-network
pins that only feed data pins are still eligible, so the clock-as-data
hold violation is repaired on the data side.

Add repair_hold_clock_as_data_clk_tree: clk1 drives r1/CK via i1 and
r2/D via dbuf.  Without this change the hold buffer is inserted on the
clk1 net driving i1/A and r1/CK clock arrival moves from 0.018 to
0.373; with it the clk1 net and r1/CK arrival are unchanged and both
hold endpoints are repaired.  repair_hold_clock_as_data.ok is updated
because its buffer now goes after dbuf instead of on the clk1 net.

Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
@maliberty maliberty self-assigned this Nov 1, 2026
@github-actions github-actions Bot added the size/M label Nov 1, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses OpenROAD issue #8075, where hold violations on register data pins sampling a clock-sourced signal were missed. It introduces a mechanism to identify the clock tree proper by traversing backward from clock sinks, ensuring hold buffers are only inserted on the data side and not on clock-tree nets. Additionally, new integration tests are added to verify the fix. The review feedback suggests adding a null check for the pin pointer during the backward traversal of the clock network to prevent potential null pointer dereferences.

Comment thread src/rsz/src/RepairHold.cc
Comment on lines +638 to +640
const sta::Pin* from_pin = edge->from(graph_)->pin();
if (clk_network->isClock(from_pin)
&& clk_tree_pins_.insert(from_pin).second) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

During the backward traversal of the clock network, edge->from(graph_)->pin() can potentially return nullptr for certain vertices (such as virtual clocks or abstract timing nodes). Passing a null pointer to clk_network->isClock() can lead to undefined behavior or crashes depending on the underlying implementation. Adding a null check for from_pin ensures robust and safe traversal.

Suggested change
const sta::Pin* from_pin = edge->from(graph_)->pin();
if (clk_network->isClock(from_pin)
&& clk_tree_pins_.insert(from_pin).second) {
const sta::Pin* from_pin = edge->from(graph_)->pin();
if (from_pin
&& clk_network->isClock(from_pin)
&& clk_tree_pins_.insert(from_pin).second) {

@maliberty
maliberty marked this pull request as ready for review November 1, 2026 01:23
@maliberty
maliberty requested a review from a team as a code owner November 1, 2026 01:23
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-11-01T01:23:53.565429Z
We couldn’t complete this review. Comment @codex review to try again.
574e73b Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@maliberty

Copy link
Copy Markdown
Member Author

Already approved in #10718

@maliberty
maliberty merged commit e517dc1 into The-OpenROAD-Project:master Nov 1, 2026
21 checks passed
@maliberty
maliberty deleted the fix/8075 branch November 1, 2026 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants