-
Notifications
You must be signed in to change notification settings - Fork 22
SpyDrNet Bootcamp
emonlux edited this page Apr 21, 2023
·
25 revisions
-
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
-
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
- Run the following in minimal.py:
-
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)
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()
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
- 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!