Hierarchical Blocks
Hierarchical blocks let a schematic instantiate another schematic as a single
subcircuit symbol (device prefix X), the way SLiCAP and SPICE handle
.subckt definitions. Subcircuits work for both schematic types; only the
file extensions and the library file format differ per dialect
(.slicap_sch / .slicap_lib versus .spice_sch / .spice_lib).
Design intent
A block is referenced, not flattened, in the capture tool. The netlist keeps the hierarchy (an
Xinstance plus a.subcktdefinition); SLiCAP / NGspice perform the flattening at analysis time. This keeps netlists small and readable and preserves the design hierarchy.A subcircuit’s interface parameters come from its
.subcktdefinition (name and default value), not from the built-in device tables — matching standard SPICE practice.A subcircuit is stored as a package in the project
lib/folder: the compiled library (.subcktdefinition), the block symbol, and the subcircuit’s own editable schematic. One folder holds everything the block needs — see Self-contained projects in /GUI/project/project_files.
Saving a schematic as a subcircuit
Any schematic can be turned into a reusable subcircuit:
Add port symbols and name them — the names become the subcircuit’s external nodes. A
ground(node 0) stays global and is never a port.In , tick Save this schematic as a subcircuit and give the document a Title (the subcircuit name).
opens the Create Subcircuit dialog, where you set the node order (this order is the
.subcktnode list) and declare the overridable parameters (name and default).Saving writes the package to
lib/: the editable source (lib/<title>.slicap_schor.spice_sch) and the compiled library (lib/<title>.slicap_libor.spice_lib).
The library file holds one .subckt definition; the ports appear in the
chosen order, and a parameter passed in on the .subckt line is not
redefined internally — the passed value (or its default) supersedes it.
Library lines placed on the schematic (device models such as inc
BC847.lib) are carried into the generated library, so the definition is
complete on its own.
Note
Libraries are always global in SLiCAP: the contents of a .lib /
.inc line go to one global namespace, wherever the line appears —
also inside a subcircuit definition. Two libraries defining the same
model name therefore conflict. (Inline .model / .param
definitions inside a .subckt are local to it.) The NGspice library
is generated to behave the same way.
Placing a block
creates (or re-assigns) a subcircuit’s block symbol and places its first instance:
Pick the subcircuit’s library file. The dialog reads its
.subcktheader and shows the block name, ordered ports and overridable parameters, and whether the subcircuit’s schematic is present.Choose the symbol: the generated box — a rectangle with one named pin per port — or any loaded symbol with a matching pin count, re-skinned as this subcircuit (an opamp macromodel gets the opamp artwork).
With the generated box, each pin is placed on the side its port symbol suggests in the subcircuit schematic: a port pointing top→bottom sits on top of the symbol, one pointing left→right on the left, and so on — read from the port’s rotation and mirror settings. Without a schematic the pins are spread clockwise from the top-left in node order. Pin sides are visual only; the netlist node order never changes.
The symbol is written to
lib/<name>_slicap_symbol.svg(or_spice_symbol.svg) and becomes a palette citizen of the project: a second instance is placed from the palette like any other component, no dialog involved.The block’s library is added to the schematic as an include (de-duplicated), and the block is placed like any other component.
When the chosen library file lives in another project, its complete
package — library, symbol and schematic — is copied into this project’s
lib/ first. The import is a snapshot: later edits stay local, the
originating project is never touched.
In the netlist the block appears as X<n> <nodes…> <name> par=val …: nodes
in port order, <name> the subcircuit, and only the parameters you
override on the placement. Unset parameters fall back to the .subckt
defaults.
Descending into the hierarchy
Double-click a placed block and choose Descend into subcircuit: the
subcircuit’s schematic opens in its own tab for inspection and editing. If
it is already open, its tab is activated instead of opening a second copy.
Saving the subcircuit re-runs the Create Subcircuit dialog and regenerates
the library, keeping schematic, symbol and .subckt definition in step.
Operating-point annotations follow the descent. When the parent
schematic holds the results of an op run, descending hands the subcircuit
view the values of that instance: internal nets show their bias voltages,
port nets show the parent nets they connect to, and the tab title names the
instance (e.g. BJTamp.spice_sch (X1)). The schematic file is the
definition and the instance is view state: there is only ever one
editable view of a subcircuit, and descending from another instance
retargets its annotations — the last descent wins. Comparing instances
side by side is parent-level information: the parent shows every instance’s
port voltages, and the Design data panel lists all internal vectors
(v(x1.…), v(x2.…)). A subcircuit opened directly (not via descend)
shows no borrowed values.
The order of run and descend does not matter: an open subcircuit view is live-updated whenever a new run installs fresh results in the parent — including nested descents. If the instance it was showing no longer exists in the netlist the run used, its annotations are cleared rather than left showing another situation’s values.
Planned
Loop detection across the hierarchy.
A full Symbol Editor for refining generated symbols.