Design Module

A design module is a Python class that generates new schematics. It computes all parameters needed to generate a schematic from user defined specifications. For example, a design module for an inverter needs to compute the width, length, and threshold flavor of the NMOS and PMOS to generate a new inverter schematic. The designer of this module can let the user specify these parameters directly, or alternatively compute them from higher level specifications, such as fanout, input capacitance, and leakage specs.

To create a default design module for a schematic generator, create a BagProject instance and call import_design_library() to import all schematic generators in a library from your CAD program into Python. The designer should then implement the three methods, design(), get_layout_params(), and get_layout_pin_mapping() (The latter two are optional if you do not use BAG to generate layout). Once you finish the design module definition, you can create new design module instances by calling create_design_module().

The following sections describe how each of these methods should be implemented.


This method computes all parameters needed to generate a schematic from user defined specifications. The input arguments should also be specified in this method.

A design module can have multiple design methods, as long as they have difference names. For example, You can implement the design() method to compute parameters from high level specifications, and define a new method named design_override() that allows the user to assign parameter values directly for debugging purposes.

To enable hierarchical design, design module has a dictionary, instances, that maps children instance names to corresponding design modules, so you can simply call their design() methods to set their parameters. See Tutorial for an simple example.

If you need to modify the schematic structure (such as adding more inverter buffers), you should call the corresponding methods before calling design() methods of child instances, as those design module could be changed. The rest of this section explains how you modify the schematic.

Pin Renaming

Most of the time, you should not rename the pin of schematic. The only time you should rename the pin is when you have a variable bus pin where the number of bits in the bus can change with the design. In this case, call rename_pin() to change the number of bits in the bus. To connect/remove instances from the added/deleted bus pins, see Instance Connection Modification

Delete Instances

Delete a child instance by calling delete_instance(). After this call, the corresponding value in instances dictionary will become None.


You don’t have to delete 0-width or 0-finger transistors; BAG already handles that for you.

Replace Instance Master

If you have two different designs of a child instance, and you want to swap between the two designs, you can call replace_instance_master() to change the instance master of a child.


You can replace instance masters only if the two instance masters have exactly the symbol, including pin names.

Instance Connection Modification

Call reconnect_instance_terminal() to change a child instance’s connection.

Arraying Child Instances

Call array_instance() to array a child instance. After this call, instances will map the child instance name to a list of design modules, one for each instance in the array. You can then iterate through this list and design each of the instances. They do not need to have the same parameter values.

Restoring to Default

If you are using the design module in a design iteration loop, or you’re using BAG interactively through the Python console, and you want to restore a deleted/replaced/arrayed child instance to the default state, you can call restore_instance().


This method should return a dictionary from layout parameter names to their values. This dictionary is used to create a layout cell that will pass LVS against the generated schematic.


This method should return a dictionary from layout pin names to schematic pin names. This method exists because a layout cell may not have the same pin names as the schematic. If a layout pin should be left un-exported, its corresponding value in the dictionary must be None.

This dictionary only need to list the layout pins that needs to be renamed. If no renaming is necessary, an empty dictionary can be returned.