Module openrtdynamics2.lang.diagram_core.signal_network.signals
Expand source code
from typing import Dict, List
from colorama import init, Fore, Back, Style
init(autoreset=True)
class Signal(object):
def __init__(self, sim, autogeneratedName : str, datatype = None ):
self.sim = sim
# the fixed and final datatype of this signals either as a result of the datatype determination phase
# or manually fixed.
self._datatype = datatype
# datatype proposal that may be filled out during the datatype determination phase
self.proposedDatatype = None
# indicates a signal that is not computed by a set of instructions but points to a memory containing the value
self._is_referencing_memory = False
# give this signal a unique default name
self._name = autogeneratedName
self._nameIsDefault = True
# the list of destinations this signals goes to
self.destinationBlocks = []
self.destinationPorts = []
# the list of signals to which the datatype of this signal is inherited
self._inherit_datatype_to_list = []
# used by graph_traversion as a helper variable to perform a marking of the graph nodes
self.graphTraversionMarker = -1
# inherit the datatype for this anonymous signals from the signal refered to by inherit_datatype_of_signal
self.inherit_datatype_of_signal = None
# In case not None: the data/value of the signal are aboutained from the given signal
# NOTE: not used so far.
self._data_link = None
# NOTE: this mus be the last in the list
# notify the creation of this signal
self.sim.datatype_propagation_instance.notifySignal(self)
# properties (user)
self._properties = None
# properties (internal, controlled by block prototypes)
self.properties_internal = {}
# optional: port number of input / output w.r.t. to the system 'sim'
self.port = None
@property
def properties(self):
return self.lookupSource()._properties
def set_properties(self, p):
self.lookupSource()._properties = p
# TODO: remove
def getDatatype(self):
return self.lookupSource()._datatype
@property
def datatype(self):
return self.lookupSource()._datatype
def update_datatype_config(self, datatype):
"""
set the datatype in case it was not defined in the constructor
"""
if self.lookupSource()._datatype is not None:
raise BaseException("datatype already defined")
self.lookupSource()._datatype = datatype
@property
def is_referencing_memory(self):
return self._is_referencing_memory
def set_is_referencing_memory(self, val : bool):
self._is_referencing_memory = val
@property
def nameIsDefault(self):
return self._nameIsDefault
@property
def system(self):
# system == simulation
return self.sim
# in case resolveUndeterminedSignals becomes obsolet, those 3 fns might be important
# otherwise TODO: remove them
def is_proxy(self):
return self.lookupSource().is_proxy()
def is_block_output(self):
return self.lookupSource().is_block_output()
def is_simulation_input(self):
return self.lookupSource().is_simulation_input()
def is_crossing_system_boundary(self, system):
"""
test if fot the given system this signals comes from an outer/higher level
system.
"""
if self.sim == system:
return False
# check if this signal is coming from an upper/outer system
# (if not it comes from a parallel system that cannot be accessed: this is an error)
# go up in the system-nesting hirachy starting at system
system_iter = system
while system_iter.parent_system is not None:
if system_iter.parent_system == self.system:
return True
system_iter = system_iter.parent_system
raise BaseException("Bad access to signal " + Fore.YELLOW + self.name + Fore.RESET + ": did you access a signal from another subsystem that cannot be reached?")
def lookupSource(self):
return self
def graphTraversionMarkerReset(self):
self.lookupSource().graphTraversionMarker = -1
def graphTraversionMarkerMarkVisited(self, level):
if level < 0:
raise BaseException("level cannot be < 0")
self.lookupSource().graphTraversionMarker = level
def graphTraversionMarkerMarkIsVisited(self):
# check of this node was marked on level or a level below
return self.lookupSource().graphTraversionMarker >= 0
def graphTraversionMarkerMarkIsVisitedOnLevelLowerThan(self, onLevel):
# check of this node was marked on level or a level below
return self.graphTraversionMarkerMarkIsVisited() and self.lookupSource().graphTraversionMarker < onLevel
# set the name of this signal
def set_name(self, name):
self.lookupSource()._name = name
# indicate that this Signal has a specified name (not a default/auto-generated name)
self._nameIsDefault = False
return self
# set the name of this signal (this method shall not get overwritten)
def set_name_raw(self, name):
self.lookupSource()._name = name
# indicate that this Signal has a specified name (not a default/auto-generated name)
self._nameIsDefault = False
return self
@property
def name(self):
return self.lookupSource()._name
def toStr(self):
ret = ''
ret += self.name
if self.datatype is not None:
ret += " (" + self.datatype.toStr() + ")"
else:
# ret += " (undef datatype)"
pass
if self.lookupSource().proposedDatatype is not None:
ret += " type proposal: (" + self.lookupSource().proposedDatatype.toStr() + ")"
else:
# ret += "proposal: (undef datatype)"
pass
if self.lookupSource().inherit_datatype_of_signal is not None:
ret = ret + 'type inherit from ' + self.lookupSource().inherit_datatype_of_signal.name
return ret
def addDestination(self, block , port : int):
# add this destination to the list
self.lookupSource().destinationBlocks.append( block )
self.lookupSource().destinationPorts.append( port )
def getDestinationBlocks(self):
return self.lookupSource().destinationBlocks
def setDatatype_nonotitication(self, datatype):
self.lookupSource()._datatype = datatype
# TODO: maybe there should be a notification in the next step in the datatype propagation phase?
# e.g.:
# self.lookupSource()._datatype_changed_but_not_notified_so_far = True
def setDatatype(self, datatype):
self.setDatatype_nonotitication( datatype )
# NOTE: should be added lookupSource() here (though effectively no difference)
# notify the change of the datatype
self.sim.datatype_propagation_instance.notifySignal(self)
def fixDatatype(self):
# this shall explicitely not trigger a notification!
self.lookupSource()._datatype = self.lookupSource().proposedDatatype
def getProposedDatatype(self):
return self.lookupSource().proposedDatatype
def setProposedDatatype(self, proposedDatatype):
# only proceed if the datatype of this signals is not already fixed
if self.lookupSource()._datatype is None:
# only proceed of the prosed datatype is diffent to the stored one
# or the stored type is None (not set before)
if not proposedDatatype.is_equal_to( self.lookupSource().proposedDatatype ) or self.lookupSource().proposedDatatype is None:
self.lookupSource().proposedDatatype = proposedDatatype
# self.lookupSource().proposedDatatypeUpdated = True
# notify the change of the datatype
self.sim.datatype_propagation_instance.notify_updateOfProposedDatatype(self)
else:
if not self.lookupSource()._datatype.is_equal_to( proposedDatatype ):
raise BaseException("setProposedDatatype: only possible for signals the datatypes of which is not already fixed!")
@property
def proposed_datatype(self):
return self.lookupSource().proposedDatatype
def inherit_datatype_from_signal(self, from_signal):
"""
The datatype of this anonymous signal shall be inherited from the given signal 'from_signal'.
This creates a bi-directional link in-between the signals self and from_signal
"""
self.lookupSource().inherit_datatype_of_signal = from_signal
from_signal.inherit_datatype_to( self )
def inherit_datatype_to(self, to_signal):
"""
add to_signal to the list of signals that inherit the datatype of this signal
"""
# once the datatype of this signal is fixed, inherit it to to_signal
self.lookupSource()._inherit_datatype_to_list.append( to_signal )
@property
def inherit_datatype_to_list(self):
return self.lookupSource()._inherit_datatype_to_list
def set_data_link(self, signal):
"""
The data/value of the signal are based on the given signal
This is used for:
1) accessing the output of a subsystem
"""
self.lookupSource()._data_link = signal
@property
def data_link(self):
return self.lookupSource()._data_link
# move to derived classes below
def getSourceBlock(self):
return self.lookupSource().sourceBlock
def set_blockname(self, name):
if not self.lookupSource().getSourceBlock() is None:
self.lookupSource().getSourceBlock().set_name(name)
return self
def ShowOrigin(self):
pass
# if not self.lookupSource().sourcePort is None and not self.lookupSource().sourceBlock is None:
# print("Signal >" + self.name + "< origin: port " + str(self.lookupSource().sourcePort) + " of block #" + str(self.lookupSource().sourceBlock.getId()) )
# else:
# print("Signal >" + self.name + "< origin not defined (so far)")
def resolveUndeterminedSignals(signals : List[Signal], ignore_signals_with_datatype_inheritance = False ):
"""
Go through a list of signals and replace (inplace) all entries of the list
with their direct source signals, i.e., signals of type UndeterminedSignal
will become the connected block output of type BlockOutputSignal
"""
if signals is None:
return
for i in range(0,len(signals)):
signal = signals[i].lookupSource()
if isinstance(signal, UndeterminedSignal):
if signal.inherit_datatype_of_signal is not None and ignore_signals_with_datatype_inheritance:
# there is an anonymous signal in the list. However, its datatype is foreseen to be inherited
# print(" --------- ignoring anonymous signal " + signal.toStr() + " as its datatype will be inherited ------- ")
pass
else:
raise BaseException("Could not resolve anonymous singal " + signal.toStr() + ". Please ensure to connect this signal to a block output." )
signals[i] = signal
class UndeterminedSignal(Signal):
"""
A signal that serves as a placeholder and will be connected later on by
calling connect(). As long as no connection to a real source is present
the blocks that are connected to this signal are colleted in a list. Once
this signal is connected, the source's signal lists are merged.
NOTE: undetermined singlas must be connected to a block's output i.e. they
cannot be simulation inputs
It is optional to specify a datatype.
"""
def __init__(self, sim, datatype = None):
# link to myself by default to be able to colltect the blocks that are connected to
# this fake-signal
# name undefined. Once connected to a block output the name is defined
self.linkedSignal = self
self.nameProposal = None
Signal.__init__(self, sim, autogeneratedName = 'anonymous', datatype=datatype)
def is_proxy(self):
return True
def toStr(self):
string = Signal.toStr(self)
if self is self.linkedSignal:
string = string + ' (anon.)'
return string
# connect to source
def setequal(self, to : Signal):
if self is to:
raise BaseException("Cannot connect to the same signal.")
# check if to is a BlockOutputSignal
if not isinstance(to.lookupSource(), BlockOutputSignal):
raise BaseException("An anonymous signal can only be connected to a block output.")
# build a link to the already existing signal 'to'
# print("== Created a signal link " + to.name + " == "+ self.name + "")
# merge the list of detination blocks
for b in self.destinationBlocks:
to.destinationBlocks.append(b)
# merge self.destinationBlocks into to.destinationBlocks
for p in self.destinationPorts:
to.destinationPorts.append(p)
# merge datatype
if self.datatype is not None and not to.datatype:
to.setDatatype_nonotitication(self.datatype)
# merge name
if self.nameProposal is not None and not to.nameIsDefault:
# TODO: check if to holds just the default name. If so update it with the proposal
to.set_name(self.nameProposal)
# overwrite self
self.linkedSignal = to
def isConnectedToSth(self):
if self is self.linkedSignal:
return False
else:
return True
# set the name of this signal
def set_name(self, name):
if not self.isConnectedToSth():
# not connected
self.nameProposal = name
else:
self.linkedSignal.lookupSource().set_name(name)
def lookupSource(self):
if not self.isConnectedToSth():
# Note at this point the anonymous signal does not have a proper
# source. return itself as a placeholder until sth. is connected
# by calling setequal().
return self
else:
return self.linkedSignal.lookupSource()
# # TODO: remove this and related...
# class SubsystemOutputLink(UndeterminedSignal):
# """
# A signal that serves as a placeholder for a subsystem output to be used in the embedding
# system. A datatype must be specified.
# Signals of this kind are automatically generated during the compilation process when cutting the signals comming
# from the subsystem blocks.
# """
# def __init__(self, sim, original_signal : Signal):
# self._original_signal = original_signal
# UndeterminedSignal.__init__(self, sim)
class BlockOutputSignal(Signal):
"""
A signal that is the output of a block (normal case)
TODO: implement and remove code from 'Signal' above
"""
def __init__(self, sim, datatype = None, sourceBlock = None, sourcePort = None):
self._sourceBlock = sourceBlock
self._sourcePort = sourcePort # counting starts at zero
# give this signal a unique default name
Signal.__init__(self, sim, autogeneratedName = 's' + str(sim.generate_new_signal_id()), datatype = datatype)
def is_block_output(self):
return True
def update_source_config(self, sourceBlock = None, sourcePort = None):
"""
In the constructor all information is optional. To add information after construction
of this signal, update config might be used
"""
if self._sourceBlock is None:
self._sourceBlock = sourceBlock
elif sourceBlock is not None:
raise BaseException("souce block already defined and cannot be changed anymore")
if self._sourcePort is None:
self._sourcePort = sourcePort
elif sourcePort is not None:
raise BaseException("souce port already defined and cannot be changed anymore")
def lookupSource(self):
return self
def set_name(self, name):
# add a prefix to the autogenerated name
Signal.set_name(self, self.name + '_' + name)
@property
def sourceBlock(self):
return self._sourceBlock
def sourcePort(self):
return self._sourcePort
def redefine_source(self, sourceBlock, sourcePort):
self._sourceBlock = sourceBlock
self._sourcePort = sourcePort
class SimulationInputSignal(Signal):
"""
A special signal that describes an input to a system.
"""
def __init__(self, sim, datatype = None):
# give this signal a unique default name
Signal.__init__(self, sim, autogeneratedName = 'signal' + str(sim.generate_new_signal_id()), datatype = datatype)
self.port = sim.simulation_input_signal_counter
sim.simulation_input_signal_counter += 1
def is_simulation_input(self):
return True
def is_crossing_system_boundary(self, system):
# as an input to a system the signal crosses the boundaries of the system
return True
def lookupSource(self):
return self
Functions
def resolveUndeterminedSignals(signals: List[Signal], ignore_signals_with_datatype_inheritance=False)
-
Go through a list of signals and replace (inplace) all entries of the list with their direct source signals, i.e., signals of type UndeterminedSignal will become the connected block output of type BlockOutputSignal
Expand source code
def resolveUndeterminedSignals(signals : List[Signal], ignore_signals_with_datatype_inheritance = False ): """ Go through a list of signals and replace (inplace) all entries of the list with their direct source signals, i.e., signals of type UndeterminedSignal will become the connected block output of type BlockOutputSignal """ if signals is None: return for i in range(0,len(signals)): signal = signals[i].lookupSource() if isinstance(signal, UndeterminedSignal): if signal.inherit_datatype_of_signal is not None and ignore_signals_with_datatype_inheritance: # there is an anonymous signal in the list. However, its datatype is foreseen to be inherited # print(" --------- ignoring anonymous signal " + signal.toStr() + " as its datatype will be inherited ------- ") pass else: raise BaseException("Could not resolve anonymous singal " + signal.toStr() + ". Please ensure to connect this signal to a block output." ) signals[i] = signal
Classes
class BlockOutputSignal (sim, datatype=None, sourceBlock=None, sourcePort=None)
-
A signal that is the output of a block (normal case)
TODO: implement and remove code from 'Signal' above
Expand source code
class BlockOutputSignal(Signal): """ A signal that is the output of a block (normal case) TODO: implement and remove code from 'Signal' above """ def __init__(self, sim, datatype = None, sourceBlock = None, sourcePort = None): self._sourceBlock = sourceBlock self._sourcePort = sourcePort # counting starts at zero # give this signal a unique default name Signal.__init__(self, sim, autogeneratedName = 's' + str(sim.generate_new_signal_id()), datatype = datatype) def is_block_output(self): return True def update_source_config(self, sourceBlock = None, sourcePort = None): """ In the constructor all information is optional. To add information after construction of this signal, update config might be used """ if self._sourceBlock is None: self._sourceBlock = sourceBlock elif sourceBlock is not None: raise BaseException("souce block already defined and cannot be changed anymore") if self._sourcePort is None: self._sourcePort = sourcePort elif sourcePort is not None: raise BaseException("souce port already defined and cannot be changed anymore") def lookupSource(self): return self def set_name(self, name): # add a prefix to the autogenerated name Signal.set_name(self, self.name + '_' + name) @property def sourceBlock(self): return self._sourceBlock def sourcePort(self): return self._sourcePort def redefine_source(self, sourceBlock, sourcePort): self._sourceBlock = sourceBlock self._sourcePort = sourcePort
Ancestors
Instance variables
var sourceBlock
-
Expand source code
@property def sourceBlock(self): return self._sourceBlock
Methods
def is_block_output(self)
-
Expand source code
def is_block_output(self): return True
def lookupSource(self)
-
Expand source code
def lookupSource(self): return self
def redefine_source(self, sourceBlock, sourcePort)
-
Expand source code
def redefine_source(self, sourceBlock, sourcePort): self._sourceBlock = sourceBlock self._sourcePort = sourcePort
def set_name(self, name)
-
Expand source code
def set_name(self, name): # add a prefix to the autogenerated name Signal.set_name(self, self.name + '_' + name)
def sourcePort(self)
-
Expand source code
def sourcePort(self): return self._sourcePort
def update_source_config(self, sourceBlock=None, sourcePort=None)
-
In the constructor all information is optional. To add information after construction of this signal, update config might be used
Expand source code
def update_source_config(self, sourceBlock = None, sourcePort = None): """ In the constructor all information is optional. To add information after construction of this signal, update config might be used """ if self._sourceBlock is None: self._sourceBlock = sourceBlock elif sourceBlock is not None: raise BaseException("souce block already defined and cannot be changed anymore") if self._sourcePort is None: self._sourcePort = sourcePort elif sourcePort is not None: raise BaseException("souce port already defined and cannot be changed anymore")
Inherited members
class Signal (sim, autogeneratedName: str, datatype=None)
-
Expand source code
class Signal(object): def __init__(self, sim, autogeneratedName : str, datatype = None ): self.sim = sim # the fixed and final datatype of this signals either as a result of the datatype determination phase # or manually fixed. self._datatype = datatype # datatype proposal that may be filled out during the datatype determination phase self.proposedDatatype = None # indicates a signal that is not computed by a set of instructions but points to a memory containing the value self._is_referencing_memory = False # give this signal a unique default name self._name = autogeneratedName self._nameIsDefault = True # the list of destinations this signals goes to self.destinationBlocks = [] self.destinationPorts = [] # the list of signals to which the datatype of this signal is inherited self._inherit_datatype_to_list = [] # used by graph_traversion as a helper variable to perform a marking of the graph nodes self.graphTraversionMarker = -1 # inherit the datatype for this anonymous signals from the signal refered to by inherit_datatype_of_signal self.inherit_datatype_of_signal = None # In case not None: the data/value of the signal are aboutained from the given signal # NOTE: not used so far. self._data_link = None # NOTE: this mus be the last in the list # notify the creation of this signal self.sim.datatype_propagation_instance.notifySignal(self) # properties (user) self._properties = None # properties (internal, controlled by block prototypes) self.properties_internal = {} # optional: port number of input / output w.r.t. to the system 'sim' self.port = None @property def properties(self): return self.lookupSource()._properties def set_properties(self, p): self.lookupSource()._properties = p # TODO: remove def getDatatype(self): return self.lookupSource()._datatype @property def datatype(self): return self.lookupSource()._datatype def update_datatype_config(self, datatype): """ set the datatype in case it was not defined in the constructor """ if self.lookupSource()._datatype is not None: raise BaseException("datatype already defined") self.lookupSource()._datatype = datatype @property def is_referencing_memory(self): return self._is_referencing_memory def set_is_referencing_memory(self, val : bool): self._is_referencing_memory = val @property def nameIsDefault(self): return self._nameIsDefault @property def system(self): # system == simulation return self.sim # in case resolveUndeterminedSignals becomes obsolet, those 3 fns might be important # otherwise TODO: remove them def is_proxy(self): return self.lookupSource().is_proxy() def is_block_output(self): return self.lookupSource().is_block_output() def is_simulation_input(self): return self.lookupSource().is_simulation_input() def is_crossing_system_boundary(self, system): """ test if fot the given system this signals comes from an outer/higher level system. """ if self.sim == system: return False # check if this signal is coming from an upper/outer system # (if not it comes from a parallel system that cannot be accessed: this is an error) # go up in the system-nesting hirachy starting at system system_iter = system while system_iter.parent_system is not None: if system_iter.parent_system == self.system: return True system_iter = system_iter.parent_system raise BaseException("Bad access to signal " + Fore.YELLOW + self.name + Fore.RESET + ": did you access a signal from another subsystem that cannot be reached?") def lookupSource(self): return self def graphTraversionMarkerReset(self): self.lookupSource().graphTraversionMarker = -1 def graphTraversionMarkerMarkVisited(self, level): if level < 0: raise BaseException("level cannot be < 0") self.lookupSource().graphTraversionMarker = level def graphTraversionMarkerMarkIsVisited(self): # check of this node was marked on level or a level below return self.lookupSource().graphTraversionMarker >= 0 def graphTraversionMarkerMarkIsVisitedOnLevelLowerThan(self, onLevel): # check of this node was marked on level or a level below return self.graphTraversionMarkerMarkIsVisited() and self.lookupSource().graphTraversionMarker < onLevel # set the name of this signal def set_name(self, name): self.lookupSource()._name = name # indicate that this Signal has a specified name (not a default/auto-generated name) self._nameIsDefault = False return self # set the name of this signal (this method shall not get overwritten) def set_name_raw(self, name): self.lookupSource()._name = name # indicate that this Signal has a specified name (not a default/auto-generated name) self._nameIsDefault = False return self @property def name(self): return self.lookupSource()._name def toStr(self): ret = '' ret += self.name if self.datatype is not None: ret += " (" + self.datatype.toStr() + ")" else: # ret += " (undef datatype)" pass if self.lookupSource().proposedDatatype is not None: ret += " type proposal: (" + self.lookupSource().proposedDatatype.toStr() + ")" else: # ret += "proposal: (undef datatype)" pass if self.lookupSource().inherit_datatype_of_signal is not None: ret = ret + 'type inherit from ' + self.lookupSource().inherit_datatype_of_signal.name return ret def addDestination(self, block , port : int): # add this destination to the list self.lookupSource().destinationBlocks.append( block ) self.lookupSource().destinationPorts.append( port ) def getDestinationBlocks(self): return self.lookupSource().destinationBlocks def setDatatype_nonotitication(self, datatype): self.lookupSource()._datatype = datatype # TODO: maybe there should be a notification in the next step in the datatype propagation phase? # e.g.: # self.lookupSource()._datatype_changed_but_not_notified_so_far = True def setDatatype(self, datatype): self.setDatatype_nonotitication( datatype ) # NOTE: should be added lookupSource() here (though effectively no difference) # notify the change of the datatype self.sim.datatype_propagation_instance.notifySignal(self) def fixDatatype(self): # this shall explicitely not trigger a notification! self.lookupSource()._datatype = self.lookupSource().proposedDatatype def getProposedDatatype(self): return self.lookupSource().proposedDatatype def setProposedDatatype(self, proposedDatatype): # only proceed if the datatype of this signals is not already fixed if self.lookupSource()._datatype is None: # only proceed of the prosed datatype is diffent to the stored one # or the stored type is None (not set before) if not proposedDatatype.is_equal_to( self.lookupSource().proposedDatatype ) or self.lookupSource().proposedDatatype is None: self.lookupSource().proposedDatatype = proposedDatatype # self.lookupSource().proposedDatatypeUpdated = True # notify the change of the datatype self.sim.datatype_propagation_instance.notify_updateOfProposedDatatype(self) else: if not self.lookupSource()._datatype.is_equal_to( proposedDatatype ): raise BaseException("setProposedDatatype: only possible for signals the datatypes of which is not already fixed!") @property def proposed_datatype(self): return self.lookupSource().proposedDatatype def inherit_datatype_from_signal(self, from_signal): """ The datatype of this anonymous signal shall be inherited from the given signal 'from_signal'. This creates a bi-directional link in-between the signals self and from_signal """ self.lookupSource().inherit_datatype_of_signal = from_signal from_signal.inherit_datatype_to( self ) def inherit_datatype_to(self, to_signal): """ add to_signal to the list of signals that inherit the datatype of this signal """ # once the datatype of this signal is fixed, inherit it to to_signal self.lookupSource()._inherit_datatype_to_list.append( to_signal ) @property def inherit_datatype_to_list(self): return self.lookupSource()._inherit_datatype_to_list def set_data_link(self, signal): """ The data/value of the signal are based on the given signal This is used for: 1) accessing the output of a subsystem """ self.lookupSource()._data_link = signal @property def data_link(self): return self.lookupSource()._data_link # move to derived classes below def getSourceBlock(self): return self.lookupSource().sourceBlock def set_blockname(self, name): if not self.lookupSource().getSourceBlock() is None: self.lookupSource().getSourceBlock().set_name(name) return self def ShowOrigin(self): pass
Subclasses
Instance variables
var data_link
-
Expand source code
@property def data_link(self): return self.lookupSource()._data_link
var datatype
-
Expand source code
@property def datatype(self): return self.lookupSource()._datatype
var inherit_datatype_to_list
-
Expand source code
@property def inherit_datatype_to_list(self): return self.lookupSource()._inherit_datatype_to_list
var is_referencing_memory
-
Expand source code
@property def is_referencing_memory(self): return self._is_referencing_memory
var name
-
Expand source code
@property def name(self): return self.lookupSource()._name
var nameIsDefault
-
Expand source code
@property def nameIsDefault(self): return self._nameIsDefault
var properties
-
Expand source code
@property def properties(self): return self.lookupSource()._properties
var proposed_datatype
-
Expand source code
@property def proposed_datatype(self): return self.lookupSource().proposedDatatype
var system
-
Expand source code
@property def system(self): # system == simulation return self.sim
Methods
def ShowOrigin(self)
-
Expand source code
def ShowOrigin(self): pass
def addDestination(self, block, port: int)
-
Expand source code
def addDestination(self, block , port : int): # add this destination to the list self.lookupSource().destinationBlocks.append( block ) self.lookupSource().destinationPorts.append( port )
def fixDatatype(self)
-
Expand source code
def fixDatatype(self): # this shall explicitely not trigger a notification! self.lookupSource()._datatype = self.lookupSource().proposedDatatype
def getDatatype(self)
-
Expand source code
def getDatatype(self): return self.lookupSource()._datatype
def getDestinationBlocks(self)
-
Expand source code
def getDestinationBlocks(self): return self.lookupSource().destinationBlocks
def getProposedDatatype(self)
-
Expand source code
def getProposedDatatype(self): return self.lookupSource().proposedDatatype
def getSourceBlock(self)
-
Expand source code
def getSourceBlock(self): return self.lookupSource().sourceBlock
def graphTraversionMarkerMarkIsVisited(self)
-
Expand source code
def graphTraversionMarkerMarkIsVisited(self): # check of this node was marked on level or a level below return self.lookupSource().graphTraversionMarker >= 0
def graphTraversionMarkerMarkIsVisitedOnLevelLowerThan(self, onLevel)
-
Expand source code
def graphTraversionMarkerMarkIsVisitedOnLevelLowerThan(self, onLevel): # check of this node was marked on level or a level below return self.graphTraversionMarkerMarkIsVisited() and self.lookupSource().graphTraversionMarker < onLevel
def graphTraversionMarkerMarkVisited(self, level)
-
Expand source code
def graphTraversionMarkerMarkVisited(self, level): if level < 0: raise BaseException("level cannot be < 0") self.lookupSource().graphTraversionMarker = level
def graphTraversionMarkerReset(self)
-
Expand source code
def graphTraversionMarkerReset(self): self.lookupSource().graphTraversionMarker = -1
def inherit_datatype_from_signal(self, from_signal)
-
The datatype of this anonymous signal shall be inherited from the given signal 'from_signal'. This creates a bi-directional link in-between the signals self and from_signal
Expand source code
def inherit_datatype_from_signal(self, from_signal): """ The datatype of this anonymous signal shall be inherited from the given signal 'from_signal'. This creates a bi-directional link in-between the signals self and from_signal """ self.lookupSource().inherit_datatype_of_signal = from_signal from_signal.inherit_datatype_to( self )
def inherit_datatype_to(self, to_signal)
-
add to_signal to the list of signals that inherit the datatype of this signal
Expand source code
def inherit_datatype_to(self, to_signal): """ add to_signal to the list of signals that inherit the datatype of this signal """ # once the datatype of this signal is fixed, inherit it to to_signal self.lookupSource()._inherit_datatype_to_list.append( to_signal )
def is_block_output(self)
-
Expand source code
def is_block_output(self): return self.lookupSource().is_block_output()
def is_crossing_system_boundary(self, system)
-
test if fot the given system this signals comes from an outer/higher level system.
Expand source code
def is_crossing_system_boundary(self, system): """ test if fot the given system this signals comes from an outer/higher level system. """ if self.sim == system: return False # check if this signal is coming from an upper/outer system # (if not it comes from a parallel system that cannot be accessed: this is an error) # go up in the system-nesting hirachy starting at system system_iter = system while system_iter.parent_system is not None: if system_iter.parent_system == self.system: return True system_iter = system_iter.parent_system raise BaseException("Bad access to signal " + Fore.YELLOW + self.name + Fore.RESET + ": did you access a signal from another subsystem that cannot be reached?")
def is_proxy(self)
-
Expand source code
def is_proxy(self): return self.lookupSource().is_proxy()
def is_simulation_input(self)
-
Expand source code
def is_simulation_input(self): return self.lookupSource().is_simulation_input()
def lookupSource(self)
-
Expand source code
def lookupSource(self): return self
def setDatatype(self, datatype)
-
Expand source code
def setDatatype(self, datatype): self.setDatatype_nonotitication( datatype ) # NOTE: should be added lookupSource() here (though effectively no difference) # notify the change of the datatype self.sim.datatype_propagation_instance.notifySignal(self)
def setDatatype_nonotitication(self, datatype)
-
Expand source code
def setDatatype_nonotitication(self, datatype): self.lookupSource()._datatype = datatype
def setProposedDatatype(self, proposedDatatype)
-
Expand source code
def setProposedDatatype(self, proposedDatatype): # only proceed if the datatype of this signals is not already fixed if self.lookupSource()._datatype is None: # only proceed of the prosed datatype is diffent to the stored one # or the stored type is None (not set before) if not proposedDatatype.is_equal_to( self.lookupSource().proposedDatatype ) or self.lookupSource().proposedDatatype is None: self.lookupSource().proposedDatatype = proposedDatatype # self.lookupSource().proposedDatatypeUpdated = True # notify the change of the datatype self.sim.datatype_propagation_instance.notify_updateOfProposedDatatype(self) else: if not self.lookupSource()._datatype.is_equal_to( proposedDatatype ): raise BaseException("setProposedDatatype: only possible for signals the datatypes of which is not already fixed!")
def set_blockname(self, name)
-
Expand source code
def set_blockname(self, name): if not self.lookupSource().getSourceBlock() is None: self.lookupSource().getSourceBlock().set_name(name) return self
def set_data_link(self, signal)
-
The data/value of the signal are based on the given signal
This is used for: 1) accessing the output of a subsystem
Expand source code
def set_data_link(self, signal): """ The data/value of the signal are based on the given signal This is used for: 1) accessing the output of a subsystem """ self.lookupSource()._data_link = signal
def set_is_referencing_memory(self, val: bool)
-
Expand source code
def set_is_referencing_memory(self, val : bool): self._is_referencing_memory = val
def set_name(self, name)
-
Expand source code
def set_name(self, name): self.lookupSource()._name = name # indicate that this Signal has a specified name (not a default/auto-generated name) self._nameIsDefault = False return self
def set_name_raw(self, name)
-
Expand source code
def set_name_raw(self, name): self.lookupSource()._name = name # indicate that this Signal has a specified name (not a default/auto-generated name) self._nameIsDefault = False return self
def set_properties(self, p)
-
Expand source code
def set_properties(self, p): self.lookupSource()._properties = p
def toStr(self)
-
Expand source code
def toStr(self): ret = '' ret += self.name if self.datatype is not None: ret += " (" + self.datatype.toStr() + ")" else: # ret += " (undef datatype)" pass if self.lookupSource().proposedDatatype is not None: ret += " type proposal: (" + self.lookupSource().proposedDatatype.toStr() + ")" else: # ret += "proposal: (undef datatype)" pass if self.lookupSource().inherit_datatype_of_signal is not None: ret = ret + 'type inherit from ' + self.lookupSource().inherit_datatype_of_signal.name return ret
def update_datatype_config(self, datatype)
-
set the datatype in case it was not defined in the constructor
Expand source code
def update_datatype_config(self, datatype): """ set the datatype in case it was not defined in the constructor """ if self.lookupSource()._datatype is not None: raise BaseException("datatype already defined") self.lookupSource()._datatype = datatype
class SimulationInputSignal (sim, datatype=None)
-
A special signal that describes an input to a system.
Expand source code
class SimulationInputSignal(Signal): """ A special signal that describes an input to a system. """ def __init__(self, sim, datatype = None): # give this signal a unique default name Signal.__init__(self, sim, autogeneratedName = 'signal' + str(sim.generate_new_signal_id()), datatype = datatype) self.port = sim.simulation_input_signal_counter sim.simulation_input_signal_counter += 1 def is_simulation_input(self): return True def is_crossing_system_boundary(self, system): # as an input to a system the signal crosses the boundaries of the system return True def lookupSource(self): return self
Ancestors
Methods
def is_simulation_input(self)
-
Expand source code
def is_simulation_input(self): return True
def lookupSource(self)
-
Expand source code
def lookupSource(self): return self
Inherited members
class UndeterminedSignal (sim, datatype=None)
-
A signal that serves as a placeholder and will be connected later on by calling connect(). As long as no connection to a real source is present the blocks that are connected to this signal are colleted in a list. Once this signal is connected, the source's signal lists are merged.
NOTE: undetermined singlas must be connected to a block's output i.e. they cannot be simulation inputs
It is optional to specify a datatype.
Expand source code
class UndeterminedSignal(Signal): """ A signal that serves as a placeholder and will be connected later on by calling connect(). As long as no connection to a real source is present the blocks that are connected to this signal are colleted in a list. Once this signal is connected, the source's signal lists are merged. NOTE: undetermined singlas must be connected to a block's output i.e. they cannot be simulation inputs It is optional to specify a datatype. """ def __init__(self, sim, datatype = None): # link to myself by default to be able to colltect the blocks that are connected to # this fake-signal # name undefined. Once connected to a block output the name is defined self.linkedSignal = self self.nameProposal = None Signal.__init__(self, sim, autogeneratedName = 'anonymous', datatype=datatype) def is_proxy(self): return True def toStr(self): string = Signal.toStr(self) if self is self.linkedSignal: string = string + ' (anon.)' return string # connect to source def setequal(self, to : Signal): if self is to: raise BaseException("Cannot connect to the same signal.") # check if to is a BlockOutputSignal if not isinstance(to.lookupSource(), BlockOutputSignal): raise BaseException("An anonymous signal can only be connected to a block output.") # build a link to the already existing signal 'to' # print("== Created a signal link " + to.name + " == "+ self.name + "") # merge the list of detination blocks for b in self.destinationBlocks: to.destinationBlocks.append(b) # merge self.destinationBlocks into to.destinationBlocks for p in self.destinationPorts: to.destinationPorts.append(p) # merge datatype if self.datatype is not None and not to.datatype: to.setDatatype_nonotitication(self.datatype) # merge name if self.nameProposal is not None and not to.nameIsDefault: # TODO: check if to holds just the default name. If so update it with the proposal to.set_name(self.nameProposal) # overwrite self self.linkedSignal = to def isConnectedToSth(self): if self is self.linkedSignal: return False else: return True # set the name of this signal def set_name(self, name): if not self.isConnectedToSth(): # not connected self.nameProposal = name else: self.linkedSignal.lookupSource().set_name(name) def lookupSource(self): if not self.isConnectedToSth(): # Note at this point the anonymous signal does not have a proper # source. return itself as a placeholder until sth. is connected # by calling setequal(). return self else: return self.linkedSignal.lookupSource()
Ancestors
Methods
def isConnectedToSth(self)
-
Expand source code
def isConnectedToSth(self): if self is self.linkedSignal: return False else: return True
def is_proxy(self)
-
Expand source code
def is_proxy(self): return True
def lookupSource(self)
-
Expand source code
def lookupSource(self): if not self.isConnectedToSth(): # Note at this point the anonymous signal does not have a proper # source. return itself as a placeholder until sth. is connected # by calling setequal(). return self else: return self.linkedSignal.lookupSource()
def set_name(self, name)
-
Expand source code
def set_name(self, name): if not self.isConnectedToSth(): # not connected self.nameProposal = name else: self.linkedSignal.lookupSource().set_name(name)
def setequal(self, to: Signal)
-
Expand source code
def setequal(self, to : Signal): if self is to: raise BaseException("Cannot connect to the same signal.") # check if to is a BlockOutputSignal if not isinstance(to.lookupSource(), BlockOutputSignal): raise BaseException("An anonymous signal can only be connected to a block output.") # build a link to the already existing signal 'to' # print("== Created a signal link " + to.name + " == "+ self.name + "") # merge the list of detination blocks for b in self.destinationBlocks: to.destinationBlocks.append(b) # merge self.destinationBlocks into to.destinationBlocks for p in self.destinationPorts: to.destinationPorts.append(p) # merge datatype if self.datatype is not None and not to.datatype: to.setDatatype_nonotitication(self.datatype) # merge name if self.nameProposal is not None and not to.nameIsDefault: # TODO: check if to holds just the default name. If so update it with the proposal to.set_name(self.nameProposal) # overwrite self self.linkedSignal = to
def toStr(self)
-
Expand source code
def toStr(self): string = Signal.toStr(self) if self is self.linkedSignal: string = string + ' (anon.)' return string
Inherited members