Hierarchical Constraints & Block Models
Hierarchical Constraints & Block Models
Large chips are too big to time as one flat netlist. So designers split the chip into blocks. A "block" is a self-contained piece of logic, like a memory controller or a signal filter. Each block is designed and timed on its own. Then the blocks are joined at the "top," the level that wires the blocks together. This split is called hierarchical design. Hierarchy makes timing manageable, but it raises a hard question. The block is timed alone, yet it lives inside a larger chip. How does the block know what happens at its boundary? The answer lies in block-level constraints, timing models, and budgeting. This chapter explains how block and top constraints relate, what timing models are, how boundaries are budgeted, and how to keep the two levels consistent.
Block-Level Versus Top-Level SDC
A block has its own SDC. It describes the block as if it were a small standalone chip. It defines the clocks that enter the block. It states the input delay on each block input and the output delay on each block output. These boundary delays stand in for the world outside the block.
The top level has its own SDC too. It defines the real chip clocks and the real outside delays at the chip pins. The top SDC sees each block as a component. It does not repeat the block's internal rules. It only cares about the block's boundaries and how blocks connect.
| Aspect | Block-level SDC | Top-level SDC |
|---|---|---|
| scope | one block in isolation | whole chip with all blocks |
| clocks | clocks entering the block | real chip clocks |
| boundary delay | models the outside world | real pin delays |
| internal paths | fully visible | hidden or modeled |
| who writes it | block owner | top integrator |

The two SDCs must agree at the boundary. The block assumes some input delay at its input. The top must actually deliver data within that assumed time. If the block assumes data arrives 0.734 ns after the clock, but the top delivers it at 0.951 ns, the boundary is broken. The block was timed for a promise the top did not keep. Keeping these promises aligned is the central task of hierarchical timing. Ownership also splits along the same line. The block owner writes and closes the block SDC. The top integrator writes the top SDC and joins the blocks. These are often different people on different schedules. That gap is exactly why boundaries drift. A clear handoff, where the block owner publishes the boundary assumptions and the top integrator reads them, keeps both sides honest. Without that handoff, each side guesses, and the guesses rarely match.
Timing Models and Abstracts
When the chip is timed at the top, the tool needs to know how each block behaves. It could read the full block netlist, but that is huge and slow. Instead it reads a "timing model." A timing model is a small summary of the block's timing at its boundary. It hides the inside and keeps only what the top needs.
A timing model captures a few things. It captures the delay from each input to each output through combinational paths. It captures the setup and hold needs at each input that feeds a flop. It captures the clock-to-output delay at each registered output. With these, the top can time across the block without seeing its guts.
| Model captures | Why the top needs it |
|---|---|
| input-to-output delay | time paths passing through the block |
| input setup / hold need | check data arriving at block inputs |
| clock-to-output delay | check data leaving block outputs |
| internal clock relationships | match clocks at the boundary |
A model is sometimes called an abstract, because it abstracts away the internal detail. The benefit is speed. A top run with models is far faster than a top run with full netlists. The risk is accuracy. A model is only as good as the block timing it was built from. If the block constraints were wrong, the model is wrong, and the top trusts a bad summary. There is also a question of how much detail the model keeps. A simple model keeps only the worst path from each input to each output. A richer model keeps context, such as how the delay changes with the input transition or the output load. A richer model is more accurate but larger and slower to use. The choice trades speed against fidelity. For a tight boundary, prefer the richer model so the top sees how the block reacts to real loads. For a loose boundary with plenty of margin, the simple model is enough.
# illustrative — names vary by tool
read_timing_model blocks/filter_core.model
report_timing -through [get_cells u_filter_core] -nworst 5
The first line loads a block model. The second checks a path that passes through the block instance. The top tool uses the model, not the full block, to time that path. The command names are local, so this block is tagged illustrative; the idea of a boundary model is portable across flows.
Budgeting Block Boundaries
The block needs boundary delays before the top is finished. So someone must estimate them early. This estimate is called a "budget." Budgeting splits the chip's timing across blocks so each block gets a fair share of the clock period at its boundary. Picture a path that starts in block A, crosses the top, and ends in block B. The whole path must fit in one clock period. You divide that period into parts. Part of it belongs to A's output. Part belongs to the top wiring between blocks. Part belongs to B's input. Each part becomes a boundary delay for that block.
A worked illustration. The clock period is 3.260 ns. A path leaves block A, crosses the top, and enters block B. You budget 1.180 ns for A's internal output path, 0.420 ns for the top wiring, and 1.660 ns for B's internal input path. The three add to 3.260 ns, the full period. So block A is given an output delay that reserves the other 2.080 ns for the top and B. Block B is given an input delay that reserves the 1.600 ns used by A and the top. Each block is timed against its own slice.
| Path segment | Budget | Becomes |
|---|---|---|
| block A internal | 1.180 ns | A output timing target |
| top wiring | 0.420 ns | top route budget |
| block B internal | 1.660 ns | B input timing target |
| total | 3.260 ns | full clock period |
Budgets start as guesses and get refined. An early budget may be even, like an equal split. As the design firms up, you measure real delays and adjust. A block that needs more time gets a bigger slice, and a neighbor with slack gives some up. The goal is that every boundary budget, summed across a path, fits the period with margin.
# standard SDC — portable across compliant tools
# block B input budget: reserve 1.600 ns for upstream, clock period 3.260 ns
set_input_delay 1.600 -clock core_clk [get_ports b_data_in]
set_output_delay 2.080 -clock core_clk [get_ports a_data_out]
The input delay tells block B that data shows up 1.600 ns after the clock. The output delay tells block A it must finish leaving room for 2.080 ns downstream. These two numbers come straight from the budget. They are the contract between the block and the top.
Keeping Block and Top Constraints Consistent
The biggest hazard in hierarchy is drift. The block SDC and the top SDC start in sync, then slowly disagree. A block owner tightens an input delay. The top integrator does not hear about it. The block passes alone but fails when joined. Consistency is not automatic; it must be checked. The first rule is a single source of truth for shared values. The clock period, the boundary budgets, and the clock names should live in one place that both levels read. If the block and top each keep their own copy, the copies drift. A shared file or a generated set of boundary constraints prevents this.
| Consistency risk | Symptom | Guard |
|---|---|---|
| boundary delay drift | block passes alone, fails at top | shared budget file |
| clock name mismatch | clocks not related at boundary | one clock naming scheme |
| period mismatch | block timed to wrong period | single period source |
| stale block model | top trusts old block timing | regenerate model on change |
The second rule is to regenerate block models whenever the block changes. A model is a frozen snapshot. If the block is re-timed with new constraints, the old model is stale. The top will trust numbers that no longer match the block. Tie model generation to block signoff so the snapshot is always fresh.
# illustrative — names vary by tool
check_boundary_consistency -block filter_core -top chip_top
report_constraint_mismatch -summary
These reports compare what the block assumes with what the top delivers. They flag any boundary where the two disagree. Run them after every block update and every top update. A clean report means the contract still holds. A mismatch means a budget drifted and must be fixed before signoff. A worked illustration. Block A assumes its output has 2.080 ns downstream. The top later adds extra routing, so the real downstream need grows to 2.240 ns. The boundary now misses by 0.160 ns. The consistency report flags it. The team has two choices: speed up block A's internal path to free 0.160 ns, or re-budget by taking 0.160 ns from block B's slice. Either way, the mismatch is caught early, not at final signoff when changes cost far more.

Interview Q&A
blocks lets each block be designed and timed on its own. The top level then joins the blocks using small models instead of full netlists, which is far faster.
the clocks entering the block and the input and output delays at its boundary. Those boundary delays stand in for the outside world the block cannot see.
captures input-to-output delays, input setup and hold needs, and clock-to-output delays. The top uses it to time across the block without reading the full block netlist.
it crosses. Each block gets a slice that becomes its boundary input or output delay, so each block can be timed before the top is complete.
clock without telling the top, or a top change alters what reaches a block. The block passes alone but fails when joined. A shared source of truth and consistency checks prevent this.
snapshot of the block's timing. If the block is re-timed with new constraints, the old model no longer matches. The top would trust stale numbers, so the model must be rebuilt at each block signoff.
Key Takeaways
- Block-level SDC times a block in isolation using boundary input and output delays that stand in for the outside world.
- Timing models abstract a block to its boundary, letting the top time across it quickly instead of reading the full netlist.
- Boundary budgeting splits the clock period across blocks and top wiring, turning each slice into a boundary delay so blocks can be timed early.
- Block and top constraints drift unless actively guarded, so keep shared values in one source and run boundary consistency checks.
- A stale block model makes the top trust wrong numbers, so regenerate the model every time the block is re-timed.
ChipBuddy
← Home
Comments
Leave a Reply