Skip to content
VLSI Mentor

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.rtl_lib./rtl/*.svgate_lib./netlist/*.v, ./ip/*.vgconfig (routingtable)design · liblist ·overrideselaborated designtop + DUT + cellsresolvedresolve each module12
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.

Continue learning

Standards & specifications

Governing standard
IEEE Std 1800 (SystemVerilog)(opens IEEE in a new tab)

Defines SystemVerilog language semantics — syntax, data types, scheduling and the behaviour a conforming simulator must produce. It does not define tool-specific synthesis support or vendor methodology.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of the SystemVerilog curriculum.