.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/extended/plot_single_use_definitions.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_extended_plot_single_use_definitions.py: ===================================== Make Instances Unique ===================================== Creates definitions for non-leaf instances so each instance has its own definition. Each library in both the original and the uniquified netlist will be printed along with each's definitions. .. GENERATED FROM PYTHON SOURCE LINES 8-198 .. rst-class:: sphx-glr-script-out .. code-block:: none ORIGINAL DEFINITIONS IN ' hdi_primitives ': ['LUT2', 'LUT3', 'IBUF', 'OBUF', 'INV'] DEFINITIONS IN ' work ': ['c', 'b', 'a', 'top'] UNIQUE DEFINITIONS IN ' hdi_primitives ': ['LUT2', 'LUT3', 'IBUF', 'OBUF', 'INV'] DEFINITIONS IN ' work ': ['c_UNIQUE_0', 'c_UNIQUE_1', 'c_UNIQUE_2', 'c_UNIQUE_3', 'c_UNIQUE_4', 'c_UNIQUE_5', 'c_UNIQUE_6', 'c_UNIQUE_7', 'c_UNIQUE_8', 'c_UNIQUE_9', 'c_UNIQUE_10', 'c_UNIQUE_11', 'c_UNIQUE_12', 'c_UNIQUE_13', 'c_UNIQUE_14', 'c_UNIQUE_15', 'c_UNIQUE_16', 'c_UNIQUE_17', 'c_UNIQUE_18', 'c_UNIQUE_19', 'c_UNIQUE_20', 'c_UNIQUE_21', 'c_UNIQUE_22', 'c_UNIQUE_23', 'c_UNIQUE_24', 'c_UNIQUE_25', 'c', 'b_UNIQUE_0', 'b_UNIQUE_1', 'b_UNIQUE_2', 'b_UNIQUE_3', 'b_UNIQUE_4', 'b_UNIQUE_5', 'b_UNIQUE_6', 'b_UNIQUE_7', 'b', 'a_UNIQUE_0', 'a_UNIQUE_1', 'a', 'top'] | .. code-block:: default import tempfile import spydrnet as sdn import collections from pathlib import Path # Check if given instance is a black box # instance: std.Instance to check # Return True if instance is a black box # (defined by no listed cables or child within child's reference), else return False def is_black_box(instance): definition = instance.reference if len(definition.cables) != 0 or len(definition.children) != 0: return False return True def increment_definition_count(definition): if definition not in definition_count: definition_count[definition] = 1 else: definition_count[definition] += 1 def trace_definition(definition): top_order = collections.deque() for child in definition.children: if len(child.pins) == 0: return top_order inner_pin = list(child.pins.keys())[0] if inner_pin.wire is None: continue top_order.extend(trace_definition(child.reference)) top_order.append(definition) increment_definition_count(definition) return top_order def get_reverse_topological_order(ir): depth_first_search = collections.deque() for child in top_def.children: if not is_black_box(child): depth_first_search.extend(trace_definition(child.reference)) visited = set() reverse_topological_order = [] while len(depth_first_search) != 0: definition = depth_first_search.popleft() if definition not in visited: visited.add(definition) reverse_topological_order.append(definition) return reverse_topological_order def copy_metadata(original, copy, copy_num=None): for key, data in original.data.items(): copy[key] = data if type(original) is sdn.Definition: if 'EDIF.identifier' in copy.data: while copy['EDIF.identifier'] + '_UNIQUE_' + str(copy_num) in definition_count: copy_num += 1 definition_count[copy['EDIF.identifier'] + '_UNIQUE_' + str(copy_num)] = 1 copy['EDIF.identifier'] = copy['EDIF.identifier'] + \ '_UNIQUE_' + str(copy_num) if '.NAME' in copy.data: copy['.NAME'] = copy['.NAME'] + '_UNIQUE_' + str(copy_num) def copy_ports(original, copy): for original_port in original.ports: new_port = copy.create_port() copy_metadata(original_port, new_port) new_port.direction = original_port.direction for original_inner_pin in original_port.pins: original_inner_pin_to_new_inner_pin[original_inner_pin] = new_port.create_pin( ) if hasattr(original_port, 'is_array'): new_port.is_array = original_port.is_array if hasattr(original_port, 'is_scalar'): new_port.is_scalar = original_port.is_scalar def make_instances_unique(instance): if len(definition_copies[instance.reference]) == 0: return definition = definition_copies[instance.reference].pop() # instance.reference = None instance.reference = definition def copy_children(original, copy): for original_child in original.children: new_child = copy.create_child() copy_metadata(original_child, new_child) new_child.reference = original_child.reference for pin in original_child.pins.keys(): outer_pin_map[original_child.pins[pin]] = new_child.pins[pin] if not is_black_box(original_child): make_instances_unique(new_child) instance_map[original_child] = new_child def copy_cable(original, copy): for original_cable in original.cables: new_cable = copy.create_cable() copy_metadata(original_cable, new_cable) for original_wire in original_cable.wires: new_wire = new_cable.create_wire() for original_pin in original_wire.pins: if isinstance(original_pin, sdn.InnerPin): new_wire.connect_pin( original_inner_pin_to_new_inner_pin[original_pin]) else: new_wire.connect_pin(outer_pin_map[original_pin]) def copy_definition(def_to_copy, def_copy, i): copy_metadata(def_to_copy, def_copy, i) copy_ports(def_to_copy, def_copy) copy_children(def_to_copy, def_copy) copy_cable(def_to_copy, def_copy) def definition_clean_up(definition): if definition in definition_copies: for child in definition.children: if child.reference in definition_copies: make_instances_unique(child) def make_definition_copies(def_to_copy, num_of_copies): copies = {} copies[def_to_copy] = collections.deque() definition_copies[def_to_copy] = [] for i in range(num_of_copies): def_copy = sdn.Definition() copy_definition(def_to_copy, def_copy, i) definition_copies[def_to_copy].append(def_copy) for y in range(len(def_to_copy.library.definitions)): if def_to_copy == def_to_copy.library.definitions[y]: break try: def_to_copy.library.add_definition(def_copy, y) except KeyError: name = def_to_copy['EDIF.identifier'] message = 'Try to add a definition with name of ' + \ name + 'but the name was already use' raise KeyError(message) definition_clean_up(def_to_copy) return definition_copies def clean(definition): for child in definition.children: if child.reference in definition_copies: make_instances_unique(child) #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) print(" DEFINITIONS IN '",library.name,"':",definitions) definition_count = {} original_inner_pin_to_new_inner_pin = {} instance_map = {} outer_pin_map = {} definition_copies = {} example_name = 'unique_challenge' ir = sdn.load_example_netlist_by_name(example_name) ir_orig = sdn.load_example_netlist_by_name(example_name) #store the original netlist for display later top_def = ir.top_instance.reference reverse_topological_order = get_reverse_topological_order(ir) for definition in reverse_topological_order: make_definition_copies(definition, definition_count[definition] - 1) clean(top_def) with tempfile.TemporaryDirectory() as td: file_name = example_name + '_unique.edf' sdn.compose(ir, Path(td, file_name)) #show the original netlist with its definitions and the new netlist with each instance now as a unique definition print("ORIGINAL") libraries_definitions(ir_orig) print("UNIQUE") libraries_definitions(ir) .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.055 seconds) .. _sphx_glr_download_auto_examples_extended_plot_single_use_definitions.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_single_use_definitions.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_single_use_definitions.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_