Welcome to the Tcl Command Reference series. This multi-part guide covers the essential Tcl commands used in physical design EDA tools like Synopsys ICC2, Cadence Innovus, and Fusion Compiler. Whether you are a beginner learning the physical design flow or an experienced engineer looking for a quick command reference, this series breaks down every stage of the P&R flow with clear explanations, real-world usage context, and practical code examples.
The complete physical design flow follows this order:
- Design & Database Setup
- Floorplanning
- Power Planning
- Placement
- Clock Tree Synthesis
- Routing
- Optimization
- Signoff & Reports
Part 1 covers Design & Database commands used to create libraries, read LEF/DEF/netlist files, link the design, and write outputs. These commands form the entry point of every physical design flow.
Quick Reference: Design & Database Commands for EDA Tools
These commands handle loading, creating, and saving design data. The design database is the central hub and every physical design flow starts by reading the netlist, LEF/DEF files, and technology libraries.
| Command | Description |
|---|---|
create_lib | Creates a new empty library |
read_lib | Reads an existing technology/library file |
read_lef | Reads a LEF file containing cell footprints, pin locations, and routing blockage info |
read_def | Reads a DEF file containing netlist connectivity, floorplan, and placement data |
read_verilog | Reads a Verilog gate-level netlist |
read_vhdl | Reads a VHDL netlist |
read_parasitics | Reads parasitic data (SPEF, DSPF, RSPF) for accurate delay calculation |
link_design | Links all design components and resolves cell references |
current_design | Sets the active design context for subsequent commands |
write_def | Writes the design out as DEF |
write_lef | Writes a merged LEF file |
write_verilog | Writes the design as a Verilog netlist |
write_sdf | Writes SDF timing data |
report_lib | Reports library information (cells, pins, timing arcs) |
report_design | Reports design summary (hierarchy, ports, instances) |
Typical Design Import Flow Script
# === Typical Design Import Flow ===
read_lib "/path/to/technology.lib"
read_lef "/path/to/merged.lef"
read_def "/path/to/floorplan.def"
read_verilog "/path/to/netlist.v"
link_design
current_design my_chip
report_design > reports/design_summary.rpt
Command Deep-Dive: Understanding Each Command
What it is: create_lib initializes a new empty technology/milkyway library in the tool's database. This is the first command you run when starting a new design from scratch, before reading any LEF, DEF, or netlist files. The library acts as a container that holds all the design data including cells, layers, and tech info.
Where we use it: Used at the very start of a physical design flow when no existing library is available. For example in Synopsys ICC2 or Cadence Innovus, you create a library to define the technology context before importing the netlist. If you already have a DEF or Milkyway library from a previous step, you would use read_lib instead.
Syntax: create_lib [-technology <file>] [-ref_libs <list>] <lib_name>
# Create a new library with a given technology LEF
create_lib -technology "/path/to/tech.lef" my_design_lib
# Create library with both tech LEF and reference libraries
create_lib -technology tech.lef -ref_libs {std_cells.lib io_cells.lib} my_chip_lib
# Once created, you can verify it
report_lib my_design_lib
What it is: read_lib loads an existing technology library (.lib, .db, or Milkyway format) into the tool's memory. Unlike create_lib which starts fresh, this command imports a pre-existing library that already contains technology information, cell definitions, timing arcs, and physical data.
Where we use it: Used when continuing a previous design session or when you have a standard cell library provided by the foundry/EDA team. In a typical flow the foundry supplies .lib (liberty timing) and .db (synopsys database) files. You read them before importing the netlist so the tool knows the available cells and their timing characteristics.
Syntax: read_lib [-format <format>] <file_list>
# Read a Synopsys .db library
read_lib "/path/to/fast.db"
read_lib "/path/to/typical.db"
read_lib "/path/to/slow.db"
# Read a Milkyway library (ICC2 format)
read_lib "/path/to/milkyway_lib"
# Read liberty .lib file directly
read_lib "/path/to/standard_cells.lib"
What it is: read_lef reads a LEF (Library Exchange Format) file containing the physical abstraction of standard cells, macros, and I/O pads including pin positions, blockage layers, and routing obstructions. LEF comes in two types: technology LEF (layer definitions, via rules, spacing) and cell LEF (cell footprints).
Where we use it: Every physical design flow reads LEF files early. Technology LEF is read once and defines the metal layers, via rules, and design rules for the process node. Cell LEF is read for each standard cell library and macro. Without LEF the tool does not know the physical dimensions of cells or where pins are located.
Syntax: read_lef [-min_max] [-library] <file_list>
# Read technology LEF (layer stack, via rules, min spacing)
read_lef "/path/to/technology.lef"
# Read cell LEF for standard cells
read_lef "/path/to/std_cells.lef"
# Read macro LEF for custom blocks
read_lef "/path/to/macro_block.lef"
# Read multiple LEF files at once
read_lef {tech.lef std_cells.lef io_cells.lef macro.lef}
What it is: read_def reads a DEF (Design Exchange Format) file containing the design's connectivity, floorplan information, component placements, pin locations, and routing data. DEF is the standard interchange format between different EDA tools in the physical design flow.
Where we use it: Used to import an existing floorplan or placement from another tool. After floorplanning in one tool you write a DEF and read it into another tool for placement and routing. It is also used for hierarchical design handoff between blocks. DEF files can contain just floorplan data or full placement and routing data.
Syntax: read_def [-allow_physical] <file>
# Read a DEF with floorplan and placement
read_def "/path/to/floorplan.def"
# Read a DEF with routing data (post-route)
read_def "/path/to/routed.def"
# Read DEF with only top-level connectivity
read_def -only_floorplan "/path/to/top.def"
What it is: read_verilog imports a gate-level Verilog netlist into the design database. This netlist is the output from logic synthesis (Design Compiler or Yosys) and contains the structural connections between standard cells, macros, and I/O ports.
Where we use it: After synthesis the gate-level netlist is fed into the physical design tool. The netlist describes which cells are used and how they are connected. The P&R tool then places these cells and routes the connections. You typically read the verilog after reading the LEF/lib files so the tool can resolve all cell references.
Syntax: read_verilog [-netlist] [-library] <file_list>
# Read synthesized gate-level netlist
read_verilog "/path/to/design_synth.v"
# Read multiple netlists (hierarchical design)
read_verilog {top.v sub_block_a.v sub_block_b.v}
# Read Verilog with define macros
read_verilog -define {USE_SDF} "/path/to/design.v"
What it is: link_design resolves all cell references in the netlist against the loaded libraries. It connects every instantiated cell to its physical and logical definition from the library. If any cell is missing from the library the command reports an error or warning.
Where we use it: Always run after reading the netlist and libraries. This is a critical validation step. If link_design succeeds all cells are resolved and the design is ready for physical implementation. Unresolved references indicate missing LEF/lib files or mismatched cell names between synthesis and the physical library.
Syntax: link_design [-top <module>]
# Basic linking
link_design
# Link with specific top-level module
link_design -top my_chip_top
# Force link even with warnings
link_design -quiet
# Check what's unresolved
link_design -report_unresolved
What it is: current_design selects which design or block in the database is currently active. All subsequent commands (placement, routing, reporting) operate on the active design. This is essential in hierarchical flows where multiple blocks are loaded simultaneously.
Where we use it: In a hierarchical physical design flow you might load the top-level design and several sub-blocks. Before working on a specific block you set it as the current design. It is also used after link_design to select the top-level module as the active context.
Syntax: current_design <design_name>
# Set the top-level design
current_design my_chip
# Switch to a sub-block for block-level implementation
current_design my_chip/sub_block_a
# Verify which design is active
current_design
# Chain with link_design for cleaner flow
link_design; current_design my_chip
What it is: write_def exports the current design's physical data (floorplan, placement, routing) to a DEF file. This is the standard handoff format between P&R tools, STA tools, and signoff tools.
Where we use it: After completing a stage like floorplanning, placement, or routing you write a DEF to save progress or hand off to another tool. It is also used for hierarchical integration where sub-blocks are written as DEF and read into the top-level design.
Syntax: write_def [-version <ver>] [-output <file>]
# Write DEF with floorplan and placement
write_def "/path/to/output.def"
# Write DEF with all routing data
write_def -include_routing "/path/to/routed.def"
# Write only floorplan (no placement)
write_def -only_floorplan "/path/to/fp.def"
What it is: write_verilog exports the design as a Verilog gate-level netlist. This output includes all physical changes made during P&R such as inserted clock buffers, filler cells, and renamed nets. The written netlist is used for verification (gate-level simulation), STA, and formal equivalence checking.
Where we use it: After routing is complete you write the final netlist for signoff. This netlist is different from the synthesis netlist because it includes all physical-only cells (fillers, tap cells, decaps) and any logic changes made during physical optimization.
Syntax: write_verilog [-compress] [-exclude <list>] [-output <file>]
# Write final routed netlist
write_verilog "/path/to/final_design.v"
# Write netlist without physical-only cells
write_verilog -no_physical_cells "/path/to/functional.v"
# Write with power/ground port declarations
write_verilog -include_pg_pins "/path/to/design_with_pg.v"
What it is: report_design prints a comprehensive summary of the current design including instance count, cell area, port list, hierarchy depth, and library usage. It is the go-to command for verifying that your design loaded correctly before starting physical implementation.
Where we use it: After loading the design and linking run report_design to verify everything is correct. Check that the instance count matches expectations, all libraries are resolved, and the hierarchy is intact. Also used during the flow to track design statistics like cell count after placement.
Syntax: report_design [-physical] [-hierarchy] [-verbose]
# Basic design report
report_design > reports/design_summary.rpt
# Report with detailed hierarchy
report_design -hierarchy > reports/hierarchy.rpt
# Report only gate count and area
report_design -summary > reports/summary.rpt
# Report library usage info
report_design -libraries > reports/lib_usage.rpt
Mastering these Design & Database commands is the first step in physical design automation. Continue to Part 2: Floorplanning Commands →