Skip to content

SystemVerilog · Module 17

config & Library Mapping

SystemVerilog config blocks and library mapping — select which implementation of each module elaborates without editing the design. Library map files, the design / default liblist / instance / cell clauses, the four resolution rules, RTL-vs-GLS and corner switching, encrypted-IP integration, nested config, and config vs filelist.

Module 17 · Page 17.5

A real design has many implementations of the same module: a behavioral RTL model, a synthesized gate-level netlist, a fast-corner cell, a slow-corner cell, a vendor's encrypted IP. The config construct (with library mapping) is how you choose which implementation elaborates for each module — without editing a single design file. You declare named libraries (collections of files) in a map file, then write a config block that names the design root, a default library search order, and per-cell or per-instance overrides. Switching from RTL simulation to gate-level simulation (GLS), or from one timing corner to another, becomes a one-line change of which config you elaborate. This lesson covers library map files, the config clauses, the four resolution rules, the canonical RTL↔GLS and encrypted-IP flows, and config vs the familiar filelist.

1. Engineering Problem — One Design, Many Implementations

The same sram_4k exists three ways: a fast behavioral model for RTL regressions, the real vendor cell for GLS, and a slow-corner variant for hold checking. The same SoC must simulate in RTL mode today and gate-level mode tomorrow, against the same testbench. A third-party pll_core ships only as an encrypted netlist you can't read but must instantiate.

The crude approach — maintain a separate filelist per scenario and hand-swap files, or `ifdef the instantiations — does not scale: it cannot override one specific instance, it cannot swap all instances of a cell type at once, and every change edits design or build files that then drift. config solves this at the elaboration layer: the design source never changes; a small configuration block declares which library serves each module, with precise per-instance and per-cell overrides. One netlist, one testbench, many elaborations — selected by which config you point the simulator at.

2. Mental Model — Libraries Are Collections, config Is a Routing Table

The picture every engineer carries:

A library is a named collection of source files (declared in a map file with a glob pattern). A config is a routing table that tells the elaborator, for every module reference it encounters: which library to look in first (default liblist), and which specific cells or instances to source from a different library (cell / instance overrides). The design root is named once (design lib.top), and you select a config at the command line (-top my_config). The design files themselves never mention libraries or configs — the mapping lives entirely outside them.

Four invariants this picture preserves:

  • Zero design edits. Switching RTL↔GLS, corners, or IP versions changes only the config you elaborate — never a line of RTL or netlist.
  • Resolution has a strict priority. instance override beats cell override beats default liblist (searched left-to-right), with the implicit work library as the final fallback.
  • work is always there. Every simulator has a built-in work library; files compiled without an explicit library land there.
  • It is an elaboration-time construct. config chooses implementations; it produces no logic and is invisible to synthesis. It is the build-selection layer, not part of the design.

3. Visual Explanation — Libraries Feed a config That Resolves the Design

Named libraries point at files on disk; the config picks which one serves each module and elaborates the design from them.

Two libraries, rtl_lib and gate_lib, feed a config routing table, which resolves into the elaborated design.resolve eachmodulertl_lib./rtl/*.svgate_lib./netlist/*.v, ./ip/*.vgconfig (routingtable)design · liblist ·overrideselaborated designtop + DUT + cellsresolved12
Figure 1 — libraries are named file collections; the config is a routing table that names the design root, the default search order, and per-cell/instance overrides. The elaborator follows it to resolve every module.

4. Declaring Libraries — the Library Map File

Libraries are declared in a library map file (a .map/.f file; exact extension varies by simulator). The library keyword names a collection and binds it to one or more file glob patterns.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// design.map — library declarations
// Syntax:  library  <name>  "glob"  [, "glob2", ...];
 
// The implicit working library — where the top-level testbench lives
library work     "./tb/*.sv", "./tb/top.sv";
 
// RTL source — functional, synthesizable
library rtl_lib  "./rtl/*.sv", "./rtl/mem/*.sv", "./rtl/core/*.sv";
 
// Gate-level netlist + vendor cell models (incl. encrypted .vg)
library gate_lib "./netlist/top_netlist.v", "./pdk/tsmc28/cells/*.v", "./ip/encrypted/*.vg";
 
// Corner libraries — for hold (slow) and setup (fast) checking
library slow_lib "./pdk/tsmc28/slow/*.v";
library fast_lib "./pdk/tsmc28/fast/*.v";

5. The config Construct

A config is a top-level block (like a module) that names the design root, a default library search order, and any overrides. You write one per simulation scenario — one for RTL, one for GLS, one per corner.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
config rtl_sim_cfg;                                 // configuration name
 
    design   work.top_tb;                           // top-level design root: lib.module
    default  liblist rtl_lib work;                  // search rtl_lib first, then work
 
    instance top_tb.u_dut.u_sram use rtl_lib.sram_behavioral;  // one exact instance
    cell     dff_x1 use gate_lib.dff_x1;            // every instance of this cell type
 
endconfig
 
// A second config for GLS — same testbench, different libraries (no design edits)
config gls_cfg;
    design   work.top_tb;
    default  liblist gate_lib work;
    instance top_tb.u_dut.u_sram use gate_lib.tsmc_sram_4k;
endconfig

Reading the clauses: config <name>endconfig declares the block (activated with -top <name>); design lib.module sets the root the elaborator starts from; default liblist L1 L2 … is the ordered search path for any unoverridden reference; instance <path> use lib.cell overrides exactly one hierarchical instance (the most precise override); cell <type> use lib.cell overrides every instance of a module type at once.

6. The Four Resolution Rules

When the elaborator hits a module instantiation, it resolves the implementation in strict priority order — and getting this order wrong is the root of most config bugs.

  1. instance rule (highest). A instance <exact path> use … override always wins for that one instance.
  2. cell rule. A cell <type> use … override applies to all instances of that module type.
  3. default liblist. Search each library left-to-right; the first one containing a module of the matching name wins.
  4. work fallback. No match in the liblist → try the implicit work library. Still nothing → elaboration fails with "module not found."
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
config priority_demo;
    design  work.top;
    default liblist rtl_lib work;          // Rule 3
    cell    dff use gate_lib.dff;          // Rule 2 — all dff instances
    // instance top.u_core.u_setup_reg.u_dff use slow_lib.dff;  // Rule 1 — one instance
endconfig
 
// Resolution for each module in top:
//   top                  → work.top        (design root)
//   u_alu                → rtl_lib.alu     (Rule 3 — default liblist)
//   u_sram               → rtl_lib.sram    (Rule 3)
//   u_dff[*]             → gate_lib.dff    (Rule 2 — cell override)
//   u_setup_reg.u_dff    → slow_lib.dff    (Rule 1 — instance override, if uncommented)

7. Use Cases

7.1 RTL ↔ GLS switch (the most common)

Two configs, same testbench; pick the mode with one flag.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
config rtl_cfg;                            // RTL functional sim
    design  work.chip_tb;
    default liblist rtl_lib work;
    cell    sram_4k use models_lib.sram_behavioral;   // fast behavioral SRAM
endconfig
 
config gls_cfg;                            // gate-level sim (netlist + SDF)
    design  work.chip_tb;
    default liblist gate_lib work;         // gate_lib FIRST — see §10 mistake 2
    cell    sram_4k use gate_lib.tsmc_sram_4k;        // real vendor SRAM
endconfig
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# VCS — select the config with -top; only -top changes between modes
vcs -sverilog -f design.map sim_configs.sv -top rtl_cfg -o sim_rtl
vcs -sverilog -f design.map sim_configs.sv -top gls_cfg \
    -sdf max:chip_tb.u_dut:chip.sdf -o sim_gls
 
# Questa
vlog -sv -mfcu sim_configs.sv ./rtl/*.sv ./gate/*.v
vsim -c gls_cfg -do "run -all; quit"
 
# Xcelium
xrun -sv -libmap design.map -top gls_cfg ./tb/*.sv ./gate/*.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
$ vcs -f design.map sim_configs.sv -top gls_cfg -o sim_gls
Config: gls_cfg (activated)   design root: work.chip_tb   default libs: gate_lib work
  Resolving chip_tb   ... work.chip_tb           [work]
  Resolving alu       ... gate_lib.alu           [default liblist]
  Resolving sram_4k   ... gate_lib.tsmc_sram_4k  [cell override]
Elaboration complete. 847 modules resolved.

7.2 Encrypted-IP integration

Third-party IP often ships as an encrypted netlist you can't read or edit but must simulate. Map just those module names to the vendor library; everything else stays in your RTL.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// design.map:  library vendor_ip "./vendor/encrypted/*.vg";
config rtl_with_vendor_ip;
    design  work.tb_top;
    default liblist rtl_lib work;          // your own RTL by default
    cell    pll_core  use vendor_ip.pll_core;   // map IP names → encrypted models
    cell    usb_phy   use vendor_ip.usb_phy;
    cell    serdes_x4 use vendor_ip.serdes_x4;
endconfig

7.3 Nested config

A cell clause can point at another config instead of a module, letting a sub-team own their block's mapping.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
config cpu_core_cfg;                       // owned by the CPU team
    design  rtl_lib.cpu_core;
    default liblist rtl_lib;
    cell    multiplier use opt_lib.fast_mul;
endconfig
 
config soc_cfg;
    design  work.soc_tb;
    default liblist rtl_lib work;
    cell    cpu_core use work.cpu_core_cfg;   // points at a CONFIG, not a module
endconfig

8. config vs Filelist

Both compile files; they solve different problems.

AspectFilelist (-f filelist.f)config construct
Switching implementationsSeparate filelist per scenario, hand-swappedSingle source, select by -top config_name
Per-instance overrideNot possible without editing design filesinstance clause — precise, path-based
Per-cell-type overrideNot possible without editing instantiationscell clause — swaps all instances at once
Encrypted IPWorks (point at the .vg)Works (dedicated library)
ComplexitySimple — everyone understands itHigher — needs libraries + resolution order
Best forSingle-mode RTL flowsMulti-mode: RTL + GLS + corners, IP integration

In practice most teams use filelists for day-to-day RTL and switch to config for multi-corner GLS or encrypted-IP integration. They compose — you can use both together.

9. Industry Usage — Where config Shows Up

  • RTL → GLS sign-off. One testbench, two configs (rtl_cfg, gls_cfg) — the standard way to reuse the verification environment across abstraction levels.
  • Multi-corner GLS. gls_slow_cfg (hold, min delays) and gls_fast_cfg (setup, max delays) select corner cell libraries via liblist order — pairs directly with the SDF corners from the previous lesson.
  • Encrypted / third-party IP. Map vendor IP module names to encrypted libraries while the rest of the design stays in source.
  • Mixed-abstraction simulation. Keep most of the chip in fast RTL and elaborate only the block-under-test at gate level — an instance/cell override picks exactly which.
  • A/B model comparison. Swap one block between two implementations (behavioral vs cycle-accurate) by changing a single cell/instance clause.

config is elaboration-time only — it selects implementations and produces no logic; synthesis never sees it.

10. Debugging Guide — The Mistakes Everyone Makes Once

config & library mapping — bugs every engineer hits the first time

1. Library glob matches no files

Symptom: A library "exists" but every lookup in it fails with a confusing "module not found."

Cause: The glob pattern doesn't match real files — e.g. "./RTL/*.sv" on a case-sensitive Linux filesystem where the directory is rtl. The library is defined but empty.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
library rtl_lib "./RTL/*.sv";   // ❌ directory is ./rtl — zero files matched

Fix: verify the glob in a shell first (ls ./rtl/*.sv); mind case sensitivity; use absolute paths while debugging.

Guardrail: a defined-but-empty library is the silent failure mode — confirm file counts before wiring the map.

2. Wrong liblist order — RTL found before gate-level

Symptom: GLS "runs" but behaves like RTL; timing checks never fire.

Cause: default liblist rtl_lib gate_lib; finds the RTL version of every cell first (same names), so gate_lib is never reached. Same names, wrong models, no error.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
config gls_cfg; default liblist rtl_lib gate_lib; ... endconfig   // ❌ RTL wins

Fix: for GLS put the gate library first — default liblist gate_lib work; — with RTL only as a fallback for testbench helpers. Verify the elaboration trace shows gate-level names.

Guardrail: liblist is left-to-right priority; the intended implementation must come first.

3. design points at the DUT, not the testbench

Symptom: Simulation finishes at time 0 with no output.

Cause: design rtl_lib.dut_top; elaborates the DUT with no stimulus driving it.

Fix: point design at the top-level simulation module (the testbench in work): design work.tb_top;. The testbench instantiates the DUT, which resolves through the liblist.

Guardrail: the design root is the thing you'd pass to -top in a normal sim — the testbench, not the DUT.

4. instance path uses module names, not instance names

Symptom: An instance override silently does nothing.

Cause: The path uses the module type name instead of the instance name. For cpu_core u_cpu_core(...), the path segment is u_cpu_core, not cpu_core.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
instance top.cpu_core.alu use fast_lib.alu;   // ❌ module names; instance is u_cpu_core/u_alu

Fix: use instance names from the instantiations: instance top.u_cpu_core.u_alu use fast_lib.alu;.

Guardrail: hierarchical paths are built from instance identifiers (the left name in type u_name(...)), never module type names.

11. Q & A

12. Cross-References & What's Next

This lesson covered library mapping and the config construct — declaring libraries, the design/liblist/instance/cell clauses, the four resolution rules, and the RTL↔GLS / encrypted-IP / nested patterns.

Related material elsewhere in the curriculum:

13. Quick Reference

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ── Library map file (design.map) ───────────────────────────────────
library work     "./tb/*.sv";
library rtl_lib  "./rtl/*.sv", "./rtl/sub/*.sv";
library gate_lib "./netlist/*.v", "./cells/*.v";
library slow_lib "./cells_slow/*.v";
 
// ── config block (sim_configs.sv) ───────────────────────────────────
config my_config;
    design   work.tb_top;                       // top-level design root
    default  liblist rtl_lib work;              // search order (left-to-right)
    cell     sram_model use gate_lib.tsmc_sram; // all instances of this type
    instance tb_top.u_dut.u_pll use gate_lib.pll_ip;  // one exact instance (highest)
    cell     cpu_core use work.cpu_core_cfg;    // nested config
endconfig
 
// Resolution priority:  instance  >  cell  >  default liblist  >  work
// ── Activate ────────────────────────────────────────────────────────
// VCS:     vcs -sv -f design.map sim_configs.sv -top my_config -o sim
// Questa:  vlog -sv -mfcu sim_configs.sv ;  vsim -c my_config
// Xcelium: xrun -sv -libmap design.map sim_configs.sv -top my_config

14. Summary

The config construct selects which implementation of each module elaborates, without editing the design. A library is a named file collection declared in a map file; a config is a routing table that names the design root (design lib.top), a default search order (default liblist), and overrides — cell for every instance of a type, instance for one exact path. The elaborator resolves each reference by strict priority: instance → cell → default liblist (left-to-right) → work fallback, erroring if nothing matches.

That mechanism makes the hard build scenarios one-line changes: RTL↔GLS by selecting -top rtl_cfg vs -top gls_cfg against the same testbench; multi-corner GLS by ordering corner libraries (pairing with the SDF min/max corners); encrypted-IP integration by mapping IP names to a vendor library; and sub-team ownership via nested configs. Put the intended library first in the liblist (gate_lib first for GLS), point design at the testbench (not the DUT), and build instance paths from instance names. Use filelists for simple RTL and layer config on for multi-mode flows — it is an elaboration-time selection layer, invisible to synthesis, that keeps one design source serving every simulation scenario.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet