Netlist tweaking is important to standardize netlists. Without tweaking, the extracted netlist may contain elements that are redundant or don't match anything found in the schematic.
Netlist tweaks are applied on the extracted Netlist object. This can be obtained with the netlist function. This function will extract the netlist if not done already.
Netlist tweaks can also be applied to the schematic netlist. For example to flatten away a model subcircuit called "NMOS", use this Netlist#flatten_circuit:
schematic.flatten_circuit("NMOS")
Circuits extracted don't have pins on the top hierarchy level as the extractor cannot figure out where to connect to this circuit. The compare function does not try to match pins in this case. But to gain a useful extracted netlists, pins are required. Without pins, a circuit can't be embedded in a testbench for example.
KLayout offers a function to create top-level pins using a simple heuristics: for every named (i.e. labeled) net in the top level circuit a pin will be created (Netlist#make_top_level_pins):
netlist.make_top_level_pins
Combining devices is important for devices which are not represented as coherent entities in the layout. Examples are:
In all these cases, the schematic usually summarizes these devices into a single one with lumped parameter values (total resistance, capacitance, transistor width). This creates a discrepancy which "device combination" avoids. "Device combination" is a step in which devices are identified which can be combined into single devices (such as serial or parallel resistors and capacitors). To run device combination, use Netlist#combine_devices:
netlist.combine_devices
The combination of serial devices might leave floating nets (the net connecting the devices originally. These nets can be removed with Netlist#purge_nets. See also Netlist#simplify, which is wrapper for several methods related to netlist normalization.
It's recommended to run "make_toplevel_pins" and "purge" before this step (see below).
It's often required to flatten circuits that do not represent a specific level of organisation but act as a wrapper to something else. In layouts, devices are often implemented as PCells and appear as specific cells for no other reason than being implemented in a subcell. The same might happen for schematic subcircuits which wrap a device. "Flattening" means that a circuit is removed and its contents are integrated into the calling circuits.
To flatten a circuit from the extracted netlist use Netlist#flatten_circuit:
netlist.flatten_circuit("CIRCUIT_NAME")
The argument to "flatten_circuit" is a glob pattern (shell-like). For example, "NMOS*" will flatten all circuits starting with "NMOS".
Instead of flattening circuits explicitly, automatic flattening is provided through the align method.
The "align" step is optional, hence useful: it will identify cells in the layout without a corresponding schematic circuit and flatten them. "Flatten" means their content is replicated inside their parent circuits and finally the cell's corresponding circuit is removed. This is useful when the layout contains structural cells: such cells are inserted not because the schematic requires them as circuit building blocks, but because layout is easier to create with these cells. Such cells can be PCells for devices or replication cells which avoid duplicate layout work.
The "align" method will also flatten schematic circuits for which there is no layout cell:
align
Circuit abstraction is a technique to reduce the verification overhead. At an early stage it might be useful to replace a cell by a simplified version or by a raw pin frame. The circuits extracted from such cells is basically empty or are intentionally simplified. But as long as there is something inside the cell which the parent circuit connects to, pins will be generated. These pins then can be thought of as the circuit's abstraction.
A useful method in this context is the "blank_circuit" method. It clears a circuit's innards from a netlist. After this, the compare algorithm will identify both circuits as identical, provided they feature the same number of pins. Named pins are required to match exactly unless declared equivalent. Unnamed pins are treated as equivalent. To name pins use labels on the pin's nets inside the circuit's layout.
To wipe out the innards of a circuit, use the Netlist#blank_circuit method:
netlist.blank_circuit("CIRCUIT_NAME") schematic.blank_circuit("CIRCUIT_NAME")
NOTE: In this version, use "blank_circuit" before "purge" or "simplify" (see below). "blank_circuit" sets a flag (Circuit#dont_purge) which prevents purging of abstract circuits.
There is a short form for this too (blank_circuit). In contrast to netlist-based "blank_circuit", this method can be used anywhere in the LVS script:
blank_circuit("CIRCUIT_NAME")
The argument to "blank_circuit" in both cases is a glob pattern (shell-like). For example, "MEMORY*" will blank out all circuits starting with the word "MEMORY".
Sometimes it is possible to omit connections in the layout because these will not carry any current. This might simplify the layout and allow denser packing, but finally there is a mismatch between schematic and layout. In general, connections can be omitted if they would connect symmetric nodes. When symmetric nodes are swapped, the circuit will not change. Hence they will always carry the same potential (at least in theory) and a connection between them will not carry any current. So it can be omitted.
This feature can be used to solve the "split_gates" problem (see "split_gates" below). The internal source/drain nodes are symmetric in the configuration shown there, so "join_symmetric_nets" can be used to solve make the required connections, e.g.:
join_symmetric_nets("NAND2")
However, there is a more specific feature available ("split_gates") which covers more cases, but is specialized on MOS devices.
The following picture describes such a situation known as "split gate configuration". In this case, the N1 and N2 are identical: swapping them will not change the circuit's topology. Hence, they will carry the same potential and the red connection is not required physically. But without such a connection, the parallel transistors (top pair and bottom pair) will not be recognized as parallel and the pairs will not be joined into one each:
KLayout provides a feature (split_gates) which will add such connections after extraction of the netlist:
split_gates("NMOS")
This function will analyze all circuits in the extracted netlist with respect to "NMOS" devices and connect all split gates relevant source/drain nodes inside. If this function is called before "combine_devices" (e.g. through "netlist.simplify"), this connection is already present then and parallel devices will be recognized and combined.
The device name must denote a MOS3, MOS4, DMOS3 or DMOS4 device. The gate lengths of all involved devices must be identical. For MOS4 and DMOS4, all devices on one gate net must share the same bulk net.
In addition to the device name, a glob-style circuit pattern can be supplied. In this case, the analysis is restricted to the circuits matching this pattern.
"split_gates" can be used anywhere in the LVS script.
Extracted netlists often contain elements without a functional aspect: via cells for example generate subcircuits with a single pin and no device. Isolated metal islands (letters, logos, fill/planarisation patches) will create floating nets etc. Two methods are available to purge those elements.
Netlist#purge will remove all floating nets, all circuits without devices or subcircuits. Netlist#purge_nets will only purge floating nets. Floating nets are nets which don't connect to any device or subcircuit.
netlist.purge netlist.purge_nets
Netlist#simplify is a wrapper for "make_top_level_pins", "purge", "combine_devices" and "purge_nets" in this recommended order:
netlist.simplify
As a technical detail, "make_top_level_pins" is included in this sequence as with pins, nets are not considered floating. So "purge_nets" will maintain pins for labeled nets even if these nets are not connected to devices. This allows adding optional pins while maintaining the top level circuit's interface.