''' Example plugin to extend functionality '''importtypingimportloggingfromspydrnet.ir.cableimportCableasCableBasefromspydrnet.irimportPort,InnerPin,OuterPiniftyping.TYPE_CHECKING:fromspydrnet.ir.cableimportCableasCableSDNfromspydrnet_physical.ir.bundleimportBundleasBundlePhyCableBase=type("BundleBase",(CableSDN,BundlePhy),{})logger=logging.getLogger("spydrnet_logs")
[docs]classCable(CableBase):''' This class extends the default Cable class '''@propertydefsize(self):''' Returns number of wires in the cable Returns: int: Returns size of cable '''returnsuper().size@propertydefis_port_cable(self):''' Checks if the wire is connected to any definition port (InnerConnection) returns: bool: true if wire belongs to definition port '''returnany(isinstance(pin,InnerPin)forwireinself._wiresforpininwire.pins)
[docs]defconnect_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 '''assertselfinport.definition.cables, \
"Cable and Port does not belong to same definition"assertisinstance(port,Port),"Argument to connect_port should be port"assertport.size,"Port has no pins"forwireinself.wires:ifself.is_downto:wire.connect_pin(port.pins[-(wire.index()+1)])else:wire.connect_pin(port.pins[wire.index()])
[docs]defconnect_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 '''assertisinstance(port,Port), \
"Argument to connect_port should be port"assertport.size,"Port has no pins"assertport.size==self.size,f"Port and cable size do not match {port.size} != {self.size}"assertportininstance.reference.ports, \
"Port %s in not part of instance definition %s"% \
(port.name,instance.reference.name)forwireinself.wires:wire.connect_pin(instance.pins[port.pins[wire.get_index]])
[docs]defassign_cable(self,cable:'Cable',upper=None,lower=None,reverse=False,assign_instance_name=None,bitwise_assignment=False):''' Create assignment beetween self and provided cable assign self = cable[upper:lower] '''assertisinstance(cable,Cable),"Cable can be assigned to another cable"assertself.definitioniscable.definition, \
"Cables belongs to two differnt definitions"assertself.definitioniscable.definition, \
"Cables belongs to differnt definitions"upper=upperor(self.sizeifself.is_downtoelse0)lower=loweror(0ifself.is_downtoelseself.size)assign_lib=self.definition._get_assignment_library()assign_def=self.definition._get_assignment_definition(assign_lib,1ifbitwise_assignmentelseself.size)ifbitwise_assignment:instances=[]forindx,wire1inenumerate(self.wires):ifself.is_downto==cable.is_downto:wire2=cable.wires[indx+lower]else:wire2=cable.wires[-1*(indx+lower+1)]instance=self.definition.create_child((assign_instance_nameorf"{self.name}_{cable.name}_assign")+f"_{indx}",reference=assign_def)i_pin=next(instance.get_port_pins("i"))o_pin=next(instance.get_port_pins("o"))wire1.connect_pin(o_pinifreverseelsei_pin)wire2.connect_pin(i_pinifreverseelseo_pin)returninstanceselse:assertself.is_downto==cable.is_downto, \
"Can not assign little endian to big endian wire "+ \
f"{self.name} is {self.is_downto} and {cable.name} is {cable.is_downto}"instance=self.definition.create_child(assign_instance_nameorf"{self.name}_{cable.name}_assign",reference=assign_def)in_port=next(assign_def.get_ports("o"ifreverseelse"i"))self.connect_instance_port(instance,in_port)out_port=next(assign_def.get_ports("i"ifreverseelse"o"))forindx,pininenumerate(out_port.pins):cable.wires[range(lower,upper+1)[indx]].connect_pin(instance.pins[pin])returninstance
[docs]defcheck_concat(self):""" This fucntion check if the cable is concatenated while connecting to other ports """assertself.size,"Cable does not contain any wires"connectedPorts=len(self._wires[0].pins)forwireinself._wires:ifnotconnectedPorts==len(wire.pins):returnFalseforpininwire.pins:ifisinstance(pin,InnerPin):ifnotpin.port.size==self.size:returnFalseifnotpin.index()==wire.index():returnFalseelse:ifnotpin.inner_pin.port.size==self.size:returnFalseifnotpin.inner_pin.index()==wire.index():returnFalsereturnTrue