def connectPortsByPathName(self, source, sourcePortName, target, targetPortName, sourcePortId = None, targetPortId = None): """Connects the source component with a target one; the path of the initiator port (in the source component) and target port (in the target component) are specified. Note that a check is performed to be sure that the type of the source and target port match. It is also possible to specify the Ids of the ports: if they are different from None it means that sourcePortName and targetPortName are the names for arrays of ports and the port id refers to the array index of the desired port """ #check if source and target are SystemC components if not helper.isSystemCComponent(source): exceptions.Exception(str(source) + ' is not a SystemC component') if not helper.isSystemCComponent(target): exceptions.Exception(str(target) + ' is not a SystemC component') #check if the source components contains the port with the specified name try: sourcePort = helper.getAttrInstance(source, sourcePortName) except Exception: raise exceptions.Exception('There is no port with name ' + sourcePortName + ' in the source component') #use the port id in case the port is contained in a vector if sourcePortId is not None and hasattr(sourcePort,'__getitem__'): if type(sourcePortId) is int: sourcePort = sourcePort[sourcePortId] else: raise exceptions.Exception('The source port ID must be an integer') #check if the target component contains the port with the specified name try: targetPort = helper.getAttrInstance(target, targetPortName) except Exception: raise exceptions.Exception('There is no port with name ' + targetPortName + ' in the target component') #use the port id in case the port is contained in a vector if targetPortId is not None and hasattr(targetPort,'__getitem__'): if type(targetPortId) is int: targetPort = targetPort[targetPortId] else: raise exceptions.Exception('The target port ID must be an integer') # Now I have to check that the ports are compatible, so that they carry the same # type of information; in order to do this I move down on the inheritance chain # of each of the two ports, until the name of the class starts with # tlm_initiator_port or tlm_target_port; then I can check the types and # connect them try: sourcePortTypeName = helper.getBase('tlm_base_initiator_socket_b', sourcePort.__class__) except Exception, e: raise exceptions.Exception('ports ' + sourcePortName + ' and ' + targetPortName + ' cannot be connected because' + 'of the following error ' + str(e))
def getProbePosition(self, probe): """Returns the probeConnectionNode. If there is no probe or the two ports are not connected, it returns None""" if helper.isSystemCComponent(probe) and probe.__class__ == self.__probeClass: for i in self.__probes.items(): if i.probe.name() == probe.name(): return i else: raise exceptions.Exception(str(probe) + ' is not a valid probe')
def connectPorts(self, source, sourcePort, target, targetPort): """Connect two ports given their instances """ #check if source and target are SystemC components if not helper.isSystemCComponent(source): exceptions.Exception(str(source) + ' is not a SystemC component') if not helper.isSystemCComponent(target): exceptions.Exception(str(target) + ' is not a SystemC component') #check if they are already connected if self.areConnected(source, sourcePort, target, targetPort): print '\nThe two ports are already connected!\n' return #check for name method if not hasattr(target,'name'): raise exceptions.Exception('Component ' + str(target) + ' doesn\'t have the method name; probably it is not an sc_module') if not hasattr(source,'name'): raise exceptions.Exception('Component ' + str(source) + ' doesn\'t have the method name; probably it is not an sc_module') if not hasattr(targetPort,'name'): raise exceptions.Exception('Port ' + str(targetPort) + ' doesn\'t have the method name; probably it is not an valid port object') if not hasattr(sourcePort,'name'): raise exceptions.Exception('Port ' + str(sourcePort) + ' doesn\'t have the method name; probably it is not an valid port object') #get sc_name (actually the only unique identifier for sc_objects) sourceName = source.name() targetName = target.name() sourcePortName = sourcePort.name() targetPortName = targetPort.name() #super(scwrapper.sc_module, targetPort).name() # check of the port types try: sourcePortTypeName = helper.getBase('tlm_base_initiator_socket_b', sourcePort.__class__) except Exception, e: raise exceptions.Exception('ports ' + sourcePortName + ' and ' + targetPortName + ' cannot be connected because' + 'of the following error ' + str(e))
def connect(self, source, target): """Connects the source component with target; in case only one initiator port is present in source and one target port in target these two ports are connected, otherwise the user is requested to specify the correct ports by using the connectPortsByPathName method. Note that source and target must represent the instances of the components that we wish to connect together, not their names """ #check if source and target are SystemC components if not helper.isSystemCComponent(source): exceptions.Exception(str(source) + ' is not a SystemC component') if not helper.isSystemCComponent(target): exceptions.Exception(str(target) + ' is not a SystemC component') # First of all I get all the initiator ports from source and all the target ports from target sourcePorts = helper.getTLMOutPort(source) targetPorts = helper.getTLMInPort(target) # check if ports are already connected. TODO improve check considering single and multi_pass_through ports candidates = [] for srcPort in sourcePorts: for trgPort in targetPorts: if not self.areConnected(source, srcPort.name(), target, trgPort.name()): candidates.append((srcPort,trgPort)) #connect if possible if len(candidates) == 0: raise exceptions.Exception('Found no possible connections among ' + str(source) + ' and ' + str(target)) elif len(candidates) > 1: errorString = 'There are too many possible connections among' + str(source) + ' and ' + str(target) errorString = errorString + 'The candidates sourcePort, targetPort are:' for candTemp in candidates: errorString = errorString + candTemp[0][1] + ' -> ' + candTemp[1][1] errorString = errorString + 'Please call connectPortsByPathName or connectPorts specifying ' + 'the ports you wish to connect' raise exceptions.Exception(errorString) else: #connect the two identified ports print('Connecting ' + source.name() + ' and ' + target.name() + ' repectively using ports ' + candidates[0][0].name() + ' and ' + candidates[0][1].name()) self.connectPorts(source, candidates[0][0], target, candidates[0][1])
def registerComponent(self, component, attributes=None): """Registers a component instantiated in the architecture in the fault location list. It is possible to specify the attribute to register; if no attribute is specified, all the possible attribute are registered""" #check if component is a valid object if not(helper.isSystemCComponent(component) and ComponentManager.getInstantiatedComponents(self).count(component.name()) == 1): raise exception.Exception(str(component) + ' is not a valid SystemC component instantiated in the architecture') #it is necessary to create a descriptor for each instance of the component if self.__locationDescriptors.has_key(component.__class__): #check if specified attributes exist in the component class compAttributes = [] for currLocationsDescriptor in self.__locationDescriptors[component.__class__]: compAttributes.append(currLocationsDescriptor.getAttribute()) if attributes == None: attributes = compAttributes else: for currAttr in attributes: if compAttributes.count(currAttr) == 0: raise exceptions.Exception(str(currAttr) + ' is not a valid attribute for component ' + str(component)) #generate location descriptors for the specified component for currLocationsDescriptor in self.__locationDescriptors[component.__class__]: if attributes.count(currLocationsDescriptor.getAttribute()): attribute = currLocationsDescriptor.getAttribute() lines = currLocationsDescriptor.getLines() wordSize = currLocationsDescriptor.getWordSize() wrapperClass = currLocationsDescriptor.getWrapperClass() #get the number of lines. #it may be a number or also the name of a function to be called in order to load the value dinamically try: #the number of lines is specified into the file lines = long(lines) except: #the number of lines is retrieved dinamically by reading an attribute or calling a method of the object try: pars = lines.split('.') parRef = component for nextParStr in pars: parRef = getattr(parRef,nextParStr) if callable(parRef): lines = parRef() else: lines = parRef except: raise exceptions.Exception(str(lines) + ' attribute has not been found in component ' + str(component)) #get the word size. #it may be a number or also the name of a function to be called in order to load the value dinamically try: wordSize = long(wordSize) except: try: pars = lines.split('.') parRef = component for nextParStr in pars: parRef = getattr(parRef,nextParStr) if callable(parRef): wordSize = parRef() else: wordSize = parRef except: raise exceptions.Exception(str(lines) + ' attribute has not been found in component ' + str(component)) #create the location descriptor ld = locationDescriptor(component.name(), attribute, wrapperClass, lines, wordSize) self.__architectureFaultLocations.append(ld)