Package empro :: Package toolkit :: Package analysis :: Package dc :: Module output
[frames] | no frames]

Source Code for Module empro.toolkit.analysis.dc.output

   1  # Copyright 1983-2019 Keysight Technologies, Inc , Keysight Confidential  
   2  from empro.toolkit import _printexception, Bunch 
   3  from docx import Document 
   4  from docx.shared import Inches 
   5  from topology import Topology 
   6  from topology import TopologyElement 
   7  from topology import TopologyConnection 
   8   
9 -def _htmlTable(header, data):
10 text = u'<table class="table table-condensed">' 11 text+= u'<thead><tr>' + u''.join([u'<th>%s</th>' % h for h in header]) + u'</tr></thead>' 12 text+= u'<tbody>' 13 for d in data: 14 text += u'<tr>' + u''.join([u'<th>%s</th>' % x for x in d]) + u'</tr>\n' 15 text+= u'</tbody></table>' 16 return text
17 18
19 -class Html(object):
20 - def __init__(self, result, tableInfo, maxCurrent, maxTemperature, showViolatingCurrent, showViolatingT, **kwargs):
21 """ 22 kwargs 23 'figures' any of "ALL", "TOP_BOTTOM", [id1,id2]. The default is 'ALL' 24 """ 25 import os 26 import empro 27 self._result = result 28 self._tableInfo = tableInfo 29 self._maxCurrent = maxCurrent 30 self._maxTemperature = maxTemperature 31 self._showViolatingCurrent = showViolatingCurrent 32 self._showViolatingT = showViolatingT 33 self._showDifference = isinstance(self._result, empro.toolkit.analysis.dc.results.DCResultsDiff) 34 self.templatesLocation = '.' 35 self.figuresLocation = '.' 36 self.name = '' 37 self._vars = {} 38 self._temperatureFormat = "%4.1f" 39 self._voltageFormat = "%6.5f" 40 self._currentDensityFormat = "%5.1f" 41 self._epsRFormat = "%3.1f" 42 self._lossTangentFormat = "%4.3f" 43 self._conductivityFormat = "%7.0f S/m" 44 self._layerStatistics = self._result.layerStatistics 45 zSortedLayerNames = [ (k,v['zMax'],v['zMin']) for (k,v) in self._layerStatistics.iteritems()] 46 self._zSortedLayerNames = sorted(zSortedLayerNames, key=lambda x:(-x[2],-x[1])) 47 parts = empro.activeProject.geometry().flatList(True) 48 conductorsName = [] 49 self.topBottomTemperatureLayersIds = [] 50 self.topBottomVoltageLayersIds = [] 51 self.topBottomCurrentLayersIds = [] 52 self.topBottomPowerdensityLayersIds = [] 53 for part in parts: 54 if isinstance(part,empro.geometry.OaConductiveLayer): 55 conductorsName.append(part.name) 56 conductiveLayers = [] 57 for item in self._zSortedLayerNames: 58 if item[0] in conductorsName: 59 conductiveLayers.append(item) 60 self._nameToLayerId = {} 61 for k,v in self._layerStatistics.iteritems(): 62 self._nameToLayerId[k] = v['layerId'] 63 toKeepLayers = [self._nameToLayerId[conductiveLayers[-1][0]],self._nameToLayerId[conductiveLayers[0][0]]] 64 index = 0 65 if not self._tableInfo == []: 66 temperatureToKeepLayers = [] 67 voltageToKeepLayers = [] 68 currentToKeepLayers = [] 69 powerdensityToKeepLayers = [] 70 for i in range(len(self._tableInfo)-2): 71 if self._tableInfo[i][1] == True: 72 temperatureToKeepLayers.append(self._nameToLayerId[self._zSortedLayerNames[index][0]]) 73 if self._tableInfo[i][2] == True: 74 voltageToKeepLayers.append(self._nameToLayerId[self._zSortedLayerNames[index][0]]) 75 if self._tableInfo[i][3] == True: 76 currentToKeepLayers.append(self._nameToLayerId[self._zSortedLayerNames[index][0]]) 77 if self._tableInfo[i][4] == True: 78 powerdensityToKeepLayers.append(self._nameToLayerId[self._zSortedLayerNames[index][0]]) 79 index = index + 1 80 if self._tableInfo[len(self._tableInfo)-2][1] == True: 81 self.topBottomTemperatureLayersIds.append(-2) 82 if self._tableInfo[len(self._tableInfo)-1][1] == True: 83 self.topBottomTemperatureLayersIds.append(-3) 84 if self._tableInfo[len(self._tableInfo)-2][2] == True: 85 self.topBottomVoltageLayersIds.append(-2) 86 if self._tableInfo[len(self._tableInfo)-1][2] == True: 87 self.topBottomVoltageLayersIds.append(-3) 88 if self._tableInfo[len(self._tableInfo)-2][3] == True: 89 self.topBottomCurrentLayersIds.append(-2) 90 if self._tableInfo[len(self._tableInfo)-1][3] == True: 91 self.topBottomCurrentLayersIds.append(-3) 92 if self._tableInfo[len(self._tableInfo)-2][4] == True: 93 self.topBottomPowerdensityLayersIds.append(-2) 94 if self._tableInfo[len(self._tableInfo)-1][4] == True: 95 self.topBottomPowerdensityLayersIds.append(-3) 96 self._temperatureIds = [-1]+[v['layerId'] for k,v in self._layerStatistics.iteritems() if v['layerId'] not in temperatureToKeepLayers] 97 self._voltageIds = [-1]+[v['layerId'] for k,v in self._layerStatistics.iteritems() if v['layerId'] not in voltageToKeepLayers] 98 self._currentIds = [-1]+[v['layerId'] for k,v in self._layerStatistics.iteritems() if v['layerId'] not in currentToKeepLayers] 99 self._powerdensityIds = [-1]+[v['layerId'] for k,v in self._layerStatistics.iteritems() if v['layerId'] not in powerdensityToKeepLayers] 100 self._bottomTopIds = [-1]+[v['layerId'] for k,v in self._layerStatistics.iteritems() if v['layerId'] not in toKeepLayers] 101 self._figuresOptions = kwargs.get('figures','ALL') 102 self._topBottomFigures = True 103 self.progressCallback = self._dummyCallback
104
105 - def _dummyCallback(self,arg1,arg2):
106 pass
107
108 - def _fillVariables(self):
109 import datetime 110 import empro 111 parts = empro.activeProject.geometry().flatList(True) 112 substrateInfo = {} 113 diels = {} 114 vias = {} 115 conductors = {} 116 for part in parts: 117 if isinstance(part,empro.geometry.OaLayout): 118 self._vars['designName'] = part._designRef.cell 119 if isinstance(part,empro.geometry.OaDielectricLayer): 120 epsR = '---' 121 lossTangent = '---' 122 m = empro.activeProject.materials()[part.material.name] 123 if hasattr(m.details.electricProperties.parameters,'relativePermittivity'): 124 epsR = m.details.electricProperties.parameters.relativePermittivity 125 if hasattr(m.details.electricProperties.parameters,'lossTangent'): 126 lossTangent = m.details.electricProperties.parameters.lossTangent 127 diels[part.name] = Bunch(name=part.name,materialName=part.material.name,thickness=part.thickness,layerNumber=part._layerNumber,Er=epsR,lossTangent=lossTangent) 128 if isinstance(part,empro.geometry.OaConductiveLayer): 129 conductivity = '---' 130 m = empro.activeProject.materials()[part.material.name] 131 if hasattr(m.details.electricProperties.parameters,'conductivity'): 132 conductivity = m.details.electricProperties.parameters.conductivity 133 conductors[part.name] = Bunch(name=part.name,materialName=part.material.name,thickness=part.thickness,layerNumber=part._layerNumber,conductivity=conductivity) 134 if isinstance(part,empro.geometry.OaViaLayer): 135 vias[part.name] = Bunch(name=part.name,materialName=part.material.name,layerNumber=part._layerNumber) 136 137 substrateInfo['conductors'] = conductors 138 substrateInfo['dielectrics'] = diels 139 substrateInfo['vias'] = vias 140 self._vars['substrate'] = substrateInfo 141 try: 142 self._vars['analysisName'] = self._result.resultName 143 except: 144 self._vars['analysisName'] = "%s vs %s" % (tuple(self._result.resultNames)) 145 self._vars['reportGenerationTime'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
146
147 - def generate(self, targetFileName):
148 import os 149 self.name = os.path.split(targetFileName)[1] 150 self._fillVariables() 151 self._generateFigures() 152 text = u'<!DOCTYPE html><html lang="en">' 153 text += self._head() 154 text += u'<body>' 155 text += self._leadIn() 156 text += self._overview() 157 text += self._powerGraph() 158 text += self._designInfo() 159 text += self._sinks() 160 text += self._vrms() 161 text += self._vias() 162 text += self._thermalComponents() 163 text += self._layers() 164 text += u'</body>' 165 text += '</html>' 166 return text
167
168 - def _generateFigures(self):
169 import empro 170 import os 171 assert(self.figuresLocation!="") 172 try: 173 setup = self._result.sipiData 174 meshFn = os.path.join(setup.simulationPath,"design.out.ovm") 175 try: 176 os.makedirs(os.path.join(self.figuresLocation,"figures_for_"+self.name)) 177 except OSError: 178 pass 179 if not self._tableInfo == []: 180 self._figuresMetaData = empro.graphing.generatePlotsFromMesh(meshFn, os.path.join(self.figuresLocation,"figures_for_"+self.name), self._temperatureIds, True, self._voltageIds, False, self._currentIds, False, self._powerdensityIds, False, self.topBottomTemperatureLayersIds, self.topBottomVoltageLayersIds, self.topBottomCurrentLayersIds, self.topBottomPowerdensityLayersIds, self.progressCallback) 181 else: 182 self._figuresMetaData = empro.graphing.generatePlotsFromMesh(meshFn, os.path.join(self.figuresLocation,"figures_for_"+self.name), self._bottomTopIds, True, [], True, [], True, [], True, [], [-2,-3], [-2,-3], [-2,-3], self.progressCallback) 183 except: 184 setup1 = self._result.sipiDatas[0] 185 meshFn1 = os.path.join(setup1.simulationPath,"design.out.ovm") 186 setup2 = self._result.sipiDatas[1] 187 meshFn2 = os.path.join(setup2.simulationPath,"design.out.ovm") 188 try: 189 os.makedirs(os.path.join(self.figuresLocation,"figures_for_"+self.name)) 190 except OSError: 191 pass 192 self._figuresMetaData = empro.graphing.generatePlotsFromMeshes(meshFn1, meshFn2, os.path.join(self.figuresLocation,"figures_for_"+self.name), self._bottomTopIds, True, self.progressCallback)
193
194 - def _variables(self):
195 return self._vars
196
197 - def _head(self):
198 import string 199 import os 200 fn = os.path.join(self.templatesLocation,'head.html') 201 template = string.Template(open(fn).read()) 202 keyValues = self._variables() 203 return template.safe_substitute(keyValues)
204
205 - def _leadIn(self):
206 import string 207 import os 208 fn = os.path.join(self.templatesLocation,'leadIn.html') 209 template = string.Template(open(fn).read()) 210 keyValues = self._variables() 211 return template.safe_substitute(keyValues)
212
213 - def _overview(self):
214 import string 215 import os 216 import empro 217 celsius = empro.units.unitByAbbreviation("degC") 218 if self._showDifference: 219 celsius = empro.units.unitByAbbreviation("K") 220 221 fn = os.path.join(self.templatesLocation,'overview.html') 222 template = string.Template(open(fn).read()) 223 try: 224 simData = self._result.sipiData.newSimulationData() 225 notes = simData.notes 226 ambientTemperature = float(simData.ambientConditions.backgroundTemperature) 227 except: 228 simData1 = self._result.sipiDatas[0].newSimulationData() 229 simData2 = self._result.sipiDatas[1].newSimulationData() 230 notes = simData1.notes 231 notes += "\n"+simData2.notes 232 ambientTemperature = float(simData1.ambientConditions.backgroundTemperature)-float(simData2.ambientConditions.backgroundTemperature) 233 234 if notes.replace('\n','').strip()=="": 235 notes = "No notes" 236 237 self._vars['ambientTemperature'] = "%3.1f" % celsius.fromReferenceUnits(ambientTemperature) + ' ' + celsius.abbreviation() 238 self._vars['notes'] = notes 239 keyValues = self._variables() 240 return template.safe_substitute(keyValues)
241
242 - def _powerGraph(self):
243 import string 244 import os 245 fn = os.path.join(self.templatesLocation,'powerGraph.html') 246 template = string.Template(open(fn).read()) 247 keyValues = self._variables() 248 pwrTreeImgNm = os.path.join(self.figuresLocation,"figures_for_"+self.name,"powerGraph.png") 249 import empro 250 import empro.gui 251 import empro.toolkit.analysis.dc.output 252 scn = empro.gui.GraphicsScene() 253 empro.toolkit.analysis.dc.output._powerGraphSceneFromResults(scn,self._result) 254 scn._save(pwrTreeImgNm) 255 #picLoc = pwrTreeImgNm.replace('\\','/') 256 #picLoc = r"file:///" + picLoc 257 picLoc = os.path.join(r"./","figures_for_"+self.name,"powerGraph.png") 258 picLoc = picLoc.replace('\\','/') 259 powerGraphImg = '<img src="%(picLoc)s"></img>' % vars() 260 if not self._result.vrms or not self._result.sinks: 261 self._vars['powerGraph'] = "" 262 else: 263 self._vars['powerGraph'] = powerGraphImg 264 return template.safe_substitute(keyValues)
265
266 - def _vrms(self):
267 import string 268 import os 269 fn = os.path.join(self.templatesLocation,'vrms.html') 270 template = string.Template(open(fn).read()) 271 272 vrms = [] 273 for index, vrm in enumerate(self._result.vrms): 274 row = [vrm.name, vrm.sourceVoltage, vrm.outputVoltage ,vrm.outputCurrent, vrm.tolerance, vrm.margin] 275 if not self._showDifference: 276 row.append(vrm.result) 277 vrms.append(row) 278 279 deltaSymbol = '' 280 header = ["Name", deltaSymbol+"Source\nVoltage [V]", deltaSymbol+"Output\nVoltage [V]", deltaSymbol+"Output\nCurrent [A]", "Tolerance", deltaSymbol+"Margin [V]", "Pass/Fail"] 281 self._vars['vrmTable'] = _htmlTable(header,vrms) 282 283 keyValues = self._variables() 284 return template.safe_substitute(keyValues)
285
286 - def _viasBulk(self):
287 import empro 288 import math 289 self.vias = [] 290 lengthUnit = empro.units.unitByAbbreviation("um") 291 areaUnit = empro.units.unitByAbbreviation("squm") 292 celsius = empro.units.unitByAbbreviation("degC") 293 if self._showDifference: 294 celsius = empro.units.unitByAbbreviation("K") 295 localParamList = empro.activeProject.parameters().clone() 296 localParamList.append("Radius",0.0) 297 localParamList.append("Plating",0.0) 298 localParamList.append("Area",0.0) 299 numberOfViolatingVias = 0 300 numberOfViolatingViasT = 0 301 for key, via in self._result.viaCurrents.iteritems(): 302 viaCurrent = float(via[0]) 303 viaTemperature = celsius.fromReferenceUnits(self._result.viaMaxTemperatures.get(key,298.15)) 304 radius, plating = self._result.viaRadiusThickness.get(key,(-1,-1)) 305 localParamList.setFormula("Radius",radius) 306 localParamList.setFormula("Plating",plating) 307 area = math.pi*radius*radius 308 if plating>0.0: 309 area -= math.pi*(radius-plating)*(radius-plating) 310 localParamList.setFormula("Area",area) 311 maxCurrent = empro.core.Expression(self._maxCurrent).evaluate(localParamList) 312 maxT = celsius.fromReferenceUnits(empro.core.Expression(self._maxTemperature).evaluate(localParamList)) 313 314 currentIsPassed = False 315 if float(via[0]) < maxCurrent: 316 currentIsPassed = True 317 else: 318 numberOfViolatingVias += 1 319 tempIsPassed = viaTemperature < maxT 320 if not tempIsPassed: 321 numberOfViolatingViasT += 1 322 323 hideRow = (self._showViolatingCurrent and currentIsPassed) or (self._showViolatingT and tempIsPassed) 324 radiusStr = lengthUnit.fromReferenceUnits(radius) 325 platingStr = lengthUnit.fromReferenceUnits(plating) 326 areaStr = areaUnit.fromReferenceUnits(area) 327 passOrFail = "" 328 if (not currentIsPassed) and tempIsPassed: 329 passOrFail = "Current fail" 330 elif currentIsPassed and (not tempIsPassed): 331 passOrFail = "Temperature fail" 332 elif (not currentIsPassed) and (not tempIsPassed): 333 passOrFail = "Both Current and T fail" 334 else: 335 passOrFail = "Pass" 336 if not hideRow: 337 if (not currentIsPassed) or (not tempIsPassed): 338 row = [str(key), viaCurrent, viaTemperature, radiusStr, platingStr, areaStr, passOrFail] 339 self.vias.append(row) 340 self.maximumCurrent = "Maximum Current: " + self._maxCurrent + " (" + "%d"%numberOfViolatingVias + " Violations)" 341 self.maximumTemperature = "Maximum Temperature: " + self._maxTemperature + " (" + "%d"%numberOfViolatingViasT + " Violations)" 342 deltaSymbol = '' 343 self.viasHeader = ["Id", deltaSymbol+"Current [A]", deltaSymbol+"T [degC]", deltaSymbol+"Radius [um]", deltaSymbol+"Plating [um]", deltaSymbol+"Area [um**2]", "Pass/Fail"] 344 return
345
346 - def _vias(self):
347 import string 348 import os 349 fn = os.path.join(self.templatesLocation,'vias.html') 350 template = string.Template(open(fn).read()) 351 self._viasBulk() 352 self._vars['maxCurrent'] = self.maximumCurrent 353 self._vars['maxTemperature'] = self.maximumTemperature 354 self._vars['viasTable'] = _htmlTable(self.viasHeader, self.vias) 355 keyValues = self._variables() 356 return template.safe_substitute(keyValues)
357
358 - def _thermalComponents(self):
359 import string 360 import os 361 fn = os.path.join(self.templatesLocation,'thermalComponents.html') 362 template = string.Template(open(fn).read()) 363 364 import empro 365 celsius = empro.units.unitByAbbreviation("degC") 366 if self._showDifference: 367 celsius = empro.units.unitByAbbreviation("K") 368 degUnit = 'T ['+celsius.abbreviation()+']' 369 degSymbol = '['+celsius.abbreviation()+']' 370 371 comps = [] 372 for index, source in enumerate(self._result.thermalComponents): 373 if hasattr(source,'heat'): 374 row = [source.name, source.heat, '---','---'] 375 else: 376 row = [source.name, source.heatDie, source.heatBoard, source.heatCase] 377 if hasattr(source,"temperature"): 378 row += [self._temperatureFormat % celsius.fromReferenceUnits(source.temperature), "---","---","---", source.bareBoardThermalResistance] 379 else: 380 row += ["---", self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureBoard), self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureDie), self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureCase), source.bareBoardThermalResistance] 381 comps.append(row) 382 383 deltaSymbol = '' 384 385 header = ["Name", deltaSymbol+"Source [W]", deltaSymbol+"Heat To\nBoard [W]", deltaSymbol+"Heat To\nCase [W]", deltaSymbol+degUnit,deltaSymbol+"Case Bottom\n"+degUnit, deltaSymbol+"Die "+degUnit, deltaSymbol+"Case Top "+degUnit, deltaSymbol+"Thermal Resistance\nBare Board [K/W]"] 386 self._vars['thermalComponentsTable'] = _htmlTable(header,comps) 387 388 keyValues = self._variables() 389 return template.safe_substitute(keyValues)
390
391 - def _sinks(self):
392 import string 393 import os 394 fn = os.path.join(self.templatesLocation,'sinks.html') 395 template = string.Template(open(fn).read()) 396 397 sinks = [] 398 for index, sink in enumerate(self._result.sinks): 399 row = [sink.name, sink.sourceCurrent, sink.vrmVoltage,sink.inputVoltage,sink.resistance, sink.tolerance, sink.margin] 400 if not self._showDifference: 401 row.append(sink.result) 402 sinks.append(row) 403 404 deltaSymbol = '' 405 header = ["Name", "Source\nCurrent [A]", "VRM\nVoltage [V]", deltaSymbol+"Input\n Voltage [V]", deltaSymbol+"Resistance\n [Ohm]", "Tolerance", deltaSymbol+"Margin [V]", "Pass/Fail"] 406 self._vars['sinksTable'] = _htmlTable(header,sinks) 407 408 keyValues = self._variables() 409 return template.safe_substitute(keyValues)
410 411
412 - def _designInfo(self):
413 import string 414 import os 415 import empro 416 lengthUnit = empro.activeProject.displayUnits['LENGTH'] 417 def _formatOr(format, value): 418 try: 419 if value=='---': 420 return value 421 except: 422 return value 423 return format % value
424 425 def _asLength(x): 426 return '%f %s' % (lengthUnit.fromReferenceUnits(float(x)), lengthUnit.abbreviation())
427 428 fn = os.path.join(self.templatesLocation,'designInfo.html') 429 template = string.Template(open(fn).read()) 430 431 dielInfo = [] 432 for k,v in self._vars['substrate']['dielectrics'].iteritems(): 433 dielInfo.append([v.name, v.materialName, _asLength(abs(float(v.thickness))),_formatOr(self._epsRFormat, v.Er), _formatOr(self._lossTangentFormat,v.lossTangent)]) 434 435 condInfo = [] 436 for k,v in self._vars['substrate']['conductors'].iteritems(): 437 condInfo.append([v.name, v.materialName, _asLength(abs(float(v.thickness))),_formatOr(self._conductivityFormat,v.conductivity)]) 438 439 viaInfo = [] 440 for k,v in self._vars['substrate']['vias'].iteritems(): 441 viaInfo.append([v.name, v.materialName]) 442 443 self._vars['dielectricsTable'] = _htmlTable(['Name','Material','Thickness','Er','LossTangent'],dielInfo) 444 self._vars['conductorsTable'] = _htmlTable(['Name','Material','Thickness','Conductivity'],condInfo) 445 self._vars['viasTable'] = _htmlTable(['Name','Material'],viaInfo) 446 keyValues = self._variables() 447 448 return template.safe_substitute(keyValues) 449
450 - def _layers(self):
451 import string 452 import os 453 import empro 454 455 temperatureMetaData = [x for x in self._figuresMetaData if 'outputType' in x and x['outputType']=='temperature'] 456 voltageMetaData = [x for x in self._figuresMetaData if 'outputType' in x and x['outputType']=='voltage'] 457 powerLossDensityMetaData = [x for x in self._figuresMetaData if 'outputType' in x and x['outputType']=='powerLossDensity'] 458 currentMetaData = [x for x in self._figuresMetaData if 'outputType' in x and x['outputType']=='current'] 459 460 fn = os.path.join(self.templatesLocation,'layers.html') 461 template = string.Template(open(fn).read()) 462 463 celsius = empro.units.unitByAbbreviation("degC") 464 if self._showDifference: 465 celsius = empro.units.unitByAbbreviation("K") 466 degUnit = 'T ['+celsius.abbreviation()+']' 467 degSymbol = '['+celsius.abbreviation()+']' 468 469 temperatureDataIds = set([int(x['layerId']) for x in temperatureMetaData]) 470 voltageDataIds = set([int(x['layerId']) for x in voltageMetaData]) 471 currentDataIds = set([int(x['layerId']) for x in currentMetaData]) 472 powerLossDensityDataIds = set([int(x['layerId']) for x in powerLossDensityMetaData]) 473 474 layerInfo = [] 475 for layer in self._zSortedLayerNames: 476 layerName = layer[0] 477 layerStats = self._layerStatistics[layerName] 478 layerNr = layerStats['layerId'] 479 layerLinks = '' 480 if temperatureMetaData and layerNr in temperatureDataIds: 481 layerLinks += r'<a class="btn btn-primary btn-sm" href="#temp_%(layerNr)d"><span class="glyphicon glyphicon-link"></span> T</a>' % vars() 482 if voltageMetaData and layerNr in voltageDataIds: 483 layerLinks +=r'<a class="btn btn-primary btn-sm" href="#voltage_%(layerNr)d"><span class="glyphicon glyphicon-link"></span> V</a>' % vars() 484 if currentMetaData and layerNr in currentDataIds: 485 layerLinks +=r'<a class="btn btn-primary btn-sm" href="#current_%(layerNr)d"><span class="glyphicon glyphicon-link"></span> A</a>' % vars() 486 if powerLossDensityMetaData and layerNr in powerLossDensityDataIds: 487 layerLinks +=r'<a class="btn btn-primary btn-sm" href="#powerLossDensity_%(layerNr)d"><span class="glyphicon glyphicon-link"></span> W/(m*m)</a>' % vars() 488 row = [layerName, layerLinks, self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMin"]), self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMax"]), self._currentDensityFormat % (layerStats["currentMin"]*1e-6),self._currentDensityFormat % (layerStats["currentMax"]*1e-6),self._voltageFormat % layerStats["voltageMin"],self._voltageFormat % layerStats["voltageMax"]] 489 layerInfo.append(row) 490 491 for layerId in [-2,-3]: 492 layerName = {-2 : "top", -3 : "bottom"}[layerId] 493 494 layerNr = layerId 495 layerLinks = '' 496 if temperatureMetaData and layerNr in temperatureDataIds: 497 layerLinks += r'<a class="btn btn-primary btn-sm" href="#temp_%(layerNr)d"><span class="glyphicon glyphicon-link"></span> T</a>' % vars() 498 if voltageMetaData and layerNr in voltageDataIds: 499 layerLinks +=r'<a class="btn btn-primary btn-sm" href="#voltage_%(layerNr)d"><span class="glyphicon glyphicon-link"></span> V</a>' % vars() 500 if currentMetaData and layerNr in currentDataIds: 501 layerLinks +=r'<a class="btn btn-primary btn-sm" href="#current_%(layerNr)d"><span class="glyphicon glyphicon-link"></span> A</a>' % vars() 502 if powerLossDensityMetaData and layerNr in powerLossDensityDataIds: 503 layerLinks +=r'<a class="btn btn-primary btn-sm" href="#powerLossDensity_%(layerNr)d"><span class="glyphicon glyphicon-link"></span> W/(m*m)</a>' % vars() 504 #layerStats = self._layerStatistics[layerName] 505 #row = [layerName, layerLinks, self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMin"]), self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMax"]), self._currentDensityFormat % (layerStats["currentMin"]*1e-6),self._currentDensityFormat % (layerStats["currentMax"]*1e-6),self._voltageFormat % layerStats["voltageMin"],self._voltageFormat % layerStats["voltageMax"]] 506 row = [layerName, layerLinks, '---', '---', '---','---','---','---'] 507 layerInfo.append(row) 508 509 510 511 deltaSymbol = '' 512 header = ["Layer", "", deltaSymbol + "Min "+degUnit,deltaSymbol + deltaSymbol+"Max "+degUnit, deltaSymbol+"Min Current\nDensity [A/mm**2]", deltaSymbol+"Max Current\nDensity [A/mm**2]",deltaSymbol+"Min\nVoltage [V]", deltaSymbol+"Max\nVoltage [V]"] 513 self._vars['layersTable'] = _htmlTable(header,layerInfo) 514 515 tempHeader = ['Name','Scale','Plot'] 516 voltageHeader = ['Name','Scale','Plot'] 517 currentHeader = ['Name','Scale','Plot'] 518 powerLossDensityHeader = ['Name','Scale','Plot'] 519 tempInfo = [] 520 voltageInfo = [] 521 currentInfo = [] 522 powerLossDensityInfo = [] 523 524 525 for layer in self._zSortedLayerNames: 526 layerName = layer[0] 527 layerStats = self._layerStatistics[layerName] 528 metaData = [x for x in temperatureMetaData if 'layerId' in x and int(x['layerId'])==int(layerStats['layerId'])] 529 if not metaData: 530 continue 531 metaData = metaData[0] 532 picLoc = metaData['fileName'] 533 #picLoc = picLoc.replace('\\','/') 534 #picLoc = r"file:///" + picLoc 535 picName = os.path.basename(picLoc) 536 picLoc = os.path.join(r"./","figures_for_"+self.name,picName) 537 picLoc = picLoc.replace('\\','/') 538 scaleStr = (self._temperatureFormat + " - " + self._temperatureFormat + " " + degSymbol) % (celsius.fromReferenceUnits(float(metaData["minValue"])),celsius.fromReferenceUnits(float(metaData["maxValue"]))) 539 layerNr = layerStats['layerId'] 540 layerAnchor = r'<span id="temp_%(layerNr)d">%(layerName)s</span>' % vars() 541 row = [layerAnchor, scaleStr, '<img src="%(picLoc)s"></img>' % vars()] 542 tempInfo.append(row) 543 544 for layerId in [-2,-3]: 545 layerName = {-2 : "top", -3 : "bottom"}[layerId] 546 metaData = [x for x in temperatureMetaData if 'layerId' in x and int(x['layerId'])==layerId] 547 if not metaData: 548 continue 549 metaData = metaData[0] 550 picLoc = metaData['fileName'] 551 #picLoc = picLoc.replace('\\','/') 552 #picLoc = r"file:///" + picLoc 553 picName = os.path.basename(picLoc) 554 picLoc = os.path.join(r"./","figures_for_"+self.name,picName) 555 picLoc = picLoc.replace('\\','/') 556 scaleStr = "%6.5f - %6.5f [V]" % (float(metaData["minValue"]),float(metaData["maxValue"])) 557 layerAnchor = r'<span id="temp_%(layerId)d">%(layerName)s</span>' % vars() 558 row = [layerAnchor, scaleStr, '<img src="%(picLoc)s"></img>' % vars()] 559 tempInfo.append(row) 560 561 prettyName = { 'power' : "Power" , 'ground' : "Ground", 'signal' : "Signal" } 562 563 for layer in self._zSortedLayerNames: 564 layerName = layer[0] 565 layerStats = self._layerStatistics[layerName] 566 for netType in ["power","ground","signal"]: 567 metaData = [x for x in voltageMetaData if 'layerId' in x and int(x['layerId'])==int(layerStats['layerId']) and 'netType' in x and x['netType']==netType] 568 if not metaData: 569 continue 570 metaData = metaData[0] 571 picLoc = metaData['fileName'] 572 #picLoc = picLoc.replace('\\','/') 573 #picLoc = r"file:///" + picLoc 574 picName = os.path.basename(picLoc) 575 picLoc = os.path.join(r"./","figures_for_"+self.name,picName) 576 picLoc = picLoc.replace('\\','/') 577 scaleStr = "%6.5f - %6.5f [V]" % (float(metaData["minValue"]),float(metaData["maxValue"])) 578 layerNr = layerStats['layerId'] 579 prettyNetType = prettyName[netType] 580 layerAnchor = r'<span id="voltage_%(layerNr)d">%(layerName)s - %(prettyNetType)s</span>' % vars() 581 row = [layerAnchor, scaleStr, '<img src="%(picLoc)s"></img>' % vars()] 582 voltageInfo.append(row) 583 584 for layerId in [-2,-3]: 585 layerName = {-2 : "top", -3 : "bottom"}[layerId] 586 for netType in ["power","ground","signal"]: 587 metaData = [x for x in voltageMetaData if 'layerId' in x and int(x['layerId'])==layerId and 'netType' in x and x['netType']==netType] 588 if not metaData: 589 continue 590 metaData = metaData[0] 591 picLoc = metaData['fileName'] 592 #picLoc = picLoc.replace('\\','/') 593 #picLoc = r"file:///" + picLoc 594 picName = os.path.basename(picLoc) 595 picLoc = os.path.join(r"./","figures_for_"+self.name,picName) 596 picLoc = picLoc.replace('\\','/') 597 scaleStr = "%6.5f - %6.5f [V]" % (float(metaData["minValue"]),float(metaData["maxValue"])) 598 prettyNetType = prettyName[netType] 599 layerAnchor = r'<span id="voltage_%(layerId)d">%(layerName)s - %(prettyNetType)s</span>' % vars() 600 row = [layerAnchor, scaleStr, '<img src="%(picLoc)s"></img>' % vars()] 601 voltageInfo.append(row) 602 603 for layer in self._zSortedLayerNames: 604 layerName = layer[0] 605 layerStats = self._layerStatistics[layerName] 606 for netType in ["power","ground","signal"]: 607 metaData = [x for x in currentMetaData if 'layerId' in x and int(x['layerId'])==int(layerStats['layerId']) and 'netType' in x and x['netType']==netType] 608 if not metaData: 609 continue 610 metaData = metaData[0] 611 picLoc = metaData['fileName'] 612 #picLoc = picLoc.replace('\\','/') 613 #picLoc = r"file:///" + picLoc 614 picName = os.path.basename(picLoc) 615 picLoc = os.path.join(r"./","figures_for_"+self.name,picName) 616 picLoc = picLoc.replace('\\','/') 617 scaleStr = "%6.5f - %6.5f [A/mm**2]" % (1e-6*float(metaData["minValue"]),1e-6*float(metaData["maxValue"])) 618 layerNr = layerStats['layerId'] 619 prettyNetType = prettyName[netType] 620 layerAnchor = r'<span id="current_%(layerNr)d">%(layerName)s - %(prettyNetType)s</span>' % vars() 621 row = [layerAnchor, scaleStr, '<img src="%(picLoc)s"></img>' % vars()] 622 currentInfo.append(row) 623 624 for layerId in [-2,-3]: 625 layerName = {-2 : "top", -3 : "bottom"}[layerId] 626 for netType in ["power","ground","signal"]: 627 metaData = [x for x in currentMetaData if 'layerId' in x and int(x['layerId'])==layerId and 'netType' in x and x['netType']==netType] 628 if not metaData: 629 continue 630 metaData = metaData[0] 631 picLoc = metaData['fileName'] 632 #picLoc = picLoc.replace('\\','/') 633 #picLoc = r"file:///" + picLoc 634 picName = os.path.basename(picLoc) 635 picLoc = os.path.join(r"./","figures_for_"+self.name,picName) 636 picLoc = picLoc.replace('\\','/') 637 scaleStr = "%6.5f - %6.5f [A/mm**2]" % (1e-6*float(metaData["minValue"]),1e-6*float(metaData["maxValue"])) 638 prettyNetType = prettyName[netType] 639 layerAnchor = r'<span id="current_%(layerId)d">%(layerName)s - %(prettyNetType)s</span>' % vars() 640 row = [layerAnchor, scaleStr, '<img src="%(picLoc)s"></img>' % vars()] 641 currentInfo.append(row) 642 643 for layer in self._zSortedLayerNames: 644 layerName = layer[0] 645 layerStats = self._layerStatistics[layerName] 646 for netType in ["power","ground","signal"]: 647 metaData = [x for x in powerLossDensityMetaData if 'layerId' in x and int(x['layerId'])==int(layerStats['layerId']) and 'netType' in x and x['netType']==netType] 648 if not metaData: 649 continue 650 metaData = metaData[0] 651 picLoc = metaData['fileName'] 652 #picLoc = picLoc.replace('\\','/') 653 #picLoc = r"file:///" + picLoc 654 picName = os.path.basename(picLoc) 655 picLoc = os.path.join(r"./","figures_for_"+self.name,picName) 656 picLoc = picLoc.replace('\\','/') 657 scaleStr = "%6.5f - %6.5f [W/mm**2]" % (1e-6*float(metaData["minValue"]),1e-6*float(metaData["maxValue"])) 658 layerNr = layerStats['layerId'] 659 prettyNetType = prettyName[netType] 660 layerAnchor = r'<span id="powerLossDensity_%(layerNr)d">%(layerName)s - %(prettyNetType)s</span>' % vars() 661 row = [layerAnchor, scaleStr, '<img src="%(picLoc)s"></img>' % vars()] 662 powerLossDensityInfo.append(row) 663 664 for layerId in [-2,-3]: 665 layerName = {-2 : "top", -3 : "bottom"}[layerId] 666 for netType in ["power","ground","signal"]: 667 metaData = [x for x in powerLossDensityMetaData if 'layerId' in x and int(x['layerId'])==layerId and 'netType' in x and x['netType']==netType] 668 if not metaData: 669 continue 670 metaData = metaData[0] 671 picLoc = metaData['fileName'] 672 #picLoc = picLoc.replace('\\','/') 673 #picLoc = r"file:///" + picLoc 674 picName = os.path.basename(picLoc) 675 picLoc = os.path.join(r"./","figures_for_"+self.name,picName) 676 picLoc = picLoc.replace('\\','/') 677 scaleStr = "%6.5f - %6.5f [W/mm**2]" % (1e-6*float(metaData["minValue"]),1e-6*float(metaData["maxValue"])) 678 prettyNetType = prettyName[netType] 679 layerAnchor = r'<span id="powerLossDensity_%(layerId)d">%(layerName)s - %(prettyNetType)s</span>' % vars() 680 row = [layerAnchor, scaleStr, '<img src="%(picLoc)s"></img>' % vars()] 681 powerLossDensityInfo.append(row) 682 683 if tempInfo: 684 layersTemperatureFiguresTable = _htmlTable(tempHeader,tempInfo) 685 else: 686 layersTemperatureFiguresTable = "" 687 if currentInfo: 688 layersCurrentFiguresTable = _htmlTable(currentHeader,currentInfo) 689 else: 690 layersCurrentFiguresTable = "" 691 if powerLossDensityInfo: 692 layersPowerLossDensityFiguresTable = _htmlTable(powerLossDensityHeader,powerLossDensityInfo) 693 else: 694 layersPowerLossDensityFiguresTable = "" 695 if voltageInfo: 696 layersVoltageFiguresTable = _htmlTable(voltageHeader,voltageInfo) 697 else: 698 layersVoltageFiguresTable = "" 699 700 self._vars['layersTemperatureFiguresTable'] = layersTemperatureFiguresTable 701 self._vars['layersVoltageFiguresTable'] = layersVoltageFiguresTable 702 self._vars['layersCurrentFiguresTable'] = layersCurrentFiguresTable 703 self._vars['layersPowerLossDensityFiguresTable'] = layersPowerLossDensityFiguresTable 704 705 keyValues = self._variables() 706 return template.safe_substitute(keyValues)
707 708
709 -def _interconnectedComponents(inResult): #deprecated?
710 interConnects = {} 711 for comp in inResult.components: 712 pinNetNames = [str(x.netName) for x in comp.pins if x.netType=="Power" or x.netType=="Signal"] 713 interConnects[comp.name] = Bunch(netNames=pinNetNames,vrms=[],sinks=[],component=comp) 714 715 for k,v in interConnects.iteritems(): 716 v.netNames = set(v.netNames) 717 718 for vrm in inResult.vrms: 719 pinNetNames = set([x.netName for x in vrm.pins if x.netType=="Power" or x.netType=="Signal"]) 720 for k,inter in interConnects.iteritems(): 721 intersection = pinNetNames.intersection(inter.netNames) 722 if intersection: 723 inter.vrms.append(vrm) 724 725 for sink in inResult.sinks: 726 pinNetNames = set([x.netName for x in sink.pins if x.netType=="Power" or x.netType=="Signal"]) 727 for k,inter in interConnects.iteritems(): 728 intersection = pinNetNames.intersection(inter.netNames) 729 if intersection: 730 inter.sinks.append(sink) 731 732 return interConnects 733
734 -def _connectedSinks(selVrm, sinks, interconnects): #deprecated?
735 selVrmNetNames = set([x.netName for x in selVrm.pins if x.netType=="Power" or x.netType=="Signal"]) 736 737 connectedSinks = [] 738 for sink in sinks: 739 pinNetNames = set([x.netName for x in sink.pins if x.netType=="Power" or x.netType=="Signal"]) 740 intersection = pinNetNames.intersection(selVrmNetNames) 741 if intersection: 742 connectedSinks.append(Bunch(sink=sink, interConnect=None)) 743 else: 744 for name, inter in interconnects.iteritems(): 745 interSinkNames = [x.name for x in inter.sinks] 746 interVrmNames = [x.name for x in inter.vrms] 747 if selVrm.name in interVrmNames and sink.name in interSinkNames: 748 connectedSinks.append(Bunch(sink=sink, interConnect=inter.component)) 749 break 750 751 return connectedSinks 752
753 -class SenseLine:
754 - def __init__(self, vrm):
755 self.name = "sense_" + vrm.name 756 self.vrmName = vrm.name 757 self.senseNetName = vrm.senseNetName
758 759
760 -def connectionLabel(fromPiece, toPiece):
761 import empro 762 layoutObj = empro.activeProject.layout 763 netNames1 = [] 764 netNames2 = [] 765 if fromPiece.instanceName: 766 instance = layoutObj.instanceByName(fromPiece.instanceName) 767 if fromPiece.pinPositionsOut: 768 for pinPos in fromPiece.pinPositionsOut: 769 pin = instance.instPin(pinPos) 770 netNames1.append(pin.netName) 771 elif fromPiece.topLevelPinName: 772 pinList = layoutObj.topLevelPins 773 for pin in pinList: 774 if pin.name == fromPiece.topLevelPinName: 775 netNames1.append(pin.netName) 776 777 if toPiece.instanceName: 778 instance = layoutObj.instanceByName(toPiece.instanceName) 779 if toPiece.pinPositionsIn: 780 for pinPos in toPiece.pinPositionsIn: 781 pin = instance.instPin(pinPos) 782 netNames2.append(pin.netName) 783 elif toPiece.topLevelPinName: 784 pinList = layoutObj.topLevelPins 785 for pin in pinList: 786 if pin.name == toPiece.topLevelPinName: 787 netNames2.append(pin.netName) 788 789 netNames1 = set(netNames1) 790 netNames2 = set(netNames2) 791 netNames = netNames1.intersection(netNames2) 792 return ",".join(netNames)
793
794 -def _switchToVrmDict(setup):
795 switchNameToVrmName = {} 796 vrmList = setup.getVrmList() 797 for vrm in vrmList: 798 if vrm.sourceType != 'PackagedVrm': 799 for pin in vrm.upSwitch.plusPins(): 800 switchNameToVrmName[pin.getInstanceName()] = vrm.name 801 break 802 for pin in vrm.lowSwitch.plusPins(): 803 switchNameToVrmName[pin.getInstanceName()] = vrm.name 804 break 805 for pin in vrm.inductor.plusPins(): 806 switchNameToVrmName[pin.getInstanceName()] = vrm.name 807 break 808 return switchNameToVrmName
809 810 ''' 811 build the power tree topology 812 the topology will consist of VRMs, sinks and components 813 the returned value will be two dimensional array where each cell representing an element to be drawn 814 '''
815 -def _buildTopology(result, showDifference):
816 import empro 817 818 layout = empro.activeProject.geometry()[0] 819 layoutObj = empro.activeProject.layout 820 tplg = Topology() 821 822 # get the setup first 823 if hasattr(result,"sipiData"): 824 setup = result.sipiData 825 else: 826 setup = result.sipiDatas[0] 827 allowedNets = [x.name for x in setup.getNetList() if x.type in [1,2,4]] 828 829 vrms = {} # map from vrm name to the list of instances attached to it 830 sinks = {} # map from sinks name to the list of instances attached to it 831 components = dict((x.name,x) for x in result.components) # used components (excludes switches) 832 connectionInstances = [] # instances used to find connections (includes switches) 833 switchToVrmDict = _switchToVrmDict(setup) 834 835 for vrm in setup.getVrmList(): 836 instList = [] 837 for pin in vrm.plusPins(): 838 instList.append((pin.getInstanceName(),pin.getPinName())) 839 break 840 instList = set(instList) 841 vrms[vrm.name] = instList 842 if vrm.sourceType != 'PackagedVrm': 843 for pin in vrm.upSwitch.plusPins(): 844 connectionInstances.append(pin.getInstanceName()) 845 break 846 for pin in vrm.lowSwitch.plusPins(): 847 connectionInstances.append(pin.getInstanceName()) 848 break 849 for pin in vrm.inductor.plusPins(): 850 connectionInstances.append(pin.getInstanceName()) 851 break 852 853 for sink in setup.getSinkList(): 854 instList = [] 855 for pin in sink.plusPins(): 856 instList.append((pin.getInstanceName(),pin.getPinName())) 857 break 858 instList = set(instList) 859 sinks[sink.name] = instList 860 sinkInstances = sum([list(x) for x in sinks.values()],[]) # required to find connections 861 sinkInstanceNames = [name for (name,pin) in sinkInstances] 862 863 for compGroup in setup.getComponentModelGroupList(): 864 for inst in compGroup.instances(): 865 connectionInstances.append(inst.name) 866 867 for vrmIterator, (vrmName, vrmInstances) in enumerate(vrms.iteritems()): 868 addedSwitches = [] 869 vrm = [x for x in result.vrms if x.name==vrmName][0] 870 vrmColor = (0.7,0.9,0.70,1) 871 if hasattr(vrm,'result') and 'pass' not in vrm.result: 872 vrmColor = (0.9,0.5,0.5,1) 873 if vrm.senseVoltage is not None: 874 tplg.addSenseLine(TopologyElement(vrmIterator, SenseLine(vrm), TopologyElement.SENSE,vrmColor)) 875 if vrm.sourceType != 'PackagedVrm': 876 continue 877 878 vrmElement = tplg.addElement(TopologyElement(vrmIterator, vrm, TopologyElement.VRM, vrmColor)) 879 880 vrmInstance, pinName = list(vrmInstances)[0] # if we have more than one, then what? 881 limitInsts = True 882 connections = layout._connectionsFromInstance((vrmInstance, pinName),sinkInstances,[2,4],allowedNets, limitInsts, connectionInstances, 0, lambda x:None) 883 884 for connectionIndex, connection in enumerate(connections): 885 previousElement = vrmElement 886 for pieceIndex, piece in enumerate(connection): 887 888 if piece.instanceName: 889 # SINK 890 if piece.instanceName in sinkInstanceNames: 891 sink = None 892 sinkPinNames = set() 893 instance = layoutObj.instanceByName(piece.instanceName) 894 for pinPos in piece.pinPositionsIn: 895 pin = instance.instPin(pinPos) 896 sinkPinNames.add(instance.name+'.'+pin.name) 897 for sinkIter in result.sinks: 898 for pin in sinkIter.pins: 899 if pin.name in sinkPinNames: 900 sink = sinkIter 901 break 902 if sink==None: 903 continue 904 905 color = (0.7,0.9,0.70,1) 906 if hasattr(sink,'result') and 'pass' not in sink.result: 907 color = (0.9,0.5,0.5,1) 908 909 sinkElement = tplg.addElement(TopologyElement(vrmIterator, sink, TopologyElement.SINK, color)) 910 label = connectionLabel(connection[pieceIndex - 1], piece) 911 tplg.addConnection(previousElement, sinkElement, inLabel=label) 912 tplg.addRow() # add a new row 913 914 # COMPONENT 915 elif piece.instanceName in components: 916 color = (0.75,0.75,0.75,1) 917 instance = layoutObj.instanceByName(piece.instanceName) 918 pinsIn = [] 919 pinsOut = [] 920 instPinNames = [] 921 for pinPos in piece.pinPositionsIn: 922 pin = instance.instPin(pinPos) 923 pinsIn.append(pin) 924 instPinNames.append( piece.instanceName + "." + pin.name) 925 for pinPos in piece.pinPositionsOut: 926 pin = instance.instPin(pinPos) 927 pinsOut.append(pin) 928 instPinNames.append( piece.instanceName + "." + pin.name) 929 930 component = components.get(piece.instanceName,None) 931 if component==None: 932 element = tplg.addElement(TopologyElement(vrmIterator, instance, TopologyElement.UNKNOWN, color)) 933 label = connectionLabel(connection[pieceIndex - 1], piece) 934 tplg.addConnection(previousElement, element, inLabel=label) 935 componentElement = element 936 previousElement = componentElement 937 continue 938 939 pinsIn = set([instance.name+"."+pin.name for pin in pinsIn]) 940 pinsOut = set([instance.name+"."+pin.name for pin in pinsOut]) 941 powerIn = [pin.voltage*pin.current for pin in component.pins if pin.name in pinsIn] 942 powerOut = [pin.voltage*pin.current for pin in component.pins if pin.name in pinsOut] 943 voltagesIn = [pin.voltage for pin in component.pins if pin.name in pinsIn] 944 voltagesOut = [pin.voltage for pin in component.pins if pin.name in pinsOut] 945 ampsIn = [pin.current for pin in component.pins if pin.name in pinsIn] 946 voltage = component.voltage 947 current = abs(sum(ampsIn)) 948 if voltagesIn and voltagesOut: 949 voltage = (sum(voltagesIn)/len(voltagesIn)) - (sum(voltagesOut)/len(voltagesOut)) 950 if powerIn and powerOut and current!=0.0: 951 voltage = (abs(sum(powerIn))-abs(sum(powerOut)))/current 952 element = tplg.addElement(TopologyElement(vrmIterator, component, TopologyElement.COMPONENT, color, metaData = {"voltage": voltage, "current": current})) 953 label = connectionLabel(connection[pieceIndex - 1], piece) 954 tplg.addConnection(previousElement, element, inLabel=label) 955 componentElement = element 956 previousElement = componentElement 957 958 # SWITCHING VRM 959 elif piece.instanceName in switchToVrmDict: 960 switchVrmName = switchToVrmDict[piece.instanceName] 961 if switchVrmName in addedSwitches: 962 previousElement = switchElement 963 continue 964 addedSwitches.append(switchVrmName) 965 switchVrm = [x for x in result.vrms if x.name==switchVrmName][0] 966 967 color = (0.7,0.9,0.70,1) 968 if hasattr(switchVrm,'result') and 'pass' not in switchVrm.result: 969 color = (0.9,0.5,0.5,1) 970 971 switchElement = tplg.addElement(TopologyElement(vrmIterator, switchVrm, TopologyElement.SWITCHVRM, color)) 972 label = connectionLabel(connection[pieceIndex - 1], piece) 973 tplg.addConnection(previousElement, switchElement, inLabel=label) 974 previousElement = switchElement 975 976 # Sink from Virtual Pin 977 elif (piece.topLevelPinName) and (pieceIndex == len(connection)-1): 978 sink = None 979 for sinkIter in result.sinks: 980 for pin in sinkIter.pins: 981 if pin.name == piece.topLevelPinName: 982 sink = sinkIter 983 break 984 if sink==None: 985 continue 986 987 color = (0.7,0.9,0.70,1) 988 if hasattr(sink,'result') and 'pass' not in sink.result: 989 color = (0.9,0.5,0.5,1) 990 991 sinkElement = tplg.addElement(TopologyElement(vrmIterator, sink, TopologyElement.SINK, color)) 992 label = connectionLabel(connection[pieceIndex - 1], piece) 993 tplg.addConnection(previousElement, sinkElement, inLabel=label) 994 tplg.addRow() # add a new row 995 996 tplg.setPreviousIterator(vrmIterator) 997 tplg.resetColumn() 998 999 matrix = tplg.topology() 1000 if len(matrix) == 0: 1001 return tplg 1002 return tplg.build()
1003
1004 -def _drawPowerGraph(scene, topology, showDifference):
1005 dx = 0 1006 dy = 0 1007 elementWidth = 150 1008 elementHeight = 75 1009 intDx = 60 1010 intDy = 10 1011 spacingWidth = elementWidth + intDx * 4.0 1012 spacingHeight = elementHeight * 1.25 1013 textColor = (0.05,0.05,0.05,1) 1014 1015 def _ellipsis(x,length=15): 1016 if len(x)>length-3: 1017 return x[:(length-3)]+'...' 1018 return x
1019 1020 def renderVrm(vrm,centerX,centerY,textColor): 1021 if vrm.senseVoltage is not None: 1022 scene.addRect(centerX-elementWidth*0.5,centerY-elementHeight*0.5,elementWidth,elementHeight) 1023 scene.addText(_ellipsis(vrm.name,24),centerX,centerY-18,8,True,textColor) 1024 scene.addText("Vnom = %4.3f V" % vrm.sourceVoltage,centerX,centerY-6,8,True,textColor) 1025 scene.addText("- %s" % (vrm.tolerance),centerX,centerY+6,8,True,textColor) 1026 scene.addText("%4.3f V" % (vrm.minVoltagePowerPins),centerX+elementWidth*0.5+intDx/2, -8+centerY,8,True,textColor) 1027 scene.addText("%4.3f A" % (-vrm.outputCurrent),centerX+elementWidth*0.5+intDx/2, 8+centerY,8,True,textColor) 1028 scene.addText("Vsense = %4.3f V" % (vrm.senseVoltage),centerX,centerY+18,8,True,textColor) 1029 scene.addText("%4.3f V" % (vrm.minSensePlusPinVoltage),25+centerX-elementWidth/4,centerY+elementHeight*0.5+intDy,8,True,textColor) 1030 scene.addText("%4.3f A" % (vrm.senseportCurrent),25+centerX-elementWidth/4,centerY+elementHeight*0.5+intDy+16,8,True,textColor) 1031 else: 1032 scene.addRect(centerX-elementWidth*0.5,centerY-elementHeight*0.5,elementWidth,elementHeight) 1033 scene.addText(_ellipsis(vrm.name,24),centerX,centerY-16,8,True,textColor) 1034 scene.addText("Vnom = %4.3f V" % vrm.sourceVoltage,centerX,centerY-0,8,True,textColor) 1035 scene.addText("- %s" % (vrm.tolerance),centerX,centerY+16,8,True,textColor) 1036 scene.addText("%4.3f V" % (vrm.minVoltagePowerPins),centerX+elementWidth*0.5+intDx/2, -8+centerY,8,True,textColor) 1037 scene.addText("%4.3f A" % (-vrm.outputCurrent),centerX+elementWidth*0.5+intDx/2, 8+centerY,8,True,textColor) 1038 1039 def renderSink(sink,centerX,centerY,textColor): 1040 scene.addRect(centerX-elementWidth*0.5,centerY-elementHeight*0.5,elementWidth,elementHeight) 1041 1042 deltaV = sink.vrmVoltage-sink.inputVoltage 1043 deltaVg = sink.maxVoltageGroundPins 1044 deltaVp = sink.vrmVoltage-sink.minVoltagePowerPins 1045 1046 scene.addText(_ellipsis(sink.name,24),centerX,centerY-24,8,True,textColor) 1047 scene.addText(u"\u00b1 %s" % (sink.tolerance),centerX,centerY-12,8,True,textColor) 1048 scene.addText(u"%4.3f V" % (sink.inputVoltage),centerX,centerY-0,8,True,textColor) 1049 scene.addText(u"\u0394V %3.1f mV" % (deltaV*1000.0),centerX,centerY+12,8,True,textColor) 1050 scene.addText(u"\u0394Vp %3.1f mV \u0394Vg %3.1f mV" % (deltaVp*1000.0,deltaVg*1000.0),centerX,centerY+24,8,True,textColor) 1051 1052 scene.addText(u"%4.3f V" % (sink.minVoltagePowerPins),centerX-elementWidth*0.5-intDx/2,centerY-8,8,True,textColor) 1053 scene.addText(u"%4.3f A" % (sink.sourceCurrent),centerX-elementWidth*0.5-intDx/2,centerY+8,8,True,textColor) 1054 1055 def renderComponent(comp,voltage, current, centerX,centerY,textColor): 1056 scene.addRect(centerX-elementWidth*0.5,centerY-elementHeight*0.5,elementWidth,elementHeight) 1057 scene.addText("%s" % _ellipsis(comp.name,24), centerX, centerY-18,8,True,textColor) 1058 scene.addText(u"%0.4f mV" % (1000.0*abs(voltage)), centerX, centerY,8,True,textColor) 1059 scene.addText("%4.3f A" % abs(current), centerX, centerY+18,8,True,textColor) 1060 1061 def renderUnknownComponent(comp,centerX,centerY,textColor): 1062 scene.addRect(centerX-elementWidth*0.5,centerY-elementHeight*0.5,elementWidth,elementHeight) 1063 scene.addText("%s" % _ellipsis(comp.name,24), centerX, centerY,8,True,textColor) 1064 1065 def renderSenseLine(senseLine, centerX, centerY, textColor): 1066 scene.penStyle = 2 1067 scene.addLine(dx - elementWidth / 4, dy - spacingHeight + elementHeight / 2, dx - elementWidth / 4, dy) 1068 scene.addLine(dx - elementWidth / 4, dy, dx + elementWidth * 0.25, dy) 1069 scene.addText(_ellipsis(senseLine.senseNetName, 24), dx, dy - 8, 8, True, textColor) 1070 scene.penStyle = 1 1071 1072 def renderSwitchVrm(vrm,centerX,centerY,textColor): 1073 scene.addRect(centerX-elementWidth*0.5,centerY-elementHeight*0.5,elementWidth,elementHeight) 1074 scene.addText(_ellipsis(vrm.name,24),centerX,centerY-24,8,True,textColor) 1075 scene.addText("Vnom = %4.3f V" % vrm.sourceVoltage,centerX,centerY-12,8,True,textColor) 1076 scene.addText("Vin = %4.3f V" % vrm.inputVoltage,centerX,centerY-0,8,True,textColor) 1077 scene.addText("- %s" % (vrm.tolerance),centerX,centerY+12,8,True,textColor) 1078 scene.addText("%4.3f V" % (vrm.switchOutputVoltage),centerX+elementWidth*0.5+intDx/2, -8+centerY,8,True,textColor) 1079 scene.addText("%4.3f A" % (-vrm.switchOutputCurrent),centerX+elementWidth*0.5+intDx/2, 8+centerY,8,True,textColor) 1080 scene.addText("%4.3f V" % (vrm.switchInputVoltage),centerX-elementWidth*0.5-intDx/2,centerY-8,8,True,textColor) 1081 scene.addText("%4.3f A" % (-vrm.switchInputCurrent),centerX-elementWidth*0.5-intDx/2,centerY+8,8,True,textColor) 1082 if vrm.senseVoltage is not None: 1083 scene.addText("Vsense = %4.3f V" % (vrm.senseVoltage),centerX,centerY+24,8,True,textColor) 1084 scene.addText("%4.3f V" % (vrm.minSensePlusPinVoltage),25+centerX-elementWidth/4,centerY+elementHeight*0.5+intDy,8,True,textColor) 1085 scene.addText("%4.3f A" % (vrm.senseportCurrent),25+centerX-elementWidth/4,centerY+elementHeight*0.5+intDy+16,8,True,textColor) 1086 1087 1088 for row in topology.topology(): 1089 for element in row: 1090 if element is not None: 1091 # draw element 1092 scene.brushColor = element.color 1093 if element.type == TopologyElement.VRM: 1094 renderVrm(element.obj, dx, dy, textColor) 1095 elif element.type == TopologyElement.SINK: 1096 renderSink(element.obj, dx, dy, textColor) 1097 elif element.type == TopologyElement.UNKNOWN: 1098 renderUnknownComponent(element.obj, dx, dy, textColor) 1099 elif element.type == TopologyElement.COMPONENT: 1100 renderComponent(element.obj, element.metaData["voltage"], element.metaData["current"], dx, dy, textColor) 1101 elif element.type == TopologyElement.SENSE: 1102 renderSenseLine(element.obj, dx, dy, textColor) 1103 elif element.type == TopologyElement.SWITCHVRM: 1104 renderSwitchVrm(element.obj, dx, dy, textColor) 1105 1106 inX = dx - elementWidth / 2 1107 inY = dy 1108 # draw input connection in case of the element has multiple inputs 1109 ''' 1110 if len(element.inputs()) > 1: 1111 inX = dx - spacingWidth / 4 1112 inY = dy 1113 scene.brushColor= (0, 0, 0, 1) 1114 scene.addCircle(inX, inY, 4) 1115 scene.addLine(inX, inY, dx - elementWidth / 2, dy) 1116 ''' 1117 1118 1119 # draw output connection in case of the element has multiple outputs 1120 if len(element.outputs()) > 1: 1121 scene.brushColor= (0, 0, 0, 1) 1122 scene.addCircle(dx + elementWidth / 2 + intDx, dy, 4) 1123 scene.addLine(dx + elementWidth / 2, dy, dx + elementWidth / 2 + intDx, dy) 1124 1125 # draw input connections 1126 for connection in element.inputs(): 1127 pos = topology.position(connection.to) 1128 outX = pos[1] * spacingWidth + elementWidth / 2 1129 outY = pos[0] * spacingHeight 1130 if len(connection.to.outputs()) > 1: 1131 outX = pos[1] * spacingWidth + elementWidth / 2 + intDx 1132 if outY != inY: 1133 scene.addLine(outX, outY, outX, inY) 1134 scene.addLine(outX, inY, inX, inY) 1135 else: 1136 scene.addLine(outX, outY, inX, inY) 1137 scene.addText("%s" % _ellipsis(connection.label), (outX + inX) / 2, inY - 8, 8, True, textColor) 1138 1139 dx += spacingWidth 1140 dx = 0 1141 dy += spacingHeight 1142
1143 -def _powerGraphSceneFromResults(scene, result):
1144 import empro 1145 showDifference = False 1146 if isinstance(result, empro.toolkit.analysis.dc.results.DCResultsDiff): 1147 showDifference = True 1148 1149 topology = _buildTopology(result, showDifference) 1150 _drawPowerGraph(scene, topology, showDifference)
1151 1152
1153 -def _powerGraphSceneFromResults1(scene, result): #deprecated?
1154 def _ellipsis(x,length=15): 1155 if len(x)>length-3: 1156 return x[:(length-3)]+'...' 1157 return x 1158 1159 interConnects = _interconnectedComponents(result) 1160 1161 dy = 0 1162 dx = 0 1163 vrmWidth = 150 1164 vrmHeight = 75 1165 sinkWidth = 150 1166 sinkHeight = 75 1167 sinkSpacing = 75*1.25 1168 compWidth = 150 1169 compHeight = 75 1170 dxToSink = 500 1171 intDx = 60 1172 intDy = 10 1173 scene.brushColor= (0.95,0.95,0.95,1) 1174 textColor = (0.05,0.05,0.05,1) 1175 sinksShown = set() 1176 1177 import empro 1178 layout = empro.activeProject.geometry()[0] 1179 layoutObj = empro.activeProject.layout 1180 if hasattr(result,"sipiData"): 1181 setup = result.sipiData 1182 else: 1183 setup = result.sipiDatas[0] 1184 allowedNets = [x.name for x in setup.getNetList() if x.type in [1,2]] 1185 1186 vrms = {} # map from vrm name to the list of instances attached to it 1187 for vrm in setup.getVrmList(): 1188 instList = [] 1189 for pin in vrm.plusPins(): 1190 instList.append((pin.getInstanceName(),pin.getPinName())) 1191 break 1192 instList = set(instList) 1193 vrms[vrm.name] = instList 1194 1195 sinks = {} 1196 for sink in setup.getSinkList(): 1197 instList = [] 1198 for pin in sink.plusPins(): 1199 instList.append((pin.getInstanceName(),pin.getPinName())) 1200 break 1201 instList = set(instList) 1202 sinks[sink.name] = instList 1203 1204 insts = [] 1205 for compGroup in setup.getComponentModelGroupList(): 1206 for inst in compGroup.instances(): 1207 insts.append(inst.name) 1208 1209 components = dict((x.name,x) for x in result.components) 1210 1211 _showDifference = False 1212 if isinstance(result, empro.toolkit.analysis.dc.results.DCResultsDiff): 1213 _showDifference = True 1214 1215 def renderVrm(vrm,centerX,centerY,textColor): 1216 if not _showDifference and vrm.senseVoltage is not None: 1217 scene.addRect(centerX-vrmWidth*0.5,centerY-vrmHeight*0.5,vrmWidth,vrmHeight) 1218 scene.addText(_ellipsis(vrm.name,24),centerX,centerY-18,8,True,textColor) 1219 scene.addText("Vnom = %4.3f V" % vrm.sourceVoltage,centerX,centerY-6,8,True,textColor) 1220 scene.addText("- %s" % (vrm.tolerance),centerX,centerY+6,8,True,textColor) 1221 sinkIndex = 0 1222 scene.addText("%4.3f V" % (vrm.minVoltagePowerPins),centerX+vrmWidth*0.5+intDx/2, -8+centerY,8,True,textColor) 1223 scene.addText("%4.3f A" % (-vrm.outputCurrent),centerX+vrmWidth*0.5+intDx/2, 8+centerY,8,True,textColor) 1224 scene.addText("Vsense = %4.3f V" % (vrm.senseVoltage),centerX,centerY+18,8,True,textColor) 1225 scene.addText("%4.3f V" % (vrm.minSensePlusPinVoltage),25+centerX-vrmWidth/4,centerY+vrmHeight*0.5+intDy,8,True,textColor) 1226 scene.addText("%4.3f A" % (vrm.senseportCurrent),25+centerX-vrmWidth/4,centerY+vrmHeight*0.5+intDy+16,8,True,textColor) 1227 else: 1228 scene.addRect(centerX-vrmWidth*0.5,centerY-vrmHeight*0.5,vrmWidth,vrmHeight) 1229 scene.addText(_ellipsis(vrm.name,24),centerX,centerY-16,8,True,textColor) 1230 scene.addText("Vnom = %4.3f V" % vrm.sourceVoltage,centerX,centerY-0,8,True,textColor) 1231 scene.addText("- %s" % (vrm.tolerance),centerX,centerY+16,8,True,textColor) 1232 sinkIndex = 0 1233 scene.addText("%4.3f V" % (vrm.minVoltagePowerPins),centerX+vrmWidth*0.5+intDx/2, -8+centerY,8,True,textColor) 1234 scene.addText("%4.3f A" % (-vrm.outputCurrent),centerX+vrmWidth*0.5+intDx/2, 8+centerY,8,True,textColor) 1235 1236 def renderSink(sink,centerX,centerY,textColor): 1237 scene.addRect(centerX-sinkWidth*0.5,centerY-sinkHeight*0.5,sinkWidth,sinkHeight) 1238 1239 deltaV = sink.vrmVoltage-sink.inputVoltage 1240 deltaVg = sink.maxVoltageGroundPins 1241 deltaVp = sink.vrmVoltage-sink.minVoltagePowerPins 1242 1243 scene.addText(_ellipsis(sink.name,24),centerX,centerY-24,8,True,textColor) 1244 scene.addText(u"\u00b1 %s" % (sink.tolerance),centerX,centerY-12,8,True,textColor) 1245 scene.addText(u"%4.3f V" % (sink.inputVoltage),centerX,centerY-0,8,True,textColor) 1246 scene.addText(u"\u0394V %3.1f mV" % (deltaV*1000.0),centerX,centerY+12,8,True,textColor) 1247 scene.addText(u"\u0394Vp %3.1f mV \u0394Vg %3.1f mV" % (deltaVp*1000.0,deltaVg*1000.0),centerX,centerY+24,8,True,textColor) 1248 1249 scene.addText(u"%4.3f V" % (sink.minVoltagePowerPins),centerX-sinkWidth*0.5-intDx/2,centerY-8,8,True,textColor) 1250 scene.addText(u"%4.3f A" % (sink.sourceCurrent),centerX-sinkWidth*0.5-intDx/2,centerY+8,8,True,textColor) 1251 1252 def renderComponent(comp,voltage, current, centerX,centerY,textColor): 1253 scene.addRect(centerX-compWidth*0.5,centerY-compHeight*0.5,compWidth,compHeight) 1254 scene.addText("%s" % _ellipsis(comp.name,24), centerX, centerY-18,8,True,textColor) 1255 scene.addText(u"%0.4f mV" % (1000.0*abs(voltage)), centerX, centerY,8,True,textColor) 1256 scene.addText("%4.3f A" % abs(current), centerX, centerY+18,8,True,textColor) 1257 1258 def renderUnknownComponent(comp,centerX,centerY,textColor): 1259 scene.addRect(centerX-compWidth*0.5,centerY-compHeight*0.5,compWidth,compHeight) 1260 scene.addText("%s" % _ellipsis(comp.name,24), centerX, centerY,8,True,textColor) 1261 1262 for vrmName, vrmInstances in vrms.iteritems(): 1263 vrmInstance, firstPinName = list(vrmInstances)[0] # if we have more than one, then what? 1264 sinkInstances = sum([list(x) for x in sinks.values()],[]) 1265 limitInsts = True 1266 connections = layout._connectionsFromInstance((vrmInstance, firstPinName),sinkInstances,[2],allowedNets, limitInsts, insts, 0, lambda x:None) 1267 1268 vrm = [x for x in result.vrms if x.name==vrmName][0] 1269 1270 vrmFailed = False 1271 if hasattr(vrm,'result'): 1272 vrmFailed = 'pass' not in vrm.result 1273 1274 if vrmFailed: 1275 scene.brushColor= (0.9,0.5,0.5,1) 1276 else: 1277 scene.brushColor= (0.7,0.9,0.70,1) 1278 1279 renderVrm(vrm,0,dy,textColor) 1280 1281 if False: 1282 print "*"*50 1283 print "Vrm", vrm.name 1284 for connection in connections: 1285 print " ","-"*50 1286 for piece in connection: 1287 print " ", piece.componentName, piece.instanceName 1288 instance = layoutObj.instanceByName(piece.instanceName) 1289 if piece.pinPositionsIn: 1290 for pinPos in piece.pinPositionsIn: 1291 pin = instance.instPin(pinPos) 1292 print " in", pin.name, pin.netName 1293 if piece.pinPositionsOut: 1294 for pinPos in piece.pinPositionsOut: 1295 pin = instance.instPin(pinPos) 1296 print " out", pin.name, pin.netName 1297 print "+"*20 1298 1299 sinkIndex = 0 1300 # add sense line lines 1301 if not _showDifference and vrm.senseVoltage is not None: 1302 scene.penStyle = 2 1303 scene.addLine(-vrmWidth/4,dy+vrmHeight*0.5,-vrmWidth/4,dy+sinkHeight*1.25) 1304 scene.addLine(-vrmWidth/4,dy+sinkHeight*1.25,vrmWidth*0.25,dy+sinkHeight*1.25) 1305 scene.addText(_ellipsis(vrm.senseNetName,24),0,-8+dy+sinkHeight*1.25,8,True,textColor) 1306 scene.penStyle = 1 1307 1308 for connectionIndex, connection in enumerate(connections): 1309 for pieceIndex, piece in enumerate(connection): 1310 if len(connection)==pieceIndex+1: 1311 # at the end, at a Sink 1312 sink = None 1313 sinkPinNames = set() 1314 if piece.instanceName: 1315 instance = layoutObj.instanceByName(piece.instanceName) 1316 for pinPos in piece.pinPositionsIn: 1317 pin = instance.instPin(pinPos) 1318 sinkPinNames.add(instance.name+'.'+pin.name) 1319 elif piece.topLevelPinName: 1320 sinkPinNames.add(piece.topLevelPinName) 1321 for sinkIter in result.sinks: 1322 for pin in sinkIter.pins: 1323 if pin.name in sinkPinNames: 1324 sink = sinkIter 1325 break 1326 ''' 1327 if sink==None and len(sinks)==1: 1328 sink = result.sinks[0] 1329 ''' 1330 if sink==None: 1331 continue 1332 1333 sinksShown.add(sink.name) 1334 sinkNetNames = set([pin.netName for pin in sink.pins if pin.netType=="Power"]) 1335 sinkFailed = False 1336 if hasattr(sink,'result'): 1337 sinkFailed = 'pass' not in sink.result 1338 textColor = (0.05,0.05,0.05,1) 1339 if sinkFailed: 1340 scene.brushColor= (0.9,0.5,0.5,1) 1341 else: 1342 scene.brushColor= (0.7,0.9,0.70,1) 1343 1344 renderSink(sink,pieceIndex*(compWidth+intDx*4.0),dy+sinkIndex*sinkSpacing,textColor) 1345 elif pieceIndex>0: 1346 scene.brushColor= (0.75,0.75,0.75,1) 1347 instance = layoutObj.instanceByName(piece.instanceName) 1348 pinsIn = [] 1349 pinsOut = [] 1350 instPinNames = [] 1351 for pinPos in piece.pinPositionsIn: 1352 pin = instance.instPin(pinPos) 1353 pinsIn.append(pin) 1354 instPinNames.append( piece.instanceName + "." + pin.name) 1355 for pinPos in piece.pinPositionsOut: 1356 pin = instance.instPin(pinPos) 1357 pinsOut.append(pin) 1358 instPinNames.append( piece.instanceName + "." + pin.name) 1359 1360 component = components.get(piece.instanceName,None) 1361 if not component: 1362 # see if we find the component in the sinks 1363 for sinkComp in result.sinks: 1364 for pin in sinkComp.pins: 1365 if pin.name in instPinNames: 1366 component = sinkComp 1367 break 1368 if not component: 1369 # see if we find the component in the vrms 1370 for vrmComp in result.vrms: 1371 for pin in vrmComp.pins: 1372 if pin.name in instPinNames: 1373 component = vrmComp 1374 break 1375 1376 if component==None: 1377 renderUnknownComponent(instance,pieceIndex*(compWidth+intDx*4.0),dy+sinkIndex*sinkSpacing,textColor) 1378 continue 1379 1380 pinsIn = set([instance.name+"."+pin.name for pin in pinsIn]) 1381 pinsOut = set([instance.name+"."+pin.name for pin in pinsOut]) 1382 powerIn = [pin.voltage*pin.current for pin in component.pins if pin.name in pinsIn] 1383 powerOut = [pin.voltage*pin.current for pin in component.pins if pin.name in pinsOut] 1384 voltagesIn = [pin.voltage for pin in component.pins if pin.name in pinsIn] 1385 voltagesOut = [pin.voltage for pin in component.pins if pin.name in pinsOut] 1386 ampsIn = [pin.current for pin in component.pins if pin.name in pinsIn] 1387 ampsOut = [pin.current for pin in component.pins if pin.name in pinsOut] 1388 voltage = component.voltage 1389 current = abs(sum(ampsIn)) 1390 if voltagesIn and voltagesOut: 1391 voltage = (sum(voltagesIn)/len(voltagesIn)) - (sum(voltagesOut)/len(voltagesOut)) 1392 if powerIn and powerOut and current!=0.0: 1393 voltage = (abs(sum(powerIn))-abs(sum(powerOut)))/current 1394 renderComponent(component,voltage, current,pieceIndex*(compWidth+intDx*4.0),dy+sinkIndex*sinkSpacing,textColor) 1395 1396 1397 # render the lines in between 1398 for pieceIndex, piece in enumerate(connection[1:]): 1399 sx = pieceIndex*(compWidth+intDx*4.0) + compWidth*0.5 1400 ex = (pieceIndex+1)*(compWidth+intDx*4.0) - compWidth*0.5 1401 cy = dy+sinkIndex*sinkSpacing 1402 1403 if connectionIndex>0 and pieceIndex==0: 1404 sx = sx+intDx 1405 scene.brushColor= (0,0,0,1) 1406 scene.addCircle(sx,cy,4) 1407 scene.addLine(sx,cy,sx,cy-sinkSpacing) 1408 if connectionIndex==0 and len(connections)>1: 1409 scene.brushColor= (0,0,0,1) 1410 scene.addCircle(sx+intDx,cy,4) 1411 1412 scene.addLine(sx,cy,ex,cy) 1413 1414 fromPiece = connection[pieceIndex] 1415 toPiece = piece 1416 netNames1 = [] 1417 netNames2 = [] 1418 instance = layoutObj.instanceByName(fromPiece.instanceName) 1419 if fromPiece.pinPositionsOut: 1420 for pinPos in fromPiece.pinPositionsOut: 1421 pin = instance.instPin(pinPos) 1422 netNames1.append(pin.netName) 1423 instance = layoutObj.instanceByName(toPiece.instanceName) 1424 if toPiece.pinPositionsIn: 1425 for pinPos in toPiece.pinPositionsIn: 1426 pin = instance.instPin(pinPos) 1427 netNames2.append(pin.netName) 1428 1429 netNames1 = set(netNames1) 1430 netNames2 = set(netNames2) 1431 netNames = netNames1.intersection(netNames2) 1432 scene.addText("%s" % _ellipsis(",".join(netNames)), 0.5*(sx+ex),cy-8,8,True,textColor) 1433 dy += sinkHeight*1.25 1434 sinkIndex += 0 # not used anymore and conflicts with dy increments 1435 if not _showDifference and vrm.senseVoltage is not None: 1436 dy += sinkHeight*1.25 1437
1438 -class Docx(Html):
1439 - def __init__(self, result, tableInfo, maxCurrent, maxTemperature, showViolatingCurrent, showViolatingT, **kwargs):
1440 Html.__init__(self, result, tableInfo, maxCurrent, maxTemperature, showViolatingCurrent, showViolatingT, **kwargs) 1441 self.document = Document()
1442
1443 - def _title(self):
1444 textTitle = self._variables() 1445 for key in textTitle.keys(): 1446 if key == "analysisName": 1447 self.document.add_heading("Analysis " + textTitle.get(key) + " Report",0) 1448 return
1449
1450 - def generate(self, targetFileName):
1451 import os 1452 self.name = os.path.split(targetFileName)[1] 1453 self._fillVariables() 1454 self._generateFigures() 1455 self._title() 1456 self._overview() 1457 self._powerGraph() 1458 self._designInfo() 1459 self._sinks() 1460 self._vrms() 1461 self._vias() 1462 self._thermalComponents() 1463 self._layers() 1464 from docx.shared import Pt 1465 style = self.document.styles['Normal'] 1466 font = style.font 1467 font.size = Pt(8) 1468 self.document.save(targetFileName) 1469 return
1470
1471 - def _overview(self):
1472 import string 1473 import os 1474 import empro 1475 celsius = empro.units.unitByAbbreviation("degC") 1476 if self._showDifference: 1477 celsius = empro.units.unitByAbbreviation("K") 1478 try: 1479 simData = self._result.sipiData.newSimulationData() 1480 notes = simData.notes 1481 ambientTemperature = float(simData.ambientConditions.backgroundTemperature) 1482 except: 1483 simData1 = self._result.sipiDatas[0].newSimulationData() 1484 simData2 = self._result.sipiDatas[1].newSimulationData() 1485 notes = simData1.notes 1486 notes += "\n"+simData2.notes 1487 ambientTemperature = float(simData1.ambientConditions.backgroundTemperature)-float(simData2.ambientConditions.backgroundTemperature) 1488 1489 if notes.replace('\n','').strip()=="": 1490 notes = "No notes" 1491 1492 self.document.add_heading("Overview", level=1) 1493 self.document.add_heading("Setup", level=2) 1494 self.document.add_paragraph("Ambient temperature: " + "%3.1f" % celsius.fromReferenceUnits(ambientTemperature) + ' ' + celsius.abbreviation(),style = 'List Bullet') 1495 self.document.add_heading("Notes", level=2) 1496 self.document.add_paragraph(notes, style = 'List Bullet') 1497 return
1498
1499 - def _designInfo(self):
1500 import string 1501 import os 1502 import empro 1503 lengthUnit = empro.activeProject.displayUnits['LENGTH'] 1504 def _formatOr(format, value): 1505 try: 1506 if value=='---': 1507 return value 1508 except: 1509 return value 1510 return format % value
1511 1512 def _asLength(x): 1513 return '%f %s' % (lengthUnit.fromReferenceUnits(float(x)), lengthUnit.abbreviation())
1514 1515 dielInfo = [] 1516 for k,v in self._vars['substrate']['dielectrics'].iteritems(): 1517 dielInfo.append([v.name, v.materialName, _asLength(abs(float(v.thickness))),_formatOr(self._epsRFormat, v.Er), _formatOr(self._lossTangentFormat,v.lossTangent)]) 1518 1519 condInfo = [] 1520 for k,v in self._vars['substrate']['conductors'].iteritems(): 1521 condInfo.append([v.name, v.materialName, _asLength(abs(float(v.thickness))),_formatOr(self._conductivityFormat,v.conductivity)]) 1522 1523 viaInfo = [] 1524 for k,v in self._vars['substrate']['vias'].iteritems(): 1525 viaInfo.append([v.name, v.materialName]) 1526 self.document.add_heading("Design information", level=1) 1527 1528 self.document.add_heading("Substrate", level=2) 1529 self.document.add_heading("Dielectrics", level=3) 1530 dielectricsHeader = ['Name','Material','Thickness','Er','LossTangent'] 1531 dielectricstable = self.document.add_table(rows= 1 , cols=len(dielectricsHeader)) 1532 dielectricstable.style = "Table Grid" 1533 hdr_cells = dielectricstable.rows[0].cells 1534 for i in range(len(dielectricsHeader)): 1535 hdr_cells[i].text = dielectricsHeader[i] 1536 for item in dielInfo: 1537 row_cells = dielectricstable.add_row().cells 1538 for i in range(len(item)): 1539 row_cells[i].text = str(item[i]) 1540 1541 self.document.add_heading("Conductors", level=3) 1542 conductorsHeader = ['Name','Material','Thickness','Conductivity'] 1543 conductorstable = self.document.add_table(rows= 1 , cols=len(conductorsHeader)) 1544 conductorstable.style = "Table Grid" 1545 hdr_cells = conductorstable.rows[0].cells 1546 for i in range(len(conductorsHeader)): 1547 hdr_cells[i].text = conductorsHeader[i] 1548 for item in condInfo: 1549 row_cells = conductorstable.add_row().cells 1550 for i in range(len(item)): 1551 row_cells[i].text = str(item[i]) 1552 1553 self.document.add_heading("Vias", level=3) 1554 viasHeader = ['Name','Material'] 1555 viastable = self.document.add_table(rows= 1 , cols=len(viasHeader)) 1556 viastable.style = "Table Grid" 1557 hdr_cells = viastable.rows[0].cells 1558 for i in range(len(viasHeader)): 1559 hdr_cells[i].text = viasHeader[i] 1560 for item in viaInfo: 1561 row_cells = viastable.add_row().cells 1562 for i in range(len(item)): 1563 row_cells[i].text = str(item[i]) 1564 return 1565
1566 - def _vrms(self):
1567 import string 1568 import os 1569 vrms = [] 1570 for index, vrm in enumerate(self._result.vrms): 1571 row = [vrm.name, vrm.sourceVoltage, vrm.outputVoltage ,vrm.outputCurrent, vrm.tolerance, vrm.margin] 1572 if not self._showDifference: 1573 row.append(vrm.result) 1574 vrms.append(row) 1575 self.document.add_heading("VRMs", level=1) 1576 deltaSymbol = '' 1577 header = ["Name", deltaSymbol+"Source\nVoltage [V]", deltaSymbol+"Output\nVoltage [V]", deltaSymbol+"Output\nCurrent [A]", "Tolerance", deltaSymbol+"Margin [V]", "Pass/Fail"] 1578 table = self.document.add_table(rows= 1 , cols=len(header)) 1579 table.style = "Table Grid" 1580 hdr_cells = table.rows[0].cells 1581 for i in range(len(header)): 1582 hdr_cells[i].text = header[i] 1583 for item in vrms: 1584 row_cells = table.add_row().cells 1585 for i in range(len(item)): 1586 row_cells[i].text = str(item[i]) 1587 return
1588
1589 - def _vias(self):
1590 import string 1591 import os 1592 self._viasBulk() 1593 self.document.add_heading("Vias", level=1) 1594 self.document.add_paragraph(self.maximumCurrent, style = 'List Bullet') 1595 self.document.add_paragraph(self.maximumTemperature, style = 'List Bullet') 1596 table = self.document.add_table(rows= 1 , cols=len(self.viasHeader)) 1597 table.style = "Table Grid" 1598 hdr_cells = table.rows[0].cells 1599 for i in range(len(self.viasHeader)): 1600 hdr_cells[i].text = self.viasHeader[i] 1601 for item in self.vias: 1602 row_cells = table.add_row().cells 1603 for i in range(len(item)): 1604 row_cells[i].text = str(item[i]) 1605 return
1606
1607 - def _thermalComponents(self):
1608 import string 1609 import os 1610 import empro 1611 celsius = empro.units.unitByAbbreviation("degC") 1612 if self._showDifference: 1613 celsius = empro.units.unitByAbbreviation("K") 1614 degUnit = 'T ['+celsius.abbreviation()+']' 1615 degSymbol = '['+celsius.abbreviation()+']' 1616 1617 comps = [] 1618 for index, source in enumerate(self._result.thermalComponents): 1619 if hasattr(source,'heat'): 1620 row = [source.name, source.heat, '---','---'] 1621 else: 1622 row = [source.name, source.heatDie, source.heatBoard, source.heatCase] 1623 if hasattr(source,"temperature"): 1624 row += [self._temperatureFormat % celsius.fromReferenceUnits(source.temperature), "---","---","---", source.bareBoardThermalResistance] 1625 else: 1626 row += ["---", self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureBoard), self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureDie), self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureCase), source.bareBoardThermalResistance] 1627 comps.append(row) 1628 self.document.add_heading("Thermal Components", level=1) 1629 deltaSymbol = '' 1630 header = ["Name", deltaSymbol+"Source [W]", deltaSymbol+"Heat To\nBoard [W]", deltaSymbol+"Heat To\nCase [W]", deltaSymbol+degUnit,deltaSymbol+"Case Bottom\n"+degUnit, deltaSymbol+"Die "+degUnit, deltaSymbol+"Case Top "+degUnit, deltaSymbol+"Thermal Resistance\nBare Board [K/W]"] 1631 table = self.document.add_table(rows= 1 , cols=len(header)) 1632 table.style = "Table Grid" 1633 hdr_cells = table.rows[0].cells 1634 for i in range(len(header)): 1635 hdr_cells[i].text = header[i] 1636 for item in comps: 1637 row_cells = table.add_row().cells 1638 for i in range(len(item)): 1639 row_cells[i].text = str(item[i]) 1640 return
1641
1642 - def _sinks(self):
1643 import string 1644 import os 1645 sinks = [] 1646 for index, sink in enumerate(self._result.sinks): 1647 row = [sink.name, sink.sourceCurrent, sink.vrmVoltage,sink.inputVoltage,sink.resistance, sink.tolerance, sink.margin] 1648 if not self._showDifference: 1649 row.append(sink.result) 1650 sinks.append(row) 1651 self.document.add_heading("Sinks", level=1) 1652 deltaSymbol = '' 1653 header = ["Name", "Source\nCurrent [A]", "VRM\nVoltage [V]", deltaSymbol+"Input\n Voltage [V]", deltaSymbol+"Resistance\n [Ohm]", "Tolerance", deltaSymbol+"Margin [V]", "Pass/Fail"] 1654 table = self.document.add_table(rows= 1 , cols=len(header)) 1655 table.style = "Table Grid" 1656 hdr_cells = table.rows[0].cells 1657 for i in range(len(header)): 1658 hdr_cells[i].text = header[i] 1659 for item in sinks: 1660 row_cells = table.add_row().cells 1661 for i in range(len(item)): 1662 row_cells[i].text = str(item[i]) 1663 return
1664
1665 - def _powerGraph(self):
1666 import string 1667 import os 1668 pwrTreeImgNm = os.path.join(self.figuresLocation,"figures_for_"+self.name,"powerGraph.png") 1669 import empro 1670 import empro.gui 1671 import empro.toolkit.analysis.dc.output 1672 scn = empro.gui.GraphicsScene() 1673 empro.toolkit.analysis.dc.output._powerGraphSceneFromResults(scn,self._result) 1674 scn._save(pwrTreeImgNm) 1675 picLoc = pwrTreeImgNm.replace('\\','/') 1676 powerGraphImg = '%(picLoc)s' % vars() 1677 self.document.add_heading("Power Graph", level=1) 1678 if not self._result.vrms or not self._result.sinks: 1679 pass 1680 else: 1681 self.document.add_picture(powerGraphImg, width=Inches(3.0)) 1682 return
1683
1684 - def plotTableTemplate(self, header, info, bookmarkName,para):
1685 from docx.oxml import OxmlElement 1686 from docx.oxml.ns import qn 1687 from docx.text.run import Run 1688 tableName = self.document.add_table(rows= 1 , cols=len(header)) 1689 tableName.style = "Table Grid" 1690 hdr_cells = tableName.rows[0].cells 1691 for i in range(len(header)): 1692 hdr_cells[i].text = header[i] 1693 for item in info: 1694 row_cells = tableName.add_row().cells 1695 for i in range(len(item)-1): 1696 if (i == 0): 1697 paragraph_bk = row_cells[0].paragraphs[0] 1698 elem = paragraph_bk._element 1699 r = OxmlElement('w:r') 1700 elem.append(r) 1701 Run(r, para).text = str(item[0]) 1702 pCaption = OxmlElement('w:bookmarkStart') 1703 pCaption.set(qn('w:id'), str(i)) 1704 pCaption.set(qn('w:name'), str(item[0]) + bookmarkName) 1705 elem.append(pCaption) 1706 pCaption = OxmlElement('w:bookmarkEnd') 1707 pCaption.set(qn('w:id'),str(i)) 1708 elem.append(pCaption) 1709 elif (i == 1): 1710 row_cells[i].text = item[i] 1711 else: 1712 row_cells[i].text = str(item[i]) 1713 paragraph = row_cells[len(item)-1].paragraphs[0] 1714 run = paragraph.add_run() 1715 run.add_picture(item[len(item)-1], width=Inches(1.25)) 1716 return
1717
1718 - def _layers(self):
1719 import string 1720 import os 1721 import empro 1722 from docx.oxml import OxmlElement 1723 from docx.oxml.ns import qn 1724 from docx.text.run import Run 1725 temperatureMetaData = [x for x in self._figuresMetaData if 'outputType' in x and x['outputType']=='temperature'] 1726 voltageMetaData = [x for x in self._figuresMetaData if 'outputType' in x and x['outputType']=='voltage'] 1727 powerLossDensityMetaData = [x for x in self._figuresMetaData if 'outputType' in x and x['outputType']=='powerLossDensity'] 1728 currentMetaData = [x for x in self._figuresMetaData if 'outputType' in x and x['outputType']=='current'] 1729 1730 celsius = empro.units.unitByAbbreviation("degC") 1731 if self._showDifference: 1732 celsius = empro.units.unitByAbbreviation("K") 1733 degUnit = 'T ['+celsius.abbreviation()+']' 1734 degSymbol = '['+celsius.abbreviation()+']' 1735 1736 temperatureDataIds = set([int(x['layerId']) for x in temperatureMetaData]) 1737 voltageDataIds = set([int(x['layerId']) for x in voltageMetaData]) 1738 currentDataIds = set([int(x['layerId']) for x in currentMetaData]) 1739 powerLossDensityDataIds = set([int(x['layerId']) for x in powerLossDensityMetaData]) 1740 1741 layerInfo = [] 1742 for layer in self._zSortedLayerNames: 1743 layerName = layer[0] 1744 layerStats = self._layerStatistics[layerName] 1745 layerNr = layerStats['layerId'] 1746 layerLinksTemperature = '' 1747 layerLinksVoltage = '' 1748 layerLinksCurrent = '' 1749 layerLinksPower = '' 1750 if temperatureMetaData and layerNr in temperatureDataIds: 1751 layerLinksTemperature += "T" 1752 if voltageMetaData and layerNr in voltageDataIds: 1753 layerLinksVoltage += "V" 1754 if currentMetaData and layerNr in currentDataIds: 1755 layerLinksCurrent += "A" 1756 if powerLossDensityMetaData and layerNr in powerLossDensityDataIds: 1757 layerLinksPower += "P" 1758 row = [layerName, layerLinksTemperature, layerLinksVoltage, layerLinksCurrent, layerLinksPower, self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMin"]), self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMax"]), self._currentDensityFormat % (layerStats["currentMin"]*1e-6),self._currentDensityFormat % (layerStats["currentMax"]*1e-6),self._voltageFormat % layerStats["voltageMin"],self._voltageFormat % layerStats["voltageMax"]] 1759 layerInfo.append(row) 1760 1761 for layerId in [-2,-3]: 1762 layerName = {-2 : "top", -3 : "bottom"}[layerId] 1763 1764 layerNr = layerId 1765 layerLinksTemperature = '' 1766 layerLinksVoltage = '' 1767 layerLinksCurrent = '' 1768 layerLinksPower = '' 1769 if temperatureMetaData and layerNr in temperatureDataIds: 1770 layerLinksTemperature += "T" 1771 if voltageMetaData and layerNr in voltageDataIds: 1772 layerLinksVoltage += "V" 1773 if currentMetaData and layerNr in currentDataIds: 1774 layerLinksCurrent += "A" 1775 if powerLossDensityMetaData and layerNr in powerLossDensityDataIds: 1776 layerLinksPower += "P" 1777 #layerStats = self._layerStatistics[layerName] 1778 #row = [layerName, layerLinks, self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMin"]), self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMax"]), self._currentDensityFormat % (layerStats["currentMin"]*1e-6),self._currentDensityFormat % (layerStats["currentMax"]*1e-6),self._voltageFormat % layerStats["voltageMin"],self._voltageFormat % layerStats["voltageMax"]] 1779 row = [layerName, layerLinksTemperature, layerLinksVoltage, layerLinksCurrent, layerLinksPower, '---', '---', '---','---','---','---'] 1780 layerInfo.append(row) 1781 1782 tempHeader = ['Name','Scale','Plot'] 1783 voltageHeader = ['Name','Scale','Plot'] 1784 currentHeader = ['Name','Scale','Plot'] 1785 powerLossDensityHeader = ['Name','Scale','Plot'] 1786 tempInfo = [] 1787 voltageInfo = [] 1788 currentInfo = [] 1789 powerLossDensityInfo = [] 1790 1791 1792 for layer in self._zSortedLayerNames: 1793 layerName = layer[0] 1794 layerStats = self._layerStatistics[layerName] 1795 metaData = [x for x in temperatureMetaData if 'layerId' in x and int(x['layerId'])==int(layerStats['layerId'])] 1796 if not metaData: 1797 continue 1798 metaData = metaData[0] 1799 picLoc = metaData['fileName'] 1800 picLoc = picLoc.replace('\\','/') 1801 #picLoc = r"file:///" + picLoc 1802 scaleStr = (self._temperatureFormat + " - " + self._temperatureFormat + " " + degSymbol) % (celsius.fromReferenceUnits(float(metaData["minValue"])),celsius.fromReferenceUnits(float(metaData["maxValue"]))) 1803 layerNr = layerStats['layerId'] 1804 layerAnchor = r'%(layerName)s' % vars() 1805 row = [layerAnchor, scaleStr, '%(picLoc)s' % vars()] 1806 tempInfo.append(row) 1807 1808 for layerId in [-2,-3]: 1809 layerName = {-2 : "top", -3 : "bottom"}[layerId] 1810 metaData = [x for x in temperatureMetaData if 'layerId' in x and int(x['layerId'])==layerId] 1811 if not metaData: 1812 continue 1813 metaData = metaData[0] 1814 picLoc = metaData['fileName'] 1815 picLoc = picLoc.replace('\\','/') 1816 #picLoc = r"file:///" + picLoc 1817 scaleStr = (self._temperatureFormat + " - " + self._temperatureFormat + " " + degSymbol) % (celsius.fromReferenceUnits(float(metaData["minValue"])),celsius.fromReferenceUnits(float(metaData["maxValue"]))) 1818 layerAnchor = r'%(layerName)s' % vars() 1819 row = [layerAnchor, scaleStr, '%(picLoc)s' % vars()] 1820 tempInfo.append(row) 1821 1822 prettyName = { 'power' : "Power" , 'ground' : "Ground" , 'signal' : "Signal"} 1823 1824 for layer in self._zSortedLayerNames: 1825 layerName = layer[0] 1826 layerStats = self._layerStatistics[layerName] 1827 for netType in ["power","ground","signal"]: 1828 metaData = [x for x in voltageMetaData if 'layerId' in x and int(x['layerId'])==int(layerStats['layerId']) and 'netType' in x and x['netType']==netType] 1829 if not metaData: 1830 continue 1831 metaData = metaData[0] 1832 picLoc = metaData['fileName'] 1833 picLoc = picLoc.replace('\\','/') 1834 #picLoc = r"file:///" + picLoc 1835 scaleStr = "%6.5f - %6.5f [V]" % (float(metaData["minValue"]),float(metaData["maxValue"])) 1836 layerNr = layerStats['layerId'] 1837 prettyNetType = prettyName[netType] 1838 layerAnchor = r'%(layerName)s- %(prettyNetType)s' % vars() 1839 row = [layerAnchor, scaleStr, '%(picLoc)s' % vars()] 1840 voltageInfo.append(row) 1841 1842 for layerId in [-2,-3]: 1843 layerName = {-2 : "top", -3 : "bottom"}[layerId] 1844 for netType in ["power","ground","signal"]: 1845 metaData = [x for x in voltageMetaData if 'layerId' in x and int(x['layerId'])==layerId and 'netType' in x and x['netType']==netType] 1846 if not metaData: 1847 continue 1848 metaData = metaData[0] 1849 picLoc = metaData['fileName'] 1850 picLoc = picLoc.replace('\\','/') 1851 #picLoc = r"file:///" + picLoc 1852 scaleStr = "%6.5f - %6.5f [V]" % (float(metaData["minValue"]),float(metaData["maxValue"])) 1853 prettyNetType = prettyName[netType] 1854 layerAnchor = r'%(layerName)s- %(prettyNetType)s' % vars() 1855 row = [layerAnchor, scaleStr, '%(picLoc)s' % vars()] 1856 voltageInfo.append(row) 1857 1858 for layer in self._zSortedLayerNames: 1859 layerName = layer[0] 1860 layerStats = self._layerStatistics[layerName] 1861 for netType in ["power","ground","signal"]: 1862 metaData = [x for x in currentMetaData if 'layerId' in x and int(x['layerId'])==int(layerStats['layerId']) and 'netType' in x and x['netType']==netType] 1863 if not metaData: 1864 continue 1865 metaData = metaData[0] 1866 picLoc = metaData['fileName'] 1867 picLoc = picLoc.replace('\\','/') 1868 #picLoc = r"file:///" + picLoc 1869 scaleStr = "%6.5f - %6.5f [A/mm**2]" % (1e-6*float(metaData["minValue"]),1e-6*float(metaData["maxValue"])) 1870 layerNr = layerStats['layerId'] 1871 prettyNetType = prettyName[netType] 1872 layerAnchor = r'%(layerName)s- %(prettyNetType)s' % vars() 1873 row = [layerAnchor, scaleStr, '%(picLoc)s' % vars()] 1874 currentInfo.append(row) 1875 1876 for layerId in [-2,-3]: 1877 layerName = {-2 : "top", -3 : "bottom"}[layerId] 1878 for netType in ["power","ground","signal"]: 1879 metaData = [x for x in currentMetaData if 'layerId' in x and int(x['layerId'])==layerId and 'netType' in x and x['netType']==netType] 1880 if not metaData: 1881 continue 1882 metaData = metaData[0] 1883 picLoc = metaData['fileName'] 1884 picLoc = picLoc.replace('\\','/') 1885 #picLoc = r"file:///" + picLoc 1886 scaleStr = "%6.5f - %6.5f [A/mm**2]" % (1e-6*float(metaData["minValue"]),1e-6*float(metaData["maxValue"])) 1887 prettyNetType = prettyName[netType] 1888 layerAnchor = r'%(layerName)s- %(prettyNetType)s' % vars() 1889 row = [layerAnchor, scaleStr, '%(picLoc)s' % vars()] 1890 currentInfo.append(row) 1891 1892 for layer in self._zSortedLayerNames: 1893 layerName = layer[0] 1894 layerStats = self._layerStatistics[layerName] 1895 for netType in ["power","ground","signal"]: 1896 metaData = [x for x in powerLossDensityMetaData if 'layerId' in x and int(x['layerId'])==int(layerStats['layerId']) and 'netType' in x and x['netType']==netType] 1897 if not metaData: 1898 continue 1899 metaData = metaData[0] 1900 picLoc = metaData['fileName'] 1901 picLoc = picLoc.replace('\\','/') 1902 #picLoc = r"file:///" + picLoc 1903 scaleStr = "%6.5f - %6.5f [W/mm**2]" % (1e-6*float(metaData["minValue"]),1e-6*float(metaData["maxValue"])) 1904 layerNr = layerStats['layerId'] 1905 prettyNetType = prettyName[netType] 1906 layerAnchor = r'%(layerName)s- %(prettyNetType)s' % vars() 1907 row = [layerAnchor, scaleStr, '%(picLoc)s' % vars()] 1908 powerLossDensityInfo.append(row) 1909 1910 for layerId in [-2,-3]: 1911 layerName = {-2 : "top", -3 : "bottom"}[layerId] 1912 for netType in ["power","ground","signal"]: 1913 metaData = [x for x in powerLossDensityMetaData if 'layerId' in x and int(x['layerId'])==layerId and 'netType' in x and x['netType']==netType] 1914 if not metaData: 1915 continue 1916 metaData = metaData[0] 1917 picLoc = metaData['fileName'] 1918 picLoc = picLoc.replace('\\','/') 1919 #picLoc = r"file:///" + picLoc 1920 scaleStr = "%6.5f - %6.5f [W/mm**2]" % (1e-6*float(metaData["minValue"]),1e-6*float(metaData["maxValue"])) 1921 prettyNetType = prettyName[netType] 1922 layerAnchor = r'%(layerName)s- %(prettyNetType)s' % vars() 1923 row = [layerAnchor, scaleStr, '%(picLoc)s' % vars()] 1924 powerLossDensityInfo.append(row) 1925 self.document.add_heading("Layers", level=1) 1926 deltaSymbol = '' 1927 header = ["Layer", "Plots", "", "", "", deltaSymbol + "Min "+degUnit,deltaSymbol + deltaSymbol+"Max "+degUnit, deltaSymbol+"Min Current\nDensity [A/mm**2]", deltaSymbol+"Max Current\nDensity [A/mm**2]",deltaSymbol+"Min\nVoltage [V]", deltaSymbol+"Max\nVoltage [V]"] 1928 table = self.document.add_table(rows= 1 , cols=len(header)) 1929 table.style = "Table Grid" 1930 hdr_cells = table.rows[0].cells 1931 for i in range(len(header)): 1932 hdr_cells[i].text = header[i] 1933 for item in layerInfo: 1934 row_cells = table.add_row().cells 1935 for i in range(len(item)): 1936 if (i > 0 and i < 5): 1937 p = row_cells[i].paragraphs[0] 1938 elem = p._element 1939 hyperlink = OxmlElement('w:hyperlink') 1940 hyperlink.set(qn('w:anchor'), str(item[0].replace(' ','_'))+ "-_Power"+str(item[i])) 1941 hyperlink.set(qn('w:history'), "1") 1942 elem.append(hyperlink) 1943 r = OxmlElement('w:r') 1944 hyperlink.append(r) 1945 rPr = OxmlElement('w:rPr') 1946 rStyle = OxmlElement('w:rStyle') 1947 rStyle.set(qn('w:val'), "Hyperlink" ) 1948 rPr.append(rStyle) 1949 u = OxmlElement('w:u') 1950 u.set(qn('w:val'), "single") 1951 rPr.append(u) 1952 color = OxmlElement('w:color') 1953 #color.set(qn('w:val'), "0070C0") 1954 color.set(qn('w:val'), "2F5496") 1955 rPr.append(color) 1956 r.append(rPr) 1957 r.text = str(item[i]) 1958 else: 1959 row_cells[i].text = str(item[i]) 1960 hdr_cells[1].merge(hdr_cells[2]).merge(hdr_cells[3]).merge(hdr_cells[4]) 1961 1962 if not(tempInfo == []): 1963 self.document.add_heading("Temperature Plots Table", level=2) 1964 self.plotTableTemplate(tempHeader, tempInfo, "-_PowerT", p) 1965 1966 if not(voltageInfo == []): 1967 self.document.add_heading("Voltage Plots Table", level=2) 1968 self.plotTableTemplate(voltageHeader, voltageInfo, "V", p) 1969 1970 if not(currentInfo == []): 1971 self.document.add_heading("Current Density Plots Table", level=2) 1972 self.plotTableTemplate(currentHeader, currentInfo, "A", p) 1973 1974 if not(powerLossDensityInfo == []): 1975 self.document.add_heading("Power Loss Density Plots Table", level=2) 1976 self.plotTableTemplate(powerLossDensityHeader, powerLossDensityInfo, "P", p) 1977 return
1978 1979 if False:
1980 - def progress(arg1, arg2):
1981 print arg1,arg2
1982 1983 import empro.toolkit.analysis.dc.results 1984 if not hasattr(empro.internal,'__tempResults'): 1985 #results1 = empro.toolkit.sipi.dc.results.DCResults(empro.activeProject.sipiSetupList()[-3]) 1986 #results2 = empro.toolkit.sipi.dc.results.DCResults(empro.activeProject.sipiSetupList()[-2]) 1987 #results = empro.toolkit.sipi.dc.results.DCResultsDiff(results1,results2) 1988 results = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[0]) 1989 empro.internal.__tempResults = results 1990 #results = empro.internal.__tempResults 1991 results = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[2]) 1992 docxinstance = Docx(results) 1993 docxinstance.figuresLocation = r'C:\Temp\report\result' 1994 docxinstance.progressCallback = progress 1995 docxinstance.targetFileName = r"C:\Temp\test.docx" 1996 import time 1997 stime = time.time() 1998 docxinstance.generate(docxinstance.targetFileName) 1999 empro.internal._figuresMetaData = docxinstance._figuresMetaData 2000 print time.time()-stime, "s" 2001 2002 if False:
2003 - def progress(arg1, arg2):
2004 print arg1,arg2
2005 2006 import empro.toolkit.analysis.dc.results 2007 if not hasattr(empro.internal,'__tempResults'): 2008 #results1 = empro.toolkit.sipi.dc.results.DCResults(empro.activeProject.sipiSetupList()[-3]) 2009 #results2 = empro.toolkit.sipi.dc.results.DCResults(empro.activeProject.sipiSetupList()[-2]) 2010 #results = empro.toolkit.sipi.dc.results.DCResultsDiff(results1,results2) 2011 results = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[-2]) 2012 empro.internal.__tempResults = results 2013 results = empro.internal.__tempResults 2014 html = Html(results) 2015 html.templatesLocation = r"F:\builds\empro-opt-64\src\empro\src\toolkit\sipi\dc\data\templates" 2016 html.figuresLocation = r'C:\Temp\report\result' 2017 html.progressCallback = progress 2018 import time 2019 stime = time.time() 2020 text = html.generate() 2021 empro.internal._figuresMetaData = html._figuresMetaData 2022 print time.time()-stime, "s" 2023 import codecs 2024 with codecs.open(r'C:\Temp\report\result\result.html','w','utf-8') as f: 2025 f.write(text) 2026 2027 2028 if False: 2029 import empro.toolkit.analysis.dc.results 2030 results = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[-1]) 2031 gr = empro.gui.GraphicsScene() 2032 _powerGraphSceneFromResults(gr,results) 2033 gr._save(r"c:\temp\powerGraph.png") 2034