You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When ORFS hardens a leaf macro, the write_timing_model step produces a <macro>_typ.lib describing its boundary timing — clock-to-output delays, input setup/hold, etc. These arcs are characterized with assumptions about the macro's internal clock tree latency that bake in to the .lib's reported source/target latencies.
Specifically:
Internal CTS sets internal clock-tree latency. Each macro's hardening flow builds its own clock tree. The internal CTS produces some insertion delay (say X ps) from the macro's clk pin to its internal flops.
write_timing_model reports arcs relative to the internal-CTS reference. The .lib treats the macro's clk input as the reference point and characterizes flop arrival as if there's an equivalent delay between clk pin and internal flop.
At chip_top, parent CTS produces a DIFFERENT delay. chip_top's CTS distributes the chip clock to each macro's clk pin. The parent insertion delay to (e.g.) u_reset_seq/clk is determined by chip_top's CTS strategy — NOT by what reset_seq's internal CTS assumed.
STA sees a mismatch. chip_top's STA combines parent insertion delay + macro's reported boundary arc. If the macro's .lib assumed a different internal latency than chip_top's CTS actually delivers, the combined arrival times don't match. Result: bogus skew, bogus hold violations.
The negative target latency is the .lib's reporting convention: the macro's .lib was characterized with its own clock-tree latency built in, expressed as a delta from the boundary. STA can't reconcile +1948 vs −932 → 1008 ps setup skew → hold-buffer pile → DRT can't converge → masked via HOLD_SLACK_MARGIN=-2000 in chip_top.config.mk.
# TODO before tape-out: replace this constraint with proper abstract-lib# generation that exposes the chain register's sequential arcs natively.# Until then, the multicycle is the industry-standard workaround for# hardened-macro shift registers. See tech/RCA_DISCIPLINE.md.
set_multicycle_path 32 -setup -through [get_pins -hierarchical *u_a/chain_w_s*]
This TODO was identified in #41 review as "load-bearing for #28" but has never had its own tracking issue. Filing here so it's not buried in a SDC comment.
Why this matters
Until the .lib faithfully represents each macro's actual boundary timing (with its internal CTS latency exposed AS A SEQUENTIAL ARC, not absorbed into reference-relative numbers), parent-level STA has no path to honest closure on any chip_top integration. Workarounds (multicycle, HOLD_SLACK_MARGIN, set_clock_uncertainty) can mask the symptom but produce LEFs that would fail foundry sign-off STA.
This is the load-bearing root cause referenced in:
Hardened macros' .lib files expose their internal clock-tree latency as explicit sequential arcs (clk → q) with real delays, not absorbed into source/target latency conventions
chip_top STA at the macro boundary uses these arcs and computes consistent setup/hold without manual multicycle SDC patches
compute_array_abut.sdc's multicycle workarounds can be removed
chip_top.config.mk's HOLD_SLACK_MARGIN=-2000 can be removed
First chip_top close achieves positive setup slack AND 0 DRC without masking knobs
Implementation options
Custom OpenROAD write_timing_model invocation with SDC that clocks the macro's internal flops separately from the boundary clock pin, so the tool emits real sequential arcs instead of folding them into reference latency. Was attempted during #40: pure abutment compute_array — 32×32 closes #41 (the subagent investigation); should be revisited.
Hierarchical CTS at chip_top that explicitly de-skews based on each macro's published internal-latency budget (requires manual set_clock_latency -source per macro pin, OR a manifest-driven flow).
Problem
When ORFS hardens a leaf macro, the
write_timing_modelstep produces a<macro>_typ.libdescribing its boundary timing — clock-to-output delays, input setup/hold, etc. These arcs are characterized with assumptions about the macro's internal clock tree latency that bake in to the .lib's reported source/target latencies.Specifically:
clkpin to its internal flops.write_timing_modelreports arcs relative to the internal-CTS reference. The .lib treats the macro'sclkinput as the reference point and characterizes flop arrival as if there's an equivalent delay betweenclkpin and internal flop.clkpin. The parent insertion delay to (e.g.)u_reset_seq/clkis determined by chip_top's CTS strategy — NOT by what reset_seq's internal CTS assumed.This was hit in #28 first-close attempt:
reset_in_sync$_DFF_PP1_/CLK(chip_top's CDC sync flop): +1948 ps source latency (chip_top's parent CTS)u_reset_seq/clk(macro boundary): −932 ps target latencyThe negative target latency is the .lib's reporting convention: the macro's .lib was characterized with its own clock-tree latency built in, expressed as a delta from the boundary. STA can't reconcile +1948 vs −932 → 1008 ps setup skew → hold-buffer pile → DRT can't converge → masked via
HOLD_SLACK_MARGIN=-2000in chip_top.config.mk.Existing TODO with no home
tech/asap7/orfs/compute_array_abut.sdc:65flags this:This TODO was identified in #41 review as "load-bearing for #28" but has never had its own tracking issue. Filing here so it's not buried in a SDC comment.
Why this matters
Until the
.libfaithfully represents each macro's actual boundary timing (with its internal CTS latency exposed AS A SEQUENTIAL ARC, not absorbed into reference-relative numbers), parent-level STA has no path to honest closure on any chip_top integration. Workarounds (multicycle, HOLD_SLACK_MARGIN, set_clock_uncertainty) can mask the symptom but produce LEFs that would fail foundry sign-off STA.This is the load-bearing root cause referenced in:
Acceptance criteria
compute_array_abut.sdc's multicycle workarounds can be removedchip_top.config.mk'sHOLD_SLACK_MARGIN=-2000can be removedImplementation options
write_timing_modelinvocation with SDC that clocks the macro's internal flops separately from the boundary clock pin, so the tool emits real sequential arcs instead of folding them into reference latency. Was attempted during #40: pure abutment compute_array — 32×32 closes #41 (the subagent investigation); should be revisited.set_clock_latency -sourceper macro pin, OR a manifest-driven flow).Option 3 is the largest architectural lift but is the only one that fully solves the class of problem. Options 1/2 are tactical patches.
Related