These four grids each constrain a different thing, and satisfying one doesn't automatically satisfy the others: the manufacturing grid quantizes what coordinates are even representable, placement sites constrain legal cell origins, routing tracks suggest wire centerlines, and the FinFET grid constrains cell/boundary alignment to the fin pitch. The manufacturing grid is usually the finest of the four โ being on it only means a coordinate is a legal, representable geometric step, not that it's a legal cell origin, and being on a legal placement site doesn't prove a pin is routable or that a macro boundary satisfies every device-alignment rule.
These three numbers all sound similar and all get reported in nanometers, but they're measuring completely different physical directions and features โ mixing them up is a common and costly mistake when reading a process datasheet. **Fin pitch** measures center-to-center spacing between neighboring fins โ the vertical silicon "fins" that run in one direction across the device.
In a planar transistor, you can dial in channel width to almost any continuous value just by drawing it wider or narrower. FinFETs don't work that way โ width comes in discrete steps because each additional "fin" (a thin vertical silicon fin) adds a fixed increment of effective channel width, and you can't have a fractional fin. A useful (simplified, teaching-level) approximation: effective width per fin โ 2 ร fin height + fin top width โ because the gate wraps around and controls both sidewalls of the fin plus its top surface, so all three contribute to the effective channel width.
Before touching any geometry, find out what grid is actually active โ `report_grids -type finfet` shows the pitch, offsets, and whether a FinFET grid is even defined for your technology, and `check_finfet_grid` tells you exactly which violations exist. Read the violation carefully: an error on a macro boundary doesn't necessarily mean the macro's origin is wrong โ a macro can have a perfectly legal origin and still fail because its width pushes the far edge off-grid.
"Legal" isn't one property โ it's the intersection of several independent grids and rules, and a cell/macro can satisfy some while quietly violating others. Think of it like a parking spot: fitting inside the painted lines (site grid) doesn't guarantee your door can open (pin-access grid) or that you're not straddling a fire lane (FinFET boundary rule).
This gate checks whether the imported, linked netlist and its timing intent are believable enough to start floorplanning โ a "do we trust this handoff" checkpoint, not a quality review. It's deliberately narrow in scope: it says nothing about placement quality or final timing results, only about whether the starting point is sound.
This gate is really a verification checklist run before you commit to floorplanning: netlist, SDC, top module name, handoff revision, logical libraries, reference/technology setup, modes/corners/scenarios, and whatever synthesis or STA summaries the upstream team can hand you. Every one of these should resolve to named, real objects you can point to โ a listed clock that actually exists, a top name that actually matches the loaded hierarchy โ not just files that happened to load without error.
A manifest is the packing list that comes with every design handoff โ it tells the receiving engineer exactly what revision, corner, mode, and producer each input file represents, so nobody has to guess. Without it, "the netlist" or "the SDC" is ambiguous โ there could be five versions floating around a project, and the wrong one silently loaded gives you a run that looks fine but is quietly analyzing the wrong design.
The top module is the boundary ICC2 believes it's implementing โ get this wrong and every count, report, and timing number downstream can look perfectly reasonable while describing the wrong design. Confirming it means matching four things against the handoff record and synthesis summary: the current block, the expected top name, the hierarchy structure, and the cell/instance inventory.
A library gives every cell its meaning โ what a NAND2X4 actually *does* electrically and logically โ while units give every number its scale. You need both settled before a timing number means anything at all. If the wrong library (or wrong corner within the right library) is loaded, delay numbers can look completely plausible while describing a cell that isn't the one actually in your design.
Reading a Verilog netlist (`read_verilog`) is like reading an address book โ it creates the names of design objects (instances, ports, nets) and records how they're supposed to connect, but it doesn't verify any of those references actually resolve to something real. Linking is the follow-up step where ICC2 actually finds the real definition for every instantiated cell โ whether that's a leaf-level library cell or a lower-level design module โ and connects the netlist's abstract references to concrete objects.
Think of `current_block` as the "you are here" pointer in ICC2 โ almost every command (`get_cells`, `report_timing`, `place_opt`, you name it) silently operates on whatever block is currently active, not the block whose name you typed in your last `open_block`. If you have several blocks open in the same session (a hierarchical flow, a sub-block plus the top level, or two design revisions loaded for comparison), a query can run cleanly against the wrong block and return a perfectly formatted, completely irrelevant answer.
An unresolved reference means an instance in the netlist points to a module or library cell that the tool's currently loaded reference context simply doesn't have. ICC2 knows something was instantiated there โ it just doesn't know what object is supposed to implement it.
A black box is only legitimate when it's a deliberate, methodology-sanctioned abstraction โ not simply a missing reference library that nobody noticed. The classic legitimate case: a hard macro or IP block delivered as a timing/physical abstract (`.lib`/`.lef`/frame view) rather than full internal detail, because the internals aren't needed (or aren't allowed to be seen) at this stage of the flow.
Linking (binding the netlist against your libraries) only tells you the tool found a definition for every instance โ it proves the netlist *parses*, not that it makes sense. `check_netlist` goes a level deeper: it looks for structural problems that can survive linking perfectly cleanly โ things like multiple drivers on one net, unconnected/dangling pins, or other connectivity defects that don't stop the netlist from loading but will definitely cause trouble later.