Multi-corner hold-fix ECO proc that runs inside a live EDA tool session — queries live setup slack from the loaded design, runs the bottleneck fix engine, and inserts hold buffers via ECO commands
Environment
fc_shell (Fusion Compiler) or icc2_shell (ICC2) — design must be loaded
Live setup slack query — queries setup slack directly from the loaded design using EDA-native commands (get_attribute max_slack or get_timing_paths -pba_mode); no offline TSV required
Offline setup margin support — also accepts pre-generated TSV files from setup_query_runtime.tcl; both live and offline can be combined (live overrides TSV when both given)
Multi-corner bottleneck approach — same engine as the Perl version; builds a global shared-node database across all hold corners and fixes the worst bottleneck node first
Prefer-cells filtering — restrict candidate delay cells by exact name or glob pattern (BUFFD1*, DLYD*)
Aggressive mode — optional per-path aggressive fallback pass after the normal fix pass; separate ECO files for each pass
Auto-discovers common libraries — at load time, walks up the directory tree from its own location to find and source common/lib/tcl_lib/; works in dev/, update/, verified/, and publish/ trees without hardcoded paths
License-controlled debug levels — 0–4 levels with access gated by the UCS license file; requested level is clamped to the licensed maximum
Environment
Note:ucs_fix_hold must be called inside an active Fusion Compiler (fc_shell) or ICC2 (icc2_shell) session with the design already loaded and timing analysis completed. It is NOT intended for use in PrimeTime (pt_shell). For PrimeTime setup-slack collection, use the companion script setup_query_runtime.tcl described in the Setup Query section below.
License required: A valid UCS license is required. The license check runs automatically when ucs_hold_fix.tcl is sourced. If the check fails, the proc ucs_fix_hold will not be available. Contact tech@universalchipstudio.com to obtain a license file (.ucs_license.conf) for your project tree.
All lib modules are sourced automatically by the entrypoint. The same directory structure exists under publish/redhat7/.
How to Load
Two ways to source the script:
Option A — Standard source (most EDA tools)
# Inside fc_shell or icc2_shell (design already loaded)
source /path/to/publish/redhat8/sta/hold/tcl_modular/bin/ucs_hold_fix.tcl
# After sourcing, the proc is available:
ucs_fix_hold -help
Option B — Pre-set path (for tools that return "" from [info script])
Some EDA sessions (e.g., Fusion Compiler HyperScale) return an empty string from [info script] when files are sourced indirectly. In this case, pre-set the path variable before sourcing:
set ::ucs_holdfix_script_path \
/path/to/publish/redhat8/sta/hold/tcl_modular/bin/ucs_hold_fix.tcl
source $::ucs_holdfix_script_path
Note: The entrypoint automatically walks up the directory tree from its own location to find common/lib/tcl_lib/ and sources the shared Tcl libraries (ucs_tcl_common_utils.tcl, ucs_tcl_dict_compat.tcl, ucs_tcl_license_check.tcl). If the common directory is not found (e.g., isolated deployment), these libraries are silently skipped and the tool falls back to built-in implementations.
Synopsis
Call ucs_fix_hold after sourcing the script. At least one of -setup_corner or -setup_margin_file is required.
Report list file. One line per corner: <corner> <target_slack_ps> <report_abs_path>. Legacy alias: -violation_list (same format).
-cell_delay_file <file>
string
Cell delay database in Perl-compatible format with [percentile_select], [percentile_delay], and [final_delay] sections. Legacy alias: -delay_config (Tcl source format, still supported).
-ref_filter <regex>
regex
Required regex to identify true leaf-cell refs in timing reports. Applied to the cell reference field of each path endpoint. Example: {^BWP}, {^SAED32}.
Setup Slack Source — at least one of the following is required
Note: When both -setup_corner and -setup_margin_file are given, the live query result from -setup_corner takes precedence over the TSV for any pin found in both. The TSV is used as a fallback for pins not covered by the live query.
Option
Type
Description
-setup_corner <corner>
string
Corner name for LIVE setup slack query. For each candidate pin, calls get_attribute $pin max_slack (or get_timing_paths -pba_mode if -pba_mode is not none). Requires the design and timing to be loaded in the current session.
-setup_margin_file <file> ...
list
OFFLINE setup margin TSV file(s) generated by setup_query_runtime.tcl in PrimeTime. Accepts multiple files. Format per line: <corner> <pin_path> <slack_ns> <direction>. All files are merged into a single in-memory database.
Hierarchy and Scope
Option
Type
Default
Description
-scope_json <file>
string
—
Optional scope database JSON for hierarchy and ref lookup. If omitted, cell refs are derived from the live EDA session (get_attribute ref_name).
-report_level <name>
string
—
Optional report-level scope name (e.g., u_top). Must be paired with -fix_level. Both require -scope_json.
-fix_level <name>
string
—
Optional fix-level scope name (e.g., u_top/u_blk). Must be paired with -report_level.
-forbidden_module <list>
list
—
Module/instance path prefixes to skip. Any pin whose hierarchical path starts with one of these prefixes is excluded from all fix passes.
-blacklist_node <file>
string
—
File of node blacklist patterns, one per line. Supports * and ? wildcards. Matched nodes are excluded from fixing.
Fix Behavior
Option
Type
Default
Description
-setup_guardband <float>
float (ps)
0
Minimum setup slack (in picoseconds) that must remain after a hold buffer insertion. Fix is applied only when setup slack exceeds this guardband.
-derate <factor>
float
1.0
Derate factor applied to hold delay requirements before computing the required buffer chain length.
-pba_mode <mode>
enum
none
PBA mode for live setup slack query via get_timing_paths: none (use max_slack attribute directly), path (pba_mode path), exhaustive (pba_mode exhaustive). Has no effect when using offline TSV only.
-prefer_cells <list>
list
all valid cells
Restrict candidate delay cells to a preferred subset. Accepts exact names (BUFFD1BWP136P5M117H3P48CPDLVT) or glob patterns (BUFFD1*, DLYD*). Intersection with globally valid cells is taken.
-time_unit <unit>
enum
auto
Time unit for delay values in the cell delay file: ns, ps, or auto (detect from the EDA session's current time unit).
-max_cells <int>
int
200
Maximum number of delay cells to chain at a single insertion point. Prevents runaway buffer chains.
-allow_output_pins
flag
off
Include output pins as fix candidate insertion points. Default: input pins only.
-enable_io_paths
flag
off
Include IO-related timing paths (paths involving design ports). Default: IO paths are excluded.
-aggressive
flag
off
Enable an aggressive fallback pass after the normal fix pass. Aggressive mode applies tighter per-path constraints. Both passes produce separate ECO output files (normal.tcl and aggressive.tcl).
Output and Debug
Option
Type
Default
Description
-output_dir <path>
string
cwd
Base directory for all output files. The script creates ucs_hold_fix_YYYYMMDD/ under this path.
-verbose
flag
off
Enable verbose progress output to stdout during fixing.
-debug <0-4>
int
0
Automatic debug dump level. 0=off; 1=stage TSV summaries; 2=level 1 + detailed path/node database views; 3=level 2 + decision trace TSVs; 4=level 3 + full JSON snapshots. All debug output goes to ucs_hold_fix_YYYYMMDD/debug/. Effective level is min(requested, licensed_max).
-help
flag
—
Print full help message and return without running the fix engine.
Setup Query Helper — setup_query_runtime.tcl
setup_query_runtime.tcl is a companion helper that runs inside PrimeTime to collect live setup slack values. It is used when setup margin TSV files need to be generated before running the hold fix. In normal workflow, this file is generated automatically by the Perl ucs_hold_fix in prepare-only mode and then sourced in PrimeTime — you do not call its procs manually.
Environment: Must be sourced inside pt_shell with the design loaded and timing analysis complete. Uses PrimeTime-native commands: get_pins, get_attribute, get_timing_paths, sizeof_collection, index_collection.
Global Variables (must be set before calling)
Variable
Type
Description
::ucs_nodes
list
List of pin path strings to query setup slack for. This list is populated automatically by the generated setup_query.tcl.
::ucs_pba_mode
string
PBA mode for timing queries: none (use max_slack attribute), path (get_timing_paths -pba_mode path), exhaustive. Defaults to none.
Exported Procs
Proc
Arguments
Returns
Description
ucs_dump_setup_margin_for_corner
corner (string)
file path
Top-level entry point. Iterates ::ucs_nodes, queries setup slack for each pin in the given corner, and writes results to ucs_setup_<corner>.tsv in the current directory. Returns the output file path.
ucs_dump_setup_margin_and_direction
out_file corner
—
Lower-level proc. Appends rows to an existing file. Useful when writing multiple corners to the same file.
Silently skipped — inserting buffers at hierarchical boundaries can break scan chains and HyperScale annotation
Slack is empty, "infinite", or "infinity"
Normalized to 9999 (treated as unconstrained / safe)
::ucs_pba_mode is not "none"
Calls get_timing_paths -through $pin -delay_type max -max_paths 1 -pba_mode $::ucs_pba_mode instead of reading max_slack attribute
Unsupported pin direction
Prints WARN: unsupported direction '...' for <pin>; pin is skipped
Three-Step Workflow with setup_query_runtime.tcl
# Step 1 — Shell: generate pre-fix DB and setup-query Tcl (Perl prepare-only mode)
ucs_hold_fix \
-report_list violations.lst \
-scope_json scope_db.json \
-ref_filter {^BWP} \
-setup_query_tcl setup_query_pt.tcl
# Step 2 — PrimeTime: source the generated Tcl to collect setup margins
# (inside pt_shell with design loaded)
source setup_query_pt.tcl
# -> writes: ucs_setup_FuncSSG0p6vRcbestCCbest0cHld.tsv (one file per corner)
# Step 3 — Fusion Compiler: run the hold fix with collected margins
# (inside fc_shell with design loaded)
source /path/to/publish/redhat8/sta/hold/tcl_modular/bin/ucs_hold_fix.tcl
ucs_fix_hold \
-report_list violations.lst \
-cell_delay_file delay_db.txt \
-ref_filter {^BWP} \
-setup_margin_file ucs_setup_FuncSSG0p6vRcbestCCbest0cHld.tsv \
-setup_guardband 20 \
-aggressive
Output Files
All outputs are placed under a timestamped directory. The base path is the current working directory (or -output_dir if set).
ucs_hold_fix_YYYYMMDD/
├── eco/
│ ├── ucs_fix_hold_$USER_YYYYMMDD.normal.tcl ← Primary ECO Tcl (insert_buffer commands)
│ └── ucs_fix_hold_$USER_YYYYMMDD.aggressive.tcl ← Aggressive ECO (if -aggressive)
├── reports/
│ ├── ucs_fix_hold_$USER_YYYYMMDD.summary.rpt ← Per-corner fix statistics
│ ├── ucs_fix_hold_$USER_YYYYMMDD.unfixed_paths.rpt ← Paths not fixed (hold req not met)
│ └── ucs_fix_hold_$USER_YYYYMMDD.unfixed_raw_paths.rpt
└── debug/ ← Only with -debug 1..4
├── post_parse.path.tsv
├── post_build_node_db.node.tsv
├── post_merge_setup.path.tsv
├── post_merge_setup.node.tsv
├── post_filter.path.tsv
├── post_filter.node.tsv
├── post_normal_fix.path.tsv
├── post_normal_fix.node.tsv
├── post_aggressive_fix.path.tsv ← only with -aggressive
├── post_aggressive_fix.node.tsv
├── normal.decision.tsv ← only with -debug 3+
├── aggressive.decision.tsv ← only with -debug 3+ and -aggressive
└── <stage>.json ← only with -debug 4
ECO file format: Each insert_buffer command is preceded by a structured comment block recording: dominant hold corner, all active hold corners, node path, number of paths covered, path IDs, remaining hold requirement per corner, and cells selected. All commands are wrapped in catch {} to allow partial execution (individual failures do not abort the ECO session).
################################################################################
# Hold Fix ECO - Shared Node u_top/u_blk/df_tcdxcn/flop_inst/SI
################################################################################
# Dominant Hold Corner: FuncSSG0p6vRcbestCCbest0cHld
# Active Hold Corners: FuncSSG0p6vRcbestCCbest0cHld FuncSSG0p6vRcworstCCworst100cHld
# Node Selected: u_top/u_blk/df_tcdxcn/flop_inst/SI
# Active Paths Covered: 6
# Path IDs: 15 103 126 555 626 651
# Remaining Hold Requirement By Corner:
# Cells Selected: BUFFD1BWP136P5M117H3P48CPDLVT
################################################################################
catch {insert_buffer u_top/u_blk/df_tcdxcn/flop_inst/SI \
BUFFD1BWP136P5M117H3P48CPDLVT \
-new_net_names ucs_fix_hold_huiyinli_20260411_net \
-new_cell_names ucs_fix_hold_huiyinli_20260411_buf}