Note
Click here to download the full example code
1.1. Display Netlist Information FunctionsΒΆ
Note
This example is taken from SpyDrNet respository
- Some example functions that can be run to display information in a netlist:
print the hierarchy in a netlist
print each library with its definitions in a netlist
print connections between ports of each instance in a netlist
print the number of times each primitive is instanced
Note: because the hierarchy function uses recursion, the maximum recursion depth may be exceeded if used for large designs
For an even simpler display of netlist information, try using these functions with the Minimal Script example.
Also, JensRestemeier (not affiliated with BYU CCL) created a tool to generate images of netlists. See his github repository.
Output log
INFO 01_display_info.py:91 (MainThread) - HIERARCHY:
INFO 01_display_info.py:40 (MainThread) - 0 --instance of fourBitCounter fourBitCounter --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of clk_IBUF_BUFG_inst BUFG --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of clk_IBUF_inst IBUF --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of enable_IBUF_inst IBUF --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of inc_dec_IBUF_inst IBUF --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out[0]_i_1 LUT1 --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out[1]_i_1 LUT3 --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out[2]_i_1 LUT4 --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out[3]_i_1 LUT5 --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out_OBUF[0]_inst OBUF --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out_OBUF[1]_inst OBUF --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out_OBUF[2]_inst OBUF --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out_OBUF[3]_inst OBUF --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out_reg[0] FDCE --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out_reg[1] FDCE --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out_reg[2] FDCE --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of out_reg[3] FDCE --
INFO 01_display_info.py:40 (MainThread) - 1 --instance of rst_IBUF_inst IBUF --
INFO 01_display_info.py:52 (MainThread) - DEFINITIONS IN 'hdi_primitives': ['BUFG', 'IBUF', 'LUT1', 'LUT3', 'LUT4', 'LUT5', 'OBUF', 'FDCE', 'INV']
INFO 01_display_info.py:52 (MainThread) - DEFINITIONS IN 'work': ['fourBitCounter']
INFO 01_display_info.py:58 (MainThread) - CONNECTIONS:
INFO 01_display_info.py:60 (MainThread) - Instance name: clk_IBUF_BUFG_inst
INFO 01_display_info.py:65 (MainThread) - Port O ----> ['C of out_reg[3]', 'C of out_reg[2]', 'C of out_reg[1]', 'C of out_reg[0]']
INFO 01_display_info.py:73 (MainThread) - ['O of clk_IBUF_inst'] ----> Port I
INFO 01_display_info.py:60 (MainThread) - Instance name: clk_IBUF_inst
INFO 01_display_info.py:65 (MainThread) - Port O ----> ['I of clk_IBUF_BUFG_inst']
INFO 01_display_info.py:73 (MainThread) - ['clk of fourBitCounter'] ----> Port I
INFO 01_display_info.py:60 (MainThread) - Instance name: enable_IBUF_inst
INFO 01_display_info.py:65 (MainThread) - Port O ----> ['CE of out_reg[3]', 'CE of out_reg[2]', 'CE of out_reg[1]', 'CE of out_reg[0]']
INFO 01_display_info.py:73 (MainThread) - ['enable of fourBitCounter'] ----> Port I
INFO 01_display_info.py:60 (MainThread) - Instance name: inc_dec_IBUF_inst
INFO 01_display_info.py:65 (MainThread) - Port O ----> ['I1 of out[2]_i_1', 'I1 of out[1]_i_1', 'I0 of out[3]_i_1']
INFO 01_display_info.py:73 (MainThread) - ['inc_dec of fourBitCounter'] ----> Port I
INFO 01_display_info.py:60 (MainThread) - Instance name: out[0]_i_1
INFO 01_display_info.py:65 (MainThread) - Port O ----> ['D of out_reg[0]']
INFO 01_display_info.py:73 (MainThread) - ['Q of out_reg[0]'] ----> Port I0
INFO 01_display_info.py:60 (MainThread) - Instance name: out[1]_i_1
INFO 01_display_info.py:65 (MainThread) - Port O ----> ['D of out_reg[1]']
INFO 01_display_info.py:73 (MainThread) - ['Q of out_reg[1]'] ----> Port I2
INFO 01_display_info.py:73 (MainThread) - ['O of inc_dec_IBUF_inst'] ----> Port I1
INFO 01_display_info.py:73 (MainThread) - ['Q of out_reg[0]'] ----> Port I0
INFO 01_display_info.py:60 (MainThread) - Instance name: out[2]_i_1
INFO 01_display_info.py:65 (MainThread) - Port O ----> ['D of out_reg[2]']
INFO 01_display_info.py:73 (MainThread) - ['Q of out_reg[1]'] ----> Port I3
INFO 01_display_info.py:73 (MainThread) - ['Q of out_reg[2]'] ----> Port I2
INFO 01_display_info.py:73 (MainThread) - ['O of inc_dec_IBUF_inst'] ----> Port I1
INFO 01_display_info.py:73 (MainThread) - ['Q of out_reg[0]'] ----> Port I0
INFO 01_display_info.py:60 (MainThread) - Instance name: out[3]_i_1
INFO 01_display_info.py:65 (MainThread) - Port O ----> ['D of out_reg[3]']
...
import logging
import spydrnet as sdn
from spydrnet.util.selection import Selection
# print the hierarchy of a netlist
logger = logging.getLogger('spydrnet_logs')
sdn.enable_file_logging(LOG_LEVEL='INFO', filename="netlist_info")
def hierarchy(current_instance, indentation="", level=0):
logger.info(" %s %d --instance of %s %s --", indentation, level,
current_instance.name, current_instance.reference.name)
for child in current_instance.reference.children:
hierarchy(child, indentation+" ", level+1)
# print a list of all libraries and definitions in a netlist
def libraries_definitions(my_netlist):
for library in my_netlist.libraries:
definitions = list(
definition.name for definition in library.definitions)
logger.info("DEFINITIONS IN '%s': %s", library.name, definitions)
# prints each instance and it's connections (what inputs to it and what it outputs to)
def print_connections(current_netlist):
logger.info("CONNECTIONS:")
for instance in current_netlist.get_instances():
logger.info("Instance name: %s", instance.name)
for out_going_pin in instance.get_pins(selection=Selection.OUTSIDE, filter=lambda x: x.inner_pin.port.direction is sdn.OUT):
if out_going_pin.wire:
next_instances = list(str(pin2.inner_pin.port.name + ' of ' + pin2.instance.name)
for pin2 in out_going_pin.wire.get_pins(selection=Selection.OUTSIDE, filter=lambda x: x is not out_going_pin))
logger.info('\t Port %s ----> %s',
out_going_pin.inner_pin.port.name, next_instances)
for in_coming_pin in instance.get_pins(selection=Selection.OUTSIDE, filter=lambda x: x.inner_pin.port.direction is sdn.IN):
if in_coming_pin.wire:
previous_instances = list(pin2 for pin2 in in_coming_pin.wire.get_pins(
selection=Selection.OUTSIDE, filter=lambda x: x is not in_coming_pin))
checked_previous_instances = list(str(x.inner_pin.port.name + ' of ' + x.instance.name) for x in previous_instances if (
x.inner_pin.port.direction is sdn.OUT or (x.inner_pin.port.direction is sdn.IN and not x.instance.is_leaf())) is True)
logger.info('\t %s ----> Port %s', checked_previous_instances,
in_coming_pin.inner_pin.port.name)
def instance_count(current_netlist):
logger.info("Number of times each primitive is instanced:")
primitives_library = next(
current_netlist.get_libraries("hdi_primitives"), None)
for primitive in primitives_library.get_definitions():
count = 0
for instance in current_netlist.get_instances():
if primitive.name == instance.reference.name:
count += 1
logger.info("\t %s : %s", primitive.name, count)
netlist = sdn.load_example_netlist_by_name("fourBitCounter")
logger.info("HIERARCHY:")
hierarchy(netlist.top_instance)
libraries_definitions(netlist)
print_connections(netlist)
instance_count(netlist)
Output log
Total running time of the script: ( 0 minutes 0.000 seconds)