Synthesis · lesson 2

Libraries and your first session

Point the tool at a Liberty library, set search paths, and learn what a library cell contains. Includes the unit trap that catches everyone once.

6 min read · Free, no login

A synthesis tool can only build with cells it knows about. This lesson covers how to tell Genus where the technology library is, what is inside that library, and how to stop the tool from using cells you do not want.

Reading time: about 6 minutes.

2.1 What a Liberty library contains

A Liberty file (.lib) describes every standard cell in a technology. For each cell it lists the area, the function, the capacitance of each input pin, and a set of tables. The delay tables are indexed by two numbers, typically the input transition time and the output load, so the tool can look up the delay of a cell for the slew and load it sees in the design.

Let us consider a NAND2 cell. If its table says the delay is 40 ps at a small load and 90 ps at a large one, the tool will prefer a larger drive strength version when the net it drives is long. The tool is not guessing. It is reading numbers from the library.

A library is characterized at one corner, a combination of process, voltage and temperature (PVT). A slow-corner library, typically low voltage and high temperature (at advanced nodes the worst temperature can be low), is normally used for setup checks. A fast-corner library is used for hold. A single run at one corner is the simplest case and is what this path uses.

2.2 Setting search paths

Genus looks for files in the directory where it was started. To keep scripts clean, the search paths are set once at the top.

set_db init_lib_search_path  /proj/libs/tech_a
set_db init_hdl_search_path  ./rtl
set_db script_search_path    ./scripts

Each attribute has one job. init_lib_search_path is searched when a library is loaded, init_hdl_search_path when RTL is read, and script_search_path when a script is run with include. More than one directory goes inside braces:

set_db init_lib_search_path {. /proj/libs/tech_a /proj/libs/common}

These need to be set before the library is read. It is better to set all three at the top of the script so that the order never matters.

2.3 Loading the library

The library is loaded with the library attribute.

set_db library typical.lib

More than one library can be given in a list:

set_db library {stdcells.lib io_cells.lib}

Compressed files (.lib.gz) are accepted. If the same cell name appears in two libraries, the result can be ambiguous, so it is worth checking the log for messages about duplicate cells.

Libraries at more than one corner are handled through a multi-mode multi-corner (MMMC) view definition file, read with read_mmmc. That setup is larger than a single set_db library line and is usually prepared once for a project. A beginner can safely ignore it and work with one library.

2.4 Checking what loaded

After loading, it is worth listing what the tool actually found. The library cells are objects in the tool's database and can be queried with get_db.

# Count how many library cells are visible
puts [llength [get_db lib_cells]]

If the count is zero, the library did not load. The log nearly always says why. A path typo is the most common cause.

2.5 Cells the tool should not use

Not every cell in a library is meant for synthesis. Some are for clock trees only, some are for test, and some a project forbids, for example a very weak buffer that is unreliable in layout. Two mechanisms exist.

  • avoid โ€“ the tool will not choose the cell on its own. Copies already instantiated in the RTL stay.
  • dont_touch โ€“ the tool must not change or remove the cell, which is usually what a designer wants for cells that were instantiated by hand.
set_db [get_db lib_cells *BUFX1] .avoid true

Cells marked dont_use or dont_touch in the Liberty file itself are also reported as unusable by the tool. If a cell that should be usable appears in that list, the log message typically points to the attribute to change. The tool prints these messages at the start, so reading the first screen of the log is a habit worth building.

2.6 The unit trap

The SDC convention for capacitance is picofarads, while Genus database queries return femtofarads. A value taken from a get_db query and passed directly to set_load will therefore be one thousand times too large.

## Suppose a script read a load of 20 from a Genus database query (fF)
set load_ff 20

## Wrong: passes 20 to a command that expects pF, so the load becomes 20 pF
set_load $load_ff [all_outputs]

## Right: convert to pF first
set_load [expr {$load_ff / 1000.0}] [all_outputs]

Delays follow the same pattern, so check the units of every number that crosses between a database query and an SDC command. Thus, state units at the top of every script, as a comment, and use the same units throughout.

2.7 Why an interviewer asks about this

The library question tests whether a candidate understands that timing comes from tables and not from formulas. Be ready to explain the two axes of a delay table, why a design is synthesized at the slow corner for setup, and what dont_touch protects. The unit trap is a favourite follow-up because it is a real mistake people make.

Key takeaways

  • A Liberty file gives the tool every cell's area, function and delay tables, and synthesis can only use what the library lists.
  • Set init_lib_search_path, init_hdl_search_path and script_search_path once, at the top, and load the library with set_db library.
  • Use avoid to discourage a cell and dont_touch to forbid changes to it.
  • SDC capacitance is in pF while database queries return fF, so convert before mixing them.