def run(self, opts, controlObj): """this function run the simulation by invoking design test function. controlObj is ExecutionControl object that specify how to run the simulation """ assert isinstance(controlObj, ExecutionControl) , \ "Error, [%s] must be instance of ExecutionControl object"%(controlObj) # assembling simulator from its components: self._execControl = controlObj self._eventQ = EventQueue() self._execEngine = ExecutionEngine(self._eventQ, self._execControl) self._simControl = SimulationControl(self._eventQ, self._execControl) if (opts.enableResolveZero) : print "Info: resolve 0 time" self._resolveZeroTime() #print "Info: Event Q debug print\n %s" % (self._eventQ) print "Info: invoke design test function" self._designTest(self._simControl) self._execEngine.run() print "Info: Done" return
class MicroSim(object): """ It exposes simulator's relevant functionality to the user. i.e. load relevant files, set topmost unit names, set test bench main function. """ def __init__(self): """build the simulator object""" self._importedModulesList = [] self._designTop = None #: pointer to top unit of the design self._designTest = None #: pointer to main test function self._execControl = None self._eventQ = None self._execEngine = None self._simControl = None #: will be passed to designTest function self._designPicFileName = DESIGN_PIC_FILE_NAME self._outQue = que.Queue() #: store messages from microSim to any listener #TODO: add input queue in future to control the simulation loop def importModules(self, moduleNameList): """Accept a list of modules to be imported into the simulator. Then the simulator may access (call) any classes / functions in these modules Arguments: - `moduleNameList`: list of all module names that should be loaded """ print "Info: python search path $PYTHONPATH:" for path in os.environ['PYTHONPATH'].split(":"): print "\t%s" % path for moduleName in moduleNameList: print "Info: importing [%s] module" %(moduleName) self._importedModulesList.append(importlib.import_module(moduleName)) def setTopTest(self, functionName): """A name of a function withing an imported modules. This function is the main test bench function that will be invoked by the simulator Arguments: - `functionName`: name of function that drives the design """ self._assertImportedModules() isFound = False for module in self._importedModulesList: try : self._designTest = getattr(module, functionName) isFound = True print 'Info: [%s] found in [%s] module' %(functionName, module) break except AttributeError: pass assert isFound , "Error, function %s was not found" % (functionName) self._assertDesignTest() return def setTopDesign(self, unitReferenceName): """A name of a reference to a topmost unit that's defined in one of the loaded files. Note: it's not unit's Name!!! Arguments: - `unitReferenceName`: name of a reference to a topmost unit. This ref must be of Unit type """ self._assertImportedModules() isFound = False for module in self._importedModulesList: #search in all modules try : self._designTop = getattr(module, unitReferenceName) isFound = True print 'Info: [%s] found in [%s] module'%( unitReferenceName, module) break except AttributeError: pass assert isFound , "Error, unit [%s] was not found" % (unitReferenceName) self._assertDesignTop() return def run(self, opts, controlObj): """this function run the simulation by invoking design test function. controlObj is ExecutionControl object that specify how to run the simulation """ assert isinstance(controlObj, ExecutionControl) , \ "Error, [%s] must be instance of ExecutionControl object"%(controlObj) # assembling simulator from its components: self._execControl = controlObj self._eventQ = EventQueue() self._execEngine = ExecutionEngine(self._eventQ, self._execControl) self._simControl = SimulationControl(self._eventQ, self._execControl) if (opts.enableResolveZero) : print "Info: resolve 0 time" self._resolveZeroTime() #print "Info: Event Q debug print\n %s" % (self._eventQ) print "Info: invoke design test function" self._designTest(self._simControl) self._execEngine.run() print "Info: Done" return def prettyPrintDesign(self): header = ["full path", "type", "num ports", "delay", "value", "host unit"] spacing = " " stack = [self._designTop, 0] while stack: level, unit = stack.pop(), stack.pop() print unit.__str__(spacing*1) # iterate all subunits for subUnit in sorted(unit, reverse=True) : stack.append(subUnit) stack.append(level+1) return def dumpHierachies(self, fileName): fileFullPath = viz.to_gif(fileName, self._designTop) self._outQue.put(("design_pic_update", fileFullPath)) def getMessage(self, block=True, timeout=None): return self._outQue.get(block, timeout) def isEmpty(self): return self._outQue.empty() ############################################################################ def _resolveZeroTime(self): """It traverses all units in the design, starting from the top and invoke the event handler at time 0 to resolve all outputs of these units""" spacing = " " stack = [self._designTop, 0] while stack: level, unit = (stack.pop(), stack.pop()) res = spacing + level*spacing + " {} - {}".format(unit.typeName, unit.name) #skip all non units objects if not isinstance(unit, Unit): continue #create event @ time=0 for all input ports of a unit for port in unit.ports.iterInputPorts(): res += "\n" + spacing + level*spacing + " {}".format(port) e = Event(0, port.value, port.handleEvent) self._eventQ.enque(e) # iterate all subunits for subUnit in sorted(unit, reverse=True) : stack.append(subUnit) stack.append(level+1) print res return ## assertion methods ####################################################### def _assertImportedModules(self): """check if imported modules are set""" assert self._importedModulesList is not None , \ "Error, 'imported modules' must be not None" assert len(self._importedModulesList) > 0 , \ "Error, list of imported modules is empty, " \ "consider checking invocation command" def _assertDesignTop(self): assert self._designTop is not None, \ "Error, 'design top' must be not None" %( self._designTop ) assert isinstance(self._designTop, Unit), \ "Error, [%s] must be instance of Unit" %( self._designTop ) def _assertDesignTest(self): assert self._designTest is not None, \ "Error, 'design test' must be not None" %( self._designTop ) assert hasattr(self._designTest, '__call__'), \ "Error, %s must be callable function" %( self._designTest )