Skip to content

SpyDrNet Bootcamp

emonlux edited this page Apr 21, 2023 · 25 revisions

Getting started with SpyDrNet

  • Here is a high level presentation of SpyDrNet

  • Read over the SpyDrNet documentation

    • work through the tutorial
    • look through and run the examples
    • refer back to it often
  • Review the cheat sheet for simple definitions of each API element

Basic Netlist Information

  • Write functions that do the following to get a feel for SpyDrNet:

    • Print the names of all libraries and their definitions
    • Print the hierarchy of the design starting from the top instance
    • Print which wires/cables connect which instances/ports
    • Note: example implementations of these functions can be found in this example
  • Parents, children, definitions, instances, and references

    • Run the following in minimal.py:
      temp = next(netlist.libraries[0].get_instances("and2_1"),None)  
      print("Instance:",temp.name)  
      print("Reference:",temp.reference.name)  
      print("Parent:",temp.parent.name)  
    • So……..
    • The function looks inside library[0] for the instance named “and2_1”. When it finds it, it prints its name, its reference, and its parent.
    • widget contains an instance of the AND2 definition. That instance is and2_1
    • widget is the parent of and2_1
    • and2_1 is the child of widget
    • AND2 is the reference of and2_1
    • See image, it’s pretty much what minimal.py creates
  • Parse an old project into SpyDrNet

    • Open an old Vivado project, open the elaborated design, get the netlist by typing "write_edif " in the tcl console
    • Then use SpyDrNet to parse it (use netlist = sdn.parse(file_name))
    • Look through all the info that SpyDrNet now holds for you. Notice how the instances and definitions match up with the design you created in Vivado.
    • Compare the wire connections in the schematic of the design in Vivado against the wire connections in SpyDrNet. They match up!
  • Ports, pins, cables, and wires

    • Ports are the input/output ‘slots’ of each definition (e.g. A,B, and Q of a simple AND gate)
    • Pins are on ports
    • Wires connect pins to pins. Wires can connect to as many pins as desired (not just two)
    • Ports (inputs and outputs of stuff) are connected by pins and wires
    • Cables are bundles of wires. Wires are inside cables
  • Try writing your own simple netlist from scratch using SpyDrNet (use minimal.py as a model)

  • Inner and Outer Pins

    • Inner pins are on definitions. Every definition has one set of inner pins
    • Outer pins are on instances. Each instance has a set of outer pins that corresponds to its reference definition’s inner pins
    • These pins are the bridge between the definition and outside instances
    • To see where inner and outer pins are used, run the following in minimal.py (it displays the pin type (class) of each instance and definition's pins)
def pin_type(current_instance):
    print("Instance:",current_instance.name," Reference definition:",current_instance.reference.name)
    for pin in current_instance.pins:
        print("\tInstance pin: ",pin.__class__)
    for pin in current_instance.reference.get_pins():
        print("\tDefinition pin: ",pin.__class__)
 
for instance in netlist.get_instances():
    pin_type(instance)

Getter Functions

This is a script that will get you started on how to use the getter functions.

# Imports the SpyDrNet package
import spydrnet as sdn
# Import Selection for pins
from spydrnet.util.selection import Selection

# Set to True to view all of the information in the netlist or 
# Set to False to view the information in a more readable format
print_everything = True

# Loads in the AND_gate netlist
netlist = sdn.load_example_netlist_by_name("AND_gate")

# This will print all of the information contained in the netlist
if (print_everything):
    for library in netlist.get_libraries():
        print("LIBRARY:", library)
        if "hdi_primitives" in library.name: # The hdi_primitives library contains all of the primitive types in the netlist
            for definition in netlist.get_definitions():
                print("\tDEFINITION", definition) 
                for port in definition.get_ports():
                    print("\t\tPORT:", port)   
                print()      
        if "work" in library.name: # The work library contains all of instances of each primitive type 
            for instance in netlist.get_instances():
                print("\tINSTANCE:", instance)
                for port in instance.get_ports():
                    print("\t\tPORT:", port)  # The ports on each instance
                    for pin in port.get_pins(selection=Selection.OUTSIDE):
                        print("\t\t\tPINS:", pin.wire) # Wire connected to each port
                print()
        print()

else:
    # This demonstrates how to get the same information as above, but in a more readable format
    for library in netlist.get_libraries():            
        print("LIBRARY:", library.name)
        if "hdi_primitives" in library.name:
            for definition in netlist.get_definitions():
                print("\tDEFINITION:", definition.name) 
                for port in definition.get_ports():
                    print("\t\tPORT:", port.name)            
        if "work" in library.name:
            for instance in netlist.get_instances():
                print("\tINSTANCE:", instance.name)
                print("\tTYPE:", instance.reference.name)
                for port in instance.get_ports():
                    print("\t\tPORT:", port.name)
                    print("\t\tDIRECTION:", port.direction)
                    for pin in port.get_pins(selection=Selection.OUTSIDE):
                        print("\t\t\tPINS:", pin.wire.cable.name)
                print()
        print()

Parser and Composer arguments

Flags added to the SpyDrNet parser and composer (these are mostly used for verilog netlists)

Parser

  • architecture - Used for verilog netlist to determine what primitive library to use

Composer

  • write_blackbox - (bool) Skips writing black boxes/verilog primitives
  • write_eblif_cname - (bool) Flag used for eblif (Yosys to F4PGA)
  • defparam - (bool) Compose parameters in defparam statements instead of using #()

Used for TMR

  • voters - List of voters for verilog netlists to add to the composed netlist

Adding to Bootcamp

  • After working through all of this, if you have any suggestions/ideas on how to make this bootcamp better, please edit the page directly or open an issue!