Skip to content
Ch 14 / 14 Chapter 14: Timing Budgeting
← Prev

CHAPTER FOURTEEN

Timing Budgeting: A Slice of the Period Is Not Signoff

By the end of this chapter you will be able to point at a clock waveform and name the launch edge, the capture edge, the period, the teaching taxes, and the remaining window. You will split that window among the rooms, lighten rooms into timing abstracts, run a virtual rehearsal called estimate_timing, read the artificial corner named estimated_corner, write files you can source, and treat a returned 1 as a heartbeat, not as a closed path.

Why this chapter matters in a real project

Think of a chip as a city of rooms. Power is already in the streets from Chapter 10. The data bus already has a map from Chapter 11. The clock already has a coarse spine from Chapter 12. The doors already sit on the walls from Chapter 13. What the city still lacks is an agreed split of one clock tick. Draw that tick as a waveform. A rising edge launches a flip-flop in CPU_CLUSTER. The next rising edge, 625 ps later, must capture the data in NPU_CORE. That is 1.60 GHz. It is not infinite. Uncertainty and setup eat the two ends of the wave. The green window that remains is what leftover glue, the CPU room, and the NPU room must share.

Sit with Nimbus-8 the morning after Chapter 13. The leftover channel is still 2.091 mm² = 2,091,000 µm². The 128-bit bus still has a map through that leftover. Clock pins still sit where you put them. The doors you placed stay. Today you do not move furniture. Today you split the remaining tick.

If you skip this chapter, two expensive things happen. Either every room is told it may use the whole 625 ps, and the leftover glue has nothing left, or you copy a nearby latency of 5 ns onto a 625 ps clock and invent eight ticks of fiction. Multiply instantiated block, then MIB: two copies of the same drawing. On Nimbus-8 those copies are u_npu_core_0 and u_npu_core_1, sharing NPU_CORE. The first instance you add for budgeting is the master. Its clocks win for the shared drawing.

One more thing, because it will happen to you. You will type estimate_timing. It will return 1. You will type compute_budget_constraints. It will return 1. That means the command finished. It does not mean the remaining 550 ps was split fairly. It does not mean estimated_corner is a library corner you tape out. It does not mean a budget file exists on disk. Those are other commands.

Prerequisites

Chapter 13, because pins are already placed and budgeting is done on rooms whose doors already sit. Chapter 12, because clock pins stay fixed and the spine is a prior, not a second CTS. Chapter 11, because leftover glue already has a bus map. Chapter 10, because M4 and M5 still carry the 20 µm power mesh. Chapter 9, because blocks are shaped. Chapter 8, because a module is a name and a block is a physical room — budgets sit on rooms, not on names. Chapter 5, because plan.budget.bbt_fixed_delay was named there and is cooked here, not re-taught from scratch. Chapter 3, because split constraints already made separate top-level and block-level SDC and UPF files. Budgeting needs those separate files. Mapping keyword this chapter is BUDGET.

The library is nimbus8.dlib. The top is NIMBUS8. Teaching pin, port, clock, and net names in this book are stand-ins. Query them with get_pins, get_ports, get_clocks, and get_nets. Brace Tcl indexes.

How to read the numbers and the notation in this chapter

Read this table slowly. Every later command uses these words. If a word here is still fog, stop and read the row again before you type Tcl.

Table 14.1 How to read the numbers, units and the symbols in this chapter
You will seeRead it asWhat you need to know
waveformhigh and low over timeThe picture of the tick. Query the real create_clock wave. Do not invent duty.
launch edgerising tick that starts the walkThe CPU flop starts here. Time zero on the teaching wave.
capture edgenext rising tick that must catch the data625 ps later on clk_cpu.
periodlaunch to capture1 / 1.60 GHz = 0.625 ns = 625 ps. Not a budget.
teaching taxesuncertainty + setup45 ps after launch, 30 ps before capture. Estimates.
remaining windowwhat rooms must share625 − 45 − 30 = 550 ps = 0.550 ns. A pie is only a nickname for this band.
budgeta promised slice of the windowTeaching split: 150 CPU / 190 leftover / 210 NPU. Not a measured delay.
virtual clockthe same waveform, no netlist sourceWhat write_budgets uses with set_input_delay / set_output_delay.
VIPOvirtual in-place optimisationestimate_timing. A rehearsal. The saved netlist stays.
estimated_corneran artificial cornerWorst-of-corners tape measure. Not SS 0.72 V.
timing abstracta light roomcreate_abstract -estimate_timing. Pins already sit.
budget shella stand-in of I/O timingEarly exploration. Not a tapeout block.
mapping keyword BUDGETwhich file the tool sourcesChapter 3 used SDC / UPF. Chapter 12 used CTS_CONSTRAINT.
quiet successreturn 1The command finished. Taste is report_timing and report_budget.

Learning objectives

After this chapter you will be able to:

  1. Point at launch, capture, period, uncertainty, setup, and the remaining 550 ps window on a clk_cpu waveform, and refuse a nearby 5 ns latency example.
  2. Merge pin changes if needed, then create timing abstracts with create_abstract -estimate_timing.
  3. Run estimate_timing, read return 1 as a heartbeat, and taste report_timing -corners estimated_corner.
  4. Name the obsolete compute_budget_constraints -estimate_timing switch and use plan.budget.estimate_timing_mode instead.
  5. Set a manual pin slice with set_pin_budget_constraints, then compute and report.
  6. Write budgets with write_budgets, source them after split constraints, and put BUDGET in the mapfile.
  7. Say what a budget shell is for, and say out loud that it is not tapeout.
  8. Pick up plan.budget.bbt_fixed_delay from Chapter 5 without re-teaching black boxes.
  9. Leave implementation for later. This chapter ends with promises you can source, not with place_opt.
Chapter 14 hero: four gates, a clk_cpu square wave with launch and capture edges, and coloured bands for uncertainty, CPU, leftover, NPU, and setup.
Figure 14.1 Same die you already know sits beside the new object: one 625 ps tick drawn as a waveform. The remaining 550 ps window is the job. Teaching purpose: read launch, capture, taxes, and slices on one wave before any command is typed.

The beginner’s mental model

A waveform is not a measured path

Hold a square wave. A rising edge launches. The next rising edge captures. The time between them is the period. You agree those two edges before anyone routes a metal. A budget is a coloured band between those edges: this much for the CPU room, this much for leftover glue, this much for the NPU room. Later, in signoff, you overlay the real data edge on the same clock. That overlay is the weighing scale. This chapter only paints the bands.

People sometimes call the remaining window a pie. That nickname is fine after you can point at the wave. It is not a replacement for the wave. A nearby example writes a clock latency of 5. That is 5 ns = 5,000 ps if the unit is nanoseconds. On this waveform the whole period is 625 ps. Five nanoseconds is eight ticks of fiction. You do not copy it. You query get_clocks. You label every teaching band an estimate.

Left: an agreed clock waveform with launch and capture labelled. Right: the same clock with a gold data edge arriving before capture, labelled later measurement.
Figure 14.2 The left wave is this chapter’s promise. The gold data edge on the right still waits for signoff. Teaching purpose: stop a budget being mistaken for a measured path.

The precise engineering model

The database already has shaped blocks, a leftover channel, a compiled power grid, a bus map, a clock spine, and placed pins. Timing budgeting adds promised delays on the boundary of those rooms. You typically lighten the rooms into timing abstracts. You run virtual in-place optimisation. You may write a manual slice on a pin you refuse to leave to the tool. You compute. You report. You write files. You source those files after the split-constraint files from Chapter 3, not instead of them.

The nearby flow picture still writes compute_budget_constraints -estimate_timing. The command page says that switch, and -no_estimate_timing, are obsolete and will be removed. New Tcl in this book runs estimate_timing yourself, sets plan.budget.estimate_timing_mode, then computes without the dead flag. Confirm with man.

The practical loop is kind to beginners. Abstracts. Estimate. Taste the artificial corner. Name the rooms. Optional manual slice. Compute. Taste the budget. Write. Source after split. Four small walks are easier to debug than one giant one.

Eight numbered gates from split constraints through write_budgets, with a navy bar naming the obsolete estimate_timing switch on compute.
Figure 14.3 The precise model is a loop with a named taste after estimate and a named taste after compute. A nearby flow still writes a switch the command page has retired. Teaching purpose: make the debug boundary and the named conflict explicit.

Concepts built from first principles

Why? Because a budget that “looks green” in a screenshot can still be a 5 ns fiction on a 625 ps wave, or a heartbeat you never tasted. First we read the waveform. Then we type commands.

Part 1 — Read the waveform first

Do not start with a command. Start with the picture the command is trying to split. If you cannot point at a launch edge, a capture edge, a tax, and a remaining window on a sketch, the Tcl will only hide the fog.

Launch, capture, period

A waveform is high and low over time. For teaching we draw clk_cpu as a square wave. The launch edge is the rising tick that starts the walk. The capture edge is the next rising tick that must catch the data. The period is the time between those two edges. For clk_cpu that is 1 / 1.60 GHz = 0.625 ns = 625 ps.

Query with get_clocks. Query the real create_clock waveform. This book’s square wave is a teaching drawing with half the tick high. Do not invent the duty on a netlist that already named it.

A teal square wave of clk_cpu with launch at t=0 and capture at t=625 ps, period brace underneath.
Figure 14.4 Launch, then capture, 625 ps later. That distance is the period. It is not a budget. Teaching purpose: give a complete beginner two named edges before any abstract is built.

Taxes sit on the ends of the tick

The capture flop needs the data to sit still for a while before its clock edge. That wait is setup. This book uses 30 ps. The two clocks might not be exactly where the drawing says. That fuzz is uncertainty. This book uses 45 ps after launch. They are estimates. They are not signoff derates.

Paint those two taxes on the wave. What is left in the middle is the remaining window: 625 − 45 − 30 = 550 ps = 0.550 ns. Required time, in this picture, is capture minus setup minus uncertainty. A budget is a promised slice of that remaining window. People call it a pie after they can point at the green band. The pie is not a second physics.

Clock waveform with pink uncertainty after launch, a wide green remaining window of 550 ps, and yellow setup before capture.
Figure 14.5 Taxes eat the two ends. The walk may only use the green window. Teaching purpose: stop a beginner giving a room the whole 625 ps period.

The walk sits on the same wave

Launch flip-flop inside CPU, leftover glue in the channel, capture flip-flop inside NPU. Put those three slices on the remaining window: 150 ps inside CPU_CLUSTER, 190 ps leftover, 210 ps inside NPU_CORE. 150 + 190 + 210 = 550. Say both units: 0.190 ns = 190 ps.

The budget files you write later constrain boundary paths: input delay, output delay, and a virtual clock that copies this waveform. They do not rewrite every gate inside the room as a full SDC of the sofa.

CPU launch flop, leftover buffer, NPU capture flop, with the same clk_cpu wave below banded 45, 150, 190, 210, and 30 ps.
Figure 14.6 The schematic and the waveform are one picture. Atlas symbols mark launch, street, and capture. The bands are the budget. Teaching purpose: put 150 / 190 / 210 ps on a wave a beginner can point at.

Do not confuse these

Table 14.1b Pairs that beginners mix, and the one-sentence repair
ThisIs not thisRepair
Launch edgeCapture edgeLaunch starts the walk. Capture must catch it, 625 ps later.
Period 625 psRemaining window 550 psTaxes ate 45 + 30. The walk uses the green band.
Budget 190 psMeasured data arrivalA promised band on the wave. Signoff still overlays gold.
Virtual clockThe netlist clock portSame waveform, no source. What a budget file uses.
estimate_timingCTS / place_optVirtual. Annotations. The saved netlist stays.
estimated_cornerA library cornerKeeps the later gold edge. Do not tape it out.
Timing abstractPlacement abstractThis chapter wants timing. Chapter 8 owned placement abstracts.
Budget fileSplit SDC from Chapter 3Source split first, then budget. Keyword BUDGET.
Budget shellImplemented blockA stand-in for exploration. Not tapeout.
Return 1A closed pathHeartbeat. Taste with report_timing and report_budget.
What changes if… you skip this part and jump to compute_budget_constraints? You will split a number you cannot point at on a wave. The command will run. The picture in your head will be a measured delay. The database will hold a promise. That gap is how quiet success gets shipped.

A budget is a promised band on a clock waveform, between launch and capture, after uncertainty and setup have eaten the ends.

On Nimbus-8, clk_cpu is still 1.60 GHz = 625 ps. After 45 ps of uncertainty and 30 ps of setup, 550 ps remains as the green window. The teaching split of that window is 150 ps inside CPU_CLUSTER, 190 ps leftover glue, and 210 ps inside NPU_CORE. Say 0.190 ns = 190 ps out loud so a nearby 5 ns example cannot hide.

What you type next is not yet compute_budget_constraints. You still need light rooms and a virtual rehearsal. What you must not confuse this with is signoff slack, CTS, or a gold data edge you have not measured.

Part 2 — estimated_corner is an artificial corner

estimate_timing creates a new corner named estimated_corner. It is artificial. Draw two gold data edges on the same clock wave. Corner A arrives at 420 ps. Corner B arrives at 520 ps. The artificial corner keeps the later edge on this path, and it keeps the later edge of the other path from the other corner. If corner A is slow on path 1 and corner B is slow on path 2, the mode paired with estimated_corner keeps both.

Taste with report_timing -modes [all_modes] -corners estimated_corner. The paths carry extra letters. A lowercase e means the value came from estimate_timing. A or a means the value came from create_abstract -estimate_timing. S means SPEF or SDF. An asterisk * means you overrode the value with set_annotated_delay. The Analysis column may say Size: None, Buff: Short net, or that three buffers were added in the rehearsal. Those buffers are virtual. They are not a netlist edit you would tape out. They may move the gold edge on this drawing. They do not change the saved netlist.

Budgets are then generated for all corners, modes, and scenarios, including the estimated ones. Do not ship estimated_corner as if it were SS 0.72 V. It is a planning tape measure.

Same clk_cpu wave with two gold-and-navy data arrivals: corner A at 420 ps, corner B at 520 ps, estimated_corner keeping the later edge.
Figure 14.7 Same launch. Same capture. The artificial corner keeps the worse data edge. It is not a library PVT you tape out. Teaching purpose: stop estimated_corner being treated as silicon.

estimated_corner is a tape measure the tool invented. It is not a library corner, and an e on a timing line is not a cell you placed.

You create it by running estimate_timing. You read it with report_timing -modes [all_modes] -corners estimated_corner. If you later override a delay with set_annotated_delay -corners estimated_corner, the letter becomes *. Take the override back with remove_annotated_delay on the same arc.

What you must not do is treat a green path on that corner as signoff, or forget that budgets generated after this rehearsal still have to be written to disk before any block can source them.

Part 3 — Timing abstracts are light rooms

A timing abstract is a smaller, more efficient copy of a room, useful for generating budgets. Pins are already placed. You do not re-place the sofa before you lighten the inside. If you placed those pins on an abstract, you must first merge_abstract so the doors copy into the full design view. Then source the block’s split top.tcl once, to apply internal constraints. Then, in the nearby cook, add_feedthrough_buffers (plural). Then create_abstract -estimate_timing.

That last command runs virtual timing optimisation on the interface logic and annotates the abstract with the result. You may omit -estimate_timing if you already ran the virtual step earlier. On multiple levels of physical hierarchy, only the lowest rooms become abstracts. Intermediate parents stay design views.

Black boxes get their own abstracts after load_block_constraints -type SDC. Do not pretend a black box was virtually optimised. Query report_abstracts for leaf-cell count, compression, and which modes and corners the abstract actually holds. Before abstracts that carry estimated_corner, set abstract.enable_improvements_for_budgeting true. Read it back with report_app_options.

Left: a design view full of D flip-flops. Right: a timing abstract labelled interface kept, inside compressed, with pin triangles on both edges.
Figure 14.8 Lighten the inside. Do not re-place the doors. The pin still has a waveform. Teaching purpose: an abstract is a lighter room, not a new floorplan.
Table 14.2 create_abstract switches this chapter actually uses
SwitchWhat it doesTeaching note
-estimate_timingRuns virtual optimisation on interface logic and stores the result in the abstract.This chapter’s default for rooms that will be budgeted.
-placementNo timing. Physical data for top-level placement.Chapter 8’s flavour. Not today’s cook.
-timing_levelnone | boundary | compact | full_interfaceLess detail, less memory. none is deprecated.
-blocksNamed block designs, not the current block alone.Reference names in the nearby cook. Mutex with -all_blocks.
-all_blocksEvery eligible child.Mutex with -blocks.
-force_recreateRebuild even if an abstract exists.Only with -blocks or -all_blocks. Alone, the current block always rebuilds.
-host_optionsDistributed processing.Plural switch. Confirm the host-option object with man.
-target_useimplementation | planningPlanning is this book’s job.
# Teaching stand-ins. Query instances first
icc2_shell> open_block nimbus8.dlib:CPU_CLUSTER.design
icc2_shell> merge_abstract
icc2_shell> source split/CPU_CLUSTER/top.tcl
icc2_shell> add_feedthrough_buffers
icc2_shell> create_abstract -estimate_timing
icc2_shell> save_lib
icc2_shell> report_abstracts

The nearby cook passes reference names to create_abstract -blocks — the drawing, not a copy. set_budget_options -add_blocks and write_budgets -blocks take instance paths. A nearby incremental example writes U1. Confirm with man. New Tcl uses {CPU_CLUSTER NPU_CORE ISP} on the abstract, and u_cpu_cluster / u_npu_core_0 on the budget commands.

Trap. The flow cook writes add_feedthrough_buffers (plural). The estimate_timing command page writes that a bad child view may run add_feedthrough_buffer (singular) and then create_abstract -estimate_timing, and that this can change the child’s netlist. Name both spellings. Confirm with man. Prefer legal child views so the tool does not “help” you by editing a room you thought was read-only.

A timing abstract is a lighter copy of a room whose pins already sit. You merge doors first if they were placed on an abstract, then you lighten the inside.

On multiple levels of physical hierarchy, only the lowest rooms become abstracts. Intermediate parents stay design views. Black boxes are loaded with load_block_constraints -type SDC and are not pretended to be virtually optimised. Compression is a report from report_abstracts, not a feeling from a screenshot.

What you type is create_abstract -estimate_timing after the merge and the split top.tcl. What you must not do is rebuild placement inside the room “just in case”, or steal Chapter 8’s placement abstract and hope it carries estimated_corner.

Part 4 — Virtual in-place optimisation is a rehearsal

estimate_timing pretends to remove repeaters, build repeater trees, and size cells. The simulated effects are stored as annotations on estimated_corner. The saved netlist stays the saved netlist — unless a child view was illegal and the tool opened it to buffer feedthroughs, as the previous trap said.

It optimises top-level logic whether or not a block is editable. Editable rooms and boundary nets that cross editable or read-only rooms are in scope. Cells or nets completely inside a non-editable block are avoided. If you defined unified topology constraints on a net, those constraints steer the delay; query estimated_analysis on a pin to see whether they were used. If they were not defined, the tool uses ordinary buffering to estimate.

Open the top. Set the constraint mapping file from Chapter 3. Source the top-level split top.tcl (or the full-chip SDC in a full-netlist flow). Then run estimate_timing. Return 1 is a heartbeat. Taste is the timing report on estimated_corner.

Left: not place_opt, clock_opt, or CTS. Right: a clock wave with a gold data edge moved by virtual buffering, labelled return 1 is a heartbeat.
Figure 14.9 A rehearsal may move the gold data edge on estimated_corner. It does not finish the clock tree. Incremental -pins needs a full run first. Teaching purpose: stop estimate_timing being treated as implementation.
Table 14.3 estimate_timing switches
SwitchWhat it doesTeaching note
(none)Full virtual optimisation of the current design.Creates estimated_corner. Return 1 is a heartbeat.
-pinsIncremental. Only paths through those pins or ports.Needs a previous full run. Otherwise there is nothing to keep.
-netsIncremental. Only those nets.Same prior: a full run first.
-host_optionsDistributed processing.Plural. Or set plan.estimate_timing.enable_multi_threading true and read it back.
# Top-level rehearsal. Mapping file is the Chapter 3 prior
icc2_shell> open_block nimbus8.dlib:NIMBUS8
icc2_shell> set_constraint_mapping_file split/mapfile
icc2_shell> source split/NIMBUS8/top.tcl
icc2_shell> set_app_options -name abstract.enable_improvements_for_budgeting \
    -value true
icc2_shell> estimate_timing
icc2_shell> report_timing -modes [all_modes] -corners estimated_corner

Acceptable child views: a design view, or a timing abstract that already carries child-level estimate_timing data. If a child is the wrong view, the tool may open it, run the singular feedthrough-buffer step, build a timing abstract, retarget the instance, and continue. That reference-view change happens unless set_editability -value false is set on the child. App options under plan.estimate_timing.abstract* steer that inner buffering. Read them with report_app_options plan.estimate_timing.abstract*. Do not invent defaults.

estimate_timing is a rehearsal that writes annotations on estimated_corner. Return 1 means the rehearsal finished, not that the remaining 550 ps is closed.

Run it at the top after the mapping file and the split top-level constraints. Taste with report_timing -corners estimated_corner. An e is estimated. A * is a delay you annotated by hand. Child views must already be a design view or a timing abstract with child-level estimate data, or the tool may change a child’s netlist while “helping”.

What you must not confuse this with is place_opt, clock_opt, or CTS. Those still wait. A nearby log that says “Virtually optimized 903 out of 13,637 cells” is a rehearsal count, not a placed netlist.

Part 5 — Constraining the estimate: layers, clips, and partial routes

You can still steer the rehearsal. set_net_estimation_rule names which layers the estimate may use for RC. Then you attach the rule to nets with set_attribute ... estimate_timing_net_rule. A nearby example uses M7 horizontal and M8 vertical. On Nimbus-8 the teaching bus from Chapter 11 is M3 horizontal and M6 vertical. Query get_layers. Do not copy M7/M8 onto a library that never had them.

# Teaching layers. Query get_layers before you copy
icc2_shell> set_net_estimation_rule -parameter layer \
    -horizontal_value M3 -vertical_value M6 rule_bus
icc2_shell> set_attribute -objects [get_nets -of_objects \
    [get_bundles cpu_npu_data]] \
    -name estimate_timing_net_rule -value rule_bus

Layer promotion on critical nets is plan.estimate_timing.optimize_layers true. That also allows promotion inside create_abstract -estimate_timing. When it is on, the global router runs in floorplan mode during the estimate. Mesh layers M4 and M5 still belong to Chapter 10. You do not promote the teaching bus onto the mesh because the metal looks fat.

Maximum net delay and maximum cell delay are plan.estimate_timing.maximum_net_delay and plan.estimate_timing.maximum_cell_delay. A nearby example sets both to 1.0. If the unit is nanoseconds, that is 1,000 ps on a 625 ps clock — larger than the whole tick. Do not copy 1.0 onto clk_cpu. If you clip at all, pick a slice you can defend, for example 0.150 ns = 150 ps, and label it an estimate. After the run, pins whose delay was replaced have is_et_delay_clipped==true.

icc2_shell> get_pins -of_objects [get_cells *] \
    -filter is_et_delay_clipped==true

Partial routes are ignored by default. Set plan.estimate_timing.honor_routes true if you want existing global or detail segments kept and only the missing bits estimated. Read the option back. Do not assert a default from memory.

The rehearsal can be steered: layers, a clip, and whether partial routes count. None of those settings is a licence to copy 1.0 onto a 625 ps clock.

Teaching bus layers stay M3 horizontal and M6 vertical unless get_layers says otherwise. A nearby M7/M8 example is someone else’s stack. A nearby 1.0 clip is 1,000 ps if the unit is nanoseconds. Query is_et_delay_clipped after you clip, so you know which pins were replaced by the ceiling.

Default behaviour ignores partial routes. Turn plan.estimate_timing.honor_routes true only when you mean the routes you already have. Read every app option back with report_app_options.

Part 6 — Incremental estimate_timing needs a full run first

By default each full run throws away previous annotations and recalculates. To update only a walk, pass -pins or -nets. Other annotations from the last full run stay. If you skip the full run, incremental has nothing to keep.

If you moved cells on the critical path, recreate abstracts for the rooms you touched: create_abstract -estimate_timing -force_recreate -blocks .... Then incremental-estimate the pin or net on that walk. A nearby log says the full chip virtually optimised 903 of 13,637 cells; the incremental walk virtually optimised 36 of 2,093. That difference is the point of incremental, not a QoR number you would ship.

icc2_shell> estimate_timing
icc2_shell> report_timing -corners estimated_corner
# After you moved cells on that walk, rebuild that room’s abstract
icc2_shell> create_abstract -estimate_timing -force_recreate \
    -blocks {CPU_CLUSTER}
icc2_shell> estimate_timing -pins [get_pins \
    {u_cpu_cluster/cpu_npu_data_reg_0_/Q}]

Teaching pin names are stand-ins. Query get_pins. Brace Tcl indexes.

Incremental -pins or -nets updates one walk and keeps the rest. It is not the first command of the day.

A full estimate_timing wipes previous annotations. That is why you run full once, taste, move what you must, rebuild abstracts for rooms you touched with -force_recreate, then incremental-estimate the walk. -force_recreate only works with -blocks or -all_blocks.

What you must not do is treat “36 of 2,093 cells” as a closed path, or mix set_annotated_delay on estimated_corner with a full rerun and then wonder why the asterisk vanished. A full run without -pins replaces the annotations. Incremental is how you keep the rest of the chip.

Part 7 — Manual budget constraints are promises you said out loud

Automatic compute still creates pin and boundary constraints for every hierarchical pin. Manual is how you override a slice you refuse to leave to the tool. You can combine them: write the manual slice, then compute.

Pin constraints: set_pin_budget_constraints. How much of a path through a door stays inside. The textbook is -internal_percent 40 on a pin such as u0_0/rstn — 40 percent inside the room, 60 percent outside. On Nimbus-8 you would query the actual pin. Percent and delay forms are mutually exclusive on the same call. -internal_percent is equivalent to -input -internal -to_percent.

Clock waveform with the remaining 550 ps window cut 40 percent inside the room and 60 percent outside, taxes still on the ends.
Figure 14.10 Forty percent inside means sixty percent stays in leftover glue and the other room. The cut is on the green window, not on the whole period. Teaching purpose: make -internal_percent a cut on the same wave.
Table 14.4 set_pin_budget_constraints switches you will actually type
SwitchWhat it doesTeaching note
-internal_percentPercent of the path kept inside the pin’s block.Sets -internal for you. Remainder stays outside.
-from_percent / -to_percentPercent before / after the pin.Mutex with other percent and delay forms.
-from_delay / -to_delay / -internal_delayAbsolute delay, in input time units.Same mutex. Query the unit. Do not copy 5.
-inputs / -outputsRestrict to input or output pins.Plural on this command. Compute uses singular. Name both.
-late_boundary / -early_boundaryAttach a named boundary constraint.Create the boundary object first.
-frozenKeep this slice; compute must not rewrite it.Feedthrough reports later show FROM_FROZEN / TO_FROZEN.
-same_as_mibCopies share the slice.NPU copies share NPU_CORE.
-all_pins | -all | pin listScope.Query pins. Do not invent u0_0/rstn on Nimbus-8.
# Teaching stand-in. Query get_pins first
icc2_shell> set_pin_budget_constraints \
    [get_pins {u_cpu_cluster/cpu_npu_data[0]}] \
    -internal_percent 40

Boundary constraints: set_boundary_budget_constraints. Driving cell and load. Then attach with -late_boundary / -early_boundary on the pin command. Latency constraints: set_latency_budget_constraints. Early and late clock latency. A nearby example uses -early_latency 5 -late_latency 5 on a clock named clk. If the unit is nanoseconds, that is 5,000 ps. Teaching latency, if you set one at all, is a small slice of 625 ps — for example 0.080 ns = 80 ps — labelled an estimate. Query get_clocks.

Two clk_cpu square waves: the port wave at t=0 and the flop wave shifted 80 ps, with a pink warning that 5 ns walks off the page.
Figure 14.11 Latency slides the whole wave. Teaching shift is 80 ps. Five nanoseconds is eight periods and is not on this drawing. Teaching purpose: stop a copied 5 from landing on a 625 ps clock.

A manual slice is a promise you said out loud. Percent and delay forms cannot share one call, and a nearby latency of 5 is not a Nimbus-8 number.

-internal_percent 40 keeps 40 percent of the path inside the room. The rest stays in leftover glue and the other room. Create named driving cells and loads with set_boundary_budget_constraints, then attach them. Latency, if you set it, is a small slice of the period you queried, not 5 ns on a 625 ps clock.

This command’s scope switches are -inputs and -outputs (plural). compute_budget_constraints uses -input and -output (singular). Mixing the families is a syntax error. Confirm with man. Automatic compute still fills every other hierarchical pin. Manual is the override, not a replacement for compute unless you truly meant to write every door by hand.

Part 8 — Naming rooms and computing the split

set_budget_options -add_blocks names the instances that will receive a budget. When a multiply instantiated block appears in the list, the instance given first is the master. Its clocks and their characteristics are used for the generated budget. On Nimbus-8, if both NPU copies are in the list, put the master you intend first. -reset clears budget constraints and options from set_budget_options, the pin / latency / boundary commands, and compute_budget_constraints.

Four cards: name rooms, split the tick, taste report_budget, write files, plus a note on the obsolete switch.
Figure 14.12 Name, compute, taste, write. A nearby flow still types a switch the command page has retired. Teaching purpose: separate compute from write, and name the obsolete flag.
Table 14.5 set_budget_options switches this chapter uses
SwitchWhat it doesTeaching note
-add_blocksDeclare instances that get a budget.Must pass instance paths. First MIB instance is master.
-remove_blocksDrop instances, or -all.They no longer receive write_budgets output.
-resetClear budget constraints and options.A broom, not a compute.
-adjust_latencyprects | target | actualDefault if never set: prects, honest early in the flow.

Then compute_budget_constraints splits the remaining window on the wave. If you specify none of -setup_delay, -boundary, or -latency_targets, the tool behaves as -setup_delay -boundary. -latency_targets must be paired with -balance. Values are actual (match current latencies) or estimated (match predicted trunk latency — clock trunk planning from Chapter 12 must already have been run).

Named conflict. A nearby flow still types compute_budget_constraints -estimate_timing. The command page says -estimate_timing and -no_estimate_timing are obsolete. Use plan.budget.estimate_timing_mode and run estimate_timing yourself. If the mode is on and estimated_corner is missing, the tool may run estimate_timing as a side effect. Prefer to run it yourself and read it. A nearby table caption also misspells the command as compute_budget_contraints (missing an s). The command is compute_budget_constraints. Confirm with man.
Table 14.6 compute_budget_constraints switches, after the obsolete flag is refused
SwitchWhat it doesTeaching note
-setup_delayCompute setup delay budgets.Default pair with -boundary if you say nothing.
-boundaryCompute boundary (drive / load) budgets.Same default pair.
-latency_targetsactual | estimatedMust pair with -balance. Estimated needs Chapter 12 trunks.
-pinsOnly those pins.Further restrict with -input / -output (singular).
-input / -outputOnly block inputs or outputs.A nearby table writes -inputs / -outputs. New Tcl uses the command page: singular. Confirm with man.
-unspecifiedOnly pins with no delay budget yet.Useful on a second pass.
-feedthroughOnly feedthrough paths.A visit from input of a room to output of the same room.
-slackOnly paths whose budget slack is worse than the value.Budget slack is actual delay versus budgeted delay.
-defaultIgnore current plan.budget.* settings.Same honesty as write_budgets -default.
-host_optionsDistributed processing.Plural. Not Chapter 12’s CTP family.
icc2_shell> set_app_options -name plan.budget.estimate_timing_mode -value true
icc2_shell> set_budget_options -add_blocks [get_cells \
    {u_cpu_cluster u_npu_core_0 u_npu_core_1}]
icc2_shell> compute_budget_constraints -setup_delay -boundary

Read plan.budget.estimate_timing_mode back. Do not invent a default. u_npu_core_0 listed first is the MIB master. plan.budget.bbt_fixed_delay is the Chapter 5 thread: when a black-box delay was measured, leave the option so the budgeter maintains it; when the delay was a guess, set it false so the budgeter may adjust, and take the tightened number to the block owner. Do not re-open Chapter 5’s black-box cook. Just decide, here, which way the option faces on the rooms that are still boxes.

Name the rooms first. Compute second. The obsolete -estimate_timing flag on compute is not new Tcl, even when a nearby flow still types it.

Set plan.budget.estimate_timing_mode, then compute_budget_constraints -setup_delay -boundary without the dead switch. If you specify nothing, you still get setup and boundary. -latency_targets without -balance is incomplete. MIB: the first instance in -add_blocks is the master.

A nearby table writes -inputs on compute. The command page writes -input. New Tcl follows the command page and names the conflict. Confirm with man. Return 1 is still a heartbeat. The taste is the next part.

Part 9 — report_budget is the taste

compute_budget_constraints finished. Taste is report_budget. If you computed in estimate-timing mode, the report may open with ABS-240: the budget is based on estimated_corner delays. That is information, not a pass. Read it as “this window was cut with the tape measure, not with the weighing scale.”

Table 14.7 report_budget switches you will actually type
SwitchWhat it doesTeaching note
-blocksList rooms selected by set_budget_options.First check: did you add the instances you think you added?
-htmlOne HTML file, current mode.Can be huge. Extension .html.
-html_dirSplit HTML plus index.html.All active modes. Kinder to the browser.
-throughWorst-slack path through that pin, with segment percents.S = slack-ish split, D = delay, B = budget in the nearby printout.
-warning_pinsImpossible constraints, missing budgets, pins with no paths.Pair with -verbose for the reason column.
-feedthroughsVisit pins, frozen flags, Manhattan, budget versus delay.CSV needs -csv and a .csv filename.
-latencyClocks crossing block boundaries.Median latency and fanout, grouped into clock groups.
-defaultIgnore current plan.budget.*.Same honesty as compute / write -default.
icc2_shell> report_budget -blocks
icc2_shell> report_budget -html_dir budget_html
icc2_shell> report_budget -warning_pins -verbose > warning_pins.txt
icc2_shell> report_budget -through [get_pins \
    {u_cpu_cluster/cpu_npu_data[0]}]

Warning-pin reasons you will actually see: clock_pin (the pin is on a clock network), false_path (every path through it is a false path), unclocked_endpoint, unconstrained_input_port. A bidirectional pin is expected to have at least one input delay and one output delay; a missing direction with no path in that direction shows up here. That is a constraint gap, not a router bug.

Table 14.8 Messages and report rows this chapter treats as sentences
You seeIt meansWhat you do
ABS-240Budget is based on estimated_corner delays.Expected after VIPO-mode compute. Do not call it signoff.
clock_pinThe pin is part of a clock network.Do not expect a data-path budget through it.
false_pathExceptions cover every path through the pin.Confirm the exception was meant.
unclocked_endpointThe named pin has no clock.Fix the clock, not the leftover channel.
unconstrained_input_portThat top port has no constraint.Look at the port. Do not rerun compute first.
Return 1, empty tasteQuiet success.-warning_pins -verbose before you write files.

report_budget is the taste. ABS-240 tells you the window was cut with estimated_corner, which is information, not a pass sticker.

Start with -blocks so you know which rooms were actually declared. Then -warning_pins -verbose so missing paths have a reason, not a shrug. Then -through on a door you care about so you can see the percent inside versus outside. HTML is a browser report; -html_dir splits it so the browser does not choke.

What you must not do is write files because compute returned 1. Warning pins that are clock pins are expected. Warning pins that are unconstrained input ports are a Chapter 3 leftover, not a leftover-channel geometry problem.

Part 10 — write_budgets writes files you can source

A computed budget is not a written budget. write_budgets writes a directory (default ./budgets) with one folder per reference, a top.tcl that sources mode and corner files, and a mapfile whose keyword is BUDGET. Those files put this same clock waveform onto a virtual clock — a clock with the waveform and no source in the netlist — then hang set_input_delay and set_output_delay off its edges. Budgets apply to boundary paths, not to internal combinational segments. Whenever you write a new budget, you must source that block’s top.tcl again. A new file overwrites the old boundary constraints.

Source order is not a style. Source split constraints first, then the budget. Budget is not a replacement for Chapter 3.

A virtual clk_cpu square wave with taxes on the ends, a blue set_input_delay band for CPU plus leftover, and 210 ps still inside NPU, plus a BUDGET mapfile.
Figure 14.13 The file copies this waveform onto a virtual clock, then names how much of the tick was already used before the pin. Keyword is BUDGET. Source split first. Teaching purpose: input delay is a delay from an edge, not a new physics.
Table 14.9 write_budgets switches this chapter uses
SwitchWhat it doesTeaching note
-blocksOnly named instances.They must already be in -add_blocks. Else it is an error.
-topWrite a budget for the top.Top always gets a full budget.
-outputDirectory name.Default ./budgets.
-forceOverwrite an existing directory.Without it, a second write refuses the folder.
-shell_subblocksWrite budget shells for those references.Forces a full budget on the parent. Not tapeout.
-full_budget_blocksFull, not incremental, for those modules.Or set plan.budget.all_full_budgets and read it back.
-defaultIgnore current plan.budget.*.Pair mentally with compute -default.
-formatdc | icc2This book’s cook is icc2 unless you said otherwise.
Named conflict. A nearby table lists write_budgets -all_blocks. The command page this chapter sat with lists -blocks, -top, -shell_subblocks, and friends, not -all_blocks (-all_blocks is on create_abstract). New Tcl writes the instances you already declared with -blocks, or confirms -all_blocks with man write_budgets on your release. Do not invent the switch from a table caption.
icc2_shell> write_budgets -blocks [get_cells \
    {u_cpu_cluster u_npu_core_0 u_npu_core_1}] \
    -force -output budgets
# Later, inside a block. Split first, then budget
icc2_shell> set_constraint_mapping_file split/mapfile
icc2_shell> source split/CPU_CLUSTER/top.tcl
icc2_shell> set_constraint_mapping_file budgets/mapfile
icc2_shell> source budgets/CPU_CLUSTER/top.tcl

set_constraint_mapping_file without -reset appends. That rule is still true from Chapter 12. If you meant to replace the map, say -reset. Optional: update_constraint_mapping_file -remove_blocks before you source. App options that change what is written: plan.budget.all_design_subblocks, all_full_budgets, allow_top_only_exceptions, hold_buffer_margin, pessimistic_driving_cells, write_hold_budgets. Read them back. Do not invent defaults.

A computed budget lives in the session. A written budget is a directory you can source, and you source it after Chapter 3’s split files, not instead of them.

Default folder is ./budgets. Each reference gets top.tcl, mode files, and corner files. The mapfile keyword is BUDGET. -force overwrites. Instances you never passed to -add_blocks are an error on -blocks. A new source overwrites previous boundary constraints for that block.

What you must not do is treat CTS_CONSTRAINT or SDC as this chapter’s keyword, or append a second mapfile and wonder why both families of files are still in play. Without -reset, mapping appends. Confirm with man.

Part 11 — A budget shell is a stand-in, not tapeout

A budget shell is a macro-like representation of the I/O timing and physical interface of a room. The parent can explore while the child is still a promise. Paths that used to walk into the child become budgeted paths to the shell ports. write_budgets -shell_subblocks takes reference names and forces a full budget on the parent. Incremental budgets are not allowed on that parent.

For final chip production to generate a tapeout database, do not use the budget-shell flow. Use implemented blocks, starting from RTL. That sentence is the nearby note, said out loud so a shell cannot hide as a finished chip.

By default the shell keeps PG pins and multivoltage Liberty attributes (voltage map, related power and ground, isolation, level-shifter ranges, and friends). Set mv.hierarchical.include_pg_in_budget_shell false only if you mean to drop them. Read it back. After the shell: reset, reload UPF for top and shells separately, commit_upf, then source the shell timing files. The nearby cook also names a shell environment variable, SYNOPSYS_LC_ROOT, as a prior for Liberty Compiler when writing shells. Name it. Do not invent a path.

# References, not a feeling. Query get_cells / ref_name first
icc2_shell> set_budget_options -add_blocks [get_cells \
    {u_cpu_cluster u_npu_core_0}]
icc2_shell> compute_budget_constraints -setup_delay -boundary \
    -latency_targets actual -balance true
# Optional: freeze a percent slice after compute
icc2_shell> set_pin_budget_constraints -internal_percent 40 -all
icc2_shell> write_budgets -shell_subblocks {CPU_CLUSTER NPU_CORE} \
    -output budget_shell

A nearby script writes get_cells "B_cell" "C_cell" as two arguments. Teaching Tcl passes one list: [get_cells {u_cpu_cluster u_npu_core_0}]. Confirm with man.

A budget shell is a stand-in of I/O timing so the parent can explore. It is not a tapeout block, and the nearby note says so in one sentence.

-shell_subblocks takes reference names and forces a full budget on the parent. Reload UPF for top and shells, commit, then source the shell timing files. SYNOPSYS_LC_ROOT is a named prior for Liberty Compiler. Do not invent the path in this book.

What you must not do is ship a shell as the production database, or mix an incremental budget on a parent that already owns a shell child. Default shells keep PG and multivoltage attributes. Turn that off only when you mean it, and read the option back.

Part 12 — Mapping, MIB, and the black-box delay

Three mapping keywords now live in this book. Chapter 3: SDC and UPF. Chapter 12: CTS_CONSTRAINT. This chapter: BUDGET. set_constraint_mapping_file without -reset appends. Read the mapfile. Do not hope.

MIB: two copies, one drawing. The first instance in -add_blocks is the master. Its clocks win. Pin slices you want shared use -same_as_mib on set_pin_budget_constraints. Copies are still u_npu_core_0 and u_npu_core_1, sharing NPU_CORE.

Black-box delay: plan.budget.bbt_fixed_delay was named in Chapter 5. This is the cook it sits in. If the black-box number was measured, keep the tool from “improving” it. If it was a guess, set the option false and take the tightened figure to the owner. Read it back. Do not re-teach black boxes here.

To run the same abstract script on several rooms, run_block_script still exists from earlier chapters. Parallel work is a host-options object, not a feeling.

Mapping appends unless you reset. MIB clocks follow the first instance you added. The black-box delay option is decided here, not re-derived from Chapter 5.

Source split files, then budget files. Keyword BUDGET is not CTS_CONSTRAINT. If both NPU copies are budgeted, say which instance is master by putting it first in -add_blocks.

What you must not do is leave plan.budget.bbt_fixed_delay untouched “because Chapter 5 already mentioned it” without saying, on this chip, whether each remaining box was measured or guessed. The option is a decision, not a souvenir.

Nimbus-8 die beside a mini clk_cpu wave and a nine-step cook from split constraints through write_budgets.
Figure 14.14 One walk on the die you already know. Pins stay. The new object is the 550 ps remaining window on the wave. Teaching purpose: put the whole cook on the leftover channel you already named.

Inputs, outputs, and readiness

Table 14.10 What must already be true, and what this chapter emits
KindObjectHonesty rule
InputSplit top and block SDC / UPFChapter 3. Budgeting needs separate files.
InputShaped blocks, leftover channelChannel 2.091 mm² = 2,091,000 µm².
InputCompiled PG meshM4/M5 still 20 µm. Not estimate layers you steal.
InputBus map and clock spineChapters 11 and 12. Clock pins stay fixed.
InputPlaced pinsChapter 13. Merge if they were placed on an abstract.
InputQueried clocks, pins, nets, layersStand-ins in this book are not a netlist.
OutputTiming abstracts with estimate dataLowest hierarchy only, if MPH.
OutputAnnotations on estimated_cornerArtificial. Taste, then compute.
Output./budgets/<ref>/top.tcl and a BUDGET mapfileSource after split. Boundary paths only.
Not outputA finished CTS tree or place_optImplementation still waits.
Not outputA tapeout shellA budget shell is exploration.

Preflight: split files exist; pins placed and merged if needed; clock pins still fixed; rooms named; clk_cpu period said out loud as 625 ps; remaining window said out loud as 550 ps on the wave; MIB master said out loud; plan.budget.bbt_fixed_delay decided for any remaining box.

Guided tool workflow

Table 14.11 Typical loop, with the home command
StepYou doCommand
1Confirm split files and mapping.set_constraint_mapping_file split/mapfile
2Merge pin changes if pins were placed on an abstract.merge_abstract
3Lighten lowest rooms.create_abstract -estimate_timing
4Virtual rehearsal at the top.estimate_timing
5Taste the artificial corner.report_timing -corners estimated_corner
6Name rooms. MIB master first.set_budget_options -add_blocks
7Optional manual slice.set_pin_budget_constraints
8Split the remaining window. No obsolete flag.compute_budget_constraints -setup_delay -boundary
9Taste.report_budget -warning_pins -verbose
10Write, then source after split.write_budgets -force

Validation gates: report_abstracts shows timing abstracts with compression you can point at; estimated_corner exists and was read; ABS-240 is expected or explained; warning pins are owned; mapfile contains BUDGET; leftover still 2.091 mm²; teaching split still labelled an estimate.

One continuous worked example

Nimbus-8. Library nimbus8.dlib. Top NIMBUS8. Leftover 2.091 mm² = 2,091,000 µm². clk_cpu 1.60 GHz = 625 ps. Remaining window 550 ps on the wave. Teaching split 190 leftover / 150 CPU / 210 NPU. Pins already placed. Clock pins already fixed.

# Teaching stand-ins. Query before you copy
icc2_shell> open_block nimbus8.dlib:NIMBUS8
icc2_shell> set_constraint_mapping_file split/mapfile
icc2_shell> source split/NIMBUS8/top.tcl

icc2_shell> set_app_options -name abstract.enable_improvements_for_budgeting \
    -value true
icc2_shell> report_app_options abstract.enable_improvements_for_budgeting
icc2_shell> create_abstract -estimate_timing -blocks \
    {CPU_CLUSTER NPU_CORE ISP}
icc2_shell> report_abstracts

icc2_shell> estimate_timing
icc2_shell> report_timing -modes [all_modes] -corners estimated_corner

icc2_shell> set_app_options -name plan.budget.estimate_timing_mode -value true
icc2_shell> report_app_options plan.budget.estimate_timing_mode
icc2_shell> set_budget_options -add_blocks [get_cells \
    {u_cpu_cluster u_npu_core_0 u_npu_core_1}]
icc2_shell> set_pin_budget_constraints \
    [get_pins {u_cpu_cluster/cpu_npu_data[0]}] \
    -internal_percent 40
icc2_shell> compute_budget_constraints -setup_delay -boundary
icc2_shell> report_budget -warning_pins -verbose > warning_pins.txt
icc2_shell> write_budgets -blocks [get_cells \
    {u_cpu_cluster u_npu_core_0 u_npu_core_1}] \
    -force -output budgets

Read return 1 as a heartbeat. Read ABS-240 as “cut with the tape measure.” If the NPU copies disagree about clocks, you listed the wrong instance first, or you budgeted only one copy and hoped the drawing would invent the other promise.

Later, inside CPU_CLUSTER: source split/CPU_CLUSTER/top.tcl, then budgets/CPU_CLUSTER/top.tcl. Mapping keyword BUDGET. Without -reset, a second set_constraint_mapping_file appends.

Failure modes and debugging

Table 14.12 What it looks like, what it usually is, what you do
What you seeWhat it usually isWhat you do
Latency 5 on a 625 ps clockA nearby example copied as nanoseconds.Query units and get_clocks. Teaching latency is a small slice, labelled estimate.
Clip 1.0, period 0.625Nearby maximum_net_delay 1.0 if the unit is ns.Do not copy 1.0. Query is_et_delay_clipped.
compute_budget_constraints -estimate_timing warned or vanishedObsolete switch.plan.budget.estimate_timing_mode. Confirm with man.
-inputs rejected on computeNearby table used the plural.Type -input. Pin-constraint command is the one with -inputs.
write_budgets -all_blocks rejectedNearby table, not the command page this chapter sat with.Write -blocks of declared instances. Confirm with man.
Child netlist changed during estimateIllegal child view. Singular feedthrough-buffer step inside estimate.Legal views first. Read plan.estimate_timing.abstract*.
Incremental -pins did nothing usefulNo prior full run.Full estimate_timing first.
Second mapfile, both families still liveAppend without -reset.Same muscle as Chapter 12. Say -reset if you meant replace.
Warning pin unconstrained_input_portChapter 3 gap, not a leftover-channel bug.Look at the port. Do not recompute first.
Shell treated as tapeoutExploration stand-in shipped.Implemented blocks from RTL. The nearby note forbids the shell for production.
Return 1, no files on diskQuiet success: compute is not write.write_budgets -force, then source after split.
Black-box path fails with nowhere to lookplan.budget.bbt_fixed_delay left true on a guess.Chapter 5 decision, cooked here. Set false if it was a guess; take the number to the owner.

Hands-on mini lab — Aldebaran-4

Aldebaran-4 has a core that is a square 900 µm = 0.900 mm on each side, so an area of 0.810 mm² = 810,000 µm². Two blocks, one leftover strip between them. One clock at 1.00 GHz = 1,000 ps. Teaching taxes 50 ps uncertainty and 30 ps setup, so the remaining window is 920 ps. No MIB. Pins already placed. Split files already exist.

  1. Query clocks, pins, and layers. Do not invent names from this page.
  2. Create timing abstracts with create_abstract -estimate_timing. Read report_abstracts.
  3. Run estimate_timing. Read return 1 as a heartbeat. Taste report_timing -corners estimated_corner.
  4. Set plan.budget.estimate_timing_mode and read it back. Do not type the obsolete compute flag.
  5. Add both block instances with set_budget_options -add_blocks. Put a 40 percent internal slice on one queried data pin.
  6. Compute with -setup_delay -boundary. Taste report_budget -warning_pins -verbose. Write with -force.

You are done when the remaining 920 ps is a window you can point at on a square wave, estimated_corner was read, warning pins are owned or empty, and budgets/<ref>/top.tcl exists to source after split. Label every number an estimate. Do not copy a 5 ns latency onto a 1,000 ps clock.

Interview preparation

BEGINNER

1. What is a timing budget, in one honest sentence?

A budget is a promised band on a clock waveform, between launch and capture, after uncertainty and setup. It is not a measured delay, and it is not signoff.

Draw clk_cpu. Launch at t = 0. Capture 625 ps later. Taxes: 45 ps after launch, 30 ps before capture. The green window is 550 ps. Teaching split: 150 CPU / 190 leftover / 210 NPU.

An estimate is a gold data edge on estimated_corner. A budget file copies this waveform onto a virtual clock and hangs input and output delays off the edges. Mixing any two is how a later report becomes a mystery.

Query get_clocks. A nearby latency of 5 ns is eight of these waves stacked if you copy it blindly.

What is being tested. Whether the candidate can keep launch, capture, remaining window, estimate, and written file apart.
BEGINNER

2. estimate_timing returned 1. Is the path closed?

No. Return 1 is a heartbeat. The taste is report_timing on estimated_corner, then report_budget after you compute.

The command finished a rehearsal. It stored annotations on an artificial corner. It did not finish CTS. It did not write a budget directory.

Letters on the timing report: e is estimated, * is a delay you annotated by hand, A/a came from create_abstract -estimate_timing.

Quiet success is how a screenshot ships. Same muscle as Chapter 12 and Chapter 13.

What is being tested. Heartbeat versus report, now on estimated_corner.
BEGINNER

3. What is estimated_corner?

An artificial corner that gathers the worst delays from several real corners. It is a tape measure, not a library PVT you tape out.

If corner A is slow on path 1 and corner B is slow on path 2, the mode paired with estimated_corner keeps both. Budgets generated afterwards still cover all corners, modes, and scenarios.

Create it with estimate_timing. Read it with report_timing -modes [all_modes] -corners estimated_corner.

Do not ship it as SS 0.72 V. Do not skip the report because the rehearsal returned 1.

What is being tested. Artificial corner literacy, and refusal to tape out a tape measure.
BEGINNER

4. Why create a timing abstract before you budget?

So the tool can split the remaining tick on a lighter room whose pins already sit, without dragging every sofa into the top-level estimate.

create_abstract -estimate_timing runs virtual optimisation on interface logic and stores the result. Pins are already placed. Merge first if they were placed on an abstract.

On multiple levels of physical hierarchy, only the lowest rooms become abstracts. Intermediate parents stay design views. Black boxes load SDC and are not pretended to be virtually optimised.

Compression is a number from report_abstracts, not a feeling.

What is being tested. Light room versus placement abstract, and MPH lowest-only.
BEGINNER

5. In what order do you source split constraints and budgets?

Split first, then budget. A budget file is not a replacement for Chapter 3. The mapping keyword this chapter is BUDGET.

Whenever you write a new budget, source that block’s top.tcl again. The new file overwrites previous boundary constraints.

set_constraint_mapping_file without -reset appends. Chapter 12 already taught that. It is still true.

CTS_CONSTRAINT was the clock-trunk keyword. Do not put it on a budget line.

What is being tested. Source order and mapping-keyword literacy.
INTERMEDIATE

6. A nearby flow types compute_budget_constraints -estimate_timing. What do you type instead?

Set plan.budget.estimate_timing_mode, run estimate_timing yourself, then compute without that flag. The command page says the switch is obsolete.

If the mode is on and estimated_corner is missing, the tool may run estimate_timing as a side effect. Prefer to run it yourself and read the report.

A nearby table caption also misspells the command as compute_budget_contraints. The command has two s characters in constraints.

Interviewers listen for the conflict, not for a silent copy of the flow picture. Confirm with man.

What is being tested. Obsolete switch named, replacement named, man page as the tie-break.
INTERMEDIATE

7. Why must -pins on estimate_timing follow a full run?

Incremental mode updates only the named walk and keeps other annotations from the previous full run. Without that run, there is nothing to keep.

A full run wipes previous annotations and recalculates. That is why you do not use -pins as the first command of the day.

If you moved cells, recreate abstracts for those rooms with -force_recreate (only with -blocks or -all_blocks), then incremental-estimate the walk.

A nearby log’s “36 of 2,093 cells” is a rehearsal count, not QoR.

What is being tested. Incremental as a scalpel with a documented prior.
INTERMEDIATE

8. set_pin_budget_constraints -inputs versus compute_budget_constraints -input. Which is right?

Both, on their own pages. The pin-constraint command uses plural -inputs / -outputs. Compute uses singular -input / -output. A nearby compute table uses the plural. New Tcl follows each command page.

Mixing the families is a syntax error. Confirm with man on the command you are typing, not on the command you typed yesterday.

The same muscle as Chapter 13’s -side versus -sides: name the conflict, pick the syntax list, do not invent a third token.

Percent and delay forms on the pin command are mutex. -internal_percent 40 is the textbook inside-the-room slice.

What is being tested. Singular versus plural across two commands, without mixing families.
INTERMEDIATE

9. What does ABS-240 mean after report_budget?

The budget is based on estimated_corner delays. That is expected after a VIPO-mode compute. It is not a signoff sticker.

Read it as “this window was cut with the tape measure.” Then still run -warning_pins -verbose so missing paths have a reason.

clock_pin is expected on clock network pins. unconstrained_input_port is a Chapter 3 gap. Do not repair it by moving leftover geometry.

Return 1 from compute is still a heartbeat. ABS-240 is a sentence, not a pass.

What is being tested. Message literacy: estimated_corner as the basis, not as signoff.
INTERMEDIATE

10. write_budgets -all_blocks from a nearby table. Defend the next line.

The command page this chapter sat with lists -blocks, -top, and -shell_subblocks, not -all_blocks. Write the instances you already passed to -add_blocks, or confirm -all_blocks with man on your release.

-all_blocks is real on create_abstract. Copying it onto write_budgets because a table said so is how a caption becomes a syntax error.

Instances that were never declared with set_budget_options -add_blocks are an error on write_budgets -blocks.

A weak recovery is “I’ll try -all.” A strong recovery is to quote both sources and run man write_budgets.

What is being tested. Conflict handling under pressure, without silent invention.
SCENARIO

11. estimate_timing changed a child’s netlist. You thought the room was read-only. What happened?

The child view was not acceptable. The command may open the design view, run add_feedthrough_buffer (singular), then create_abstract -estimate_timing, and retarget the instance. That can change the netlist unless editability is false.

Acceptable children: a design view, or a timing abstract that already carries child-level estimate data. Prefer those, so the tool does not “help.”

The flow cook writes add_feedthrough_buffers (plural). The estimate page writes the singular. Name both. App options live under plan.estimate_timing.abstract*. Read them back.

This is not CTS. It is a side effect of an illegal view. Repair the view, then rerun.

What is being tested. Child-view legality, singular versus plural buffer command, netlist honesty.
SCENARIO

12. A colleague pastes -early_latency 5 -late_latency 5 onto clk_cpu. What do you say?

If the unit is nanoseconds, 5 ns is 5,000 ps. clk_cpu’s period is 625 ps. That is eight ticks of fiction. Query the unit and get_clocks. Teaching latency is a small slice, labelled an estimate.

The same trap as Chapter 12’s nearby -delay 20. A number without a unit you queried is not a Nimbus-8 number.

If you set latency at all, 0.080 ns = 80 ps is a slice you can defend on a 625 ps clock. Label it an estimate. Do not tape it out.

compute_budget_constraints -latency_targets actual -balance true is the automatic family. Manual 5 is not “more precise.” It is a copied example.

What is being tested. Unit literacy against a nearby example, same muscle as Chapter 12.
SCENARIO

13. Both NPU copies share NPU_CORE. After write_budgets the clocks disagree. What did you skip?

The first instance in set_budget_options -add_blocks is the MIB master. Its clocks win for the shared drawing. Copies do not invent a second clock story.

Name the instances: u_npu_core_0 and u_npu_core_1. Put the master you intend first. Pin slices you want shared use -same_as_mib.

This is the same MIB honesty as Chapter 13’s matching doors, now on promised delays rather than metal shapes.

Do not budget only one copy and hope the drawing writes the other folder.

What is being tested. MIB master-instance rule, carried from pins to budgets.
SCENARIO

14. You sourced budgets/CPU_CLUSTER/top.tcl and the internal SDC exceptions vanished. Why?

You sourced the budget without the split file, or you treated budget as a replacement for Chapter 3. Budgets apply to boundary paths. Internal constraints live in the split top.tcl.

Correct order: mapping for split, source split top.tcl, mapping for budgets (reset if you meant replace), source budget top.tcl.

A new budget source overwrites previous boundary constraints. It should not be asked to carry the whole internal SDC.

Keyword BUDGET in the mapfile is how the tool finds that file. It is not how it finds Chapter 3.

What is being tested. Source order, boundary versus internal, mapping keyword.
SCENARIO

15. Someone wants a budget shell for tapeout next week. What do you say?

No. A budget shell is a stand-in for top-level exploration. Final chip production uses implemented blocks starting from RTL. The nearby note says that out loud.

write_budgets -shell_subblocks takes reference names and forces a full budget on the parent. Reload UPF, commit, then source the shell timing files. That is exploration.

SYNOPSYS_LC_ROOT is a named prior for Liberty Compiler when writing shells. Do not invent a path in an interview. Name the variable.

Breadth is knowing the shell exists. Recklessness is shipping it as the database.

What is being tested. Shell versus implemented block, with the production prohibition named.
SCENARIO

16. Pins are done. Budgets are written. Someone asks you to run place_opt in the same script. What do you say?

This chapter ends with promises you sourced. Implementation still waits. Mixing place_opt into a budget cook hides both plots.

What you can say, cleanly: leftover still 2.091 mm²; M4/M5 still mesh; clock pins still fixed; doors still sit; remaining window 550 ps split 190 leftover / 150 CPU / 210 NPU, labelled estimate; BUDGET mapfile written; warning pins owned.

The design-planning cook that this book sat with ends at budgeting. The next work is implementation, not a fifteenth planning verb invented in the same session.

Breadth is naming that boundary. Recklessness is pasting place_opt into a session whose budget files you have not sourced.

What is being tested. Flow hygiene and the boundary with implementation.

Chapter close

Sign-off checklist for this planning stage

  1. You can point at launch, capture, period, uncertainty, setup, and the remaining 550 ps window on a clk_cpu waveform.
  2. Clocks, pins, nets, and layers were queried, not invented.
  3. clk_cpu was said as 1.60 GHz = 625 ps. Remaining window was said as 550 ps on the waveform. Teaching split 190 leftover / 150 CPU / 210 NPU was labelled an estimate.
  4. Pins from Chapter 13 were already placed. Clock pins from Chapter 12 stayed fixed.
  5. Abstracts used create_abstract -estimate_timing. MPH kept intermediate parents as design views.
  6. estimate_timing return 1 was followed by report_timing -corners estimated_corner.
  7. The obsolete compute flag was refused. plan.budget.estimate_timing_mode was read back.
  8. report_budget -warning_pins was read. ABS-240 was treated as information.
  9. write_budgets wrote files. They were sourced after split. Mapfile keyword is BUDGET.
  10. A budget shell, if used, was not called tapeout. plan.budget.bbt_fixed_delay was decided for any remaining box.
  11. Implementation was not mixed into this script.

Key-concept flashcards

Period

The whole tick. clk_cpu is 625 ps. Not a budget.

The wave

Launch, then capture. 625 ps. Taxes 45 + 30. Window 550 ps.

Budget

A promised band on that window. Not a measured delay. Not signoff.

estimated_corner

Artificial tape measure. An e is estimated. A * is yours.

VIPO

estimate_timing is a rehearsal. Return 1 is a heartbeat.

Abstract

Light room, pins already sit. Lowest hierarchy only, if MPH.

Obsolete flag

compute -estimate_timing is retired. Use the app option.

Mapping

BUDGET this chapter. Appends without -reset.

Write

Compute is not write. Source after split.

Shell

Stand-in for exploration. Not tapeout.

MIB master

First instance in -add_blocks. Its clocks win.

Next

Promises are written. Implementation still waits.

Compact glossary

Table 14.13 Chapter 14 glossary
TermMeaning as used in this book
Launch edgeRising tick that starts the walk. Time zero on the teaching wave.
Capture edgeNext rising tick that must catch the data. 625 ps later on clk_cpu.
Remaining windowPeriod minus teaching taxes. 550 ps on clk_cpu. A pie is only a nickname for this band.
BudgetA promised band on that window, written as boundary delays on a virtual clock.
Virtual clockThe same waveform, no netlist source. What write_budgets uses.
Budget shellA stand-in of I/O timing for parent exploration. Not tapeout.
BUDGETMapping-file keyword for this chapter’s files.
estimated_cornerArtificial corner created by estimate_timing.
Remaining tick / piePeriod minus teaching taxes. 550 ps on clk_cpu.
Timing abstractA lighter room with interface timing, pins already placed.
VIPOVirtual in-place optimisation: estimate_timing.
Budget slackHow much actual delay sits under the promised delay.
MIB masterFirst instance in -add_blocks. Its clocks characterise the drawing.
Quiet successReturn 1. Taste is the report, then the written file.

Five-question self-check

Antares-2 has a core that is a square 1,100 µm = 1.100 mm on each side, so an area of 1.21 mm² = 1,210,000 µm². Two copies of one reference. One clock at 800 MHz = 1,250 ps. Teaching taxes 45 ps + 30 ps, so the remaining window is 1,175 ps. Pins already placed. Split files already exist.

  1. A colleague draws a 625 ps clk_cpu wave and paints the whole tick green for the NPU room. What two taxes did they skip, and what remaining window should they have painted?
  2. You run estimate_timing -pins as the first command of the day. Why is that incomplete, and what do you run first?
  3. You type compute_budget_constraints -inputs and the tool rejects it. Why, and which other command uses the plural?
  4. After write, Antares-2’s two copies disagree about clock latency in the budget files. Which set_budget_options rule did you skip?
  5. A colleague asks to tape out the budget shell you just wrote for Antares-2. What do you say, and which nearby prohibition do you quote?

Answers.

1. They skipped 45 ps of uncertainty after launch and 30 ps of setup before capture. The remaining window on Nimbus-8’s clk_cpu is 550 ps, not 625 ps. (Antares-2’s own remaining window would be 1,175 ps.)

2. Incremental -pins needs a previous full run so other annotations have somewhere to stay. Run full estimate_timing first, taste estimated_corner, then incremental.

3. Compute’s command page uses singular -input / -output. A nearby table uses the plural. The plural lives on set_pin_budget_constraints -inputs. Do not mix the families. Confirm with man.

4. The first instance in set_budget_options -add_blocks is the MIB master. Its clocks are used for the generated budget. Name both copies and put the intended master first.

5. No. A budget shell is a stand-in for exploration. Final chip production uses implemented blocks starting from RTL. That is the nearby prohibition, said out loud.

Why implementation follows, and this chapter stops

The leftover channel now has a bus map, a clock spine, a set of doors you checked, and a set of promised slices you can source. The mesh still holds power. The remaining 550 ps on clk_cpu is split on paper as 190 leftover / 150 CPU / 210 NPU, labelled an estimate. What the chip still lacks is the implementation that turns those promises into placed cells, a real clock tree, and a path you would weigh. That work is not a tail on write_budgets. This chapter ends with budgets. The next session, after you have reviewed this one, begins at implementation — not at a fifteenth planning verb invented in the same cook.

Chapter 14 recap: a mini clk_cpu wave plus eight panels for the remaining window, the numbers, the habit, conflicts, files, checks, and next.
Figure 14.15 Chapter 14 on one page: launch, capture, remaining window, then abstract, estimate, compute, write. Quiet success is not QoR. Implementation still waits. Teaching purpose: a photographable end-of-chapter flow.