6. Uniquify API#
This chapter describes the public API for hardening parameterized modules. For a worked walkthrough see the uniquify tutorial.
A hardened macro is parameter-free, so a parameterized module cannot be hardened
and reused directly. Uniquified discovers the concrete parameter
combinations a design uses, generates a parameter-free variant for each (to
harden) plus a parameterized wrapper that dispatches to them, and integrates the
results into a SiliconCompiler flow.
6.1. Uniquified#
Write the generated wrapper/variant sources to |
|
Harden the variants into macro libraries. |
|
Load previously built macros from |
|
Wire the wrappers and macros into a parent ASIC project. |
|
Path to the hardening run manifest for |
|
Hierarchy path from a wrapper down to its hardened variant instance. |
- class siliconcompiler.tools.slang.utils.macro.Uniquified(design: Design | Project, modules: Sequence[str], filesets: Sequence[str] | None = None, libdir: str | None = None)[source]#
Uniquify parameterized modules of a design and integrate the results.
Note
Beta feature. This API is new and may change in a future release.
Construction performs setup only – enumeration, code generation (in memory) and fileset registration on
design. It writes nothing to disk and runs no EDA tools; the generated sources are materialized on the firstbuild()/wireup()(or an explicitwrite()). Callbuild()to harden the variants andwireup()to wire the wrappers and macros into a parent project.Unparameterized modules are supported too: one with no overridable parameters needs no wrapper, so it is hardened directly and blackboxed at
wireup()(themacro_reusepattern). This means a singleUniquifiedcan harden a mix of parameterized and unparameterized modules.- Parameters:
design (Design | Project) – The context that instantiates the target modules (its elaboration determines the real parameterizations). If a
Projectis given, its design and selected filesets are used.modules (list) – Names of the modules to uniquify/harden (parameterized or not).
filesets (list, optional) – Design filesets to elaborate. Defaults to the project’s filesets, or
["rtl"]for a bare design.libdir (str, optional) – Root directory for uniquify’s artifacts – the persisted macro manifests at its root and the generated sources + hardening build tree under
<libdir>/build. Defaults tobuild/<design>/uniquify.
- Raises:
UniquifyError – If a requested module is not found among the filesets or is not instantiated anywhere in the design.
- __init__(design: Design | Project, modules: Sequence[str], filesets: Sequence[str] | None = None, libdir: str | None = None) None[source]#
- build(target: Callable[[ASIC], None] | None = None, macros: str | Sequence[str] | None = None, parallel: bool = False, rebuild: bool = False) Dict[str, StdCellLibrary][source]#
Harden the variants into macro libraries.
Built macros are persisted under this instance’s
libdirso subsequent runs reuse them (unlessrebuildis set).- Parameters:
target – SiliconCompiler target callback
fn(project)that sets the PDK/flow/SDC on each variant’s ASIC project (e.g.freepdk45_demo). Required unless every selected macro already has a cached build.macros – Which macros (variants) to build.
Nonebuilds all; a module name expands to its variants; anything else is matched as a variant name or glob (e.g."mod__W*") – useful for a rebuild.parallel – If True, harden the selected macros concurrently.
rebuild – Force re-hardening even if a cached macro exists.
- Returns:
{variant: StdCellLibrary}for the selected macros.- Return type:
dict
- property hardened_filesets: Dict[str, str]#
Mapping of variant name -> its hardening fileset.
- instance_path(variant: str, parent: str | None = None) str[source]#
Hierarchy path from a wrapper down to its hardened variant instance.
The generated wrapper dispatches to each variant inside a
generateblock labelledg_<variant>holding an instance named after the configured instance name, so within the wrapper the variant sits atg_<variant>/<instance>. This is the scope needed to, e.g., map VCD switching activity onto the hardened netlist.Only parameterized modules have a wrapper generate block; calling this for a variant of an unparameterized module is an error (it is instantiated directly, with no
g_<variant>level).- Parameters:
variant (str) – A variant (macro) name.
parent (str, optional) – The wrapper’s own instance path (e.g. a testbench DUT scope). If given, it is prepended to form an absolute path.
- Returns:
g_<variant>/<instance>, prefixed withparentif given.- Return type:
str
- Raises:
UniquifyError – If
variantis unknown or belongs to an unparameterized (unwrapped) module.
- property libdir: str#
Directory the variants are hardened under and their macros persisted.
- load_macros() Dict[str, StdCellLibrary][source]#
Load previously built macros from
libdirinto state.Reuses macros persisted by an earlier
build()without re-hardening.- Returns:
{variant: StdCellLibrary}for every macro found.- Return type:
dict
- property macros: Dict[str, StdCellLibrary]#
Variant name -> built (or loaded) macro; populated by
build().
- manifest(variant: str) str[source]#
Path to the hardening run manifest for
variant.Points at the
<design>.pkg.jsonwritten bybuild()underlibdir; load it (ASIC.from_manifest) to locate the variant’s implementation results (netlist, SDC, parasitics).- Parameters:
variant (str) – A variant (macro) name.
- Returns:
Absolute path to the run’s manifest.
- Return type:
str
- property modules: List[str]#
The uniquified module names.
- property outdir: str#
Directory the generated wrapper/variant sources are written to.
- property variant_names: List[str]#
All variant (macro) names across every module.
- property variants: Dict[str, List[str]]#
Mapping of module name -> its variant (macro) names.
- wireup(project: ASIC, require_all: bool = True) ASIC[source]#
Wire the wrappers and macros into a parent ASIC project.
For a parameterized module, aliases its RTL to the generated wrapper (so synthesis elaborates the dispatch). For an unparameterized module, blackboxes it (aliases to nothing) so the injected macro provides it. In both cases the hardened macros are added via
add_asiclib.- Parameters:
project – The parent ASIC project instantiating the modules.
require_all – If True (default), raise unless every variant has a built/loaded macro – an unhardened but used variant would make the wrapper’s
$errorbranch fire at elaboration.
- Returns:
The same
project, wired up.- Return type:
- Raises:
UniquifyError – If
require_alland some variants have no macro.
- property wrapper_filesets: Dict[str, str]#
Mapping of module name -> its wrapper fileset (plus ‘all’).
Only parameterized modules have a wrapper; unparameterized modules are omitted (they are hardened and blackboxed directly, with no wrapper).
- write() str[source]#
Write the generated wrapper/variant sources to
outdir(idempotent).Construction registers the filesets but does not touch disk; the sources are materialized here.
build()andwireup()call this automatically – call it directly only to materialize the sources without hardening (e.g. to lint the wrappers).- Returns:
The output directory the sources were written to.
- Return type:
str
6.2. Packaging a macro#
- siliconcompiler.tools.slang.utils.macro.build_macro(project: ASIC, name: str) StdCellLibrary[source]#
Package a completed variant hardening run into a
StdCellLibrary.Bundles the results of
project(a finished ASIC run of one variant) into a macro library, following themacro_reuseexample. Beyond the physical (LEF/GDS) and per-corner Liberty views a reusable macro needs, it also carries the implementation’s gate-level netlist and constraints so downstream flows (gate-level simulation, timing/power signoff) can pull them straight from the macro. The filesets are:models.physical– LEF + GDS for place-and-route in a parent.models.timing.<corner>– Liberty (nldm) per timing scenario ([constraint,timing,scenario,...]), so it adapts to single- and multi-corner PDKs.rtl– the gate-level netlist as a simulation view, bundling the standard-cell Verilog models (as a dependency) so it simulates standalone.netlist– the same gate-level netlist as a structural view for STA, dependency-free (STA resolves cells from Liberty).sdc– the implementation-generated constraints (propagated clocks).
The
rtlview’s cell-model dependency is serialized into the macro’s manifest (seeDependencySchema), so it is recovered when the macro is reloaded: a consumer can simulate thertlview without re-registering the PDK library. Thertl/netlist/sdcfilesets are added only when the run produced the corresponding result, so flows that stop short of them still yield a valid macro.- Parameters:
project – A completed ASIC project whose top module is a variant.
name (str) – Name for the resulting macro library. Also the netlist’s top module name (the parameter-free variant).
- Returns:
The packaged macro, ready for
Uniquified.wireup().- Return type:
- Raises:
UniquifyError – If the project defines no timing scenario.