Skip to content
Ch 07 / 8 Chapter 7: Hierarchical Implementation
← Prev Next →
Detailed Design Analysis Hierarchical Implementation ICC2 Implementation Mentor Guide

Detailed Design Analysis

Hierarchical Implementation in ICC2: A Mentor Guide

How a design too large to hold in one placement database gets cut into blocks, closed in parallel, and reassembled, partitioning, pin assignment, feedthroughs, timing budgeting, abstract views, ETMs, and top-level closure, taught from zero, the way a senior engineer would explain it to a new hire at their desk.

Teaching project: Nimbus‑8 Stage 7 of 8 Zero experience → working engineer
Part 1 — Chapter orientation

Why a finished, manufacturable design still needs this chapter

Picture a construction site big enough that no single supervisor can walk the whole thing in a day. The company does not hand one person the entire blueprint and a hard hat. It splits the site into zones, gives each zone its own foreman, its own crew and its own daily target, and agrees in advance exactly where each zone's walls meet its neighbour's. Nimbus‑8, at 9.90 million standard cells and 73 macros, is that site. Chapters 1 through 6 of this guide implemented a single zone, the u_sens_tile sensor partition, as if it were the whole chip. This chapter is about the rest of the site: how the whole thing gets divided, how the zones agree on their shared walls, and how the pieces come back together into one building that a foundry can pour.

A beginner arriving here usually assumes hierarchy is an optimization, something you turn on for a big design the way you might turn on multithreading. That is close, but it understates the cost. Hierarchy is a trade. You get parallel work and a tool run that finishes overnight instead of never. You pay for it in a permanent gap between what each block's model claims and what the real block does. This chapter's whole job is teaching you to see that gap, measure it, and keep it small enough that it never surprises you at the end.

What this chapter covers, in the order you will use it

The order matters and it is not arbitrary. You partition the design before you shape the blocks, because shape depends on what is inside each partition. You shape and assign pins before you write a timing budget, because a budget is a number attached to a real pin at a real location, not an abstract promise. You budget before you build an abstract, because an abstract's job is to prove the budget is achievable. And you do all of that before top-level closure, because closure is the step that checks whether every promise the earlier steps made turned out to be true. By the end of this chapter you will be able to decide how to partition a design and defend the decision. You will assign pins and push feedthroughs through a block correctly, and split and rebudget timing across a boundary. You will choose between an abstract, a frame and an ETM with reasons. You will run top-level closure, read why it failed when every block passed, and hand a closed hierarchical design to the next stage with a defined exit state.

Stage boundary for Hierarchical Implementation
What enters this stageWhat must leave it
A fixed Nimbus‑8 netlist, elaborated and linked, with 0 unresolved references (Part 3, Dashboard 1).A defined partition set: every block named, sized and bounded, with its cell count and area reconciled to the Nimbus‑8 totals (Part 4).
Chip-level SDC and UPF, complete and checked (Part 3).Every block's pins assigned at real pitch, on legal layers, with feedthroughs pushed down and accounted for (Part 5).
A fixed 3.20 × 3.20 mm core floorplan and a full macro inventory (Part 3).A timing budget on every boundary-crossing path, split and later rebudgeted (Part 6).
The u_sens_tile partition, already closed at block level in Chapters 5–6, as a fixed sub-block of the whole.A top-level model, abstract, frame or ETM, chosen per block with its accuracy measured, not assumed (Parts 7–8).
A design planning flow available for hierarchical use (design planning UG Ch 1).A top level closed on real timing, in every scenario, with the reason recorded if any block ever needed a second pass (Part 9).
A saved, reopenable top-level checkpoint and a written exit state for ECO Flow (Part 12).
Figure 1 — Flat versus hierarchical implementation Two views of the same Nimbus-8 core: on the left implemented flat as one database, on the right divided into four named partitions, each its own closeable block.
Read it: The left panel shows Nimbus‑8 as one flat placement database: 9.90 million cells, no internal boundaries. The right panel shows the same core area cut into four partitions, u_sens_tile, u_dsp_core, u_io_ring and u_pwr_ctrl, each with a heavy boundary, each closeable on its own. The core area and the total cell count are identical on both sides; only the organisation changes.
Cost ledger — flat vs. hierarchical (u_sens_tile-sized block)
Runtime, one placement passflat: ~14 h  |  hierarchical block: ~50 min
Peak memoryflat: ~48 GB  |  hierarchical block: ~4 GB
Team parallelismflat: 1 engineer  |  hierarchical: 4 blocks in parallel
Interface accuracy lost0 (flat sees everything)  |  up to 7 ps worst-case interface arc error (Dashboard 3)

What hierarchy costs, stated honestly

Every stage boundary you draw creates a boundary a signal has to cross, and every boundary a signal crosses is a place where the tool's knowledge becomes less complete. Inside a block, the place-and-route engine can see every gate on a path. Across a block boundary, at top level, it can only see whatever model that block chose to publish, and that model, by design, throws most of the block away. This chapter's thesis, stated once here and proven with numbers for the rest of the book: hierarchy buys parallelism and capacity, and it pays for that with interface accuracy. Every model is a lie of a known size. Your job, from Part 4 onward, is to know the size.

Part 2 — Beginner foundations

The vocabulary of hierarchy, before any command

Every chapter before this one worked on a design you could open, place, route and inspect as a single object. That stops being practical somewhere between a few hundred thousand cells and a few million, and Nimbus‑8, at 9.90 million, is well past the line. This Part gives you the words for what happens next, in the order the rest of the chapter uses them.

Vocabulary

Core vocabulary for hierarchical implementation
TermDefinition
BlockA named, physically bounded sub-portion of the design, implemented and closed largely on its own.
PartitionThe act, and the result, of deciding where block boundaries go.
Top levelThe design level above every block: the level that instantiates the blocks and owns anything not assigned to one.
Abstract viewA reduced model of a block that keeps only its boundary logic, PG, blockages and timing arcs, for use at the top level.
Frame viewAn even smaller model: physical outline, pins and vias only, extracted from the design view, with no logic or timing at all. Every abstract needs a matching frame view to make top-level routing possible.
ETM (extracted timing model)A timing-only model built from characterised arcs, with no physical geometry.
Black boxA module represented by its interface alone, pin names and directions, with no netlist, timing or physical content at all.
Pin (block pin)Real, physical connection geometry on a block's boundary, at a pitch, on a layer, with a direction, not merely a name in a netlist.
FeedthroughA top-level net that is routed through a block's interior rather than around it, borrowing the block's own tracks and pin sites.
Timing budgetA portion of a chip-level timing requirement, assigned to a block or to the top level, so each piece can be closed on its own number.
RebudgetingRevising a budget after a block's real optimization result is known, moving slack to wherever it is actually needed.
Top-level closureThe process of proving, with real top-level timing, that every block's model and every budget actually held.
Transparent hierarchy optimization (THO)Concurrent optimization of the top level and selected subblock design views, in top-level timing context, with physical block boundaries honored throughout — it lets a boundary-crossing path be optimized once, end to end, without flattening the design.
Early data check (EDC)A policy-driven check run before hierarchical work begins, to catch a design that is not ready to be partitioned.
Figure 2 — The model ladder Five representations of the same block side by side: full design view, abstract view, frame view, ETM and black box, each with what it keeps, what it discards, relative file size and one question it can still answer.
Read it: Each row is one model of the same block, from the full design view (everything, 100% size) down to a black box (interface only, under 0.1% size). Reading left to right on any row: what the model keeps, what it discards, its size relative to the full view, and one question it can still answer. This is the vocabulary the rest of the chapter uses whenever it names a model type. The size column is illustrative, an order-of-magnitude sense of relative footprint, not a value from the manual — UG Ch. 11 gives no size figures for any of these models. The abstract and frame rows are otherwise condensed from UG pp.730–731 and p.738.
Part 3 — Prerequisites, readiness and early data checks

Before you cut a design into blocks, prove it is ready to be cut

This chapter restates Nimbus‑8's identity early, so it reads on its own. It is a fictional SoC teaching design: 9.90 million standard cells, 72 SRAM macros, one DDR PHY hard macro, and a 3.20 × 3.20 mm core. It runs four clocks (1.60 GHz, 1.10 GHz, 800 MHz, 200 MHz) and two named scenarios carried forward from every earlier chapter: func_ss_0p72v_125c (worst-case setup) and func_ff_0p88v_m40c (worst-case hold). Its u_sens_tile partition is already closed at block level from Chapters 5 and 6, and stays fixed: 46,200 cells, two SRAM macros, 0.70 × 0.62 mm, 79.6% utilized. This chapter defines the rest of the partition set around it.

The IC Compiler II design planning flow lists design partitioning, generating hierarchical constraints and allocating top-level timing budgets as the first stage of hierarchical work, run before any block is placed. This chapter follows that order: readiness, then partitioning, then everything downstream of it.

Figure 3 — Early data check flow A short decision flow: set the early-data-check policy, run report_early_data_checks, and route the result to PASS, REVIEW or BLOCKER.
Read it: The policy is set once with set_early_data_check_policy. The report is generated with report_early_data_checks. Its result routes to one of three outcomes: PASS proceeds, REVIEW needs a named owner and a decision before proceeding, and BLOCKER stops the flow until resolved. Dashboard 1 below is exactly this report, applied to Nimbus‑8.
Dashboard 1 — partition readiness

Partitioning is expensive to redo. This board exists so the decision to commit blocks is made on evidence, not on habit carried over from the RTL hierarchy.

Partition readiness dashboard — is Nimbus-8 ready to be cut into blocks? (part 1 of 2)
ItemEvidenceSource command /
report
ThresholdStatusRequired action
Netlist and constraint completeness
1. Netlist elaborated and linked0 unresolved references, 0 black boxes unaccounted forreport_design -unresolved_references0 unresolvedPASS
2. Chip-level SDC completeAll 4 clocks defined, all I/O delays set, 0 unconstrained portscheck_timing0 unconstrained endpointsPASS
3. Chip-level UPF loaded1 power domain (single-voltage baseline), all supply nets definedload_upfLoads with 0 errorsPASS
4. RTL hierarchy inspected, not assumedHierarchy browser walked; 3 candidate cuts compared (Figure 2)hierarchy browser sessionAt least one alternative to the RTL tree consideredPASS
Partition readiness dashboard — is Nimbus-8 ready to be cut into blocks? (continued — part 2 of 2)
ItemEvidenceSource command /
report
ThresholdStatusRequired action
Floorplan and macro maturity
5. Core area fixed3.20 x 3.20 mm, 10.24 mm^2initialize_floorplanCore area frozen before block shapingPASS
6. All 72 SRAM + 1 DDR PHY identified73 macros inventoried, sizes and pin sides knownmacro inventory review100% of macros identified before shapingPASS
7. I/O placedplace_io run, 100% of I/O pads placedplace_io100% placedPASS
8. Utilization target sanity-checked81.9% chip-level, no single block target above 82%arithmetic check against Nimbus-8 totalsNo block above 85% (routing headroom)PASS
Black boxes and UPF-across-hierarchy readiness
9. Netlist settle window closedLast RTL change 2 days ago; team norm is a 5-day settle window before committing blocksdesign change logNo RTL change in the settle windowREVIEWHold commit_block for 3 more days, or get written sign-off from the RTL owner that no further change is expected before then.
10. Block-level UPF strategy definedOnly chip-level UPF exists today; per-block supply nets not yet split outUPF reviewEach planned block has an UPF strategy before shapingREVIEWRun split_constraints to generate block-level UPF alongside SDC once the partition set (Part 4) is final.
11. Black-box references created for un-owned IP0 required — Nimbus-8 has no third-party black-box IP in this releaseIP inventoryEvery un-owned module has a black-box reference or is waivedPASS
12. Hierarchy browser data flow reviewedData flow analysis run for macro-heavy candidate cutshierarchy browser, data flow viewReviewed before committing blocksPASS

Readiness verdict for Nimbus-8: 10 PASS, 2 REVIEW, 0 BLOCKER → GO, with two items to close before block shaping begins.

Read it: Read gates 9 and 10 first — both are REVIEW, and both are exactly the kind of gap that looks harmless until a block is already committed. A netlist that has not settled and a UPF file that only exists at chip level are fixable now, cheaply. They are not fixable cheaply after commit_block.

Field values are this chapter's illustrative teaching data.

Reading the readiness verdict

Dashboard 1 is not a formality. It is the evidence that the decision to partition Nimbus‑8 was made on real checks, not on habit. Ten of twelve gates are PASS. Two are REVIEW: the netlist settle window and the block-level UPF strategy. Neither blocks the chapter from proceeding, both are closed explicitly before Part 4 commits the partition set, and the continuity ledger delta records that they were closed, not silently dropped.

Part 4 — Partitioning and block definition

Drawing the boundaries, and paying for every one of them

The design planning flow gives four factors to weigh when deciding on physical partitions. Size: group small blocks, split large ones. Function: partition along functional units, watching top-level connectivity and pin count. Floorplan style: an abutted layout implies a different physical hierarchy than a channeled one. And common hierarchy with the front-end tool, so SCANDEF exchanges cleanly between the two. None of those four factors is “whatever the RTL author already grouped together,” and that omission is deliberate.

Figure 4 — The partition decision One floorplan region shown flat, then partitioned three different ways -- by function, by size only, and on the RTL tree -- with nets cut and feedthroughs implied for each, and a verdict.
Read it: Panel A is the unpartitioned baseline. Panel B cuts along functional units and is recommended: 6 nets cut, 2 implied feedthroughs. Panel C cuts purely by size, ignoring function, and is marked review: 14 nets cut, 5 feedthroughs. Panel D follows the RTL module tree exactly and is marked avoid: 22 nets cut, 9 feedthroughs, the RTL grouping crosses more real signal paths than either physically motivated cut.
Cost ledger — the partition decision (per candidate cut)
A: flat (baseline)0 nets cut, 0 feedthroughs implied
B: cut by function (recommended)6 nets cut, 2 feedthroughs implied
C: cut by size only (review)14 nets cut, 5 feedthroughs implied
D: cut on RTL tree (avoid)22 nets cut, 9 feedthroughs implied

Nimbus‑8's partition set

u_sens_tile is fixed: 46,200 standard cells, two SRAM macros, a 0.70 × 0.62 mm footprint, 79.6% utilized. Chapter 6 recorded those numbers publicly and they do not change here. But reconciling them against Nimbus‑8's chip-level totals surfaces something worth stating plainly, in the open, rather than quietly working around.

Nimbus‑8 partition set, reconciled to chip-level totals
BlockStd. cellsSRAM macrosMacro areaFootprintUtilization
u_sens_tile46,2002 (large sensor-buffer, 0.159 mm² each)0.318 mm²0.70 × 0.62 mm79.6% (fixed, Ch. 5–6)
u_dsp_core6,200,000400.732 mm²2.42 × 2.30 mm (illustrative)80% (target)
u_io_ring1,200,00020 + 1 DDR PHY1.216 mm²1.90 × 1.31 mm (illustrative)78% (target)
u_pwr_ctrl2,453,800100.183 mm²1.66 × 1.25 mm (illustrative)80% (target)
Total9,900,00072 + 1 DDR PHY2.449 mm²81.9% chip-level

Cell counts sum to 9,900,000 exactly. Macro area sums to 2.449 mm² against a published 2.45 mm² (rounding on the per-macro average). Every other figure this chapter draws is built against this table, and it is repeated verbatim in qa/continuity-ledger-delta.md.

Committing the blocks

Once the partition set is decided, blocks are committed early in the floorplanning flow so abstract views can generate an initial floorplan and timing budget for the design. Design planning uses read_verilog_outline to read the design, initialize_floorplan to set up the core, place_io for I/O, and commit_block to fix the chosen partition boundaries. Block shaping follows in the same flow: set_macro_constraints constrains the hard macros and I/O cells inside a block (orientation, preferred location, alignment grid), create_keepout_margin adds margin around them, and shape_blocks then shapes and places every shaping object in the design as one set, with respect to constraints and utilization requirements — it is not called per block, it acts once on the whole design's shaping objects together.

Committing and shaping a block Verified

Design planning flow, constraining the two large sensor-buffer SRAM macros inside u_sens_tile (Part 4's reconciliation) before shaping the whole design.

  1. 1Read the outlined netlist: read_verilog_outline.
  2. 2Initialize the floorplan: initialize_floorplan.
  3. 3Explore the hierarchy and fix the boundary: commit_block.
  4. 4Constrain the hard macros, add keepout margin, then shape the design's shaping objects as a set:
    icc2_shell> set_macro_constraints -allowed_orientations {R0 MX} \
      [get_cells {u_sens_tile/u_sram_buf0 u_sens_tile/u_sram_buf1}]
    icc2_shell> create_keepout_margin -type hard_macro -outer {2.0 2.0 2.0 2.0} \
      [get_cells {u_sens_tile/u_sram_buf0 u_sens_tile/u_sram_buf1}]
    icc2_shell> shape_blocks -pg_strategy nimbus8_sensor_pg
    set_macro_constraints and create_keepout_margin both take a positional object collection, not -blocks, and both operate on hard macros or I/O cells — not on the physical block itself. -outer takes a four-value margin list, {left bottom right top}, not a single number. shape_blocks takes no object list at all: it shapes every shaping object of the current design together. -pg_strategy takes the name of a strategy already created with set_pg_strategy, not a keyword — nimbus8_sensor_pg above is that strategy's name, not an enum value.
Part 5 — Pin assignment and feedthroughs

A pin is geometry, and a feedthrough is a borrowed room

A netlist pin is a name and a direction. A physical pin is a rectangle of real metal, on a real layer, at a real coordinate, obeying that layer's preferred routing direction, and until it has all four of those properties, nothing at the top level can actually connect to it. This Part is about giving every block boundary that real geometry, and about the one mechanism, the feedthrough, that lets a top-level net cross a block it does not belong to.

Figure 5 — Pin assignment on a block edge Real pin geometry along one block edge at pin pitch, on two metal layers with preferred directions, with a dimensioned pitch and a layer legend.
Read it: Pins sit at a fixed 1.0 µm pitch down the block edge, alternating between M3 and M4, 18 of 22 slots filled. Four slots along this edge are left empty on purpose, reserved headroom rather than an omission — the dashed outlines mark them. The dimension below the panel measures the pitch directly against the grid it describes.
Cost ledger — pin assignment on a block edge
Pins placed18 of 22 available slots on this edge
Pin pitch1.0 µm, M3/M4
Slots reserved, unused4 (headroom for a later ECO)

Pin constraints are set with create_pin_constraint before pins are actually placed with place_pins, which performs global routing for pin locations honoring individual and bundle constraints, layer, width, length and spacing requirements. A pin blockage can be created first with create_pin_blockage to reserve a region no pin may use.

Assigning pins on a block edge Verified

u_sens_tile's boundary, individual pin constraints.

  1. 1Constrain a pin's edge and layer: create_pin_constraint. The edge and layer options are plural, -sides and -layers, even for a single pin.
    icc2_shell> create_pin_constraint -type individual \
      -pins {sens_data_out[0]} -sides {1} -layers {M3}
  2. 2Repeat for every constrained pin, or leave the rest to the placer.
  3. 3Place pins for the current block: place_pins.
  4. 4Check legality: check_legality.

Feedthroughs: with, and without

Figure 6 — Feedthrough: with and without The same top-level net routed around a block on the left, and pushed through it as a feedthrough on the right.
Read it: On the left the net detours entirely around block B, using only top-level routing space. On the right the same net enters block B on one boundary pin and exits on another, running on the block's own M4 track between them. The right-hand path is shorter overall, at the cost of the pins and track it consumes inside the block.
Cost ledger — feedthrough: with vs. without
Pins added to the block+2 (routed around: 0)
Internal track consumed+1 track through the block
Added wire length+40 µm vs. the routed-around path
Added delay+18 ps

When a block contains feedthrough nets, push_down_objects creates an electrically equivalent port on the lower-level block where the net crosses it; specifying -allow_feedthroughs true with create_pin_constraint creates an actual feedthrough port in the lower block instead. Feedthroughs pushed down from the top carry the is_shadow attribute on their pins, nets and buffers, marking them as not the block's own logic.

Figure 7 — Abutted versus channel blocks The same two blocks placed edge to edge on the left, and with a routing channel between them on the right.
Read it: Abutted (left), block A and block B share an edge directly; any top-level net between them must feed through one of the two. With a channel (right), a 38-µm gap carries top-level routing on its own tracks, at the cost of the area the channel occupies.
Cost ledger — abutted vs. channel blocks
Abutted: top-level routing space0 — no channel exists
Channel: top-level routing space38 µm wide channel, 5 tracks on M5
Abutted: area saved+38 µm x block height reclaimed

Feedthrough sharing on a multiply instantiated block

Figure 8 — A multiply instantiated block One block definition placed three times, each instance needing a different number of feedthroughs.
Read it: The same block definition is placed three times. Instance 0 needs 2 feedthroughs, instance 1 needs 5, instance 2 needs 2. Because all three instances share one physical definition, the feedthrough capacity that definition can offer is the minimum across every placement that uses it, here, 2, not 5.
Cost ledger — a multiply instantiated block
Instance 0 feedthrough need2
Instance 1 feedthrough need5
Instance 2 feedthrough need2
Shared feedthrough capacitymin(2, 5, 2) = 2 — instance 1 cannot use the shared definition as-is

Feedthrough sharing in multiply instantiated blocks is constrained exactly this way: a shared block definition can only offer the feedthrough paths every instance can accommodate. Instance 1's extra three feedthroughs need either a second, dedicated definition or a top-level routing plan that does not depend on this block carrying them.

Part 6 — Timing budgeting

Splitting one number across blocks that cannot see each other

A path that starts in one block, crosses the top level, and ends in another block has one timing requirement as a whole, but no single tool run can ever see the whole path at once, because each block is closed largely on its own. Budgeting is the step that turns one chip-level requirement into pieces small enough for a block, working alone, to close against.

To support budgeting, chip-level SDC and UPF are partitioned into top-level and block-level files, using split_constraints when only chip-level constraints exist yet. The timing budgeter itself works in four steps: create lightweight timing abstracts for the blocks with create_abstract, virtually optimize each block with estimate_timing to get a realistic starting timing picture, apply any manual constraints with set_pin_budget_constraints and set_boundary_budget_constraints, update the computed budget with compute_budget_constraints, and write the result out with write_budgets. The budgeter is fully multimode, multicorner aware, and understands multiply instantiated blocks.

Figure 9 — Splitting a timing budget across a boundary One timing path crossing two blocks through the top level, with the total 1.20 ns budget dimensioned as 0.45 ns block A, 0.30 ns top, 0.45 ns block B.
Read it: The path starts in block A, crosses the top level, and ends in block B. The total path budget, 1.20 ns, is dimensioned as three segments along the path: 0.45 ns inside block A, 0.30 ns at the top level, and 0.45 ns inside block B. Each segment is a number a single tool run can actually optimize against.
Cost ledger — splitting a timing budget
Total path budget1.20 ns
Block A share0.45 ns
Top-level share0.30 ns
Block B share0.45 ns

Generating a timing budget Verified

The four-step budgeter flow, applied chip-wide.

  1. 1Split chip-level constraints if needed: split_constraints.
  2. 2Create block timing abstracts: create_abstract.
  3. 3Virtually optimize each block: estimate_timing.
  4. 4Compute and write the budget. The pin list is positional, not -pins, and the split is stated with -from_delay: this pin is the boundary a path arrives at, so 0.45 ns is the delay allocated from the start of the path up to this pin, with whatever remains left for the segment past it.
    icc2_shell> set_pin_budget_constraints -from_delay 0.45 {sens_data_out[0]}
    icc2_shell> compute_budget_constraints
    icc2_shell> write_budgets -output nimbus8_budgets_v1

Rebudgeting

A budget is a starting point, not a promise held in place forever. Once a block has actually been placed and optimized, its real result is known, and that real result almost never matches the initial split exactly.

Figure 10 — Rebudgeting after place_opt The same path after block-level place_opt, with block A closing faster than its budget and block B needing more, redrawn to the new split.
Read it: Block A closed at 0.35 ns against its 0.45 ns budget, 0.10 ns to spare. Block B needed 0.55 ns against its own 0.45 ns budget, 0.10 ns short. The top-level share, 0.30 ns, is unchanged. Moving the spare 0.10 ns from A to B keeps the same 1.20 ns total and turns two violations (one comfortable, one tight) into a design where both blocks fit their real numbers.
Cost ledger — rebudgeting after place_opt
Block A: budget vs. closed0.45 ns budget, closed at 0.35 ns (-0.10 ns to spend elsewhere)
Top-level share0.30 ns, unchanged
Block B: budget vs. closed0.45 ns budget, needs 0.55 ns (+0.10 ns moved from block A)
Dashboard 2 — block interface board

An interface is not one property. It is six, and a block can be PASS on five of them and still be unusable at the top level because of the sixth.

Block interface board — per-block pins, feedthroughs, budget and PG (part 1 of 3)
ItemEvidenceSource command /
report
ThresholdStatusRequired action
u_sens_tile (46,200 cells, 2 sensor-buffer SRAMs)
1. Pins assigned18 pins, pitch 1.0 um, M3/M4place_pins100% of declared pins placedPASS
2. Pin-layer legality0 layer-direction violationscheck_legality0 violationsPASS
3. Feedthroughs2 in, 0 outpush_down_objectsDeclared count matches top-level net listPASS
4. Budget assigned0.45 ns on the sensor-read critical pathset_pin_budget_constraintsEvery timing-critical pin has a budgetPASS
5. Constraints splitBlock-level SDC and UPF generatedsplit_constraintsBlock file exists and loads cleanPASS
6. PG at boundaryMesh continuity verified at abutment edgesPG connectivity check0 opens at the boundaryPASS
Block interface board — per-block pins, feedthroughs, budget and PG (continued — part 2 of 3)
ItemEvidenceSource command /
report
ThresholdStatusRequired action
u_dsp_core (6,200,000 cells, 40 SRAMs)
7. Pins assigned212 pins, pitch 1.0 um, M3/M4place_pins100% placedPASS
8. Pin-layer legality0 violationscheck_legality0 violationsPASS
9. Feedthroughs6 in, 3 outpush_down_objectsDeclared count matches top-level net listPASS
10. Budget assigned0.60 ns worst-case on the DSP MAC pathset_pin_budget_constraintsEvery timing-critical pin has a budgetPASS
11. Constraints splitBlock-level SDC and UPF generatedsplit_constraintsBlock file exists and loads cleanPASS
12. PG at boundaryMesh continuity verifiedPG connectivity check0 opensPASS
Block interface board — per-block pins, feedthroughs, budget and PG (continued — part 3 of 3)
ItemEvidenceSource command /
report
ThresholdStatusRequired action
u_io_ring (1,200,000 cells, 20 SRAMs, DDR PHY)
13. Pins assigned348 pins (incl. DDR PHY I/O), M3/M4/M5place_pins100% placedPASS
14. Pin-layer legality0 violationscheck_legality0 violationsPASS
15. Feedthroughs9 in, 5 out — highest in the designpush_down_objectsDeclared count matches top-level net listREVIEW9 in / 5 out is high for one block. Review with the floorplan owner whether one feedthrough can move to an abutted path instead (Part 5).
16. Budget assigned0.80 ns worst-case, DDR PHY calibration pathset_pin_budget_constraintsEvery timing-critical pin has a budgetPASS
17. Constraints splitBlock-level SDC and UPF generatedsplit_constraintsBlock file exists and loads cleanPASS
18. PG at boundaryMesh continuity verifiedPG connectivity check0 opensPASS
u_pwr_ctrl (2,453,800 cells, 10 SRAMs)
19. Pins assigned96 pins, M3/M4place_pins100% placedPASS
20. Pin-layer legality0 violationscheck_legality0 violationsPASS
21. Feedthroughs3 in, 2 outpush_down_objectsDeclared count matches top-level net listPASS
22. Budget assigned0.35 ns worst-case, power-switch enable pathset_pin_budget_constraintsEvery timing-critical pin has a budgetPASS
23. Constraints splitBlock-level SDC generated; UPF strategy still pending (Dashboard 1, item 10)split_constraintsBlock file exists and loads cleanREVIEWClose Dashboard 1 item 10 before this block's UPF is considered final.
24. PG at boundaryMesh continuity verifiedPG connectivity check0 opensPASS

Interface verdict: 4 blocks, 22 PASS, 2 REVIEW, 0 BLOCKER → all four interfaces usable for top-level assembly, with 2 items to close before final closure.

Read it: u_sens_tile is the block carried over from Chapters 5 and 6; its feedthrough count (2) and budget (0.45 ns) are the numbers Figure 15C draws. u_io_ring carries the DDR PHY and shows the highest feedthrough count, which is expected of a periphery block that other blocks route through to reach pads.

Field values are this chapter's illustrative teaching data.

Part 7 — Abstract views

Keeping the boundary, discarding everything behind it

In an abstract view, a block's gate-level netlist is modelled by a partial netlist. That partial netlist keeps only the required interface logic: everything between an input port and the first register of each timing path, everything between the last register of a path and an output port, any pure input-to-output combinational logic, and the clock connections and clock trees that drive the preserved registers. Register-to-register logic in the interior is discarded entirely.

Figure 11 — Anatomy of an abstract One block drawn in full on the left, and the same block as an abstract on the right, with the discarded interior greyed out and the retained boundary highlighted.
Read it: The left panel shows the full design view: every internal cell drawn. The right panel shows the same block as an abstract: the interior is greyed out and labelled discarded, while the boundary, the outline itself, plus every boundary pin, is kept and highlighted in teal. Nothing inside the grey region is visible to the top level any more.
Cost ledger — anatomy of an abstract
Cells keptboundary-adjacent logic only, ~5-15% of the block
Cells discardedall register-to-register interior logic
File size vs. full view (illustrative)~8% for u_sens_tile's abstract
Measured interface error4 ps worst-case arc (Dashboard 3)

Creating an abstract uses create_abstract. Its options preserve power information, keep signal electromigration data, preserve minimum pulse-width analysis, and handle multiple levels of physical hierarchy. The one setting that matters most for how much of the interface an abstract actually keeps is -timing_level, covered below. create_abstract -preserve_block_instances false and read-only variants exist for specific top-level closure needs. report_abstract_inclusion_reason explains, for a given included object, why it was kept — it reports inclusion only, never discards, and it does not report for hierarchical cells or pins on hierarchical cells. It is useful when an abstract's size looks larger than expected: you find out why the things that are there are there, not why something you expected is missing.

Creating and reading an abstract Verified

u_sens_tile, once its pins and budget are final.

  1. 1Confirm pins and budget are final (Parts 5–6). Do not build the abstract before this.
  2. 2Create the abstract: create_abstract -timing_level compact.
  3. 3Check why an object was included: report_abstract_inclusion_reason. Reported reason codes come from a fixed legend — mv for MV logic, comp for compact interface logic, cell for cell inclusion — and one object can carry several.
    icc2_shell> report_abstract_inclusion_reason [get_pins \
      -of_objects [get_cells sens_buf_reg*]]
    get_pins takes -of_objects, plural — the User Guide prints -of_object, singular; the Tool Command Reference spelling above is authoritative.
  4. 4Save the block: save_block.

Choosing a timing level

create_abstract -timing_level none(deprecated)|boundary|compact|full_interface is the fidelity dial that decides how much boundary timing an abstract keeps, and it trades memory and runtime against accuracy directly. none is marked deprecated and slated for removal in the Tool Command Reference, so the table below covers only the three settings actually worth choosing between:

SettingWhat it keepsWhen to use it
boundaryBoundary cells only, one level of logic per boundary port, plus feedthrough data paths, feedthrough combinational clock paths, and internal clock logic driving output ports.Fixing DRC violations at the top level.
compact — defaultTiming for the critical setup and hold paths of the interface logic only.Preferred for top-level design closure; this is what u_sens_tile uses.
full_interfaceTiming for all interface logic, not just the critical paths.Multiply-instantiated blocks (MIBs), when the constraints for different MIB instances differ at the top level.

This connects straight back to Part 4's MIB material. A MIB placed at three sites can face three different top-level timing contexts, and compact only carries the critical paths against one of them. full_interface is what lets every instance's own constraints show up in its own abstract's timing, which is exactly the mismatch Figure 8 and interview questions 18 and 31 are built around. -blocks / -all_blocks create lower-level abstracts in bulk, -force_recreate rebuilds even when the tool thinks an abstract is current, and -include_objects forces specific objects into the abstract that the timing level alone would not keep. -target_use planning | implementation changes the tool's internal settings based on how the abstract will be used. -read_only works the opposite way from what its name suggests: a read-only abstract leaves the block's own design view editable, while the default (not read-only) makes the design view read-only once an abstract references it.

If a block changes after its abstract was created, the abstract has to be regenerated, it is not automatically kept in sync. Abstract views can also be shrunk further while maintaining timing accuracy on the arcs they still carry, and the PG structure can be recreated on an existing abstract without rebuilding the whole thing from the design view. A frame view goes one step further: physical outline, pins and vias only — blockage, pin, and via information extracted from the design view, with no logic or timing arcs at all — created with create_frame. Every abstract view must have a corresponding frame view to perform top-level routing, including virtual routing, which is the reason a frame view exists at all, not just a lighter-weight convenience for congestion estimation.

Linking abstracts at the top level

At the top level, report_abstracts reports which abstract views the design is linking to. Because the tool does not currently modify abstract contents during top-level closure, abstracts used this way can be created read-only. If a block needs to change between its abstract and its full design view, the command is change_abstract -view design|abstract -references <block>. Switching a block to its design view is not a one-line swap: it requires removing the scenarios, modes and corners built against the abstract, then re-applying the full-chip timing constraints, because the design view exposes internal structure the abstract's constraints were never written against.

icc2_shell> remove_scenarios -all
icc2_shell> remove_modes -all
icc2_shell> remove_corners -all
icc2_shell> change_abstract -view design -references u_sens_tile
icc2_shell> source full_chip_scenario_creation.tcl

link_block -rebind is a different operation: it relinks a reference after the label switch list has been changed with set_label_switch_list, not after an abstract/design view switch. Switching between an ETM and an abstract is a third command again, set_reference (Part 8). Also available: change_abstract -reload reloads a changed abstract from disk; report_abstracts reports which abstracts the design links to; remove_abstract removes an abstract and returns the design view to editable.

Dashboard 3 — model fidelity board

A model is a lie of a known size. This board is where the size gets written down, so a stale model is caught before it costs a top-level closure cycle.

Model fidelity board — what each block's top-level model omits
ItemEvidenceSource command /
report
ThresholdStatusRequired action
Model choice and what it omits
1. u_sens_tileAbstract — small, stable interface, top-level route needs real boundary geometrycreate_abstractOmits: all register-to-register logic inside the tilePASS
2. u_dsp_coreAbstract — large block, top-level place and route still needs its physical boundarycreate_abstractOmits: all internal DSP datapath logicPASS
3. u_io_ringAbstract — DDR PHY pin geometry must be visible for top-level pad-ring routingcreate_abstractOmits: PHY calibration logic interiorPASS
4. u_pwr_ctrlETM — small block, high pin-to-logic ratio, top-level STA needed fast and accurate more than physical detailextract_model (ICC2)Omits: physical geometry entirelyPASS
Measured error and staleness
5. u_sens_tile error vs full view4 ps worst-case interface arc (Figure 15D)abstract-vs-full timing comparison≤ 10 ps on any interface arcPASS
6. u_dsp_core error vs full view7 ps worst-case interface arcabstract-vs-full timing comparison≤ 10 ps on any interface arcPASS
7. u_io_ring error vs full view6 ps worst-case interface arcabstract-vs-full timing comparison≤ 10 ps on any interface arcPASS
8. u_pwr_ctrl error vs full view3 ps worst-case interface arcETM-vs-full timing comparison≤ 10 ps on any interface arcPASS
9. u_sens_tile regenerated vs changedRegenerated 1 day after last block editmodel timestamp vs block edit logRegenerated within 14 days of any editPASS
10. u_pwr_ctrl regenerated vs changedETM regenerated 9 days after last block editmodel timestamp vs block edit logRegenerated within 14 days of any editREVIEWStill inside policy, but close to it. Schedule the next ETM regeneration for this block first.

Fidelity verdict: 4 models in use (3 abstract, 1 ETM), 3 PASS, 1 REVIEW → usable for top-level closure, with one regeneration due.

Read it: The Regenerated vs Changed column is the one to watch. u_pwr_ctrl's ETM is 9 days older than the block's last edit — still inside this project's 14-day staleness policy, but close enough to flag.

Field values are this chapter's illustrative teaching data.

Part 8 — ETMs and choosing your model

When an abstract is not accurate enough

An extracted timing model, or ETM, is a timing-only model with no physical geometry at all, built instead from characterised timing arcs across every mode and corner the block needs. It is more accurate than an abstract for pure timing questions, because it is not derived from geometry at all; it is measured, arc by arc, against the real block.

ETMs can be created directly in the ICC2 tool with extract_model, after a frame view is created for library preparation and PrimeTime options are set; StarRC parasitic extraction can be selected explicitly. The same command combines timing extraction and cell-library packaging in one step. Alternatively, ETMs can be created per scenario in the PrimeTime tool itself, reading the block's netlist and parasitics, applying UPF and mode/corner constraints, and calling extract_model -library_cell -format db; for multicorner-multimode designs, one ETM is required per scenario. A third path builds ETM cell libraries in the Library Manager tool, combining PrimeTime-created ETMs with physical information.

Creating an ETM in the ICC2 tool Verified

u_pwr_ctrl, chosen for an ETM over an abstract (Dashboard 3).

  1. 1Open the block and create a frame view: create_frame.
  2. 2Set PrimeTime options and a post-link script.
  3. 3Optionally select StarRC extraction: set_app_options -name extract.starrc_mode -value true.
  4. 4Create the ETM and its cell library: extract_model.
    icc2_shell> create_frame
    icc2_shell> set_pt_options -pt_exec <path> -work_dir ETM_work_dir
    icc2_shell> extract_model
    Errata: the User Guide prints -pt_exec_path; the Tool Command Reference spells it -pt_exec, confirmed in its own worked examples. The Tool Command Reference is authoritative — use -pt_exec.

Choosing a model: abstract, frame or ETM

Return to Figure 2's model ladder. An abstract is the right default when the top level still needs real boundary geometry, place and route, congestion, physical DRC near the boundary. A frame is the right choice when even abstract-level timing is more than is needed, typically early floorplanning. An ETM is the right choice when a block's pin-to-logic ratio is high, its physical detail rarely matters to the top level, and top-level STA speed and accuracy both matter more than geometry, exactly Nimbus‑8's u_pwr_ctrl, per Dashboard 3.

Part 9 — Top-level closure and transparent hierarchy optimization

Proving every promise the earlier Parts made was true

Every block in Nimbus‑8's partition set can close cleanly at block level and the top level can still fail. That is not a contradiction. It is the direct, structural consequence of every block being closed against a model of its neighbours rather than against the neighbours themselves.

Figure 12 — Why a top level fails when every block passed The budget promised 0.45 ns of arrival slack; the real block delivered 0.30 ns; the top level inherits the 0.15 ns gap as a violation nobody at block level saw.
Read it: The budget (top box) promised 0.45 ns of arrival slack at a boundary pin. The real, closed block (bottom box) delivered only 0.30 ns, still a legitimate, PASS result against a different, looser internal target the block owner used. The top level, assembling both, inherits the 0.15 ns gap between what was promised and what was real, as a violation that belonged to neither block alone.
Cost ledger — why a top level fails when every block passed
Budget promised0.45 ns arrival slack
Real block delivered0.30 ns arrival slack
Top-level gap inherited0.15 ns violation

Preparing for top-level closure with abstracts means checking designs with abstracts for top-level-closure issues before running full closure, check_hier_design -stage timing is the check used at the top-level design. Once abstracts are in place, top-level synthesis, placement, optimization, clock tree synthesis, routing and postroute optimization can all run using the same commands supported at block level.

Figure 13 — Top-level closure loop A decision flow: close blocks, create abstracts, assemble the top level, check with check_hier_design, and either exit or return to a block.
Read it: Four steps run in sequence: close blocks, create abstracts, assemble the top level, and check with check_hier_design. If the check fails, the red path returns to a block for another pass. If it passes with WNS ≥ 0 in every scenario, the loop exits. This is a loop with a real exit condition, not a single one-way pass.

Top-level closure loop Verified

  1. 1Check for closure issues before assembling: check_hier_design -stage timing.
  2. 2Assemble and optimize the top level using abstracts, then re-check.
  3. 3Report where a boundary still violates: report_timing, report_qor.
  4. 4If a block needs another pass, return to it, close, regenerate its abstract, and re-assemble.

Transparent hierarchy optimization

Rebudgeting fixes a stale split. It does not fix a boundary path whose real delay never had a chance to be seen by either optimizer, because each side only ever worked from a guess about what the other side would deliver. Transparent hierarchy optimization (THO) closes that gap without giving up the hierarchy: it opens selected subblock design views and optimizes them together with the top level, in the context of top-level timing, so an interblock or block-to-top path is optimized once, end to end, by one engine, with CCD, AWP and PrimeTime delay calculation available across it. THO honors the physical block boundaries throughout. It does not move logic across a boundary, it does not change a subblock's shape, and it does not change the physical hierarchy. By default it does not even move pins — there is an option to let it reassign pin locations to improve QoR, and that is the only boundary-adjacent thing it may touch. Because the hierarchy never flattens, signoff extraction and PrimeTime STA can still run hierarchically, and late ECOs stay easier to implement.

THO runs at two points in the flow: during the final_opto stage of place_opt, and during route_opt or hyper_route_opt at postroute. Both are points where placement, and later routing, are settled enough that a cross-boundary path has a real delay to optimize against — running it earlier would mean optimizing against geometry that has not converged yet.

Figure 14 — Transparent hierarchy optimization: same boundary, wider optimization scope Two panels sharing one identical boundary position. Left, without THO: the boundary is solid, two tinted optimization domains meet at the boundary pin with a budget value written there, each side optimizing only to that budget. Right, with THO: the same boundary in the same position, now one tinted domain spanning both sides, the budget value replaced by a real end-to-end arrival time, and the block-side logic re-sized in place without crossing the boundary.
Read it: The boundary (heavy vertical line) sits in the identical position in both panels — check the x-coordinate against the ruler tick if you don't believe it. Left, without THO: two separate tinted optimization domains meet at the boundary pin, each optimizing only to the 0.45 ns budget written at the pin; neither side ever sees the other's real logic. Right, with THO: one tinted domain now spans both sides of the same, unmoved boundary; the budget number at the pin is gone, replaced by the real 0.52 ns end-to-end arrival the path actually has. The register and buffer on the block side have been resized by the optimizer — that is legitimate THO work — but neither one has crossed to the top-level side of the line.
Cost ledger — transparent hierarchy optimization
Optimization scopeblock-only → top level + block, concurrent
Boundary geometryunchanged — same position, both panels
Pin locationshonored (default; not reassigned)
Path WNS, before → after-0.07 ns → +0.006 ns, this boundary

Applying THO Verified

  1. 1Open the libraries in edit mode: open_lib top.nlib -ref_libs_for_edit. The design view of each participating block must be editable.
  2. 2Switch the blocks you want to optimize from abstract to design view: change_abstract -view design -references <blk> (see Part 7 for the full constraint-removal sequence this requires).
  3. 3Enable editing on those blocks: set_editability -blocks {u_sens_tile u_dsp_core} -value true, and verify with report_editability -blocks [get_blocks -hierarchical].
  4. 4Set the scope: set_hierarchy_options -optimize_interface_only true opens only the interface logic for optimization; false opens the whole subblock. set_hierarchy_options -optimize_shared_logic unrestricted also opens logic shared between the interface and register-to-register paths. Report the settings with report_hierarchy_options. For distributed subblock work, add set_host_options and set_hierarchy_options -host_option — without them, subblock operations run serially in the main process.
  5. 5Run THO at the final optimization stage:
    icc2_shell> init_hier_optimization -flow pre_route
    icc2_shell> place_opt -from final_opto -to final_opto
    icc2_shell> commit_hier_optimization
    init_hier_optimization is what turns THO on for the run that follows, and it also triggers automatic promotion of block-level CCD useful-skew and latency offsets into the top-level timing context. commit_hier_optimization writes the result back. Skip either one and place_opt -from final_opto is an ordinary optimization pass, not THO.
  6. 6Rebudget. After a THO place_opt, block interface timing no longer matches the standalone implementation, so the blocks need updated constraints before clock_opt. CCD balance-point offsets may have moved and must be made block-context-specific.
  7. 7Run THO at postroute, on the same bracketing pattern:
    icc2_shell> init_hier_optimization -flow post_route
    icc2_shell> route_opt                      ;# or hyper_route_opt
    icc2_shell> commit_hier_optimization
    ECO routing after optimization runs on every subblock that is open for editing.
Dashboard 4 — top-level closure board

This is the board that decides whether the loop in Figure 11 exits or sends a block back.

Top-level closure board — WNS/TNS, interface violations, THO (part 1 of 2)
ItemEvidenceSource command /
report
ThresholdStatusRequired action
Top-level timing per scenario
1. WNS, func_ss_0p72v_125c+0.006 nsreport_timingWNS ≥ 0PASS
2. TNS, func_ss_0p72v_125c0 nsreport_qorTNS = 0PASS
3. WNS, func_ff_0p88v_m40c+0.011 nsreport_timingWNS ≥ 0PASS
4. TNS, func_ff_0p88v_m40c0 nsreport_qorTNS = 0PASS
Interface violations by block
5. u_sens_tile interface0 violationscheck_hier_design -stage timing0PASS
6. u_dsp_core interface0 violationscheck_hier_design -stage timing0PASS
7. u_io_ring interface1 violation, 0.008 ns, before rebudgetingcheck_hier_design -stage timing0PASSResolved by the rebudgeting pass in Part 6 (Figure 10); 0 remaining.
8. u_pwr_ctrl interface0 violationscheck_hier_design -stage timing0PASS
Top-level closure board — WNS/TNS, interface violations, THO (continued — part 2 of 2)
ItemEvidenceSource command /
report
ThresholdStatusRequired action
Feedthrough timing and clock trunk arrival
9. Feedthrough delay, worst case+18 ps, u_io_ring feedthrough (Figure 6)top-level timing report on feedthrough netWithin the block's assigned budgetPASS
10. Clock trunk arrival at u_sens_tile boundary0.312 ns insertion delay, 6 ps skew to siblingclock trunk reportWithin clock-tree budget for this levelPASS
11. Clock trunk arrival at u_dsp_core boundary0.298 ns insertion delay, 5 ps skew to siblingclock trunk reportWithin clock-tree budget for this levelPASS
Transparent hierarchy optimization
12. THO applied during place_opt final_optou_io_ring/top boundary optimized concurrently; boundary unmoved, pins honored (Figure 14)init_hier_optimization -flow pre_routeApplied wherever a boundary path benefits from concurrent top+block optimizationPASS
13. THO applied during route_opt0 changes needed — place_opt's pass closed the gaproute_optPASS

Closure verdict: WNS +0.006 ns / TNS 0 ns on func_ss_0p72v_125c, WNS +0.011 ns / TNS 0 ns on func_ff_0p88v_m40ctop-level closure PASS, both scenarios.

Read it: The top-level WNS is positive but small — +0.006 ns on the tighter scenario. That is the margin the budgets in Part 6 were built to protect. Read it as a result that is correct, not as one that is comfortable.

Field values are this chapter's illustrative teaching data.

Part 10 — Worked example: Nimbus‑8

u_sens_tile through the whole hierarchical flow, one region, four panels

u_sens_tile is the one partition this guide has followed since Chapter 5. This Part follows it through the rest of the hierarchical flow, the same region, the same coordinates, in every panel, pairing what the block's structure is at each stage against what it costs.

Figure 15A — Partitioned u_sens_tile shown as a defined boundary inside the Nimbus-8 core, nothing else assigned yet.
Read it: The boundary of u_sens_tile is fixed, from Part 4's partition set. The status strip shows blocks defined; pins, feedthroughs, budget and WNS all show —, not yet decided.
Cost ledger — 15A: partitioned
Blocks definedyes
Pins / f/t / budgetnot yet
Interface slack / model error / top WNSn/a / n/a / n/a
Figure 15B — Shaped u_sens_tile with its final outline and macro keepouts for its two large sensor-buffer SRAM instances.
Read it: The block's outline is now final at 0.70 × 0.62 mm, with keepouts marked around its two large sensor-buffer SRAM instances (Part 4's reconciliation). Pins, feedthroughs, budget and WNS remain —: shaping only fixes the physical outline.
Cost ledger — 15B: shaped
Shape finalyes, 0.70 x 0.62 mm
Pins / f/t / budgetnot yet
Interface slack / model error / top WNSn/a / n/a / n/a
Figure 15C — Pins assigned and budgeted u_sens_tile with 18 of 22 pin slots filled along its left edge, 4 unassigned slots drawn as empty outlines, and two feedthrough routes crossing the block from the left edge to the top edge.
Read it: 18 of the block's 22 pin slots are filled (solid) along the left edge; the 4 still-reserved slots are drawn as empty dashed outlines, not hidden. Two feedthrough routes (red) cross the block from the left edge to the top edge — the two feedthroughs Part 5 introduced. The block carries a 0.45 ns budget on its critical sensor-read path (Figure 6). The status strip shows pins 18 of 22, f/t 2, budget 0.45 ns, WNS still —: no top-level assembly yet.
Cost ledger — 15C: pins assigned and budgeted
Pins assigned18 of 22 slots
Feedthroughs2
Budget assigned0.45 ns
Interface slack+0.04 ns
Figure 15D — Abstracted and top-level closed u_sens_tile's interior greyed to an abstract, the same 18 of 22 pins and two feedthroughs from 15C carried forward, with a top-level WNS value now filled in.
Read it: The interior is gone from the top level's view; the same 18-of-22 pins and two feedthroughs from 15C are still drawn on the boundary, matching Figure 4's anatomy. The status strip now fills in the last column: pins 18 of 22, f/t 2, budget 0.45 ns, WNS +0.006 ns — the number Dashboard 4 reports for the whole chip.
Cost ledger — 15D: abstracted and top-level closed
Modelabstract
Size (illustrative)~8% of full view
Top-level checkPASS
Model error4 ps worst-case arc
Top-level WNS+0.006 ns

Read the four panels as one continuous story. A boundary with nothing decided (15A) becomes a shaped outline (15B). That outline becomes a block with real pins, two feedthroughs and a real number to hit (15C). It finally becomes the reduced model the top level actually sees, checked and passing (15D). The same five status-strip fields — blocks, pins, f/t, budget, WNS — run across all four panels, filling in left to right as the block moves through the flow. Every number in 15C and 15D traces back to a figure or dashboard earlier in this chapter; nothing here is invented for the worked example alone.

Part 11 — Guided lab

Partition, pin, budget and close a block yourself

Here is the orientation for this Part. Reading about a budget split is not the same as watching one actually fail to add up. This lab is built around one small region, taken through the whole flow, with one deliberate mistake in the middle of it.

Exercise 1, Compare three candidate cuts before choosing one

Using the hierarchy browser, pick a region of your design with at least two natural sub-blocks. Propose three different ways to cut it: by function, by size alone, and along the RTL module tree, matching Figure 4. For each, count the nets crossing the cut and the feedthroughs implied.

Close with: three candidate cuts, each with a net-crossing count. PASS if you can state, in one sentence, why your chosen cut beats the other two.

Exercise 2, Commit and shape a block

Commit your chosen block boundary with commit_block, constrain its hard macros with set_macro_constraints and their keepouts with create_keepout_margin, then run shape_blocks once for the whole design — it shapes every shaping object together, it is not called per block. Record the resulting footprint.

Close with: a committed, shaped block and its footprint dimensions. PASS if the shaped outline respects every macro keepout you declared.

Exercise 3, Assign pins and push one feedthrough through

Assign pins on your block's boundary with place_pins. Then identify one net that would naturally cross your block's footprint, and push it through as a feedthrough with push_down_objects, rather than routing it around.

Close with: a pin count, and one feedthrough with its added pin count, track and length recorded, matching Figure 6's ledger format. PASS if the feedthrough's cost is stated in the same four numbers Figure 6 uses.

Exercise 4, Budget a boundary-crossing path

Pick one timing path that crosses your block's boundary. Split its total requirement into a block segment, a top-level segment and (if it crosses two blocks) a second block segment, using set_pin_budget_constraints and compute_budget_constraints.

Close with: a budget split that sums to the path's total requirement. PASS if the three segments add up exactly.

Exercise 5, The deliberate mistake

This is the exercise that teaches the chapter. You are going to build an abstract before the block's pins are actually final, on purpose.

  1. Assign pins as in Exercise 3, and build an abstract from that state with create_abstract. Record the abstract's pin count. Call this A.
  2. Now, without rebuilding the abstract, move one pin, change its side or layer, as if a late floorplan change forced it.
  3. Report the abstract's pin count again. Call this B.
  4. Now rebuild the abstract with create_abstract and report the pin count a third time. Call this C.

You will find that B equals A, and C does not. Moving the real pin did nothing to the already-built abstract, it kept reporting the old geometry. Only rebuilding it produced a model that matched the real block. Any top-level work done against B's abstract in between was done against geometry that no longer existed.

Close with: three pin counts, A, B and C, and one sentence explaining why B was unsafe to use. PASS if C differs from A and you can say why B was the dangerous one, not C.

Exercise 6, Run a top-level closure loop and force one failure

Assemble a small top level using your block's abstract. Run check_hier_design -stage timing. Then deliberately set one boundary budget slightly tighter than what Exercise 4 showed the block could actually deliver, and re-run the check.

Close with: one clean closure result, and one deliberately forced failure, with a one-sentence diagnosis of which mechanism from Figure 12 caused it. PASS if your diagnosis names the specific budget-versus-real-block gap, not a vague “timing failed.”

Exercise 7, Write the exit state

Using Part 12's checklist, write a one-page exit state for your lab block: model type, top-level status, checkpoint name, and what a downstream ECO engineer would need to know.

Close with: a written exit state matching Figure 16's four fields. PASS if every field is filled with a real value, not a placeholder.

Part 12 — Stage-exit checklist and handoff

What leaves this stage, stated once, completely

Chapter 8, ECO Flow, needs more than a checkpoint file. It needs to know, per block, what closed, what model represents it, what the top level's real timing is, and which saved artifact proves each of those claims. This Part writes that down once, completely, rather than leaving it implicit in a folder of files.

Figure 16 — What leaves this stage A handoff table: the block set, the models in use, the closed constraints and the checkpoint name Chapter 8 receives.
Read it: Four rows: the block set (4 partitions, all closed), the models in use (3 abstract, 1 ETM), the top-level timing result (WNS +0.006 ns, both scenarios), and the checkpoint name ECO Flow will reopen, nimbus8_top_hier_closed_v1.
Dashboard 5 — stage-exit go/no-go

Every other board in this chapter feeds this one. This is the board a reviewer who has ten minutes should read.

Stage-exit go/no-go board — one decision, with its evidence
ItemEvidenceSource command /
report
ThresholdStatusRequired action
Exit criteria and their evidence
1. All 4 blocks closed at block level0 setup/hold violations, all blocks, both scenariosreport_qor0 violations, per blockPASSnimbus8_<block>_closed_v1 checkpoints
2. Top-level closedWNS +0.006 ns / +0.011 ns, TNS 0 ns, both scenariosreport_timingWNS ≥ 0, TNS = 0, both scenariosPASSnimbus8_top_hier_closed_v1 checkpoint
3. Models regenerated within policy4/4 blocks within the 14-day staleness policyDashboard 3100% within policyPASSDashboard 3 record
4. Feedthroughs accounted for20 feedthrough nets total, all pushed down and budgetedpush_down_objects100% accounted forPASSDashboard 2 record
5. PG continuous at every boundary0 opens, all 4 blocksPG connectivity check0 opensPASSDashboard 2 record
6. Early data checks clear0 BLOCKER, 0 REVIEW outstandingreport_early_data_checks0 BLOCKER at exitPASSEDC report, saved
7. Partition arithmetic reconciled9.90M cells / 2.45 mm^2 macro area, sums verifiedarithmetic checkSums to Nimbus-8 totals exactlyPASSqa/continuity-ledger-delta.md
8. Stream-out-ready checkpoint savednimbus8_top_hier_closed_v1save_blockCheckpoint exists and reopens cleanPASSnimbus8_top_hier_closed_v1
9. Handoff package written for ECO FlowBlock set, models, constraints, checkpoint names (Figure 16)handoff reviewAll four items presentPASSqa/continuity-ledger-delta.md

Stage-exit verdict: 9 PASS, 0 REVIEW, 0 BLOCKER → GO. Nimbus-8 hierarchical implementation is handed to ECO Flow.

Read it: Every row names the saved artifact that proves it, not just a claim. A reviewer who does not trust the claim can open the named checkpoint or report and check it directly.

Field values are this chapter's illustrative teaching data.

Exit checklist

Stage-exit checklist for Hierarchical Implementation
ItemEvidenceStatus
Partition set defined and reconciledPart 4 table; qa/continuity-ledger-delta.mdPASS
Every block's pins assigned and legalDashboard 2PASS
Every boundary-crossing path budgetedDashboard 2, Part 6PASS
Every block has a chosen, current modelDashboard 3PASS
Top level closed, both scenariosDashboard 4PASS
THO scope and result recorded, where appliedDashboard 4, item 12PASS
Checkpoint saved and reopens cleannimbus8_top_hier_closed_v1PASS
Exit state written for ECO FlowThis Part; delta filePASS

Every row above is PASS. Three earlier boards carried a REVIEW: the netlist settle window and block-level UPF strategy in Dashboard 1, the DDR PHY feedthrough count in Dashboard 2, and the ETM staleness margin in Dashboard 3. Each was closed explicitly before this checklist was written. The closure is recorded in qa/continuity-ledger-delta.md, not silently dropped.

Part 13 — Knowledge reinforcement and interview bank

40 questions, tiered, every answer grounded in this chapter

Forty questions across four tiers: 14 beginner, 14 intermediate, 8 advanced, and 4 senior/architect. Every answer draws only on what this chapter taught; illustrative numbers are labelled as such, and no new command is introduced in an answer that was not already verified in the body text.

Beginner, 14 questions

1. What is a block abstract, and what does it contain?
An abstract is a reduced model of a block containing only its interface logic: paths from input ports to the first register, from the last register to output ports, pure input-to-output combinational logic, the clock connections and clock trees that drive the preserved registers, and the physical boundary itself, pins, PG and blockages. Everything else, all register-to-register interior logic, is discarded.
2. Why can a design be too large to implement flat?
A flat placement database has to hold every cell, net and timing arc at once, and every optimization pass touches a meaningful fraction of it. At Nimbus‑8's scale, 9.90 million cells, that makes each flat pass slow enough that a full flow can take far longer than a team's schedule allows. Partitioning does not shrink the design; it shrinks the unit of work each tool run has to handle.
3. What is a feedthrough?
A feedthrough is a top-level net that is routed through a block's interior instead of around it, entering on one boundary pin and exiting on another, using the block's own internal track. It borrows space inside a block for a signal that is not the block's own logic.
4. Name the four factors used to decide on a physical partition.
Size (group small blocks, split large ones), function (partition along functional units, watching top-level connectivity and pin count), floorplan style (abutted versus channeled layouts imply different hierarchies), and common hierarchy with the front-end tool, so SCANDEF and similar data exchange cleanly between front-end and back-end.
5. What is a black box, in the design-planning sense?
A black box is a module with no netlist, only a partial netlist, or one that is not yet bound to a higher-level module. It lets design planning continue on a design that has un-owned or not-yet-available IP, without waiting for every module to be complete.
6. What does “pin pitch” mean for a block boundary pin?
Pin pitch is the fixed spacing between consecutive pin positions along a block edge, on a given layer. A pin is real metal geometry, not just a name, and it has to sit at a legal position on that pitch, on a layer with a stated preferred direction, before anything can actually route to it.
7. What is a timing budget?
A timing budget is the portion of a chip-level timing requirement assigned to one block or to the top level, so a path that crosses more than one implementation database can still be closed piece by piece. A single path's total requirement is split into segments, one per block or top-level portion it crosses.
8. What is the difference between an abstract view and a frame view?
An abstract keeps boundary logic, PG, blockages and timing arcs. A frame view keeps only the physical outline, pins, PG and blockages, with no logic or timing arcs at all, smaller and faster to use than an abstract, at the cost of any timing information.
9. What is an ETM?
An extracted timing model: a timing-only model built from characterised arcs across the modes and corners a block needs, with no physical geometry at all. It is created either directly in ICC2 with extract_model, or in PrimeTime per scenario.
10. What does top-level closure check that block-level closure does not?
Block-level closure checks only that a block meets the budget it was given, using its own internal optimizer's view of itself. Top-level closure checks the real, assembled top-level timing across every block's boundary together, which is the only place a mismatch between a budget and a block's real result, or between two blocks' independently-chosen budgets, can actually be caught.
11. What is an early data check, and when does it run?
An early data check is a policy-driven set of checks run before a design is committed to a partition set, covering netlist stability, constraint completeness and similar readiness gates. It runs early because a problem found before blocks are committed is cheap to fix, and the same problem found after is not.
12. Why does u_sens_tile's abstract discard its interior logic safely?
The top level never needs to know how u_sens_tile computes its outputs internally, only how long the computation takes at its boundary and where its pins sit. The abstract keeps exactly the boundary timing arcs and physical geometry the top level actually reads, so discarding the interior logic does not remove anything the top level was using.
13. What command assigns real pin geometry to a block's boundary?
place_pins, after pin constraints are declared with create_pin_constraint. place_pins performs global routing for pin locations, honoring individual and bundle constraints along with layer, width, length and spacing requirements.
14. What is transparent hierarchy optimization, in one sentence?
Concurrent optimization of the top level and selected subblock design views, in top-level timing context, available during the final stage of place_opt and during route_opt/hyper_route_opt — physical block boundaries are honored throughout, and pin locations are honored by default.

Intermediate, 14 questions

15. An abstract was created before the block's pins were finalised. What goes wrong, and when do you find out?
The abstract keeps whatever pin geometry existed at the moment it was built. If the real pins move afterward, the abstract silently keeps reporting the old geometry, nothing flags it as stale. You find out only when top-level place-and-route, or top-level timing, is built against the mismatched abstract and produces results that do not match the real block, usually much later and further from the original pin change than is convenient to trace.
16. Why does a timing budget have to exist before a block is implemented rather than after?
A block's own place-and-route optimization needs a target for every boundary-crossing path from its first placement pass onward; without one it has no basis for judging whether a given boundary delay is acceptable. Budgeting after implementation means discovering, once the block is already closed, that its interface timing does not fit the rest of the chip, and reopening a closed block is expensive.
17. What does a frame view give you that an abstract does not?
Mostly, speed and size: a frame strips out timing arcs and logic entirely, keeping only the outline, pins, PG and blockages, so it is faster to generate and lighter to use than an abstract for tasks, typically early floorplanning and congestion estimation, that never needed timing accuracy in the first place.
18. Why is feedthrough sharing constrained on a multiply instantiated block?
All instances of a multiply instantiated block share one physical definition, so the feedthrough capacity that definition can offer is limited to what every instance can accommodate, the minimum across all placements, not the maximum any one instance happens to need.
19. What does split_constraints actually produce?
It partitions chip-level SDC and UPF into a top-level constraint file (top-level and top-to-block boundary timing, no block-internal constraints) and block-level constraint files (internal constraints for each block), so budgeting and block-level optimization each have the right scope of constraint to work against.
20. What is rebudgeting, and why is it normal rather than a failure signal?
Rebudgeting is revising a budget split after a block's real, closed timing is known, moving slack from a block that closed comfortably to a neighbour that needed more. It is normal because the initial split is only an estimate; a design where every block's real result matched its initial budget exactly would be a coincidence, not evidence of good budgeting.
21. Why would you choose an ETM over an abstract for a given block?
When the block has a high pin-to-logic ratio, its physical detail rarely matters to top-level work, and top-level STA speed and accuracy both matter more than physical geometry, an ETM gives measured, characterised timing rather than timing derived from geometry, at the cost of losing all physical information for that block.
22. What does report_abstract_inclusion_reason do, and when would you use it?
It reports the reasons a netlist object was included in an abstract, one reason code per object against a fixed legend, and it does not report anything for objects that were discarded, nor for hierarchical cells or pins on hierarchical cells. You would use it when an abstract's size looks larger than expected, to see exactly why the things that are there are there, then judge from that whether the inclusion is legitimate.
23. What is set_editability used for, and why does it matter more with more than two hierarchy levels?
It marks which blocks or design levels are editable at the current level of work. With only a top level and blocks, this is simple; with three or more physical hierarchy levels, a lower level's editability has to be explicitly enabled or disabled for planning at a given level, or work at one level can accidentally change data another level depends on.
24. Why does u_io_ring show the highest feedthrough count in Nimbus‑8's partition set?
As the periphery block carrying the DDR PHY, other blocks' top-level nets that need to reach the pads naturally route through or near its footprint, so more feedthroughs are expected there than in an interior-only block like u_pwr_ctrl. It is a REVIEW item in Dashboard 2 precisely because a high count still deserves a second look, not automatic acceptance.
25. What is the practical difference between an abutted and a channeled block pair?
Abutted blocks share an edge directly, with no space between them for top-level routing, any top-level net between them has to feed through one of the two blocks. A channel leaves a dedicated gap with its own tracks for top-level routing, at the cost of the chip area the channel occupies.
26. Why is the netlist settle window a readiness gate rather than a formality?
Every downstream artifact of partitioning, the boundaries, the pin assignment, the budget, is built against a specific netlist. If the RTL is still changing, everything built against today's version may need to be redone against tomorrow's, so committing blocks before the netlist has genuinely settled risks rework across the whole partition set, not just one item.
27. What does check_hier_design -stage timing check, specifically?
It checks a top-level design that uses abstracts for closure-blocking issues before top-level assembly and optimization proceed, catching problems with the hierarchical setup itself, separately from running the full top-level timing closure loop.
28. Why does THO apply only during specific stages rather than throughout optimization?
THO runs in final_opto and in route_opt/hyper_route_opt because those are the points where placement, and later routing, are settled enough that a cross-boundary path has a real, meaningful delay to optimize against. Running it earlier would mean optimizing a boundary path against geometry that has not converged, which wastes the concurrent-optimization machinery on a number that is about to change anyway.

Advanced, 8 questions

29. Every block closed timing at block level and the top level fails. Give three distinct mechanisms that produce this, and say how you would tell them apart.
First, a budget mismatch: the block's real, closed arrival slack differs from what the budget promised (Figure 12), check by comparing the budget file's value against the block's own closed timing report at the same pin. Second, a stale model: the abstract or ETM in use does not match the block's current state (Dashboard 3), check the model's regeneration timestamp against the block's last edit. Third, a genuine interblock arithmetic error: two neighbouring blocks' independently-set budgets do not actually sum to the shared path's total requirement, check by adding the segments back up against the original chip-level constraint. All three produce the same symptom, a top-level violation on a path whose blocks each individually passed; only tracing the specific number back to its source distinguishes them.
30. When would you spend the time to build an ETM instead of using an abstract, and what does that decision cost you?
Build an ETM when a block's pin-to-logic ratio is high and top-level timing accuracy and STA runtime both matter more than the top level's need for that block's physical geometry, Nimbus‑8's u_pwr_ctrl is exactly this case. The cost is real: an ETM has to be built once per mode/corner scenario, using either the ICC2 extract_model path or a PrimeTime-based flow, and it has to be rebuilt whenever the block's closed timing changes, which is a heavier maintenance burden than an abstract's rebuild-on-pin-change trigger. It also discards all physical geometry, so it cannot serve any top-level step that needs to route around or check blockages against that block.
31. A multiply instantiated block needs 5 feedthroughs at one placement and only 2 at its other two placements. What are your options, and what does each cost?
One option is to give the 5-feedthrough instance a separate, dedicated block definition, losing the reuse benefit of a shared definition for that one instance but letting each instance's feedthrough needs be met exactly. A second option is to route the extra 3 feedthroughs around that instance at the top level instead of through it, keeping one shared definition but adding top-level routing length and possibly congestion near that instance. Which is cheaper depends on how much area and routing headroom exists around that specific instance, it depends, and the chapter deliberately does not pick a universal answer, because the right choice is a floorplan-specific trade-off.
32. Nimbus‑8's u_sens_tile was reconciled to carry two large sensor-buffer SRAMs rather than two average-sized ones. What would have happened if that reconciliation had not been done?
Either the partition set's macro-area arithmetic would not sum to Nimbus‑8's published 2.45 mm² total, or the block's own utilization (79.6%, fixed from Chapters 5–6) would not be achievable with only its stated 46,200 standard cells and two average-sized SRAMs, one of the numbers already published would have to silently change to make the rest work, which the guide explicitly refuses to do. Stating the reconciliation in the text instead keeps every previously published number true and shows a reader how to resolve a real discrepancy rather than hiding it.
33. Why might a design deliberately choose a channel over abutment even though abutment reclaims area?
A channel gives top-level routing dedicated space that does not have to feed through either neighbouring block, which matters when the top-level net count between two blocks is high enough that feedthrough capacity, pin-side congestion, or interior track consumption inside either block would become the bottleneck instead. It depends on the actual top-level net count and each block's spare feedthrough and pin capacity, a channel trades area for headroom, and whether that trade is worth it is a per-boundary judgment, not a fixed rule.
34. A THO place_opt pass just ran on a boundary path and closed it. What has to happen to the block's own budget as a result, and why?
The block has to be rebudgeted before clock_opt runs again, because THO optimized the interface logic together with the top level, against the real end-to-end path, not against the block's standalone budget target. The block's interface timing after a THO pass no longer matches what a standalone implementation would produce, and CCD balance-point offsets may have shifted and need to be made block-context-specific again. Treating the pre-THO budget split as still valid would apply a number to a state of the block that THO has already changed.
35. How would you decide between fixing a top-level violation by rebudgeting versus by reaching for THO?
Rebudgeting is the cheaper move: if slack exists in a neighbouring block or segment of the same path, redistributing it keeps each side's optimization independent and costs nothing structurally. THO is worth reaching for when the path's real delay depends on how the logic on each side of the boundary is actually shaped, not just on how the budget is split, because rebudgeting only reallocates a number, while THO lets one engine see and optimize the real path across the join. It is not a last resort gated behind rebudgeting failing; it is the tool for boundary-limited paths specifically, used at the stage where placement or routing has settled enough to optimize against.
36. A block's abstract shows a 4 ps measured error against its full view, well inside this project's stated tolerance. Is that error acceptable on every scenario, or does it need re-checking per scenario?
It depends on whether the error was measured across every mode/corner scenario the design actually uses, or only on one. An abstract's boundary timing arcs can differ in accuracy from corner to corner, so a single favourable measurement does not guarantee the same margin on, for instance, a hold-dominated corner versus a setup-dominated one. The honest answer is to re-verify the measured error per scenario before trusting it chip-wide, not to assume one good number covers all of them.

Senior / architect, 4 questions

37. You are handed an RTL hierarchy and asked to partition on it. When would you refuse, and what would you propose instead?
I would refuse when the RTL grouping was made for design and verification convenience rather than physical size, function or floorplan style, the exact situation Figure 4 draws, where the RTL-tree cut crosses more nets and implies more feedthroughs than either physically motivated alternative. I would propose walking the hierarchy browser with the four design-planning criteria explicitly in hand, size, function, floorplan style, and common-hierarchy needs with the front-end tool, and presenting at least one alternative cut with its net-crossing count measured, the way this chapter's own worked comparison does, so the decision is made on evidence rather than on whatever grouping happened to already exist.
38. How would you structure block ownership and model regeneration across a twelve-week schedule so top-level closure is not a cliff at the end?
I would assign one owner per block from the partition-set decision onward, each responsible for their block's pins, budget, model and its regeneration, not just its internal timing. I would put a model-fidelity board like Dashboard 3 under continuous tracking from week one, with a staleness policy enforced automatically rather than checked once near the end, and run a lightweight top-level closure pass on a fixed weekly or biweekly cadence throughout the schedule, using whatever models are current at that point, rather than only at the end. The goal is that every top-level closure failure in week eleven is a small, already-anticipated adjustment, because the interface between budget and reality has been checked continuously, not a first discovery that every block's own local view was individually correct and the assembled whole was not.
39. A block owner wants to skip building a frame view and go straight from full design view to abstract, to save time. When would you allow it, and when would you not?
I would allow it on a block whose floorplanning and congestion estimation needs were already satisfied by other means, for instance, a block shaped early and unchanged since, where nothing at the top level still needs the frame's lighter-weight physical-only view. I would not allow it on a block still under active floorplan iteration, where the top level needs fast, frequent physical-only updates and building a full abstract for every iteration would waste time on timing detail nobody is using yet. It depends on what the top level actually needs from that block at that point in the schedule, not on a blanket rule either way.
40. Design an ownership boundary for UPF and PG continuity across block boundaries. Who owns what, and what would you refuse to let a block owner change unilaterally?
I would have the top-level power architect own the chip-level UPF and the PG mesh's continuity requirements at every block boundary, with each block owner responsible only for their block's internal supply structure conforming to that shared boundary contract. I would refuse to let a block owner unilaterally change a boundary-adjacent supply net's naming, voltage domain assignment, or PG mesh pitch at the block edge, because any of those changes can silently break continuity with a neighbouring block that has no visibility into the change, that decision belongs with whoever owns the chip-level power intent, not with an individual block owner acting alone.

ICC2 Implementation Mentor Guide — Detailed Design Analysis series. Chapter 7: Hierarchical Implementation.

All design data in this chapter describes Nimbus‑8, a fictional teaching project. Every measured value is illustrative teaching data, not a tool transcript. Commands were verified against the IC Compiler II Tool Command Reference and the IC Compiler II Design Planning and Implementation User Guides; see the command-verification record in the delivered package.