Source code for spydrnet_physical.ir.cable

''' Example plugin to extend functionality '''
import typing
from spydrnet.ir.cable import Cable as CableBase
from spydrnet.ir import Port, InnerPin, OuterPin


if typing.TYPE_CHECKING:
    from spydrnet.ir.cable import Cable as CableSDN
    from spydrnet_physical.ir.bundle import Bundle as BundlePhy
    CableBase = type("BundleBase", (CableSDN, BundlePhy), {})


[docs]class Cable(CableBase): ''' This class extends the default Cable class ''' @property def size(self): ''' Returns number of wires in the cable Returns: int: Returns size of cable ''' return super().size @property def is_port_cable(self): ''' Checks if the wire is connected to any definition port (InnerConnection) returns: bool: true if wire belongs to definition port ''' return any(isinstance(pin, InnerPin) for wire in self._wires for pin in wire.pins)
[docs] def connect_port(self, port, reverse=False): ''' Connects cable to the port of definition. This is internal connection to the InnerPins of the definition args: port (Port): Port to connect ''' assert self in port.definition.cables, \ "Cable and Port does not belong to same definition" assert isinstance( port, Port), "Argument to connect_port should be port" assert port.size, "Port has no pins" for wire in self.wires: if self.is_downto: wire.connect_pin(port.pins[-(wire.index()+1)]) else: wire.connect_pin(port.pins[wire.index()])
[docs] def connect_instance_port(self, instance, port): ''' Connects cable to the port of the given instance. args: instance (Instance): Instance to consider port (Port): Port to connect ''' assert isinstance(port, Port), \ "Argument to connect_port should be port" assert port.size, "Port has no pins" assert port.size == self.size, "Port and cable size do not match" assert port in instance.reference.ports, \ "Port %s in not part of instance definition %s" % \ (port.name, instance.reference.name) for wire in self.wires: wire.connect_pin(instance.pins[port.pins[wire.get_index]])
[docs] def assign_cable(self, cable: 'Cable', upper=None, lower=None, reverse=False, assign_instance_name=None): ''' Create assignment beetween self and provided cable assign self = cable[upper:lower] ''' assert isinstance( cable, Cable), "Cable can be assigned to another cable" assert self.definition is cable.definition, \ "Cables belongs to two differnt definitions" assert self.definition is cable.definition, \ "Cables belongs to differnt definitions" upper = upper or (self.size if self.is_downto else 0) lower = lower or (0 if self.is_downto else self.size) assign_lib = self.definition._get_assignment_library() assign_def = self.definition._get_assignment_definition( assign_lib, self.size) instance = self.definition.create_child( assign_instance_name or f"{self.name}_{cable.name}_assign", reference=assign_def) in_port = next(assign_def.get_ports("o" if reverse else "i")) self.connect_instance_port(instance, in_port) out_port = next(assign_def.get_ports("i" if reverse else "o")) for indx, pin in enumerate(out_port.pins): cable.wires[range(lower, upper+1)[indx] ].connect_pin(instance.pins[pin]) return instance
def split(self, get_name=None): get_name = get_name or (lambda x: f"{self.name}_{x}") for indx, wire in enumerate(self._wires[::-1]): new_cable = self.definition.create_cable(get_name(indx)) self.remove_wire(wire) new_cable.add_wire(wire) self.definition.remove_cable(self)
[docs] def check_concat(self): """ This fucntion check if the cable is concatenated while connecting to other ports """ assert self.size, "Cable does not contain any wires" connectedPorts = len(self._wires[0].pins) for wire in self._wires: if not connectedPorts == len(wire.pins): return False for pin in wire.pins: if isinstance(pin, InnerPin): if not pin.port.size == self.size: return False if not pin.index() == wire.index(): return False else: if not pin.inner_pin.port.size == self.size: return False if not pin.inner_pin.index() == wire.index(): return False return True