Package empro :: Package toolkit :: Package analysis
[frames] | no frames]

Source Code for Package empro.toolkit.analysis

   1  # Copyright 1983-2019 Keysight Technologies, Inc, Keysight Confidential 
   2  import types 
   3  import warnings 
   4   
   5  import empro 
   6  from empro import _deprecation 
   7  from empro.toolkit import long_path_util 
   8   
   9  if not hasattr(empro.internal,"analysis"): 
  10      empro.internal.analysis = types.ModuleType("empro.internal.analysis") 
  11   
  12  with warnings.catch_warnings(): 
  13      warnings.simplefilter("ignore", DeprecationWarning) 
  14      if not hasattr(empro.internal, "sipi"): 
  15          _deprecation.module_set_deprecated_attr( 
  16              empro.internal, 
  17              "sipi", 
  18              empro.internal.analysis, 
  19              version=410, 
  20              message="Use empro.internal.analysis instead") 
  21   
  22  PIDC, PIAC, PASI, PPR, THERMAL, ELECTRO_THERMAL = 1,2,3,4,5,6 
  23  EMFU, EMUD, EMSM = 7,8,9 
  24  EMFUPE, EMUDPE = 10,11 
  25   
  26  FARZONE_ANGLE_INCREMENT = 5  # [degrees] 
  27  from empro.toolkit import _printexception 
  28   
  29  _minimumPPRFrequency = 1e6 
30 31 -def startEnvironment():
32 import gui 33 gui.initialize() 34 # make vendor components work in command-line simulations 35 if not hasattr(empro.gui, "activeProjectView"): 36 import os 37 os.chdir(os.path.join(os.environ['EMPROHOME'], os.pardir, os.pardir)) 38 try: 39 args = [] 40 baseApp = empro.gui.BaseApp() 41 baseApp.init(args) 42 except: 43 pass
44 45 if not hasattr(empro.internal.analysis,"momentumDir"): 46 empro.internal.analysis.momentumDir = None
47 -def setMomentumDir(momentum_dir):
48 empro.internal.analysis.momentumDir = momentum_dir
49
50 -def loadDesign(**kwargs):
51 import os 52 import empro 53 import empro.toolkit.analysis 54 import json 55 import shutil 56 57 # NOTE!! 58 # we need to modify the initialization 59 # the personality app info should be altered when the type of the view 60 # has been determined and/or reading the content of the setup view file tool 61 # member has been done 62 63 # initialize sipi environment 64 empro.toolkit.analysis.startEnvironment() 65 os.environ["EMPRO_CONE_DIMENSION"]="3" 66 67 # load OA libraries 68 wrkPath = kwargs.get("wrkDirPath", None) 69 if not wrkPath: 70 wrkPath = kwargs.get("path", "") # legacy name 71 hpeesof_dir = kwargs.get("hpeesof_dir", "") 72 if hpeesof_dir: 73 empro.liboa.loadOALibraries(wrkPath, hpeesof_dir) 74 else: 75 empro.liboa.loadOALibraries(wrkPath) 76 libDefAttributes = empro.liboa.getAllLibDefAttributes() 77 for library, attributes in libDefAttributes.iteritems(): 78 for key,value in attributes.iteritems(): 79 if key=="addon_path": 80 import empro.toolkit.addon as addon 81 addon.loadAdditionalAddons(searchDirs=value, forceEnabled=True) 82 83 # handle display.drf 84 drfPath = kwargs.get("drfPath") # full path to some display.drf 85 loadDisplayResourceFiles(wrkPath, drfPath) 86 87 # determine project location 88 setupFile = kwargs.get("libCellViewSetupFilePath", None) 89 oaDesignRefMap = None 90 if setupFile: 91 # first ensure the designrefmap in the setupFile is OK. 92 # -- using a setupfile we are not assured the designrefmap is OK 93 # so we do not need to interfere with the rest of the flow 94 # which assumes a correct designrefmap 95 if not os.path.exists(setupFile): 96 from empro.gui import MessageBox 97 MessageBox.critical( "Load Design", "No such file: " + setupFile, 0, 0 ) 98 return 99 repairInstructions = "" 100 repairDict = kwargs.get("repair_dict", None) 101 if repairDict: 102 repairInstructions = json.dumps(repairDict) 103 try: 104 # oaDesignRefMap = empro.geometry._readAndRepairOaDesignRefMapFromSetupFile(setupFile, repairInstructions) 105 oaDesignRefMap = empro.gui._readAndRepairOaDesignRefMapFromSetupFile(setupFile, repairInstructions) 106 except: 107 from empro.gui import MessageBox 108 import sys 109 msg = str(sys.exc_info()[1]) 110 MessageBox.critical( "Load Design", "Error processing file {}:\n{} ".format(setupFile, msg), 0, 0 ) 111 return 112 113 projectLocation = empro.libCellViewSetupFileProjectLocation(setupFile) 114 lib = projectLocation.lib 115 cell = projectLocation.cell 116 emview = projectLocation.view 117 else: 118 lib = kwargs.get("lib","") 119 cell = kwargs.get("cell","") 120 emview = kwargs.get("sipi_view","sipiSetup") 121 projectLocation = empro.libCellViewProjectLocation(lib, cell, emview) 122 123 if lib.startswith("/"): 124 lib = lib[1:] 125 126 # various initialization 127 empro.simulation.SimulatorSetup.addAvailablePresetsFromOa(lib) 128 empro.VendorPartsDbList.instance()._initUserVendorPartsDb(lib); 129 130 # copy extra files as needed 131 defaultSimDir = empro.simulation.directoryForSimulations(projectLocation, False) 132 legacySimDir = os.path.join("simulation", empro.internal.__fileSystemName(lib, True), empro.internal.__fileSystemName(cell, True), empro.internal.__fileSystemName(emview, True)) 133 extraInputBaseDir = os.path.join(defaultSimDir, "extra") 134 defaultExtraInputDir = os.path.join(extraInputBaseDir, "0") 135 copyFromLegacyLocations = not os.path.exists(extraInputBaseDir) 136 kw_ltd_subst = kwargs.get("ltd_subst","") 137 if kw_ltd_subst: 138 if os.path.exists(kw_ltd_subst): 139 if not os.path.exists(defaultExtraInputDir): os.makedirs(defaultExtraInputDir) 140 shutil.copyfile(kw_ltd_subst, os.path.join(defaultExtraInputDir, "proj.ltd")) 141 elif os.path.exists(os.path.join(defaultExtraInputDir, "proj.ltd")): 142 os.remove(os.path.exists(os.path.join(defaultExtraInputDir, "proj.ltd"))) 143 elif copyFromLegacyLocations: 144 if os.path.exists(os.path.join(defaultSimDir, "proj.ltd")): 145 if not os.path.exists(defaultExtraInputDir): os.makedirs(defaultExtraInputDir) 146 shutil.copyfile(os.path.join(defaultSimDir, "proj.ltd"), os.path.join(defaultExtraInputDir, "proj.ltd")) 147 elif os.path.exists(os.path.join(legacySimDir, "proj.ltd")): 148 if not os.path.exists(defaultExtraInputDir): os.makedirs(defaultExtraInputDir) 149 shutil.copyfile(os.path.join(legacySimDir, "proj.ltd"), os.path.join(defaultExtraInputDir, "proj.ltd")) 150 kw_libS3D = kwargs.get("libS3D","") 151 if kw_libS3D: 152 if os.path.exists(kw_libS3D): 153 if not os.path.exists(defaultExtraInputDir): os.makedirs(defaultExtraInputDir) 154 shutil.copyfile(kw_libS3D, os.path.join(defaultExtraInputDir, "proj_libS3D.xml")) 155 elif os.path.exists(os.path.join(defaultExtraInputDir, "proj_libS3D.xml")): 156 os.remove(os.path.exists(os.path.join(defaultExtraInputDir, "proj_libS3D.xml"))) 157 elif copyFromLegacyLocations: 158 if os.path.exists(os.path.join(defaultSimDir, "proj_libS3D.xml")): 159 if not os.path.exists(defaultExtraInputDir): os.makedirs(defaultExtraInputDir) 160 shutil.copyfile(os.path.join(defaultSimDir, "proj_libS3D.xml"), os.path.join(defaultExtraInputDir, "proj_libS3D.xml")) 161 elif os.path.exists(os.path.join(legacySimDir, "proj_libS3D.xml")): 162 if not os.path.exists(defaultExtraInputDir): os.makedirs(defaultExtraInputDir) 163 shutil.copyfile(os.path.join(legacySimDir, "proj_libS3D.xml"), os.path.join(defaultExtraInputDir, "proj_libS3D.xml")) 164 var_dict = kwargs.get("var_dict") 165 if var_dict is not None: 166 if not os.path.exists(defaultExtraInputDir): os.makedirs(defaultExtraInputDir) 167 with open(os.path.join(defaultExtraInputDir, "varDict.json"), 'w') as outfile: 168 json.dump(var_dict, outfile) 169 expr_dict = kwargs.get("expr_dict") 170 if expr_dict is not None: 171 if not os.path.exists(defaultExtraInputDir): os.makedirs(defaultExtraInputDir) 172 with open(os.path.join(defaultExtraInputDir, "exprDict.json"), 'w') as outfile: 173 json.dump(expr_dict, outfile) 174 175 ## in virtuoso a small comment is written in the file so it will not 176 ## be deleted by the platform ... 177 # check if the project file is existed 178 projectDirectory = projectLocation.directory() 179 sipiViewProjectFile = os.path.join(projectDirectory, "eesof_empro.xml") 180 if not os.path.exists(sipiViewProjectFile): 181 sipiViewProjectFile = os.path.join(projectDirectory, "Project.xml") 182 if os.path.exists(sipiViewProjectFile) and os.path.getsize(sipiViewProjectFile) > 50 : 183 # load the project 184 empro.activeProject.loadActiveProjectFrom(lib, cell, emview) 185 else: 186 # read layout view 187 try: 188 with empro.activeProject as project: 189 sim = project.createSimulationData() 190 sim.engine="FemEngine" 191 project.location = projectLocation 192 if not oaDesignRefMap: 193 oaDesignRefMap = empro.geometry._readOaDesignRefMapFromViewSetup(lib, cell, emview) 194 for key, oaDesignRef in oaDesignRefMap.items(): 195 layout = empro.geometry.OaLayout.readLayoutEx(oaDesignRef, key, extraInputBaseDir) 196 project.geometry().append(layout) 197 project.displayUnits.setPreference(layout.userUnits) 198 defaultName = { empro.analysis.Analysis.DCAnalysisType : "DC Analysis", 199 empro.analysis.Analysis.ACAnalysisType : "AC Analysis", 200 empro.analysis.Analysis.PPRAnalysisType : "PPR Analysis", 201 empro.analysis.Analysis.PASIAnalysisType : "PA-SI Analysis", 202 empro.analysis.Analysis.THAnalysisType : "Thermal Analysis", 203 empro.analysis.Analysis.ETHAnalysisType : "Electro-Thermal Analysis",} 204 205 analysisTypes = [empro.analysis.Analysis.DCAnalysisType, empro.analysis.Analysis.ACAnalysisType, empro.analysis.Analysis.PPRAnalysisType, empro.analysis.Analysis.PASIAnalysisType, empro.analysis.Analysis.THAnalysisType, empro.analysis.Analysis.ETHAnalysisType] 206 207 if "rfpro" in empro.core.ApplicationInfo.personality(): 208 defaultName[empro.analysis.Analysis.EMFUAnalysisType] = "Full EM Analysis" 209 defaultName[empro.analysis.Analysis.EMUDAnalysisType] = "User Defined EM Analysis" 210 analysisTypes = [] 211 analysisTypes.append(empro.analysis.Analysis.EMFUAnalysisType) 212 analysisTypes.append(empro.analysis.Analysis.EMUDAnalysisType) 213 214 if "pepro" in empro.core.ApplicationInfo.personality(): 215 defaultName[empro.analysis.Analysis.EMFUPEAnalysisType] = "Parasitic Extraction-All Nets" 216 defaultName[empro.analysis.Analysis.EMUDPEAnalysisType] = "Parasitic Extraction-Selected Nets" 217 analysisTypes = [] 218 analysisTypes.append(empro.analysis.Analysis.EMFUPEAnalysisType) 219 analysisTypes.append(empro.analysis.Analysis.EMUDPEAnalysisType) 220 221 for index, analysisType in enumerate(analysisTypes): 222 setup = empro.analysis.Analysis() 223 setup.analysisType = analysisType 224 setup.name = defaultName[analysisType] 225 empro.activeProject.analyses.append(setup) 226 project._clearUndoStack() 227 except: 228 from empro.gui import MessageBox 229 import sys 230 msg = str(sys.exc_info()[1]) 231 MessageBox.critical( "Load Project", "The project has failed to load: " + msg, 0, 0 ) 232 233 if hasattr(empro.gui, "activeProjectView"): 234 # handle international characters in emview name 235 emview_utf8 = "Unknown" 236 try: 237 emview_utf8 = emview.decode(encoding='UTF-8', errors='strict') 238 except: 239 pass 240 title = cell + "[*] [" + lib + ":" + cell + ":" + emview_utf8 + "] " + getDisplayName() 241 _updateGui(title) 242 243 # set callback to add ADS components to vendor parts database 244 if hasattr(empro.gui, '_setADSCmptToVendorDBPythonCallback'): 245 try: 246 import empro.toolkit.analysis.schematic_generation as schematic_generation 247 empro.gui._setADSCmptToVendorDBPythonCallback(schematic_generation.addADSComponentInstancesToVendorDB) 248 except: 249 import sys 250 msg = str(sys.exc_info()[1]) 251 print "Failed to set addADSComponentInstancesToVendorDBcallback function:\n", msg 252 253 # activate addons (only in GUI mode) 254 if hasattr(empro, "addons"): 255 # show dock widget with layer visibility settings 256 if hasattr(empro.addons, "LayersDisplay"): 257 try: 258 empro.addons.LayersDisplay.activateDockWidget() 259 except: 260 pass 261 # activate the PDN table view addon 262 if hasattr(empro.addons, "PDNTableView"): 263 try: 264 empro.addons.PDNTableView.activate() 265 except: 266 import sys 267 pass 268 # activate the PDN optimization addon 269 if hasattr(empro.addons, "PDNOptimization_TableView"): 270 try: 271 empro.addons.PDNOptimization_TableView.activate() 272 except: 273 import sys 274 pass 275 # activate the PDN optimization addon 276 if hasattr(empro.addons, "PDNOptimization_MultiModelTableView"): 277 try: 278 empro.addons.PDNOptimization_MultiModelTableView.activate() 279 except: 280 import sys 281 pass
282
283 -def _updateGui(title):
284 if hasattr(empro.gui, "activeProjectView"): 285 pv = empro.gui.activeProjectView() 286 gv = pv.geometryView() 287 # set window title 288 pv.windowTitle = title 289 # update geometry view 290 gv.useCamera("top") 291 pv.showGeometryView() 292 gv.zoomGeometryViewToExtents()
293
294 295 -def getDisplayName():
296 # we should be using appInfo but for that initialization needs to be fixed 297 # app_info = empro.core.ApplicationInfo 298 # return app_info.applicationName(), 299 import empro.core, empro.toolkit.rpc 300 if not empro.core.CommunicationWithParent.wasActivated(): 301 return "(SIPro/PIPro Setup)" 302 isAdsBusy = False 303 try: 304 isAdsBusy = empro.toolkit.rpc.callIsShowingModalOrPopupWidget() 305 except: 306 isAdsBusy = True 307 if isAdsBusy: 308 return "(SIPro/PIPro Setup)" 309 useLegacyCall = False 310 try: 311 displayName = empro.toolkit.rpc.callParent("displayName", [empro.core.ApplicationInfo.personality()] ) 312 except: 313 useLegacyCall = True 314 if useLegacyCall: 315 displayName = empro.toolkit.rpc.callAEL("sipiSetupView_displayName") 316 return "(" + displayName + ")"
317
318 319 -def _removeSimulationForSetup(setup):
320 if not setup.simulationPath: 321 return 322 with empro.activeProject as project: 323 for index, sim in enumerate(project.simulations()): 324 if sim.simulationPath()==setup.simulationPath: 325 del empro.activeProject.simulations()[index] 326 return
327
328 -def _simulationExistsForSetup(setup):
329 with empro.activeProject as project: 330 for index, sim in enumerate(project.simulations()): 331 if sim.simulationPath()==setup.simulationPath: 332 return True 333 return False
334
335 336 -def _createPinHash():
337 pinHash = {} 338 for part in empro.activeProject.geometry().flatList(True): 339 if isinstance(part, empro.geometry.OaLayout): 340 for index in range(part._instanceCount()): 341 inst = part._instance(index) 342 for pi in range(inst.instPinCount()): 343 pin = inst.instPin(pi) 344 fullPinName = inst.name + "." + pin.name 345 pinHash[fullPinName] = pin.uniqueId() 346 for index in range(part._pinCount()): 347 pin = part._pin(index) 348 fullPinName = pin.name 349 pinHash[fullPinName] = pin.uniqueId() 350 return pinHash
351
352 -def _createPinHashWithLayout():
353 pinHash = {} 354 for part in empro.activeProject.geometry().flatList(True): 355 if isinstance(part, empro.geometry.OaLayout): 356 layoutId = part.uniqueId() 357 for index in range(part._instanceCount()): 358 inst = part._instance(index) 359 for pi in range(inst.instPinCount()): 360 pin = inst.instPin(pi) 361 fullPinName = inst.name + "." + pin.name 362 pinHash[(layoutId,fullPinName)] = pin.uniqueId() 363 for index in range(part._pinCount()): 364 pin = part._pin(index) 365 fullPinName = pin.name 366 pinHash[(layoutId,fullPinName)] = pin.uniqueId() 367 return pinHash
368
369 -def _createInstanceHash():
370 instanceHash = {} 371 for part in empro.activeProject.geometry().flatList(True): 372 if isinstance(part, empro.geometry.OaLayout): 373 for i in range(part._instanceCount()): 374 inst = part._instance(i) 375 instanceHash[inst.name] = inst.uniqueId() 376 return instanceHash
377
378 -def _createPinHashPositions():
379 pinHash = {} 380 for part in empro.activeProject.geometry().flatList(True): 381 if isinstance(part, empro.geometry.OaLayout): 382 for index in range(part._instanceCount()): 383 inst = part._instance(index) 384 for pi in range(inst.instPinCount()): 385 pin = inst.instPin(pi) 386 pinHash[pin.uniqueId()] = empro.geometry.CoordinateSystemPosition( pin.dotPosition ) 387 388 for index in range(part._pinCount()): 389 pin = part._pin(index) 390 pinHash[pin.uniqueId()] = empro.geometry.CoordinateSystemPosition( pin.dotPosition ) 391 392 return pinHash
393
394 -def _createPinHashNetName():
395 pinHash = {} 396 for part in empro.activeProject.geometry().flatList(True): 397 if isinstance(part, empro.geometry.OaLayout): 398 for index in range(part._instanceCount()): 399 inst = part._instance(index) 400 for pi in range(inst.instPinCount()): 401 pin = inst.instPin(pi) 402 pinHash[pin.uniqueId()] = pin.netName 403 for index in range(part._pinCount()): 404 pin = part._pin(index) 405 pinHash[pin.uniqueId()] = pin.netName 406 return pinHash
407
408 -def _createPinHashNetType():
409 netNameToType = {} 410 pinHash = {} 411 for part in empro.activeProject.geometry().flatList(True): 412 if isinstance(part, empro.geometry.OaLayout): 413 for net in part._netList(): 414 netNameToType[net.name]=net.type 415 for index in range(part._instanceCount()): 416 inst = part._instance(index) 417 for pi in range(inst.instPinCount()): 418 pin = inst.instPin(pi) 419 pinHash[pin.uniqueId()] = netNameToType.get(pin.netName) 420 for index in range(part._pinCount()): 421 pin = part._pin(index) 422 pinHash[pin.uniqueId()] = netNameToType.get(pin.netName) 423 return pinHash
424
425 -def _createPinHashNetTypeString():
426 intHash = _createPinHashNetType() 427 stringHash = {} 428 for (pinId,netTypeInt) in intHash.iteritems(): 429 if netTypeInt == 1: 430 netTypeString = "sig" 431 elif netTypeInt == 2: 432 netTypeString = "pwr" 433 elif netTypeInt == 4: 434 netTypeString = "gnd" 435 else: 436 netTypeString = "" 437 stringHash[pinId] = netTypeString 438 return stringHash
439
440 @_printexception 441 -def _allNetNames(sipiData):
442 netNames = [] 443 for part in empro.activeProject.geometry().flatList(True): 444 if isinstance(part, empro.geometry.OaLayout): 445 allNetNames = part._netList().getAllNetNames() 446 netNames += allNetNames 447 return netNames
448
449 @_printexception 450 -def _netNamesUsed(sipiData):
451 if sipiData.analysisType in [EMFU, EMFUPE]: 452 usedNetNames = _allNetNames(sipiData) 453 else: 454 usedNetNames = [net.name for net in sipiData.getNetList()] 455 return usedNetNames
456
457 @_printexception 458 -def _netNamesUsedWithLayout(sipiData):
459 usedNetNames = [] 460 if sipiData.analysisType in [empro.analysis.Analysis.EMFUAnalysisType, empro.analysis.Analysis.EMFUPEAnalysisType, empro.analysis.Analysis.THAnalysisType, empro.analysis.Analysis.ETHAnalysisType]: 461 for part in empro.activeProject.geometry().flatList(True): 462 if isinstance(part, empro.geometry.OaLayout): 463 allNetNames = part._netList().getAllNetNames() 464 usedNetNames += [(part.uniqueId(),x) for x in allNetNames] 465 else: 466 usedNetNames = [(net.getParentLayoutUniqueId(), net.name) for net in sipiData.getNetList()] 467 return usedNetNames
468
469 470 @_printexception 471 -def _getNetTypesForUsedNets(sipiData):
472 netTypes = [] 473 usedNetNames = _netNamesUsed(sipiData) 474 for part in empro.activeProject.geometry().flatList(True): 475 if isinstance(part, empro.geometry.OaLayout): 476 netList = part._netList() 477 signalNetNames = netList.getSignalNetNames() 478 powerNetNames = netList.getPowerNetNames() 479 groundNetNames = netList.getGroundNetNames() 480 switchingNetNames = netList.getSwitchingNetNames() 481 for usedNetName in usedNetNames: 482 if usedNetName in signalNetNames: 483 netTypes.append([usedNetName,1]) #=1 # signal net 484 elif usedNetName in powerNetNames: 485 netTypes.append([usedNetName,2]) #=2 # power net 486 elif usedNetName in groundNetNames: 487 netTypes.append([usedNetName,4]) #=4 # ground net 488 elif usedNetName in switchingNetNames: 489 netTypes.append([usedNetName,16]) #=16 # switching net 490 else: 491 netTypes.append([usedNetName,8]) #=8 # undefined net 492 return netTypes
493
494 495 @_printexception 496 -def _pinsUsed(sipiData):
497 usedPins = set() 498 499 thermalComponentGroupList = sipiData.getThermalComponentGroupList() 500 for group in thermalComponentGroupList: 501 for source in group: 502 instance = source.instance() 503 pinNames = [instance.name + "." + pin.name for pin in instance.pins()] 504 [usedPins.add(name) for name in pinNames] 505 for port in sipiData.getVrmList(): 506 [usedPins.add(x.name) for x in port.pins()] 507 if port.hasSenseLine: 508 [usedPins.add(x.name) for x in port.sensePort.pins()] 509 if port.sourceType != 'PackagedVrm': 510 [usedPins.add(x.name) for x in port.upSwitch.pins()] 511 [usedPins.add(x.name) for x in port.lowSwitch.pins()] 512 [usedPins.add(x.name) for x in port.inductor.pins()] 513 for port in sipiData.getSinkList(): 514 [usedPins.add(x.name) for x in port.pins()] 515 for port in sipiData.getPortList(): 516 [usedPins.add(x.name) for x in port.pins()] 517 518 for componentGroup in sipiData.getComponentModelGroupList(): 519 for componentInstance in componentGroup.instances(): 520 for pin in componentInstance.instance().pins(): 521 pinName = componentInstance.instance().name + "." + pin.name 522 usedPins.add(pinName) 523 return usedPins
524
525 @_printexception 526 -def _pinsUsedAsPort(sipiData):
527 usedPins = set() 528 529 thermalComponentGroupList = sipiData.getThermalComponentGroupList() 530 for group in thermalComponentGroupList: 531 for source in group: 532 instance = source.instance() 533 pinNames = [instance.name + "." + pin.name for pin in instance.pins()] 534 [usedPins.add(name) for name in pinNames] 535 for port in sipiData.getVrmList(): 536 [usedPins.add(x.name) for x in port.pins()] 537 if port.hasSenseLine: 538 [usedPins.add(x.name) for x in port.sensePort.pins()] 539 if port.sourceType != 'PackagedVrm': 540 [usedPins.add(x.name) for x in port.upSwitch.pins()] 541 [usedPins.add(x.name) for x in port.lowSwitch.pins()] 542 [usedPins.add(x.name) for x in port.inductor.pins()] 543 for port in sipiData.getSinkList(): 544 [usedPins.add(x.name) for x in port.pins()] 545 for port in sipiData.getPortList(): 546 [usedPins.add(x.name) for x in port.pins()] 547 548 for componentGroup in sipiData.getComponentModelGroupList(): 549 if componentGroup.updateableAfterSimulation: 550 for componentInstance in componentGroup.instances(): 551 for pin in componentInstance.instance().pins(): 552 pinName = componentInstance.instance().name + "." + pin.name 553 usedPins.add(pinName) 554 return usedPins
555
556 @_printexception 557 -def _instanceIdsUsed(sipiData):
558 usedInstanceIds = set() 559 instanceIdMapping = _createInstanceHash() 560 561 thermalComponentGroupList = sipiData.getThermalComponentGroupList() 562 for group in thermalComponentGroupList: 563 for source in group: 564 usedInstanceIds.add(instanceIdMapping[source.instance().name]) 565 for port in sipiData.getVrmList(): 566 for pin in port.pins(): 567 try: 568 usedInstanceIds.add(instanceIdMapping[pin.getInstanceName()]) 569 except KeyError: 570 pass 571 for port in sipiData.getSinkList(): 572 for pin in port.pins(): 573 try: 574 usedInstanceIds.add(instanceIdMapping[pin.getInstanceName()]) 575 except KeyError: 576 pass 577 for port in sipiData.getPortList(): 578 for pin in port.pins(): 579 try: 580 usedInstanceIds.add(instanceIdMapping[pin.getInstanceName()]) 581 except KeyError: 582 pass 583 for componentGroup in sipiData.getComponentModelGroupList(): 584 [usedInstanceIds.add(instanceIdMapping[componentInstance.name]) for componentInstance in componentGroup.instances()] 585 return usedInstanceIds
586
587 @_printexception 588 -def _netNamesUsedByPins(sipiData):
589 usedPins = _pinsUsed(sipiData) 590 591 pinHash = _createPinHash() 592 pinNetNames = _createPinHashNetName() 593 594 names = [] 595 for pinName in usedPins: 596 hashOfPin = pinHash[pinName] 597 names.append( pinNetNames[hashOfPin] ) 598 return set(names)
599
600 @_printexception 601 -def _canonicalNameMultiPort(componentName, portNr):
602 # return the name for the portNr'th port in a componentName port 603 return "%s__%d" % (componentName, portNr)
604
605 @_printexception 606 -def _generateCircuitComponentsForComponentModels(sipiData, pinHash, pinLocations):
607 components = [] 608 import os 609 610 for componentGroup in sipiData.getComponentModelGroupList(): 611 updateableAfterSimulation = componentGroup.updateableAfterSimulation 612 for componentInstance in componentGroup.instances(): 613 component = componentInstance.instance() 614 615 if len(component.pins())<=2: 616 pin1 = component.pins()[0] 617 pin2 = component.pins()[1] 618 pinName1 = component.name + "." + pin1.name 619 pinName2 = component.name + "." + pin2.name 620 621 circuitComponent = empro.components.CircuitComponent() 622 circuitComponent.name = component.name 623 624 if hasattr(circuitComponent, "calibration"): 625 circuitComponent.calibration = "NoCalibration" 626 if updateableAfterSimulation and sipiData.newSimulationData().componentsTreatedAsPorts and sipiData.analysisType != 4: 627 circuitComponent.port = True 628 circuitComponentDefinition = empro.components.Feed() 629 circuitComponentDefinition.name = circuitComponent.name 630 circuitComponentDefinition.impedance.resistance = componentInstance.referenceImpedanceFromPins() 631 circuitComponentDefinition.feedType = "Voltage" 632 circuitComponentDefinition.amplitudeMultiplier = 1 633 circuitComponent.definition = circuitComponentDefinition 634 else: 635 circuitComponent.port = False 636 if len(componentGroup.models()) == 0: 637 raise RuntimeError("No models are defined") 638 componentModel = componentGroup.models()[ componentGroup.defaultModelIndex ] 639 circuitComponentDefinition = componentModel.getPassiveLoad().clone() 640 circuitComponentDefinition.name = circuitComponent.name 641 circuitComponent.definition = circuitComponentDefinition 642 643 assert(len(component.pins())==2) 644 circuitComponent.tail = pin1.dotPosition 645 circuitComponent.head = pin2.dotPosition 646 647 minList = [] 648 plusList = [] 649 plusList.append( empro.components.MultiPinExtentPin(pinName1, pinLocations[pinHash[pinName1]]) ) 650 minList.append( empro.components.MultiPinExtentPin(pinName2, pinLocations[pinHash[pinName2]]) ) 651 circuitExtent = empro.components.MultiPinExtent(minList, plusList) 652 circuitComponent.extent = circuitExtent 653 circuitComponent.useExtent = True #(len(minList)+len(plusList))>2 654 components.append(circuitComponent) 655 else: 656 portMap = componentGroup.pinPortMap() 657 for portNr, minPlusPins in portMap.getPinNamesForPortNumbers(True): 658 circuitComponent = empro.components.CircuitComponent() 659 circuitComponent.name = _canonicalNameMultiPort(component.name, portNr) 660 if sipiData.newSimulationData().componentsTreatedAsPorts and sipiData.analysisType != 4: 661 circuitComponent.port = True 662 circuitComponentDefinition = empro.components.Feed() 663 circuitComponentDefinition.name = circuitComponent.name 664 circuitComponentDefinition.impedance.resistance = componentInstance.referenceImpedanceFromPins() 665 circuitComponentDefinition.feedType = "Voltage" 666 circuitComponentDefinition.amplitudeMultiplier = 1 667 circuitComponent.definition = circuitComponentDefinition 668 else: 669 if not componentGroup._requiresUpdateableAfterSimulation: 670 circuitComponent.port = False 671 if len(componentGroup.models()) == 0: 672 raise RuntimeError("No models are defined") 673 componentModel = componentGroup.models()[ componentGroup.defaultModelIndex ] 674 circuitComponentDefinition = componentModel.getPassiveLoad().clone() 675 circuitComponentDefinition.name = circuitComponent.name 676 circuitComponent.definition = circuitComponentDefinition 677 else: 678 raise RuntimeError("Embedded multiport circuit components not supported") 679 680 minList = [] 681 plusList = [] 682 683 for plusPinName in minPlusPins[0]: 684 pinName1 = component.name + "." + plusPinName 685 plusList.append( empro.components.MultiPinExtentPin(pinName1, pinLocations[pinHash[pinName1]]) ) 686 for minusPinName in minPlusPins[1]: 687 if minusPinName == empro.geometry.OaLayout.getCoverPinName(): 688 continue 689 pinName2 = component.name + "." + minusPinName 690 minList.append( empro.components.MultiPinExtentPin(pinName2, pinLocations[pinHash[pinName2]]) ) 691 692 circuitExtent = empro.components.MultiPinExtent(minList, plusList) if len(minList)>0 else empro.components.MultiPinExtent(plusList) 693 circuitComponent.extent = circuitExtent 694 circuitComponent.useExtent = True #(len(minList)+len(plusList))>2 695 696 circuitComponent.tail = minList[0].position if len(minList) else plusList[0].position 697 circuitComponent.head = plusList[0].position 698 699 components.append(circuitComponent) 700 return components
701
702 @_printexception 703 -def _generateCircuitComponentsForAC(sipiData):
704 # create the pinName to hash mapping 705 import datetime 706 import os 707 708 vrmArePorts = True 709 if "SIPI_AC_VRMS_ARE_NOT_PORTS" in os.environ.keys(): 710 vrmArePorts = False 711 712 pinHash = _createPinHash() 713 pinLocations = _createPinHashPositions() 714 715 lumped = 0 716 vrmList = sipiData.getVrmList() 717 sinkList = sipiData.getSinkList() 718 simPath = sipiData.simulationPath 719 720 components = [] 721 722 def haveAtLeast(x, minimumValue): 723 if float(x)<minimumValue: 724 return minimumValue 725 return x
726 727 for vrm in vrmList: 728 port = vrm 729 730 circuitComponent = empro.components.CircuitComponent() 731 circuitComponent.name = vrm.name 732 # VRM -> Input TermType 733 circuitComponent._termType = empro.components._ettInput 734 if hasattr(circuitComponent, "calibration"): 735 circuitComponent.calibration = "NoCalibration" 736 737 if vrmArePorts: 738 circuitComponentDefinition = empro.components.Feed() 739 if sipiData.analysisType==4: 740 circuitComponentDefinition.impedance.resistance = haveAtLeast(vrm.resistance, 1e-6) 741 else: 742 circuitComponentDefinition.impedance.resistance = haveAtLeast(port.referenceImpedance,1e-6) 743 circuitComponentDefinition.feedType = "Voltage" 744 circuitComponentDefinition.amplitudeMultiplier = 1 745 circuitComponentDefinition.name = circuitComponent.name 746 circuitComponent.definition = circuitComponentDefinition 747 else: 748 circuitComponentDefinition = empro.components.PassiveLoad() 749 circuitComponentDefinition.name = circuitComponent.name 750 circuitComponentDefinition.impedance.resistance = haveAtLeast(vrm.resistance, 1e-6) 751 circuitComponentDefinition.impedance.inductance = vrm.inductance 752 circuitComponentDefinition.impedance.capacitance = 0.0 753 circuitComponent.definition = circuitComponentDefinition 754 755 plusPinNames = [x.name for x in port.plusPins()] 756 minusPinNames = [x.name for x in port.minusPins()] 757 758 minList = [] 759 plusList = [] 760 for pinName in plusPinNames: 761 plusList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 762 for pinName in minusPinNames: 763 minList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 764 765 circuitExtent = empro.components.MultiPinExtent(minList, plusList) 766 circuitComponent.extent = circuitExtent 767 circuitComponent.useExtent = True #(len(minList)+len(plusList))>2 768 circuitComponent.port = vrmArePorts 769 circuitComponent.tail = minList[0].position 770 circuitComponent.head = plusList[0].position 771 components.append(circuitComponent) 772 773 for sink in sinkList: 774 port = sink 775 776 circuitComponent = empro.components.CircuitComponent() 777 # Sink -> Output TermType 778 circuitComponent._termType = empro.components._ettOutput 779 if sink.pinCurrentModel=="EqualCurrent": 780 circuitComponent._pinModel = empro.components._EqualCurrent 781 circuitComponent.name = sink.name 782 if hasattr(circuitComponent, "calibration"): 783 circuitComponent.calibration = "NoCalibration" 784 circuitComponentDefinition = empro.components.Feed() 785 circuitComponentDefinition.name = circuitComponent.name 786 circuitComponentDefinition.feedType = "Current" 787 circuitComponentDefinition.amplitudeMultiplier = 1 #-sink.current 788 if sipiData.analysisType == 4: 789 circuitComponentDefinition.impedance.resistance = haveAtLeast(sink.resistance, 1e-6) 790 else: 791 circuitComponentDefinition.impedance.resistance = haveAtLeast(port.referenceImpedance,1e-6) 792 circuitComponent.definition = circuitComponentDefinition 793 794 plusPinNames = [x.name for x in port.plusPins()] 795 minusPinNames = [x.name for x in port.minusPins()] 796 797 minList = [] 798 plusList = [] 799 for pinName in plusPinNames: 800 plusList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 801 for pinName in minusPinNames: 802 minList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 803 804 circuitExtent = empro.components.MultiPinExtent(minList, plusList) 805 circuitComponent.extent = circuitExtent 806 circuitComponent.useExtent = True #(len(minList)+len(plusList))>2 807 circuitComponent.port = True 808 circuitComponent.tail = minList[0].position 809 circuitComponent.head = plusList[0].position 810 components.append(circuitComponent) 811 812 components += _generateCircuitComponentsForComponentModels(sipiData, pinHash, pinLocations) 813 814 with empro.activeProject as project: 815 project.circuitComponents().clear() 816 project.circuitComponents().appendList(components) 817
818 819 @_printexception 820 -def _generateCircuitComponentsForPASI(sipiData):
821 # create the pinName to hash mapping 822 import datetime 823 import os 824 825 pinHash = _createPinHash() 826 pinLocations = _createPinHashPositions() 827 828 simPath = sipiData.simulationPath 829 830 components = [] 831 832 def haveAtLeast(x, minimumValue): 833 if float(x)<minimumValue: 834 return minimumValue 835 return x
836 837 ioPorts = sipiData.getPortList() 838 for port in ioPorts: 839 circuitComponent = empro.components.CircuitComponent() 840 circuitComponent.name = port.name 841 if hasattr(circuitComponent, "calibration"): 842 circuitComponent.calibration = "NoCalibration" 843 circuitComponentDefinition = empro.components.Feed() 844 circuitComponentDefinition.name = port.name 845 circuitComponentDefinition.feedType = "Current" 846 circuitComponentDefinition.amplitudeMultiplier = 1 #-sink.current 847 circuitComponentDefinition.impedance.resistance = haveAtLeast(port.referenceImpedance, 1e-6) 848 circuitComponent.definition = circuitComponentDefinition 849 circuitComponent._termType = empro.components._ettInputOutput 850 851 plusPinNames = [x.name for x in port.plusPins()] 852 minusPinNames = [x.name for x in port.minusPins()] 853 854 minList = [] 855 plusList = [] 856 for pinName in plusPinNames: 857 plusList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 858 for pinName in minusPinNames: 859 minList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 860 861 circuitExtent = empro.components.MultiPinExtent(minList, plusList) 862 circuitComponent.extent = circuitExtent 863 circuitComponent.useExtent = True #(len(minList)+len(plusList))>2 864 circuitComponent.port = True 865 circuitComponent.tail = minList[0].position 866 circuitComponent.head = plusList[0].position 867 components.append(circuitComponent) 868 869 components += _generateCircuitComponentsForComponentModels(sipiData, pinHash, pinLocations) 870 871 with empro.activeProject as project: 872 project.circuitComponents().clear() 873 project.circuitComponents().appendList(components) 874
875 @_printexception 876 -def _generateCircuitComponentsForEMExtraction(sipiData):
877 # create the pinName to hash mapping 878 import datetime 879 import os 880 881 pinHash = _createPinHash() 882 pinLocations = _createPinHashPositions() 883 884 simPath = sipiData.simulationPath 885 886 components = [] 887 888 def haveAtLeast(x, minimumValue): 889 if float(x)<minimumValue: 890 return minimumValue 891 return x
892 893 ioPorts = sipiData.getPortList() 894 for port in ioPorts: 895 circuitComponent = empro.components.CircuitComponent() 896 circuitComponent.name = port.name 897 if hasattr(circuitComponent, "calibration"): 898 circuitComponent.calibration = "NoCalibration" 899 circuitComponentDefinition = empro.components.Feed() 900 circuitComponentDefinition.name = port.name 901 circuitComponentDefinition.feedType = "Current" 902 circuitComponentDefinition.amplitudeMultiplier = 1 #-sink.current 903 circuitComponentDefinition.impedance.resistance = haveAtLeast(port.referenceImpedance, 1e-6) 904 circuitComponent.definition = circuitComponentDefinition 905 circuitComponent._termType = empro.components._ettInputOutput 906 907 plusPinNames = [x.name for x in port.plusPins()] 908 minusPinNames = [x.name for x in port.minusPins()] 909 910 minList = [] 911 plusList = [] 912 for pinName in plusPinNames: 913 plusList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 914 for pinName in minusPinNames: 915 minList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 916 917 circuitExtent = empro.components.MultiPinExtent(minList, plusList) if len(minList)>0 else empro.components.MultiPinExtent(plusList) 918 circuitComponent.extent = circuitExtent 919 circuitComponent.useExtent = True #(len(minList)+len(plusList))>2 920 circuitComponent.port = True 921 circuitComponent.tail = minList[0].position if len(minList) else plusList[0].position 922 circuitComponent.head = plusList[0].position 923 components.append(circuitComponent) 924 925 components += _generateCircuitComponentsForComponentModels(sipiData, pinHash, pinLocations) 926 927 with empro.activeProject as project: 928 project.circuitComponents().clear() 929 project.circuitComponents().appendList(components) 930
931 932 @_printexception 933 -def _generateCircuitComponentsForEMExtractionWithTouchingPortsReduction(sipiData):
934 935 components = [] 936 937 pinHash = _createPinHash() 938 pinLocations = _createPinHashPositions() 939 940 def _haveAtLeastResistance(x, minimumValue): 941 d = float(x) 942 return str(d if d > minimumValue else minimumValue) + "ohm"
943 944 #### based on _exportPortsToMomEngineData in engine_support/mom/__init__.py 945 portsReduction = empro.analysis.TouchingPortsReduction(sipiData) 946 originalPortsReduction = portsReduction.originalPortsReduction 947 originalPortNames = portsReduction.originalPortNames 948 originalZRefs = portsReduction.originalZRefs 949 emModelReduction = portsReduction.emModelReduction 950 951 def _nextPortInfo(): 952 result = None 953 reducedPortIdx = originalPortsReduction[_nextPortInfo.portIdx] 954 if _nextPortInfo.nextEmIdx < len(emModelReduction) and emModelReduction[_nextPortInfo.nextEmIdx] == reducedPortIdx: 955 result = (originalPortNames[_nextPortInfo.portIdx], originalZRefs[_nextPortInfo.portIdx]) 956 _nextPortInfo.nextEmIdx = _nextPortInfo.nextEmIdx + 1 957 _nextPortInfo.portIdx = _nextPortInfo.portIdx + 1 958 return result 959 960 _nextPortInfo.portIdx = 0 961 _nextPortInfo.nextEmIdx = 0 962 #### 963 964 for port in sipiData.getPortList(): 965 nextPortInfo = _nextPortInfo(); 966 if nextPortInfo: 967 circuitComponent = empro.components.CircuitComponent() 968 circuitComponent.name = port.name 969 if hasattr(circuitComponent, "calibration"): 970 circuitComponent.calibration = "NoCalibration" 971 circuitComponentDefinition = empro.components.Feed() 972 circuitComponentDefinition.name = port.name 973 circuitComponentDefinition.feedType = "Current" 974 circuitComponentDefinition.amplitudeMultiplier = 1 #-sink.current 975 circuitComponentDefinition.impedance.resistance = _haveAtLeastResistance(port.referenceImpedance, 1e-6) 976 circuitComponent.definition = circuitComponentDefinition 977 circuitComponent._termType = empro.components._ettInputOutput 978 circuitComponent._portFeedType = port.feedType 979 980 plusPinNames = [x.name for x in port.plusPins()] 981 minusPinNames = [x.name for x in port.minusPins()] 982 983 minList = [] 984 plusList = [] 985 for pinName in plusPinNames: 986 plusList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 987 for pinName in minusPinNames: 988 minList.append( empro.components.MultiPinExtentPin(pinName, pinLocations[pinHash[pinName]]) ) 989 990 circuitExtent = empro.components.MultiPinExtent(minList, plusList) if len(minList)>0 else empro.components.MultiPinExtent(plusList) 991 circuitComponent.extent = circuitExtent 992 circuitComponent.useExtent = True #(len(minList)+len(plusList))>2 993 circuitComponent.port = True 994 circuitComponent.tail = minList[0].position if len(minList) else plusList[0].position 995 circuitComponent.head = plusList[0].position 996 components.append(circuitComponent) 997 998 for componentGroup in sipiData.getComponentModelGroupList(): 999 pinPortMap = componentGroup.pinPortMap() 1000 ignoreNonUsedPorts = True 1001 ports = pinPortMap.getPinNamesForPortNumbers(ignoreNonUsedPorts) 1002 for componentInstance in componentGroup.instances(): 1003 component = componentInstance.instance() 1004 for (portNr, (plusPins, minusPins)) in ports: 1005 nextPortInfo = _nextPortInfo(); 1006 if nextPortInfo: 1007 circuitComponent = empro.components.CircuitComponent() 1008 circuitComponent.name = _canonicalNameMultiPort(component.name, portNr) 1009 if sipiData.newSimulationData().componentsTreatedAsPorts: 1010 circuitComponent.port = True 1011 circuitComponentDefinition = empro.components.Feed() 1012 circuitComponentDefinition.name = circuitComponent.name 1013 circuitComponentDefinition.impedance.resistance = str(componentInstance.referenceImpedanceFromPins()) + "ohm" 1014 circuitComponentDefinition.feedType = "Voltage" 1015 circuitComponentDefinition.amplitudeMultiplier = 1 1016 circuitComponent.definition = circuitComponentDefinition 1017 circuitComponent._componentPort = True 1018 circuitComponent._deEmbeddingType = componentGroup.deEmbeddingType 1019 else: 1020 circuitComponent.port = False 1021 if len(componentGroup.models()) == 0: 1022 raise RuntimeError("No models are defined") 1023 componentModel = componentGroup.models()[ componentGroup.defaultModelIndex ] 1024 circuitComponentDefinition = componentModel.getPassiveLoad().clone() 1025 circuitComponentDefinition.name = circuitComponent.name 1026 circuitComponent.definition = circuitComponentDefinition 1027 1028 minList = [] 1029 plusList = [] 1030 1031 for plusPinName in plusPins: 1032 pinName1 = component.name + "." + plusPinName 1033 plusList.append( empro.components.MultiPinExtentPin(pinName1, pinLocations[pinHash[pinName1]]) ) 1034 for minusPinName in minusPins: 1035 if minusPinName == empro.geometry.OaLayout.getCoverPinName(): 1036 continue 1037 pinName2 = component.name + "." + minusPinName 1038 minList.append( empro.components.MultiPinExtentPin(pinName2, pinLocations[pinHash[pinName2]]) ) 1039 1040 circuitExtent = empro.components.MultiPinExtent(minList, plusList) if len(minList)>0 else empro.components.MultiPinExtent(plusList) 1041 circuitComponent.extent = circuitExtent 1042 circuitComponent.useExtent = True #(len(minList)+len(plusList))>2 1043 1044 circuitComponent.tail = minList[0].position if len(minList) else plusList[0].position 1045 circuitComponent.head = plusList[0].position 1046 1047 components.append(circuitComponent) 1048 1049 1050 with empro.activeProject as project: 1051 project.circuitComponents().clear() 1052 project.circuitComponents().appendList(components) 1053
1054 1055 -def copyCommonSimulationData(sipiData):
1056 # Copies the simulation settings (common to all analysis types) from the sipi setup to the global new simulation data. 1057 simData = empro.activeProject.createSimulationData() 1058 sipiSimData = sipiData.newSimulationData() 1059 1060 simData.name = sipiData.name 1061 simData.engine = sipiSimData.engine 1062 1063 simData.femMeshSettings.resolution = sipiSimData.femMeshSettings.resolution 1064 simData.femMeshSettings.arcResolution = sipiSimData.femMeshSettings.arcResolution 1065 simData.femMeshSettings.minimumNumberOfPasses = sipiSimData.femMeshSettings.minimumNumberOfPasses 1066 simData.femMeshSettings.maximumNumberOfPasses = sipiSimData.femMeshSettings.maximumNumberOfPasses 1067 simData.femMeshSettings.autoTargetMeshSize = sipiSimData.femMeshSettings.autoTargetMeshSize 1068 simData.femMeshSettings.useTargetMeshSize = sipiSimData.femMeshSettings.useTargetMeshSize 1069 simData.femMeshSettings.targetMeshSize = sipiSimData.femMeshSettings.targetMeshSize 1070 1071 simData.femMeshSettings.autoConductorMeshing = sipiSimData.femMeshSettings.autoConductorMeshing 1072 simData.femMeshSettings.autoConductorMeshingEdges = sipiSimData.femMeshSettings.autoConductorMeshingEdges 1073 simData.femMeshSettings.autoConductorMeshingVertices = sipiSimData.femMeshSettings.autoConductorMeshingVertices 1074 simData.femMeshSettings.autoConductorMeshingEdgeFactor = sipiSimData.femMeshSettings.autoConductorMeshingEdgeFactor 1075 simData.femMeshSettings.autoConductorMeshingVertexFactor = sipiSimData.femMeshSettings.autoConductorMeshingVertexFactor 1076 simData.femMeshSettings.edgeMeshLength = sipiSimData.femMeshSettings.edgeMeshLength 1077 simData.femMeshSettings.vertexMeshLength = sipiSimData.femMeshSettings.vertexMeshLength 1078 1079 simData.femMeshSettings.deltaError = sipiSimData.femMeshSettings.deltaError 1080 simData.sParametersEnabled = sipiSimData.sParametersEnabled 1081 simData.femMeshSettings.orderOfBasisFunctions = sipiSimData.femMeshSettings.orderOfBasisFunctions 1082 simData.femMatrixSolver.solverType = sipiSimData.femMatrixSolver.solverType 1083 simData.portOnlyMode = sipiSimData.portOnlyMode 1084 simData.componentsTreatedAsPorts = sipiSimData.componentsTreatedAsPorts 1085 simData.femMeshSettings.includeResistiveLossesInGround = sipiSimData.femMeshSettings.includeResistiveLossesInGround 1086 simData.femMeshSettings.includeResistiveLossesInGroundAndPower = sipiSimData.femMeshSettings.includeResistiveLossesInGroundAndPower 1087 simData.femMeshSettings.useMeshDomainOptimization = sipiSimData.femMeshSettings.useMeshDomainOptimization 1088 simData.femMeshSettings.useFemDomainSplitting = sipiSimData.femMeshSettings.useFemDomainSplitting 1089 simData.femMeshSettings.useResolution = sipiSimData.femMeshSettings.useResolution 1090 1091 simData.vemMatrixSolver = sipiSimData.vemMatrixSolver 1092 1093 simData.coplanarGroundModel = sipiSimData.coplanarGroundModel 1094 simData.viaModel = sipiSimData.viaModel 1095 simData.resourceSettings = sipiSimData.resourceSettings 1096 1097 simData.ambientConditions = sipiSimData.ambientConditions 1098 1099 simData.saveFieldsFor = sipiSimData.saveFieldsFor 1100 simData.femMeshSettings.refinementStrategy = sipiSimData.femMeshSettings.refinementStrategy 1101 simData.femMeshSettings.refinementFrequency = sipiSimData.femMeshSettings.refinementFrequency 1102 sourceFreqPlanList = sipiSimData.femMeshSettings.refinementFrequencyPlan 1103 destFreqPlanList = simData.femMeshSettings.refinementFrequencyPlan 1104 destFreqPlanList.clear() 1105 for plan in sourceFreqPlanList: 1106 destFreqPlanList.append(plan) 1107 1108 simData.femMeshSettings.refineAtSpecificFrequency = sipiSimData.femMeshSettings.refineAtSpecificFrequency
1109
1110 1111 -def copySimulatorSetupData(sipiData):
1112 # Copies the simulator setup from the sipi setup to the global new simulation data. 1113 simData = empro.activeProject.createSimulationData() 1114 sipiSimData = sipiData.newSimulationData() 1115 1116 simData.name = sipiData.name 1117 1118 simData.engine = sipiSimData.engine 1119 1120 simData.femMeshSettings = sipiSimData.femMeshSettings 1121 simData.femEigenSolverSettings = sipiSimData.femEigenSolverSettings 1122 simData.femMatrixSolver = sipiSimData.femMatrixSolver 1123 simData.femPerLayerOverrides = sipiSimData.femPerLayerOverrides 1124 simData.momPhysModel = sipiSimData.momPhysModel 1125 simData.momMeshSettings = sipiSimData.momMeshSettings 1126 simData.momMatrixSolver = sipiSimData.momMatrixSolver 1127 simData.momPerLayerOverrides = sipiSimData.momPerLayerOverrides 1128 simData.momPerNetOverrides = sipiSimData.momPerNetOverrides 1129 simData.momExpertSettings = sipiSimData.momExpertSettings 1130 simData.preprocessorSettings = sipiSimData.preprocessorSettings 1131 simData.vemMatrixSolver = sipiSimData.vemMatrixSolver 1132 1133 simData.preset = sipiSimData.preset 1134 1135 simData.sParametersEnabled = sipiSimData.sParametersEnabled 1136 simData.portOnlyMode = sipiSimData.portOnlyMode 1137 simData.componentsTreatedAsPorts = sipiSimData.componentsTreatedAsPorts 1138 simData.vemMatrixSolver = sipiSimData.vemMatrixSolver 1139 simData.coplanarGroundModel = sipiSimData.coplanarGroundModel 1140 simData.viaModel = sipiSimData.viaModel 1141 simData.resourceSettings = sipiSimData.resourceSettings 1142 simData.ambientConditions = sipiSimData.ambientConditions 1143 simData.saveFieldsFor = sipiSimData.saveFieldsFor 1144 1145 # in RFPro we need to copy the far zone sensor data 1146 simData.farFieldEnabled = sipiSimData.farFieldEnabled 1147 simData.farFieldAngularResolution = sipiSimData.farFieldAngularResolution
1148
1149 1150 -def runEMExtractionSimulationFlow(sipiData, waitForConfirmation=True, saveProject=False):
1151 import os 1152 import empro 1153 # (mom) solver generates its inputfiles from sipiDataToUseForSimulation 1154 empro.internal.analysis.sipiDataToUseForSimulation = sipiData 1155 pl = empro.activeProject.parameters() 1156 startFreq = pl.formula("minFreq") 1157 endFreq = pl.formula("maxFreq") 1158 1159 # customization event subscribeRunBeforeSimulationCreation 1160 sipiData._invokePublishRunBeforeSimulationCreation() 1161 1162 copySimulatorSetupData(sipiData) 1163 1164 simData = empro.activeProject.createSimulationData() 1165 sipiSimData = sipiData.newSimulationData() 1166 1167 simData.componentsTreatedAsPorts = True 1168 1169 bc = empro.activeProject.boundaryConditions() 1170 boundaryType = "Absorbing" 1171 xyBoundaryType = "Absorbing" 1172 bc.xLowerBoundaryType = xyBoundaryType 1173 bc.xUpperBoundaryType = xyBoundaryType 1174 bc.yLowerBoundaryType = xyBoundaryType 1175 bc.yUpperBoundaryType = xyBoundaryType 1176 bc.zLowerBoundaryType = boundaryType 1177 bc.zUpperBoundaryType = boundaryType 1178 1179 #copy fp plans 1180 simData.femFrequencyPlanList().clear() 1181 for fpi in range(len(sipiSimData.femFrequencyPlanList())): 1182 fp = sipiSimData.femFrequencyPlanList()[fpi] 1183 if not fp.enabled: 1184 continue 1185 if fp.type == "Automatic": 1186 realStartF, stopF = fp.startFrequency, fp.stopFrequency 1187 realStartF = max(realStartF, 20000.0) 1188 startF = max([realStartF, 2.0e6]) # up to 2 Mhz we do a linear sweep 1189 highestRecommendedFreqAfs = sipiData._highestAdaptiveFrequencyForSI() 1190 highestRecommendedFreqAfs = int(highestRecommendedFreqAfs/1000.0)*1000.0 1191 newFrequencyPlans = [] 1192 if startF<highestRecommendedFreqAfs: 1193 # start with the adaptive part 1194 newFp = empro.simulation.FrequencyPlan() 1195 newFp.type = "Adaptive" 1196 newFp.startFrequency = startF 1197 newFp.stopFrequency = min([highestRecommendedFreqAfs,stopF]) 1198 newFp.numberOfFrequencyPoints = fp.numberOfFrequencyPoints 1199 newFp.samplePointsLimit = fp.samplePointsLimit 1200 newFp.enabled = fp.enabled 1201 newFrequencyPlans.append(newFp) 1202 1203 if stopF>highestRecommendedFreqAfs: 1204 electricalLength = (sipiData._largestNetLength()*2.0/3e8)*float(stopF) 1205 1206 newFp = empro.simulation.FrequencyPlan() 1207 newFp.type = "Linear" 1208 newFp.startFrequency = max([startF,highestRecommendedFreqAfs]) 1209 newFp.stopFrequency = stopF 1210 newFp.numberOfFrequencyPoints = int(10.0*(electricalLength)*((stopF-highestRecommendedFreqAfs)/(1.0+stopF))+1)+1 1211 newFp.enabled = fp.enabled 1212 newFrequencyPlans.append(newFp) 1213 1214 if realStartF<startF: 1215 newFp = empro.simulation.FrequencyPlan() 1216 newFp.type = "Linear" 1217 newFp.startFrequency = realStartF 1218 newFp.stopFrequency = startF 1219 newFp.numberOfFrequencyPoints = 2 1220 newFp.enabled = fp.enabled 1221 newFrequencyPlans.append(newFp) 1222 1223 for fp in newFrequencyPlans: 1224 simData.femFrequencyPlanList().append(fp) 1225 1226 elif fp.type == "SMPS": 1227 newFrequencyPlans = _generateSMPSFreqPlan(fp) 1228 if not newFrequencyPlans: 1229 raise RuntimeError("SMPS frequency plan is invalid") 1230 for fp1 in newFrequencyPlans: 1231 simData.femFrequencyPlanList().append(fp1) 1232 1233 else: 1234 fp = fp.clone() 1235 1236 if fp.type=="Automatic": 1237 raise RuntimeError("Automatic Frequency plans are not supported") 1238 simData.femFrequencyPlanList().append(fp) 1239 1240 import empro.toolkit.analysis as sipi 1241 with empro.activeProject as project: 1242 project.farZoneSensors().clear() 1243 if sipiSimData.farFieldEnabled and simData.saveFieldsFor!="NoFrequencies": 1244 import math 1245 rad = math.pi / 180.0 1246 project.circuitComponentDefinitions().clear() 1247 farzoneSensor = empro.sensor.FarZoneSensor() 1248 farzoneSensor.angle1Start = 0.0 1249 farzoneSensor.angle1Increment = max(0.1, sipiSimData.farFieldAngularResolution * rad) 1250 farzoneSensor.angle1Stop = math.pi 1251 farzoneSensor.angle2Start = 0.0 1252 farzoneSensor.angle2Increment = max(0.1, sipiSimData.farFieldAngularResolution * rad) 1253 farzoneSensor.angle2Stop = math.pi * 2.0 1254 project.farZoneSensors().append(farzoneSensor) 1255 1256 sipi._generateCircuitComponentsForEMExtractionWithTouchingPortsReduction(sipiData) 1257 1258 existingPath = sipiData.simulationPath 1259 if existingPath and os.path.exists(existingPath): 1260 if waitForConfirmation: 1261 import empro.gui 1262 continueSimulating = empro.gui.MessageBox.question("Existing Results Found", "Previous simulation results exist and will be overwritten.\nWould you still like to continue?", 16384 + 65536, 16384) == 16384 1263 if not continueSimulating: 1264 return 1265 1266 import pyfemPlugin as pyfemPost 1267 pyfemPost.removeOptionManager(os.path.join(existingPath,"emds_dsn","design")) 1268 optionsXml = os.path.join(existingPath,"emds_dsn","design","options.xml") 1269 if os.path.exists(long_path_util.resolveLongPath(optionsXml)): 1270 os.remove(long_path_util.resolveLongPath(optionsXml)) 1271 1272 _removeSimulationForSetup(sipiData) 1273 sim = empro.activeProject.createSimulationEx(True, False, existingPath) 1274 else: 1275 sim = empro.activeProject.createSimulationEx(True, False, "") 1276 sipiData.simulationPath = sim.simulationPath() 1277 1278 # customization event subscribeRunAfterSimulationCreation 1279 sipiData._invokePublishRunAfterSimulationCreation(sim) 1280 1281 # save project so not to dismiss the created simulation path if requested 1282 if saveProject: 1283 empro.activeProject.saveActiveProject() 1284 elif hasattr(empro.gui, "activeProjectView"): 1285 empro.gui._projectUpdatedNoUndo() 1286 1287 # Set the cti file directory 1288 ctiDir = sipiData.simulationPath 1289 try: 1290 ctiDir = os.path.join(sipiData.simulationPath, "emds_dsn", "design") 1291 if not os.path.exists(ctiDir): 1292 os.makedirs(ctiDir) 1293 except EnvironmentError as error: 1294 ctiDirTmp = os.path.join(existingPath,"emds_dsn","design") 1295 if not os.path.exists(ctiDirTmp): 1296 ctiDir = sipiData.simulationPath 1297 1298 try: 1299 import os 1300 os.remove(os.path.join(sipiData.simulationPath,"emds_dsn","design",".next_solver_id")) 1301 except OSError: 1302 pass 1303 1304 sipiData._saveComponentHashes() 1305 1306 # Write ports list to file 1307 portList = [] 1308 index = 0 1309 circuitComponents = empro.activeProject.circuitComponents() 1310 for ci in range(len(circuitComponents)): 1311 # get the circuit component by index 1312 circComp = circuitComponents[ci] 1313 portList.append((circComp.name, circComp._termType, index)) 1314 index = index+1 1315 with open(os.path.join(ctiDir, "ports.txt"), "w") as portsFile: 1316 for port in portList: 1317 portsFile.write("%s,%d,%d\n" % (port[0], port[1], port[2])) 1318 1319 if hasattr(empro.gui, "activeProjectView"): 1320 pv = empro.gui.activeProjectView() 1321 pv.showSimulationQueueView()
1322
1323 1324 -def runDCSimulationFlow(sipiData, waitForConfirmation=True, saveProject=False):
1325 import os 1326 import empro 1327 # (mom) solver generates its inputfiles from sipiDataToUseForSimulation 1328 empro.internal.analysis.sipiDataToUseForSimulation = sipiData 1329 if hasattr(empro.gui, "activeProjectView"): 1330 pv = empro.gui.activeProjectView() 1331 pv.showSimulationQueueView() 1332 1333 # customization event subscribeRunBeforeSimulationCreation 1334 sipiData._invokePublishRunBeforeSimulationCreation() 1335 1336 copyCommonSimulationData(sipiData) 1337 simData = empro.activeProject.createSimulationData() 1338 1339 simData.engine = "VemEngine" 1340 existingPath = sipiData.simulationPath 1341 1342 import pyfemPlugin as pyfemPost 1343 pyfemPost.removeOptionManager(existingPath) 1344 optionsXml = os.path.join(existingPath,"options.xml") 1345 if os.path.exists(long_path_util.resolveLongPath(optionsXml)): 1346 os.remove(long_path_util.resolveLongPath(optionsXml)) 1347 solverOptionsFile = os.path.join(existingPath,"design.opt") 1348 if os.path.exists(long_path_util.resolveLongPath(solverOptionsFile)): 1349 os.remove(long_path_util.resolveLongPath(solverOptionsFile)) 1350 1351 if existingPath and os.path.exists(long_path_util.resolveLongPath(existingPath)): 1352 if waitForConfirmation: 1353 import empro.gui 1354 continueSimulating = empro.gui.MessageBox.question("Existing Results Found", "Previous simulation results exist and will be overwritten.\nWould you still like to continue?", 16384 + 65536, 16384) == 16384 1355 if not continueSimulating: 1356 return 1357 1358 _removeSimulationForSetup(sipiData) 1359 sim = empro.activeProject.createSimulationEx(False, False, existingPath) 1360 else: 1361 sim = empro.activeProject.createSimulationEx(False, False, "") 1362 sipiData.simulationPath = sim.simulationPath() 1363 1364 # customization event subscribeRunAfterSimulationCreation 1365 sipiData._invokePublishRunAfterSimulationCreation(sim) 1366 1367 # save project so not to dismiss the created simulation path if requested 1368 if saveProject: 1369 empro.activeProject.saveActiveProject() 1370 elif hasattr(empro.gui, "activeProjectView"): 1371 empro.gui._projectUpdatedNoUndo() 1372 1373 # generate solver options 1374 solverOptions = "\nOptFile 1.0" 1375 solverType = {"Auto":0, "Direct":1, "Iterative":2}.get(simData.vemMatrixSolver.solveMatrixType, 0) 1376 solverOptions += "\nElectric.solver: %d" % solverType 1377 solverOptions += "\nThermal.solver: %d" % solverType 1378 with open(long_path_util.resolveLongPath(os.path.join(sipiData.simulationPath,"design.opt")),"w") as optionsFile: 1379 optionsFile.write(solverOptions) 1380 1381 # generate the mesh options 1382 import math 1383 resolution = float(simData.femMeshSettings.resolution) 1384 useResolution = simData.femMeshSettings.useResolution 1385 edgeMaxAngle = float(simData.femMeshSettings.arcResolution)*180.0/math.pi 1386 useTargetMesh = str(simData.femMeshSettings.useTargetMeshSize) 1387 targetMeshSize = float(simData.femMeshSettings.targetMeshSize) 1388 numberOfThreads = simData.resourceSettings.numberOfThreads 1389 1390 engine = "VemEngine" 1391 if sipiData.analysisType in [THERMAL, ELECTRO_THERMAL]: 1392 engine = "VemEngineThermal" 1393 if sipiData.analysisType in [ELECTRO_THERMAL]: 1394 engine = "VemEngineElectroThermal" 1395 1396 optionsText = r"""<!DOCTYPE OptionsFile> 1397 <OptionFile version="1" creator="sipro"> 1398 <mesh> 1399 <option> 1400 <name>resolution</name> 1401 <initialValue>1e-6</initialValue> 1402 <value>%(resolution)15.15f</value> 1403 </option> 1404 <option> 1405 <name>useResolution</name> 1406 <initialValue>0</initialValue> 1407 <value>%(useResolution)d</value> 1408 </option> 1409 <option> 1410 <name>edgeMaxAngle</name> 1411 <initialValue>60</initialValue> 1412 <value>%(edgeMaxAngle)f</value> 1413 </option> 1414 <option> 1415 <name>useTargetMeshSize</name> 1416 <initialValue>False</initialValue> 1417 <value>%(useTargetMesh)s</value> 1418 </option> 1419 <option> 1420 <name>targetMeshSize</name> 1421 <initialValue>100 um</initialValue> 1422 <value>%(targetMeshSize)f</value> 1423 </option> 1424 </mesh> 1425 <general> 1426 <option> 1427 <name>engine</name> 1428 <initialValue>FemEngine</initialValue> 1429 <value>%(engine)s</value> 1430 </option> 1431 <option> 1432 <name>NB_THREADS</name> 1433 <initialValue>0</initialValue> 1434 <value>%(numberOfThreads)d</value> 1435 </option> 1436 </general> 1437 </OptionFile>""" % vars() 1438 with open(long_path_util.resolveLongPath(os.path.join(sipiData.simulationPath,"options.xml")),"w") as optionsFile: 1439 optionsFile.write(optionsText) 1440 1441 simLength = len(empro.activeProject.simulations()) 1442 for simNr in range(simLength): 1443 simFromList = empro.activeProject.simulations()[simLength-simNr-1] 1444 if simFromList.simulationPath()==sim.simulationPath(): 1445 simFromList.setQueued(True) 1446 break 1447 sipiData._saveComponentHashes()
1448
1449 1450 -def runPASISimulationFlow(sipiData, waitForConfirmation=True, saveProject=False):
1451 import os 1452 import empro 1453 # (mom) solver generates its inputfiles from sipiDataToUseForSimulation 1454 empro.internal.analysis.sipiDataToUseForSimulation = sipiData 1455 pl = empro.activeProject.parameters() 1456 startFreq = pl.formula("minFreq") 1457 endFreq = pl.formula("maxFreq") 1458 1459 copyCommonSimulationData(sipiData) 1460 1461 # customization event subscribeRunBeforeSimulationCreation 1462 sipiData._invokePublishRunBeforeSimulationCreation() 1463 1464 simData = empro.activeProject.createSimulationData() 1465 sipiSimData = sipiData.newSimulationData() 1466 1467 simData.componentsTreatedAsPorts = True 1468 1469 bc = empro.activeProject.boundaryConditions() 1470 boundaryType = "Absorbing" 1471 xyBoundaryType = "Absorbing" 1472 bc.xLowerBoundaryType = xyBoundaryType 1473 bc.xUpperBoundaryType = xyBoundaryType 1474 bc.yLowerBoundaryType = xyBoundaryType 1475 bc.yUpperBoundaryType = xyBoundaryType 1476 bc.zLowerBoundaryType = boundaryType 1477 bc.zUpperBoundaryType = boundaryType 1478 1479 #copy fp plans 1480 simData.femFrequencyPlanList().clear() 1481 for fpi in range(len(sipiSimData.femFrequencyPlanList())): 1482 fp = sipiSimData.femFrequencyPlanList()[fpi] 1483 if not fp.enabled: 1484 continue 1485 if fp.type == "Automatic": 1486 realStartF, stopF = fp.startFrequency, fp.stopFrequency 1487 realStartF = max(realStartF, 20000.0) 1488 startF = max([realStartF, 2.0e6]) # up to 2 Mhz we do a linear sweep 1489 highestRecommendedFreqAfs = sipiData._highestAdaptiveFrequencyForSI() 1490 highestRecommendedFreqAfs = int(highestRecommendedFreqAfs/1000.0)*1000.0 1491 newFrequencyPlans = [] 1492 if startF<highestRecommendedFreqAfs: 1493 # start with the adaptive part 1494 newFp = empro.simulation.FrequencyPlan() 1495 newFp.type = "Adaptive" 1496 newFp.startFrequency = startF 1497 newFp.stopFrequency = min([highestRecommendedFreqAfs,stopF]) 1498 newFp.numberOfFrequencyPoints = fp.numberOfFrequencyPoints 1499 newFp.samplePointsLimit = fp.samplePointsLimit 1500 newFp.enabled = fp.enabled 1501 newFrequencyPlans.append(newFp) 1502 1503 if stopF>highestRecommendedFreqAfs: 1504 electricalLength = (sipiData._largestNetLength()*2.0/3e8)*float(stopF) 1505 1506 newFp = empro.simulation.FrequencyPlan() 1507 newFp.type = "Linear" 1508 newFp.startFrequency = max([startF,highestRecommendedFreqAfs]) 1509 newFp.stopFrequency = stopF 1510 newFp.numberOfFrequencyPoints = int(10.0*(electricalLength)*((stopF-highestRecommendedFreqAfs)/(1.0+stopF))+1)+1 1511 newFp.enabled = fp.enabled 1512 newFrequencyPlans.append(newFp) 1513 1514 if realStartF<startF: 1515 newFp = empro.simulation.FrequencyPlan() 1516 newFp.type = "Linear" 1517 newFp.startFrequency = realStartF 1518 newFp.stopFrequency = startF 1519 newFp.numberOfFrequencyPoints = 2 1520 newFp.enabled = fp.enabled 1521 newFrequencyPlans.append(newFp) 1522 1523 for fp in newFrequencyPlans: 1524 simData.femFrequencyPlanList().append(fp) 1525 else: 1526 fp = fp.clone() 1527 1528 if fp.type=="Automatic": 1529 raise RuntimeError("Automatic Frequency plans are not supported") 1530 simData.femFrequencyPlanList().append(fp) 1531 1532 import empro.toolkit.analysis as sipi 1533 with empro.activeProject as project: 1534 project.circuitComponentDefinitions().clear() 1535 1536 sipi._generateCircuitComponentsForPASI(sipiData) 1537 1538 existingPath = sipiData.simulationPath 1539 if existingPath and os.path.exists(existingPath): 1540 if waitForConfirmation: 1541 import empro.gui 1542 continueSimulating = empro.gui.MessageBox.question("Existing Results Found", "Previous simulation results exist and will be overwritten.\nWould you still like to continue?", 16384 + 65536, 16384) == 16384 1543 if not continueSimulating: 1544 return 1545 1546 _removeSimulationForSetup(sipiData) 1547 sim = empro.activeProject.createSimulationEx(True, False, existingPath) 1548 else: 1549 sim = empro.activeProject.createSimulationEx(True, False, "") 1550 sipiData.simulationPath = sim.simulationPath() 1551 1552 try: 1553 import os 1554 os.remove(os.path.join(existingPath,"emds_dsn","design",".next_solver_id")) 1555 except OSError: 1556 pass 1557 1558 # save project so not to dismiss the created simulation path if requested 1559 if saveProject: 1560 empro.activeProject.saveActiveProject() 1561 elif hasattr(empro.gui, "activeProjectView"): 1562 empro.gui._projectUpdatedNoUndo() 1563 1564 # Set the cti file directory 1565 ctiDir = sipiData.simulationPath 1566 try: 1567 ctiDir = os.path.join(sipiData.simulationPath, "emds_dsn", "design") 1568 if not os.path.exists(long_path_util.resolveLongPath(ctiDir)): 1569 os.makedirs(long_path_util.resolveLongPath(ctiDir)) 1570 except EnvironmentError as error: 1571 ctiDirTmp = os.path.join(existingPath,"emds_dsn","design") 1572 if not os.path.exists(long_path_util.resolveLongPath(ctiDirTmp)): 1573 ctiDir = sipiData.simulationPath 1574 1575 sipiData._saveComponentHashes() 1576 1577 # Write ports list to file 1578 with open(long_path_util.resolveLongPath(os.path.join(ctiDir, "ports.txt")), "w") as portsFile: 1579 portList = [] 1580 index = 0 1581 circuitComponents = empro.activeProject.circuitComponents() 1582 for ci in range(len(circuitComponents)): 1583 # get the circuit component by index 1584 circComp = circuitComponents[ci] 1585 portList.append((circComp.name, circComp._termType, index)) 1586 index = index+1 1587 for port in portList: 1588 portsFile.write("%s,%d,%d\n" % (port[0], port[1], port[2])) 1589 1590 ioPortList = sipiData.getPortList() 1591 _writePortPinInformation(ioPortList, ctiDir) 1592 1593 # customization event subscribeRunAfterSimulationCreation 1594 sipiData._invokePublishRunAfterSimulationCreation(sim) 1595 1596 if hasattr(empro.gui, "activeProjectView"): 1597 pv = empro.gui.activeProjectView() 1598 pv.showSimulationQueueView()
1599
1600 @_printexception 1601 -def _writePortPinInformation(portList, ctiDir):
1602 import os 1603 portInfoList = [] 1604 1605 for i, port in enumerate(portList): 1606 thisPortDict = {} 1607 plusPins = port.plusPins() 1608 minusPins = port.minusPins() 1609 1610 thisPortDict[ "nb_plus_pins"] = str(len(plusPins)) 1611 thisPortDict[ "nb_minus_pins"] = str(len(minusPins)) 1612 for j, pin in enumerate(plusPins): 1613 thisPortDict[ "plus_pin_name_%d"%j ] = pin.getPinName() 1614 thisPortDict[ "plus_pin_net_name_%d"%j ] = pin.getNetName() 1615 thisPortDict[ "plus_pin_instance_name_%d"%j ] = pin.getInstanceName() 1616 for j, pin in enumerate(minusPins): 1617 thisPortDict[ "minus_pin_name_%d"%j ] = pin.getPinName() 1618 thisPortDict[ "minus_pin_net_name_%d"%j ] = pin.getNetName() 1619 thisPortDict[ "minus_pin_instance_name_%d"%j ] = pin.getInstanceName() 1620 1621 portInfoList.append(thisPortDict) 1622 1623 with open(long_path_util.resolveLongPath(os.path.join(ctiDir, "sio_attributes.json")), "w") as portsFile: 1624 import json 1625 portsFile.write(json.dumps(portInfoList, indent=4))
1626
1627 1628 -def runACSimulationFlow(sipiData, waitForConfirmation=True, saveProject=False):
1629 import os 1630 import empro 1631 # (mom) solver generates its inputfiles from sipiDataToUseForSimulation 1632 empro.internal.analysis.sipiDataToUseForSimulation = sipiData 1633 pl = empro.activeProject.parameters() 1634 startFreq = pl.formula("minFreq") 1635 endFreq = pl.formula("maxFreq") 1636 1637 # customization event subscribeRunBeforeSimulationCreation 1638 sipiData._invokePublishRunBeforeSimulationCreation() 1639 1640 copyCommonSimulationData(sipiData) 1641 1642 simData = empro.activeProject.createSimulationData() 1643 sipiSimData = sipiData.newSimulationData() 1644 1645 simData.componentsTreatedAsPorts = True 1646 1647 bc = empro.activeProject.boundaryConditions() 1648 boundaryType = "PMC" 1649 xyBoundaryType = "Absorbing" 1650 bc.xLowerBoundaryType = xyBoundaryType 1651 bc.xUpperBoundaryType = xyBoundaryType 1652 bc.yLowerBoundaryType = xyBoundaryType 1653 bc.yUpperBoundaryType = xyBoundaryType 1654 bc.zLowerBoundaryType = boundaryType 1655 bc.zUpperBoundaryType = boundaryType 1656 1657 # generate all the options 1658 newSimData = empro.activeProject.createSimulationData() 1659 1660 #copy fp plans 1661 simData.femFrequencyPlanList().clear() 1662 1663 for fpi in range(len(sipiSimData.femFrequencyPlanList())): 1664 fp = sipiSimData.femFrequencyPlanList()[fpi] 1665 if not fp.enabled: 1666 continue 1667 if fp.type == "Automatic": 1668 startF, stopF = fp.startFrequency, fp.stopFrequency 1669 highestRecommendedFreqAfs = sipiData._highestAdaptiveFrequencyForAC() 1670 highestRecommendedFreqAfs = int(highestRecommendedFreqAfs/1000.0)*1000.0 1671 newFrequencyPlans = [] 1672 if startF<highestRecommendedFreqAfs: 1673 # start with the adaptive part 1674 newFp = empro.simulation.FrequencyPlan() 1675 newFp.type = "Adaptive" 1676 newFp.startFrequency = startF 1677 newFp.stopFrequency = min([highestRecommendedFreqAfs,stopF]) 1678 newFp.numberOfFrequencyPoints = fp.numberOfFrequencyPoints 1679 newFp.samplePointsLimit = fp.samplePointsLimit 1680 newFrequencyPlans.append(newFp) 1681 1682 newFp = empro.simulation.FrequencyPlan() 1683 newFp.type = "Logarithmic" 1684 newFp.startFrequency = startF 1685 newFp.stopFrequency = min([highestRecommendedFreqAfs,stopF]) 1686 newFp.pointsPerDecade = 3 1687 newFrequencyPlans.append(newFp) 1688 1689 if stopF>highestRecommendedFreqAfs: 1690 electricalLength = (sipiData._largestNetLength()*2.0/3e8)*float(stopF) 1691 newFp = empro.simulation.FrequencyPlan() 1692 newFp.type = "Logarithmic" 1693 newFp.startFrequency = max([startF,highestRecommendedFreqAfs]) 1694 newFp.stopFrequency = stopF 1695 newFp.pointsPerDecade = 5 1696 newFrequencyPlans.append(newFp) 1697 1698 for fp in newFrequencyPlans: 1699 simData.femFrequencyPlanList().append(fp) 1700 else: 1701 fp = fp.clone() 1702 1703 if fp.type=="Automatic": 1704 raise RuntimeError("Automatic Frequency plans are not supported") 1705 simData.femFrequencyPlanList().append(fp) 1706 1707 import empro.toolkit.analysis as sipi 1708 with empro.activeProject as project: 1709 project.circuitComponentDefinitions().clear() 1710 sipi._generateCircuitComponentsForAC(sipiData) 1711 existingPath = sipiData.simulationPath 1712 if existingPath and os.path.exists(existingPath): 1713 if waitForConfirmation: 1714 import empro.gui 1715 continueSimulating = empro.gui.MessageBox.question("Existing Results Found", "Previous simulation results exist and will be overwritten.\nWould you still like to continue?", 16384 + 65536, 16384) == 16384 1716 if not continueSimulating: 1717 return 1718 1719 import pyfemPlugin as pyfemPost 1720 pyfemPost.removeOptionManager(os.path.join(existingPath,"emds_dsn","design")) 1721 optionsXml = os.path.join(existingPath,"emds_dsn","design","options.xml") 1722 if os.path.exists(long_path_util.resolveLongPath(optionsXml)): 1723 os.remove(long_path_util.resolveLongPath(optionsXml)) 1724 1725 _removeSimulationForSetup(sipiData) 1726 sim = empro.activeProject.createSimulationEx(True, False, existingPath) 1727 else: 1728 sim = empro.activeProject.createSimulationEx(True, False, "") 1729 sipiData.simulationPath = sim.simulationPath() 1730 1731 try: 1732 import os 1733 os.remove(long_path_util.resolveLongPath(os.path.join(existingPath,"emds_dsn","design",".next_solver_id"))) 1734 except OSError: 1735 pass 1736 1737 # save project so not to dismiss the created simulation path if requested 1738 if saveProject: 1739 empro.activeProject.saveActiveProject() 1740 elif hasattr(empro.gui, "activeProjectView"): 1741 empro.gui._projectUpdatedNoUndo() 1742 1743 # Write the ports file needed for the SIPI Impedance Dialog 1744 sipiData._saveComponentHashes() 1745 writePortsFile(sipiData) 1746 1747 # customization event subscribeRunAfterSimulationCreation 1748 sipiData._invokePublishRunAfterSimulationCreation(sim) 1749 1750 1751 if hasattr(empro.gui, "activeProjectView"): 1752 pv = empro.gui.activeProjectView() 1753 pv.showSimulationQueueView()
1754
1755 @_printexception 1756 -def writePortsFile(sipiData):
1757 import empro 1758 import os 1759 1760 # Set the cti file directory 1761 ctiDir = sipiData.simulationPath 1762 try: 1763 ctiDir = os.path.join(sipiData.simulationPath, "emds_dsn", "design") 1764 if not os.path.exists(long_path_util.resolveLongPath(ctiDir)): 1765 os.makedirs(long_path_util.resolveLongPath(ctiDir)) 1766 except EnvironmentError as error: 1767 existingPath = sipiData.simulationPath 1768 ctiDirTmp = os.path.join(existingPath,"emds_dsn","design") 1769 if not os.path.exists(ctiDirTmp): 1770 ctiDir = sipiData.simulationPath 1771 1772 # Create mapping from vrm name to vrm object 1773 vrmNameToVrm = {} 1774 for vrm in sipiData.getVrmList(): 1775 vrmNameToVrm[vrm.name] = vrm 1776 1777 # Create mapping from sink name to vrm object 1778 sinkNameToSink = {} 1779 for sink in sipiData.getSinkList(): 1780 sinkNameToSink[sink.name] = sink 1781 1782 # Create mapping from component name to impedance specification 1783 cmptNameToImp = {} 1784 cmptNameToModelType = {} 1785 for componentModelGroup in sipiData.getComponentModelGroupList(): 1786 selectedModel = componentModelGroup.models()[componentModelGroup.defaultModelIndex] 1787 impedanceSpec = selectedModel.getPassiveLoad().impedance 1788 modelType = selectedModel.modelType 1789 for componentInstance in componentModelGroup.instances(): 1790 component = componentInstance.instance() 1791 if len(component.pins())<=2: 1792 cmptNameToImp[componentInstance.name] = impedanceSpec 1793 cmptNameToModelType[componentInstance.name] = modelType 1794 else: 1795 portMap = componentModelGroup.pinPortMap() 1796 for portNr, minPlusPins in portMap.getPinNamesForPortNumbers(True): 1797 cmptNameToImp[_canonicalNameMultiPort(componentInstance.name,portNr)] = impedanceSpec 1798 cmptNameToModelType[_canonicalNameMultiPort(componentInstance.name,portNr)] = modelType 1799 1800 1801 # Create port list 1802 portList = [] 1803 index = 0 1804 circuitComponents = empro.activeProject.circuitComponents() 1805 1806 if sipiData.analysisType!=3: 1807 # PA-SI flow excluded 1808 1809 for ci in range(len(circuitComponents)): 1810 # get the circuit component by index 1811 circComp = circuitComponents[ci] 1812 # VRM 1813 if circComp._termType == 0: 1814 vrm = vrmNameToVrm[circComp.name] 1815 portList.append((circComp.name, circComp._termType, index, float(vrm.resistance), float(vrm.inductance), 0, "Series")) 1816 # Sink 1817 elif circComp._termType == 1: 1818 sink = sinkNameToSink[circComp.name] 1819 portList.append((circComp.name, circComp._termType, index, float(sink.resistance), 0, 0, "Series")) 1820 # Component model 1821 elif circComp._termType == 5: 1822 cmptImpSpec = cmptNameToImp[circComp.name] 1823 modelType = cmptNameToModelType[circComp.name] 1824 if modelType==1: 1825 # Lumped model type 1826 resistance = float(cmptImpSpec.resistance) 1827 inductance = float(cmptImpSpec.inductance) 1828 capacitance = float(cmptImpSpec.capacitance) 1829 portList.append((circComp.name, circComp._termType, index, resistance, inductance, capacitance, cmptImpSpec.elementArrangement)) 1830 index = index+1 1831 1832 # Write ports list to file 1833 with open(long_path_util.resolveLongPath(os.path.join(ctiDir, "ports.txt")), "w") as portsFile: 1834 fieldHeaders = ["Name","Type","PortNbr","R","L","C","ElementArrangement"] 1835 portsFile.write("%s\n" % (','.join(str(fieldHeader) for fieldHeader in fieldHeaders))) 1836 for port in portList: 1837 line = ','.join(str(field) for field in port) 1838 portsFile.write("%s\n" % line)
1839
1840 -def runPPRSimulationFlow(sipiData, waitForConfirmation=True, saveProject=False):
1841 import os 1842 import empro 1843 # (mom) solver generates its inputfiles from sipiDataToUseForSimulation 1844 empro.internal.analysis.sipiDataToUseForSimulation = sipiData 1845 existingPath = sipiData.simulationPath 1846 if existingPath and os.path.exists(existingPath): 1847 if waitForConfirmation: 1848 import empro.gui 1849 continueSimulating = empro.gui.MessageBox.question("Existing Results Found", "Previous simulation results exist and will be overwritten.\nWould you still like to continue?", 16384 + 65536, 16384) == 16384 1850 if not continueSimulating: 1851 return 1852 1853 pl = empro.activeProject.parameters() 1854 startFreq = pl.formula("minFreq") 1855 endFreq = pl.formula("maxFreq") 1856 1857 # customization event subscribeRunBeforeSimulationCreation 1858 sipiData._invokePublishRunBeforeSimulationCreation() 1859 1860 copyCommonSimulationData(sipiData) 1861 1862 sipiSimData = sipiData.newSimulationData() 1863 simData = empro.activeProject.createSimulationData() 1864 1865 simData.componentsTreatedAsPorts = False 1866 1867 bc = empro.activeProject.boundaryConditions() 1868 boundaryType = "Absorbing" 1869 xyBoundaryType = "Absorbing" 1870 bc.xLowerBoundaryType = xyBoundaryType 1871 bc.xUpperBoundaryType = xyBoundaryType 1872 bc.yLowerBoundaryType = xyBoundaryType 1873 bc.yUpperBoundaryType = xyBoundaryType 1874 bc.zLowerBoundaryType = boundaryType 1875 bc.zUpperBoundaryType = boundaryType 1876 1877 #copy fp plans 1878 simData.femFrequencyPlanList().clear() 1879 for fpi in range(len(sipiSimData.femFrequencyPlanList())): 1880 fp = sipiSimData.femFrequencyPlanList()[fpi] 1881 if not fp.enabled: 1882 continue 1883 fp = fp.clone() 1884 if float(fp.startFrequency)<_minimumPPRFrequency: 1885 fp.startFrequency = "%f" % _minimumPPRFrequency 1886 if fp.type=="Automatic": 1887 raise RuntimeError("Automatic Frequency plans are not supported") 1888 simData.femFrequencyPlanList().append(fp) 1889 1890 lowFreqLimit = sipiSimData.femEigenSolverSettings.lowFreqLimit 1891 simData.femEigenSolverSettings.lowFreqLimit = lowFreqLimit 1892 if lowFreqLimit<_minimumPPRFrequency: 1893 simData.femEigenSolverSettings.lowFreqLimit = _minimumPPRFrequency 1894 simData.femEigenSolverSettings.nbEigenFreq = sipiSimData.femEigenSolverSettings.nbEigenFreq 1895 simData.femEigenSolverSettings.highFreqLimit = sipiSimData.femEigenSolverSettings.highFreqLimit 1896 simData.femEigenSolverSettings.iterationTolerance = sipiSimData.femEigenSolverSettings.iterationTolerance 1897 1898 import empro.toolkit.analysis as sipi 1899 sipi._generateCircuitComponentsForAC(sipiData) 1900 1901 existingPath = sipiData.simulationPath 1902 if existingPath and os.path.exists(existingPath): 1903 import pyfemPlugin as pyfemPost 1904 pyfemPost.removeOptionManager(os.path.join(existingPath,"emds_dsn","design")) 1905 optionsXml = os.path.join(existingPath,"emds_dsn","design","options.xml") 1906 if os.path.exists(long_path_util.resolveLongPath(optionsXml)): 1907 os.remove(long_path_util.resolveLongPath(optionsXml)) 1908 projectLog = os.path.join(existingPath,"project.log") 1909 if os.path.exists(long_path_util.resolveLongPath(projectLog)): 1910 os.remove(long_path_util.resolveLongPath(projectLog)) 1911 1912 _removeSimulationForSetup(sipiData) 1913 sim = empro.activeProject.createSimulationEx(True, False, existingPath) 1914 else: 1915 sim = empro.activeProject.createSimulationEx(True, False, "") 1916 sipiData.simulationPath = sim.simulationPath() 1917 1918 try: 1919 import os 1920 os.remove(os.path.join(existingPath,"emds_dsn","design",".next_solver_id")) 1921 except OSError: 1922 pass 1923 1924 # customization event subscribeRunAfterSimulationCreation 1925 sipiData._invokePublishRunAfterSimulationCreation(sim) 1926 1927 # save project so not to dismiss the created simulation path if requested 1928 if saveProject: 1929 empro.activeProject.saveActiveProject() 1930 elif hasattr(empro.gui, "activeProjectView"): 1931 empro.gui._projectUpdatedNoUndo() 1932 1933 sipiData._saveComponentHashes() 1934 1935 if hasattr(empro.gui, "activeProjectView"): 1936 pv = empro.gui.activeProjectView() 1937 pv.showSimulationQueueView()
1938 1939 import xml.sax
1940 -class NameIdContentHandler(xml.sax.ContentHandler):
1941 - def __init__(self):
1942 xml.sax.ContentHandler.__init__(self) 1943 self.lastName = None 1944 self.lastId = None 1945 self.mapping = {}
1946
1947 - def endElement(self, name):
1948 if name == "OALayoutOverview": 1949 return False 1950 if name == "id": 1951 self.lastId = int(self.content) 1952 if name == "name": 1953 self.lastName = self.content 1954 if self.lastId!=None: 1955 self.mapping[self.lastId]=self.lastName 1956 self.lastId = None
1957
1958 - def characters(self, content):
1959 self.content = content
1960
1961 -class NoSimulationAvailable(RuntimeError):
1962 - def __init__(self,name):
1963 self.name = name
1964
1965 @_printexception 1966 -def _filterData(sipiData,pathSuffix=""):
1967 import xml.sax 1968 import os 1969 if sipiData.simulationPath=="" or not os.path.exists(long_path_util.resolveLongPath(sipiData.simulationPath)): 1970 raise NoSimulationAvailable(sipiData.name) 1971 if pathSuffix: 1972 sourceFileName = os.path.join(sipiData.simulationPath, pathSuffix, "design_ser.xml") 1973 else: 1974 sourceFileName = os.path.join(sipiData.simulationPath, "design_ser.xml") 1975 1976 excerpt = [] 1977 with open(long_path_util.resolveLongPath(sourceFileName),"r") as openedFile: 1978 line = " " 1979 while line: 1980 line = openedFile.readline() 1981 excerpt.append(line) 1982 if "/OALayoutOverview" in line: 1983 excerpt.append("</SIPIDesign>") 1984 break 1985 handler = NameIdContentHandler() 1986 xml.sax.parseString("\n".join(excerpt), handler) 1987 return handler.mapping
1988
1989 1990 @_printexception 1991 -def generateTestBench(sipiData, overwrite=0, noErrorMessageBox=False):
1992 try: 1993 import empro.toolkit.analysis.schematic_generation as schematic_generation 1994 import os 1995 workingDirectory = os.getcwd() 1996 oaLayout = empro.activeProject.geometry()[0] 1997 libName = oaLayout._designRef.lib 1998 cellName = oaLayout._designRef.cell 1999 lcvName = schematic_generation.generateSchematic(workingDirectory, sipiData, libName, cellName, schematicType=1, overwrite=overwrite, noErrorMessageBox=noErrorMessageBox) 2000 return lcvName 2001 except: 2002 if noErrorMessageBox: 2003 raise 2004 import sys 2005 msg = str(sys.exc_info()[1]) 2006 empro.gui.MessageBox.critical("Failed to generate test bench", "Failed to generate test bench.\nReason:\n" + msg,0,0)
2007
2008 @_printexception 2009 -def generateSubCircuit(sipiData, overwrite=0, noErrorMessageBox=False, whereToSave=1):
2010 try: 2011 import empro.toolkit.analysis.schematic_generation as schematic_generation 2012 import os 2013 workingDirectory = os.getcwd() 2014 oaLayout = empro.activeProject.geometry()[0] 2015 libName = oaLayout._designRef.lib 2016 cellName = oaLayout._designRef.cell 2017 lcvName = schematic_generation.generateSchematic(workingDirectory, sipiData, libName, cellName, schematicType=2, overwrite=overwrite, noErrorMessageBox=noErrorMessageBox, whereToSave=whereToSave) 2018 return lcvName 2019 except: 2020 if noErrorMessageBox: 2021 raise 2022 import sys 2023 msg = str(sys.exc_info()[1]) 2024 empro.gui.MessageBox.critical("Failed to generate sub circuit", "Failed to generate sub circuit.\nReason:\n" + msg,0,0)
2025
2026 @_printexception 2027 -def simulateTestBench(lcvName, overwrite=0, closeDesign = 0, noErrorMessageBox=False):
2028 try: 2029 import empro.toolkit.analysis.schematic_generation as schematic_generation 2030 datasetName = schematic_generation.requestAdsToSimulateSchematic( lcvName, overwrite, closeDesign ) 2031 return datasetName 2032 except: 2033 if noErrorMessageBox: 2034 raise 2035 import sys 2036 msg = str(sys.exc_info()[1]) 2037 empro.gui.MessageBox.critical("Failed to simulate test bench", "Failed to simulate test bench.\nReason:\n" + msg,0,0)
2038
2039 @_printexception 2040 -def generateVoltageSpikesTB(sipiData, overwrite=0, noErrorMessageBox=False, whereToSave=1):
2041 import empro.toolkit.analysis.schematic_generation as schematic_generation 2042 # get design data 2043 AnalysisName = sipiData.name 2044 AnalysisName = schematic_generation._fixSetupName(AnalysisName) 2045 oaLayout = empro.activeProject.geometry()[0] 2046 libName = oaLayout._designRef.lib 2047 cellName = oaLayout._designRef.cell 2048 lcvName = None 2049 2050 # Create/overwrite sub-circuit before the testbench generation 2051 # This also opens the sub-circuit schematic 2052 try: 2053 lcvName = generateSubCircuit(sipiData, 1, noErrorMessageBox, 2) 2054 except: 2055 return 2056 finally: 2057 # Close the sub-circuit schematic 2058 # The purpose is to create/overwrite and open testbench, not a sub-circuit 2059 empro.toolkit.rpc.callAEL('deempe_close_subcircuit_if_opened', [AnalysisName, libName, cellName]) 2060 2061 # If return value from generateSubCircuit is None, 2062 # we do not proceed with the testbench generation 2063 if lcvName is None: 2064 return 2065 2066 try: 2067 lcvName = schematic_generation.generateVoltageSpikesTestbench(sipiData, libName, cellName, overwrite, noErrorMessageBox) 2068 return lcvName 2069 except: 2070 if noErrorMessageBox: 2071 raise 2072 import sys 2073 msg = str(sys.exc_info()[1]) 2074 empro.gui.MessageBox.critical("Failed to generate testbench for voltage spikes", "Failed to generate testbench for voltage spikes.\nReason: " + msg,0,0)
2075
2076 @_printexception 2077 -def generateConductedEmiTB(sipiData, overwrite=0, noErrorMessageBox=False, whereToSave=1):
2078 import empro.toolkit.analysis.schematic_generation as schematic_generation 2079 # get design data 2080 AnalysisName = sipiData.name 2081 AnalysisName = schematic_generation._fixSetupName(AnalysisName) 2082 oaLayout = empro.activeProject.geometry()[0] 2083 libName = oaLayout._designRef.lib 2084 cellName = oaLayout._designRef.cell 2085 lcvName = None 2086 2087 # Create/overwrite sub-circuit before the testbench generation 2088 # This also opens the sub-circuit schematic 2089 try: 2090 lcvName = generateSubCircuit(sipiData, 1, noErrorMessageBox, 2) 2091 except: 2092 return 2093 finally: 2094 # Close the sub-circuit schematic 2095 # The purpose is to create/overwrite and open testbench, not a sub-circuit 2096 empro.toolkit.rpc.callAEL('deempe_close_subcircuit_if_opened', [AnalysisName, libName, cellName]) 2097 2098 # If return value from generateSubCircuit is None, 2099 # we do not proceed with the testbench generation 2100 if lcvName is None: 2101 return 2102 2103 try: 2104 lcvName = schematic_generation.generateConductedEmiTestbench(sipiData, libName, cellName, overwrite, noErrorMessageBox) 2105 return lcvName 2106 except: 2107 if noErrorMessageBox: 2108 raise 2109 import sys 2110 msg = str(sys.exc_info()[1]) 2111 empro.gui.MessageBox.critical("Failed to generate testbench for Conducted EMI", "Failed to generate testbench for Conducted EMI.\nReason: " + msg,0,0)
2112
2113 2114 @_printexception 2115 -def viewDCOverview(sipiData):
2116 # also load the dialog 2117 try: 2118 import empro.toolkit.analysis.results_overview as sipigui 2119 import empro.toolkit.analysis.dc.results as sipiresults 2120 results = sipiresults.DCResults(sipiData) 2121 resultsOverview = sipigui.ResultsOverview(results) 2122 resultsOverview.show() 2123 except: 2124 import sys 2125 import traceback 2126 msg = str(sys.exc_info()[1]) 2127 empro.gui.MessageBox.critical("Failed to Display Overview", "Failed to Display Overview.\nReason:\n" + msg,0,0)
2128
2129 @_printexception 2130 -def viewPPROverview(sipiData):
2131 # also load the dialog 2132 try: 2133 import empro.toolkit.analysis.ppr_results_overview as sipigui 2134 resultsOverview = sipigui.ResultsOverview(sipiData) 2135 resultsOverview.show() 2136 except: 2137 import sys 2138 import traceback 2139 import os 2140 #traceback.print_tb(sys.exc_info()[2]) 2141 logFile = sipiData.simulationPath+r"/project.log" 2142 if not os.path.exists(logFile): 2143 msg = "Simulation Not Found" 2144 else: 2145 msg = "Simulation Failed or No Existing Results Found" 2146 empro.gui.MessageBox.critical("Failed to Display Overview", "Failed to Display Overview.\nReason:\n" + msg,0,0)
2147
2148 @_printexception 2149 -def getDCResultFilter(sipiData):
2150 resultFilter = [] 2151 filterData = _filterData(sipiData) 2152 filterData[-1] = "Not Set" 2153 resultFilter.append((("Layer","LayerId"),filterData)) 2154 resultFilter.append((("Net Type","NetId"), {4:"Signal", 1:"Power", 2:"Ground"})) 2155 return resultFilter
2156
2157 2158 @_printexception 2159 -def getTemperatureResultFilter(sipiData):
2160 resultFilter = [] 2161 filterData = _filterData(sipiData) 2162 filterData[-1] = "Not Set" 2163 resultFilter.append((("Layer","LayerIdExt"),filterData)) 2164 resultFilter.append((("Net Type","NetId"), {-1: "Not Available", 0 : "Not Set", 4:"Signal", 1:"Power", 2:"Ground"})) 2165 return resultFilter
2166
2167 2168 @_printexception 2169 -def viewVoltage(result):
2170 try: 2171 sipiData = result.getData() 2172 import os 2173 if sipiData.simulationPath=="" or not os.path.exists(sipiData.simulationPath): 2174 raise NoSimulationAvailable(sipiData.name) 2175 import empro 2176 gv = empro.gui.activeProjectView() 2177 gv.showGeometryView() 2178 gv = gv.geometryView() 2179 gv.displayResult(result, "[" + sipiData.name + "]: Voltage", getDCResultFilter(sipiData)) 2180 except NoSimulationAvailable: 2181 import empro 2182 empro.gui.MessageBox.warning("Failed to Display Fields", "No simulation available for <%s>" %sipiData.name,0,0) 2183 except: 2184 import sys 2185 import traceback 2186 msg = str(sys.exc_info()[1]) 2187 empro.gui.MessageBox.critical("Failed to Display Voltage", "Failed to Display Voltage.\nReason:\n" + msg,0,0)
2188
2189 2190 @_printexception 2191 -def viewTemperature(result):
2192 try: 2193 sipiData = result.getData() 2194 import os 2195 if sipiData.simulationPath=="" or not os.path.exists(sipiData.simulationPath): 2196 raise NoSimulationAvailable(sipiData.name) 2197 import empro 2198 gv = empro.gui.activeProjectView() 2199 gv.showGeometryView() 2200 gv = gv.geometryView() 2201 resultFilter = getTemperatureResultFilter(sipiData) 2202 gv.displayResult(result, "[" + sipiData.name + "]: Temperature", resultFilter) 2203 except NoSimulationAvailable: 2204 import empro 2205 empro.gui.MessageBox.warning("Failed to Display Fields", "No simulation available for <%s>" %sipiData.name,0,0) 2206 except: 2207 import sys 2208 import traceback 2209 msg = str(sys.exc_info()[1]) 2210 empro.gui.MessageBox.critical("Failed to Display Temperature", "Failed to Display Temperature.\nReason:\n" + msg,0,0)
2211
2212 2213 @_printexception 2214 -def viewPowerDensity(result):
2215 try: 2216 sipiData = result.getData() 2217 import os 2218 if sipiData.simulationPath=="" or not os.path.exists(sipiData.simulationPath): 2219 raise NoSimulationAvailable(sipiData.name) 2220 import empro 2221 gv = empro.gui.activeProjectView() 2222 gv.showGeometryView() 2223 gv = gv.geometryView() 2224 gv.displayResult(result, "[" + sipiData.name + "]: Power Loss Density", getDCResultFilter(sipiData)) 2225 except NoSimulationAvailable: 2226 import empro 2227 empro.gui.MessageBox.warning("Failed to Display Fields", "No simulation available for <%s>" %sipiData.name,0,0) 2228 except: 2229 import sys 2230 import traceback 2231 msg = str(sys.exc_info()[1]) 2232 empro.gui.MessageBox.critical("Failed to Display Power Density", "Failed to Display Power Density.\nReason:\n" + msg,0,0)
2233
2234 2235 @_printexception 2236 -def viewCurrent(result):
2237 try: 2238 sipiData = result.getData() 2239 import os 2240 if sipiData.simulationPath=="" or not os.path.exists(sipiData.simulationPath): 2241 raise NoSimulationAvailable(sipiData.name) 2242 import empro 2243 gv = empro.gui.activeProjectView() 2244 gv.showGeometryView() 2245 gv = gv.geometryView() 2246 gv.displayResult(result, "[" + sipiData.name + "]: Current Density", getDCResultFilter(sipiData)) 2247 except NoSimulationAvailable: 2248 import empro 2249 empro.gui.MessageBox.warning("Failed to Display Current", "No simulation available for <%s>" %sipiData.name,0,0) 2250 except: 2251 import sys 2252 import traceback 2253 msg = str(sys.exc_info()[1]) 2254 empro.gui.MessageBox.critical("Failed to Display Current", "Failed to Display Current.\nReason:\n" + msg,0,0)
2255
2256 2257 @_printexception 2258 -def executeInVendorPartsDb(sqlstatement):
2259 vendorPartsDb = empro.VendorPartsDb.instance() 2260 import sqlite3 2261 db = sqlite3.connect(vendorPartsDb.pathToDb) 2262 sqlresult = db.execute( sqlstatement ) 2263 fields = [x[0] for x in sqlresult.description] 2264 rows = sqlresult.fetchall() 2265 row = rows[0] 2266 data = dict(zip(fields,row)) 2267 db.close() 2268 return data
2269
2270 @_printexception 2271 -def getVendorPartsDir():
2272 import os 2273 return os.path.abspath(os.path.join(empro.liboa.getLibDefsDirPath(), "simulation", "eemSipi", empro.activeProject.location.lib))
2274
2275 @_printexception 2276 -def _vrmToImpedance(vrm):
2277 rlc = empro.components.RLCSpecification(vrm.name) 2278 rlc.resistance = float(vrm.resistance) 2279 rlc.inductance = float(vrm.inductance) 2280 rlc.capacitance = 0 2281 rlc.elementArrangement = "Series" 2282 return rlc
2283
2284 @_printexception 2285 -def _sinkToImpedance(sink):
2286 rlc = empro.components.RLCSpecification(sink.name) 2287 rlc.resistance = float(sink.resistance) 2288 rlc.inductance = 0 2289 rlc.capacitance = 0 2290 rlc.elementArrangement = "Series" 2291 return rlc
2292
2293 @_printexception 2294 -def _ioToImpedance(port):
2295 rlc = empro.components.RLCSpecification(port.name) 2296 rlc.resistance = float(port.referenceImpedance) 2297 rlc.inductance = 0 2298 rlc.capacitance = 0 2299 rlc.elementArrangement = "Series" 2300 return rlc
2301
2302 @_printexception 2303 -def _modelToImpedance(componentModelGroup):
2304 selectedModel = componentModelGroup.models()[componentModelGroup.defaultModelIndex] 2305 modelType = selectedModel.modelType 2306 compName = "bla" 2307 if modelType == 1: # Lumped RLC 2308 imp = selectedModel.getPassiveLoad().impedance 2309 if not isinstance(imp, empro.components.RLCSpecification): 2310 raise RuntimeError("Lumped component expected") 2311 rlc = imp.clone() 2312 rlc.name = compName 2313 return rlc 2314 elif modelType == 2: # Vendor parts database 2315 if False: 2316 # [SD] To be removed 2317 data = executeInVendorPartsDb( "SELECT * FROM Cmpts WHERE PartNbr='%s'" % selectedModel.partNbr ) 2318 nbPorts = int(data["NumberOfPorts"]) 2319 if nbPorts>1 or not data["RModel"] or not data["LModel"] or not data["CModel"] or not data["Topology"]: 2320 import os 2321 snp = empro.components.SnPSpecification(compName) 2322 snp.fileName = os.path.join(getVendorPartsDir(), "measSnp_%s" % selectedModel.partNbr, selectedModel.partNbr + '.snp') 2323 return snp 2324 else: 2325 rlc = empro.components.RLCSpecification(compName) 2326 rlc.resistance = float(data["RModel"]) 2327 rlc.inductance = float(data["LModel"]) 2328 rlc.capacitance = float(data["CModel"]) 2329 rlc.elementArrangement = data["Topology"] 2330 return rlc 2331 return selectedModel.getPassiveLoadFromVendorPartsDb().impedance.clone() 2332 elif modelType == 3: # SnP component 2333 imp = selectedModel.getPassiveLoad().impedance 2334 if not isinstance(imp, empro.components.SnPSpecification): 2335 raise RuntimeError("SnP component expected") 2336 snp = imp.clone() 2337 snp.name = compName 2338 return snp
2339
2340 -def _getImpedanceSpecGenerators(sipiSetupData, pinType = "plus"):
2341 index = 0 2342 vrmNameToIndex = [] 2343 sinkNameToIndex = [] 2344 ioPortNameToIndex = [] 2345 cmptNameToIndex = [] 2346 impedanceSpecsGenerators = [] 2347 2348 pinHash = _createPinHash() 2349 pinNetNames = _createPinHashNetName() 2350 def getNetNamesOfComponent(port, pinHash, pinNetNames): 2351 if pinType == "plus": 2352 return list(set([ pinNetNames[ pinHash[x.name] ] for x in port.plusPins()])) 2353 else: 2354 return list(set([ pinNetNames[ pinHash[x.name] ] for x in port.minusPins()]))
2355 2356 def getPinNamesOfComponent(port): 2357 plusPinNames = [] 2358 for x in port.plusPins(): 2359 plusPinNames.append(x.name) 2360 minusPinNames = [] 2361 for x in port.minusPins(): 2362 minusPinNames.append(x.name) 2363 return [plusPinNames, minusPinNames] 2364 2365 # Get the analysis type 2366 analysisType = int(sipiSetupData.analysisType) 2367 if analysisType in [sipiSetupData.ACAnalysisType, sipiSetupData.PPRAnalysisType]: 2368 loadVRMs = True 2369 loadSinks = True 2370 loadIoPorts = False 2371 loadComponents = True 2372 elif analysisType == sipiSetupData.PASIAnalysisType: 2373 loadVRMs = False 2374 loadSinks = False 2375 loadIoPorts = True 2376 loadComponents = True 2377 else: 2378 raise RuntimeError("Impedance/Sparameter plots not supported for analysis type %d" % analysisType) 2379 2380 # Get the path of the CITI file 2381 import os 2382 if hasattr(sipiSetupData, "simulationPath"): 2383 pathToSimulate = sipiSetupData.simulationPath 2384 else: 2385 lastSimulation = empro.activeProject.simulations()[-1] 2386 pathToSimulate = lastSimulation.simulationPath() 2387 ctiDir = os.path.join(pathToSimulate, "emds_dsn", "design") 2388 ctiFileLocation = os.path.join(ctiDir, "design_ffs.cti") 2389 if not os.path.exists(ctiFileLocation): 2390 ctiFileLocation = os.path.join(ctiDir, "design.cti") 2391 if not os.path.exists(ctiFileLocation): 2392 ctiFileLocation = os.path.join(ctiDir, "design_dfs.cti") 2393 if not os.path.exists(ctiFileLocation): 2394 msg = "Failed to find results." 2395 empro.gui.MessageBox.critical("Failed to Show Impedance", "Failed to Generate Impedance.\nReason:\n" + msg,0,0) 2396 return 2397 2398 # VRMs 2399 if loadVRMs: 2400 for vrm in sipiSetupData.getVrmList(): 2401 netNames = getNetNamesOfComponent(vrm, pinHash, pinNetNames) 2402 vrmNameToIndex.append((vrm.name, (index, netNames) )) 2403 impedanceSpecsGenerators.append( (vrm, _vrmToImpedance) ) 2404 index += 1 2405 2406 # Sinks 2407 if loadSinks: 2408 for sink in sipiSetupData.getSinkList(): 2409 netNames = getNetNamesOfComponent(sink, pinHash, pinNetNames) 2410 sinkNameToIndex.append((sink.name, (index, netNames) )) 2411 impedanceSpecsGenerators.append( (sink, _sinkToImpedance) ) 2412 index += 1 2413 2414 # IO ports 2415 if loadIoPorts: 2416 for ioPort in sipiSetupData.getPortList(): 2417 netNames = getNetNamesOfComponent(ioPort, pinHash, pinNetNames) 2418 ioPortNameToIndex.append((ioPort.name, (index, netNames) )) 2419 impedanceSpecsGenerators.append( (ioPort, _ioToImpedance) ) 2420 index += 1 2421 2422 # Components 2423 if loadComponents: 2424 for componentModelGroup in sipiSetupData.getComponentModelGroupList(): 2425 for componentInstance in componentModelGroup.instances(): 2426 cmptNameToIndex.append((componentInstance.name, index)) 2427 impedanceSpecsGenerators.append( (componentModelGroup, _modelToImpedance) ) 2428 index += 1 2429 2430 return impedanceSpecsGenerators, ctiFileLocation, vrmNameToIndex, sinkNameToIndex, ioPortNameToIndex, cmptNameToIndex 2431
2432 -def _ioPortListToDifferentialPairs(portList):
2433 diffPairList = [] 2434 for diffPair in portList.differentialPairs(): 2435 P0 = diffPair[0] 2436 P1 = diffPair[1] 2437 C = "Common(%s,%s)"%(P0,P1) 2438 D = "Diff(%s,%s)"%(P0,P1) 2439 diffPairList.append(((P0,P1),(D,C))) 2440 return diffPairList
2441
2442 -def _getDifferentialPairGenerators(sipiSetupData):
2443 dpg = [] 2444 dpg.append( (sipiSetupData.getPortList(), _ioPortListToDifferentialPairs) ) 2445 return dpg
2446
2447 @_printexception 2448 -def viewImpedance(sipiDatas):
2449 import empro 2450 for sipiData in sipiDatas: 2451 empro.gui.showImpedanceDialog(sipiData)
2452
2453 @_printexception 2454 -def viewSParameters(sipiDatas):
2455 import empro 2456 for sipiData in sipiDatas: 2457 empro.gui.showSParameterDialog(sipiData)
2458
2459 @_printexception 2460 -def viewFarField(sipiData):
2461 import empro, os 2462 2463 def fieldDataAvailable(simDir): 2464 import fnmatch 2465 for root, dirs, files in os.walk(simDir): 2466 for file in fnmatch.filter(files, "*.ffp"): 2467 return True 2468 return False
2469 2470 gv = empro.gui.activeProjectView() 2471 gv.showGeometryView() 2472 gv = gv.geometryView() 2473 if sipiData.newSimulationData().engine=="MomEngine": 2474 if sipiData.newSimulationData().momPhysModel.solveModelType=="RF": 2475 empro.gui.MessageBox.warning("Failed to Display Far Field", "Far Field is not available for Momentum RF",0,0) 2476 return 2477 momDir = os.path.join(sipiData.simulationPath, "work") 2478 if not os.path.exists(momDir): 2479 empro.gui.MessageBox.warning("Failed to Display Far Field", "Simulation results directory does not exist",0,0) 2480 return 2481 msfFile = os.path.join(momDir,"proj.msf") 2482 if not os.path.exists(long_path_util.resolveLongPath(msfFile)): 2483 empro.gui.MessageBox.warning("Failed to Display Far Field", "No Far Field data available",0,0) 2484 return 2485 gv.displayMomFarfield(sipiData.simulationPath, sipiData.newSimulationData().farFieldAngularResolution) 2486 else: 2487 # fem 2488 femDir = os.path.join(sipiData.simulationPath, "emds_dsn", "design") 2489 optionsXml = os.path.join(femDir,"options.xml") 2490 if not fieldDataAvailable(femDir) or not os.path.exists(long_path_util.resolveLongPath(optionsXml)) : 2491 empro.gui.MessageBox.warning("Failed to Display Far Field", "No Far Field data available",0,0) 2492 return 2493 gv.displayFarfield(sipiData.simulationPath) 2494
2495 2496 @_printexception 2497 -def _getACResultFilter(sipiData):
2498 resultFilter = [] 2499 fullFilterMap = _filterData(sipiData,"emds_dsn/design") 2500 reducedFilterMap = {} 2501 for k,v in fullFilterMap.iteritems(): 2502 if "Dielectric Layer" in v: continue 2503 reducedFilterMap[k] = v 2504 resultFilter.append((("Layer","LayerId"),reducedFilterMap)) 2505 #resultFilter.append((("Net Type","NetId"), {1:"Power", 2:"Ground"})) 2506 return resultFilter
2507
2508 @_printexception 2509 -def viewFemField(result):
2510 sipiData = result.getData() 2511 import empro, os 2512 2513 def fieldDataAvailable(simDir): 2514 import fnmatch 2515 for root, dirs, files in os.walk(simDir): 2516 for file in fnmatch.filter(files, "*.blg"): 2517 return True 2518 for file in fnmatch.filter(files, "*.blp"): 2519 return True 2520 for file in fnmatch.filter(files, "*solution.bin"): 2521 return True 2522 return False
2523 2524 if empro.activeProject._hasEncryptedData(): 2525 empro.gui.MessageBox.warning("Failed to Display Fields", "Field Visualization is not available for encrypted substrates,...",0,0) 2526 return 2527 2528 resultType = result.getType() 2529 2530 gv = empro.gui.activeProjectView() 2531 gv.showGeometryView() 2532 gv = gv.geometryView() 2533 if sipiData.analysisType in [EMFU, EMUD, EMSM, EMFUPE, EMUDPE]: 2534 if resultType == 10: 2535 #TODO: Should we check simulation engine used for analysis in different way?? 2536 #Currently we just get it from "current" setup 2537 if sipiData.newSimulationData().engine=="MomEngine": 2538 empro.gui.MessageBox.warning("Failed to Display Fields", "Electric Field is not available for Momentum",0,0) 2539 return 2540 elif sipiData.newSimulationData().saveFieldsFor == "NoFrequencies": 2541 empro.gui.MessageBox.warning("Failed to Display Fields", "Electric Fields were not stored for any frequency",0,0) 2542 return 2543 fieldName = "E" 2544 resultName = "Electric Fields" 2545 elif resultType == 11: 2546 if sipiData.newSimulationData().engine=="MomEngine": 2547 empro.gui.MessageBox.warning("Failed to Display Fields", "Magnetic Field is not available for Momentum",0,0) 2548 return 2549 elif sipiData.newSimulationData().saveFieldsFor == "NoFrequencies": 2550 empro.gui.MessageBox.warning("Failed to Display Fields", "Magnetic Fields were not stored for any frequency",0,0) 2551 return 2552 fieldName = "H" 2553 resultName = "Magnetic Fields" 2554 elif resultType == 12: 2555 if sipiData.newSimulationData().saveFieldsFor == "NoFrequencies": 2556 empro.gui.MessageBox.warning("Failed to Display Current Density", "Current Density was not stored for any frequency",0,0) 2557 return 2558 fieldName = "Jc" 2559 resultName = "Current Density" 2560 else: 2561 raise RuntimeError("unknown field type") 2562 try: 2563 if sipiData.newSimulationData().engine=="MomEngine": 2564 momDir = os.path.join(sipiData.simulationPath, "work") 2565 gv.displayMomField(momDir) 2566 else: 2567 femDir = os.path.join(sipiData.simulationPath, "emds_dsn", "design") 2568 optionsXml = os.path.join(femDir,"options.xml") 2569 if not fieldDataAvailable(femDir) or not os.path.exists(long_path_util.resolveLongPath(optionsXml)) : 2570 empro.gui.MessageBox.warning("Failed to Display " + resultName, "No " + resultName + " data available",0,0) 2571 return 2572 topologyFilter = empro.output.MultiPlaneFilter("multi plane filter") 2573 gv.displayMultiField(femDir, fieldName, topologyFilter) 2574 except: 2575 import traceback 2576 traceback.print_exc() 2577 empro.gui.MessageBox.warning("Failed to Display %s" % fieldName, "Result is not available.\nRun the analysis with field storage enabled to display %s results." % fieldName,0,0) 2578 else: 2579 try: 2580 if resultType == 10: fieldName = "Electric Field" 2581 elif resultType == 11: fieldName = "Magnetic Field" 2582 elif resultType == 12: fieldName = "Current Density" 2583 elif resultType == 18: fieldName = "Nearfield" 2584 else: fieldName = "unknown field type" 2585 acFilter = _getACResultFilter(sipiData) 2586 gv.displayResult(result, "[" + sipiData.name + "]: " + fieldName, acFilter) 2587 except NoSimulationAvailable: 2588 empro.gui.MessageBox.warning("Failed to Display Fields", "No simulation available for <%s>"%sipiData.name,0,0) 2589 except: 2590 import traceback 2591 traceback.print_exc() 2592 empro.gui.MessageBox.warning("Failed to Display Fields", "Fields are not available.\nRun the analysis with field storage enabled to display field results.",0,0) 2593
2594 2595 # convenience methods to support automation 2596 -def createVrmFromInstance(instanceName, preferredPowerNetNames=None, preferredGroundNetNames=None):
2597 instance = empro.activeProject.layout.instanceByName(instanceName) 2598 powerNets = preferredPowerNetNames or empro.activeProject.layout.nets.getPowerNetNames() 2599 groundNets = preferredGroundNetNames or empro.activeProject.layout.nets.getGroundNetNames() 2600 2601 vrm = empro.analysis.Vrm() 2602 for pin in instance.pins(): 2603 if pin.netName in groundNets: 2604 vrm.appendMinus(empro.analysis.PinRef(instance.name+"."+pin.name, empro.activeProject.geometry()[0])) 2605 if pin.netName in powerNets: 2606 vrm.appendPlus(empro.analysis.PinRef(instance.name+"."+pin.name, empro.activeProject.geometry()[0])) 2607 2608 vrm.inductance = "0 H" 2609 vrm.resistance = "0 Ohm" 2610 vrm.voltage = "1.5 V" 2611 vrm.tolerance = "0.01" 2612 return vrm
2613
2614 -def createSinkFromInstance(instanceName, preferredPowerNetNames=None, preferredGroundNetNames=None):
2615 instance = empro.activeProject.layout.instanceByName(instanceName) 2616 powerNets = preferredPowerNetNames or empro.activeProject.layout.nets.getPowerNetNames() 2617 groundNets = preferredGroundNetNames or empro.activeProject.layout.nets.getGroundNetNames() 2618 sink = empro.analysis.Sink() 2619 for pin in instance.pins(): 2620 if pin.netName in groundNets: 2621 sink.appendMinus(empro.analysis.PinRef(instance.name+"."+pin.name, empro.activeProject.geometry()[0])) 2622 if pin.netName in powerNets: 2623 sink.appendPlus(empro.analysis.PinRef(instance.name+"."+pin.name, empro.activeProject.geometry()[0])) 2624 2625 sink.current = "3 A" 2626 sink.tolerance = "0.01" 2627 sink.resistance = "1 MOhm" 2628 return sink
2629
2630 -def createThermalComponentFromInstance(instanceName):
2631 source = empro.analysis.ThermalComponent(instanceName, empro.activeProject.geometry()[0]) 2632 return source
2633
2634 -def appendPinsToPort(preferredPort, preferredPlusPins, preferredMinusPins):
2635 plusPins= [empro.analysis.PinRef(i, empro.activeProject.geometry()[0]) for i in preferredPlusPins] 2636 minusPins = [empro.analysis.PinRef(i, empro.activeProject.geometry()[0]) for i in preferredMinusPins] 2637 for pin in plusPins: 2638 preferredPort.appendPlus(pin) 2639 for pin in minusPins: 2640 preferredPort.appendMinus(pin) 2641 return
2642
2643 -def createVrmFromPins(preferredPlusPins, preferredMinusPins, name=None):
2644 vrm = empro.analysis.Vrm() 2645 if name: 2646 vrm.name=name 2647 appendPinsToPort(vrm, preferredPlusPins, preferredMinusPins) 2648 return vrm
2649
2650 -def createSinkFromPins(preferredPlusPins, preferredMinusPins, name=None):
2651 sink = empro.analysis.Sink() 2652 if name: 2653 sink.name=name 2654 appendPinsToPort(sink, preferredPlusPins, preferredMinusPins) 2655 return sink
2656
2657 -def createPortFromPins(preferredPlusPins, preferredMinusPins, name=None):
2658 port = empro.analysis.Port() 2659 if name: 2660 port.name=name 2661 appendPinsToPort(port, preferredPlusPins, preferredMinusPins) 2662 return port
2663
2664 -def createComponentGroupFromComponent(componentName):
2665 component = empro.activeProject.layout.componentByCellName(componentName) 2666 componentGroup = empro.analysis.ComponentModelGroup(component._libCellName, empro.activeProject.geometry()[0]) 2667 return componentGroup
2668
2669 -def createThermalComponentGroupFromComponent(componentName):
2670 component = empro.activeProject.layout.componentByCellName(componentName) 2671 componentGroup = empro.analysis.ThermalComponentGroup(component._libCellName, empro.activeProject.geometry()[0]) 2672 return componentGroup
2673
2674 -def createComponentInstanceFromInstance(instanceName):
2675 instance = empro.activeProject.layout.instanceByName(instanceName) 2676 if not instance: 2677 return None 2678 return empro.analysis.ComponentInstance(instance.name, empro.activeProject.geometry()[0])
2679
2680 -def runAnalysis(setup, waitForConfirmation=True):
2681 import empro.toolkit.analysis 2682 analysisType = setup.analysisType 2683 if analysisType in [PIDC, THERMAL, ELECTRO_THERMAL]: 2684 empro.toolkit.analysis.runDCSimulationFlow(setup, waitForConfirmation) 2685 elif analysisType==PIAC: 2686 empro.toolkit.analysis.runACSimulationFlow(setup, waitForConfirmation) 2687 elif analysisType==PASI: 2688 empro.toolkit.analysis.runPASISimulationFlow(setup, waitForConfirmation) 2689 elif analysisType==PPR: 2690 empro.toolkit.analysis.runPPRSimulationFlow(setup, waitForConfirmation) 2691 elif analysisType in [EMFU, EMUD, EMFUPE, EMUDPE]: 2692 empro.toolkit.analysis.runEMExtractionSimulationFlow(setup, waitForConfirmation) 2693 else: 2694 raise RuntimeError("Unknown Analysis Type")
2695
2696 -def getSimulation(setup):
2697 simulation = None 2698 for sim in empro.activeProject.simulations(): 2699 if setup.simulationPath == sim.simulationPath(): 2700 simulation = sim 2701 if simulation : 2702 return simulation 2703 else : 2704 raise RuntimeError("Simulation for the %s under path %s not Found"%(setup.name, setup.simulationPath))
2705
2706 # mode: 0 = run analyses, 1 = generate test bench, 2 = run circuit simulation 2707 -def runAnalysesAndCallAel(mode, aelFunctionName = '', **kwargs):
2708 import empro.toolkit.analysis.regression_tester as regression_tester 2709 tester = regression_tester.RegressionTester(mode, aelFunctionName, **kwargs) 2710 tester.runAnalysesAndCallAel()
2711
2712 2713 -class CircuitResultEvaluator:
2714
2715 - def __init__(self, sipiSetupData, verbose=False):
2716 2717 # loading impedance specification from the UI 2718 self.data = sipiSetupData 2719 temp = _getImpedanceSpecGenerators(sipiSetupData) 2720 self.impSpecGenerators = temp[0] 2721 self.ctiFileLocation = temp[1] 2722 2723 # loading the raw S-parameters 2724 import empro.enparams as enparams 2725 self.evaluator = enparams.CitiEvaluator(self.ctiFileLocation, False) 2726 self.Sstored = enparams.VectorOfScatteringMatrices(self.evaluator.nbPorts(),self.evaluator.nbStoredFrequencies()) 2727 self.evaluator.loadSampledSparameters(self.Sstored) 2728 2729 # name mappings 2730 self.names = {} 2731 self.activeComponents = [] 2732 for name, id in temp[2]: 2733 self.names[id[0]] = name 2734 self.activeComponents.append(id[0]) 2735 for name, id in temp[3]: 2736 self.names[id[0]] = name 2737 self.activeComponents.append(id[0]) 2738 for name, id in temp[4]: 2739 self.names[id[0]] = name 2740 self.activeComponents.append(id[0]) 2741 for name, id in temp[5]: 2742 self.names[id] = name 2743 self.name2id = {} 2744 for k,v in self.names.iteritems(): 2745 self.name2id[v] = k 2746 2747 self.Sloaded = None 2748 2749 if verbose: 2750 print "RAW PORTS:" 2751 keys = sorted(self.names.keys()) 2752 for key in keys: 2753 print "%3d : %s" % (key, self.names[key])
2754
2755 - def getNbComponents(self):
2756 return self.evaluator.nbPorts()
2757
2758 - def getNbActiveComponents(self):
2759 return len(self.activeComponents)
2760
2761 - def getImpedanceSpecifications(self, verbose):
2762 impSpecs = [] 2763 for comp, fun in self.impSpecGenerators: 2764 impSpecs.append(fun(comp)) 2765 for i in range(len(impSpecs)): 2766 impSpecs[i].name = self.names[i] 2767 if verbose: 2768 print "IMPEDANCE SPECIFICATIONS:" 2769 cnt = 0 2770 for impSpec in impSpecs: 2771 print "%3d: %s" % (cnt, impSpec.str()) 2772 cnt += 1 2773 return impSpecs
2774
2775 - def str(self):
2776 result = "" 2777 result += "Result Evaluator for <%s>" % self.data.name 2778 result += "\n\tsimulation directory: %s" % self.data.simulationPath 2779 impSpecs = self.getImpedanceSpecifications() 2780 cnt = 0 2781 for impSpec in impSpecs: 2782 cnt += 1 2783 result += "\n\tcomponent %3d: %s" % (cnt, impSpec.str()) 2784 return result
2785
2786 - def refreshLoadedSparameters(self, Zref=50, verbose=False):
2787 import empro.enparams as enparams 2788 if not self.Sloaded or self.Sloaded.nbPorts()!=self.getNbActiveComponents() or self.Sloaded.nbFrequencies()!=self.evaluator.nbStoredFrequencies(): 2789 self.Sloaded = enparams.VectorOfScatteringMatrices(self.getNbActiveComponents(),self.evaluator.nbStoredFrequencies()) 2790 self.Sstored.reduce(self.getImpedanceSpecifications(verbose), self.activeComponents, Zref, self.Sloaded)
2791
2792 - def getVectorOfSparameters(self, Zref=50, refresh=False, verbose=False):
2793 import empro.enparams as enparams 2794 if not self.Sloaded or refresh: 2795 self.refreshLoadedSparameters(Zref, verbose) 2796 return self.Sloaded
2797
2798 2799 -def loadDisplayResourceFiles(workingDirectory=None, drfPath=None):
2800 import os 2801 import empro.core 2802 # if a toolspecific displayresource file is availble (saved by the platform), use it instead of the default search mechnism 2803 toolDisplayDrf = os.path.join(workingDirectory or os.getcwd(), "_" + empro.core.ApplicationInfo.personality() + "Display.drf") 2804 if os.path.exists(toolDisplayDrf): 2805 empro.liboa.loadDisplayResourceFile(toolDisplayDrf) 2806 #print "loading display resources from %s" % toolDisplayDrf 2807 if drfPath: 2808 empro.liboa.loadDisplayResourceFile(drfPath) 2809 else: 2810 cdsInstDir = os.getenv("CDS_INST_DIR") 2811 if cdsInstDir: 2812 empro.liboa.loadDisplayResourceFile(os.path.join(cdsInstDir, "share/cdssetup/dfII/default.drf")) 2813 if drfPath: 2814 empro.liboa.loadDisplayResourceFile(drfPath) 2815 cdsSite = os.getenv("CDS_SITE") 2816 if cdsSite: 2817 empro.liboa.loadDisplayResourceFile(os.path.join(cdsSite, "display.drf")) 2818 cdsProject = os.getenv("CDS_PROJECT") 2819 if cdsProject: 2820 empro.liboa.loadDisplayResourceFile(os.path.join(cdsProject, "display.drf")) 2821 empro.liboa.loadDisplayResourceFile(os.path.expanduser("~/display.drf")) 2822 empro.liboa.loadDisplayResourceFile(os.path.join(workingDirectory or os.getcwd(), "display.drf"))
2823
2824 2825 -def loadSimulatorSetupPresets(dirname):
2826 import os 2827 for fname in os.listdir(dirname): 2828 if not fname.endswith('.simulatorsetup.xml'): 2829 continue 2830 path = os.path.join(dirname, fname) 2831 try: 2832 preset = empro.simulation.SimulatorSetup.fromFile(path) 2833 empro.simulation.SimulatorSetup.addAvailablePreset(preset) 2834 except RuntimeError as err: 2835 print "Failed to load SimulatorSetup preset '{}': {}".format(path, err)
2836
2837 -def _generateSMPSFreqPlan(freqPlan):
2838 SMPS_NZTORIP = 6 2839 SMPS_NRIPHARM = 10 2840 SMPS_NRIPHARMTOSWDEC = 5 2841 SMPS_NSWHARM = 40 2842 SMPS_NSWHARMTOMAXDEC = 20 2843 SMPS_DEFAULTRIP = 1.0e3 2844 SMPS_MAXFREQSCALE = 5.0 2845 SMPS_MAXFREQCAP = 2.0e9 2846 2847 sw = freqPlan.switchingFrequency 2848 rp = freqPlan.rippleFrequency 2849 tr = freqPlan.riseTime 2850 tf = freqPlan.fallTime 2851 2852 if rp.formula() == "" or rp.formula() == None: 2853 rp = SMPS_DEFAULTRIP 2854 elif not rp.isValid() or rp <= 0.0: 2855 raise RuntimeError("SMPS frequency plan is invalid\nRipple frequency is invalid") 2856 2857 if (not sw.isValid()) or sw <= 0.0: 2858 raise RuntimeError("SMPS frequency plan is invalid\nSwitching frequency is invalid") 2859 if (not tr.isValid()) or tr <= 0.0: 2860 raise RuntimeError("SMPS frequency plan is invalid\nRise time is invalid") 2861 if (not tf.isValid()) or tf <= 0.0: 2862 raise RuntimeError("SMPS frequency plan is invalid\nFall time is invalid") 2863 2864 # get max freq in Hz 2865 fmax = min(1.0/min(tr, tf)*SMPS_MAXFREQSCALE, SMPS_MAXFREQCAP) 2866 2867 smpsplan = [] 2868 # construct SMPS frequency plan, DC to AC/ripple 2869 newFp = empro.simulation.FrequencyPlan() 2870 newFp.type = "Linear" 2871 newFp.startFrequency = 0.0 2872 newFp.stopFrequency = rp 2873 newFp.frequencyStep = rp/(SMPS_NZTORIP-1) 2874 newFp.numberOfFrequencyPoints = SMPS_NZTORIP 2875 newFp.enabled = True 2876 smpsplan.append(newFp) 2877 # AC/rippel to its harmonics 2878 newFp = empro.simulation.FrequencyPlan() 2879 newFp.type = "Linear" 2880 newFp.startFrequency = rp 2881 newFp.stopFrequency = rp*SMPS_NRIPHARM 2882 newFp.frequencyStep = rp 2883 newFp.enabled = True 2884 smpsplan.append(newFp) 2885 # AC/ripple*Harm to switching 2886 if rp*SMPS_NRIPHARM < sw: 2887 newFp = empro.simulation.FrequencyPlan() 2888 newFp.type = "Logarithmic" 2889 newFp.startFrequency = rp*SMPS_NRIPHARM 2890 newFp.stopFrequency = sw 2891 newFp.pointsPerDecade = SMPS_NRIPHARMTOSWDEC 2892 newFp.numberOfFrequencyPoints = _getNumPointsFromDecade(newFp.startFrequency, newFp.stopFrequency, newFp.pointsPerDecade) 2893 newFp.enabled = True 2894 smpsplan.append(newFp) 2895 # switching to its harmonics 2896 newFp = empro.simulation.FrequencyPlan() 2897 newFp.type = "Linear" 2898 newFp.startFrequency = sw 2899 newFp.stopFrequency = sw*SMPS_NSWHARM 2900 newFp.frequencyStep = sw 2901 newFp.enabled = True 2902 smpsplan.append(newFp) 2903 # to max 2904 if sw*SMPS_NSWHARM < fmax: 2905 newFp = empro.simulation.FrequencyPlan() 2906 newFp.type = "Logarithmic" 2907 newFp.startFrequency = sw*SMPS_NSWHARM 2908 newFp.stopFrequency = fmax 2909 newFp.pointsPerDecade = SMPS_NSWHARMTOMAXDEC 2910 newFp.numberOfFrequencyPoints = _getNumPointsFromDecade(newFp.startFrequency, newFp.stopFrequency, newFp.pointsPerDecade) 2911 newFp.enabled = True 2912 smpsplan.append(newFp) 2913 return smpsplan
2914
2915 -def _getNumPointsFromDecade(start, stop, perdec):
2916 import math 2917 numDec = math.log10(stop/start) 2918 return max(int(math.ceil(numDec*perdec))+1, 2)
2919