1
2 from empro.gui import SimpleDialog, TableView, Cancel, ComboBox, Label, GridLayout,TabWidget
3 import string
4 from string import Template
5 import os
6
7 from empro.toolkit import _printexception
8 from empro.toolkit import Bunch
13 import webbrowser
14 webbrowser.open( url )
15
18 import webbrowser
19 webbrowser.open( file )
20
22 @_printexception
24
25 import empro.gui
26 import empro
27 self.dialog = SimpleDialog(0)
28
29 self._showDifference = False
30 self._temperatureFormat = "%4.1f"
31 self._voltageFormat = "%4.4f"
32 self._milliVoltageFormat = "%2.2f"
33 self._currentDensityFormat = "%5.1f"
34 self._epsRFormat = "%3.1f"
35 self._lossTangentFormat = "%4.3f"
36 self._conductivityFormat = "%7.0f S/m"
37
38 if isinstance(resultsDiff, empro.toolkit.analysis.dc.results.DCResults):
39 self.dialog.title = "DC Results Overview - " + resultsDiff.resultName
40 elif isinstance(resultsDiff, empro.toolkit.analysis.dc.results.DCResultsDiff):
41 self.dialog.title = "DC Results Overview - " + resultsDiff.resultNames[0] + " vs " + resultsDiff.resultNames[1]
42 self._showDifference = True
43 self.dialog.resize(860, 600)
44 self.dialog.onFinished = self.onFinished
45 self.results = resultsDiff
46 self.tableInfo = []
47 self.orgTableInfo = []
48 self.acceptFlag = 0
49 self.alwaysExport = False
50 self.path = ""
51 self._viaHighlightSegment = "sipi_overview_via_highlight"
52 self._viaHighlightSegmentLines = "sipi_overview_via_highlight_lines"
53 self._viaHighlightColor = (1.0, 0.25, 0.25, 1.0)
54 self._pinResultHighlightSegment = "sipi_overview_pin_result_highlight"
55 self._pinResultHighlightColor=(255,0,0)
56 self._passIcon = empro.gui.Icon(":/application/Valid.ico")
57 self._failIcon = empro.gui.Icon(":/application/Invalid.ico")
58 self.tabWidget = TabWidget()
59 w = empro.gui.Widget()
60 self.powerGraphTabId, self.sinksTabId, self.vrmsTabId, self.thermalComponentsTabId, self.layersTabId, self.pinsTabId, self.viasTabId, self.reportsTabId = range(8)
61 self.tabWidget.insertTab(self.powerGraphTabId, self._powerGraphTab(), "Power Graph")
62 self.tabWidget.insertTab(self.sinksTabId, self._sinkTab(), "Sinks")
63 self.tabWidget.insertTab(self.vrmsTabId, self._vrmsTab(), "VRMs")
64 self.tabWidget.insertTab(self.thermalComponentsTabId, self._thermalComponentsTab(), "Thermal Components")
65 self.tabWidget.insertTab(self.layersTabId, self._layersTab(), "Layers")
66 self.tabWidget.insertTab(self.pinsTabId, self._pinsTab(), "Pins")
67 self.tabWidget.insertTab(self.viasTabId, self._viasTab(), "Vias")
68 self.tabWidget.onCurrentChanged = self._tabChanged
69
70 self._containerWidget = self.dialog.mainWidget()
71 self._menuBar = empro.gui.MenuBar()
72 self._m = self._menuBar.addMenu("File")
73 self._mo = self._menuBar.addAction("Options...")
74 self._optionsActions = []
75 self._optionsActions.append(self._mo)
76 self._optionsActions[-1].onTriggered = lambda x:self._plotOptions()
77 self._compareActions = []
78 self._exportActions = []
79 if not self._showDifference:
80 self._compareMenu = self._m.addMenu("Compare to")
81 for setup in empro.activeProject.analyses:
82 if self.results.resultName!=setup.name and setup.analysisType in [empro.analysis.Analysis.THAnalysisType,empro.analysis.Analysis.ETHAnalysisType,empro.analysis.Analysis.DCAnalysisType]:
83 self._compareActions.append(self._compareMenu.addAction(setup.name))
84 self._compareActions[-1].onTriggered = lambda x,y=setup:self._compareTo(y)
85
86 self._exportMenu = self._m.addMenu("Export")
87 self._exportActions.append(self._exportMenu.addAction("HTML..."))
88 self._exportActions[-1].onTriggered = lambda x:self._exportToHtml()
89 self._exportActions.append(self._exportMenu.addAction("DocX..."))
90
91 self._exportActions[-1].onTriggered = lambda x:self._exportToDocX()
92
93
94 self.dialog.layout.add(self._menuBar)
95
96 self.dialog.layout.add(self.tabWidget)
97
98 self.geometryViewExportedForReporting = False
99 self.tempimgfilename = None
100
101 self.dialog.windowFlags = empro.gui.WF_Window
102 self.dialog.windowFlags &= ~empro.gui.WF_WindowStaysOnTopHint
103
104 import empro
105 celsius = empro.units.unitByAbbreviation("degC")
106 if self._showDifference:
107 celsius = empro.units.unitByAbbreviation("K")
108
109 index = 0
110
111 zSortedLayerNames = [ (k,v['zMax'],v['zMin']) for (k,v) in self.results.layerStatistics.iteritems()]
112 zSortedLayerNames = sorted(zSortedLayerNames, key=lambda x:(-x[2],-x[1]))
113
114
115 for layer in zSortedLayerNames:
116 layerName = layer[0]
117 layerStats = self.results.layerStatistics[layerName]
118 row = [layerName, self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMin"]), self._temperatureFormat % celsius.fromReferenceUnits(layerStats["temperatureMax"]), layerStats["currentMin"]*1e-6,layerStats["currentMax"]*1e-6,layerStats["voltageMin"],layerStats["voltageMax"]]
119 self._layersTable.setRow(index, row)
120 index += 1
121
122 self._hasAtLeastOneSenseLine = False
123 self._hasAtLeastOneSwitch = False
124 for vrm in self.results.vrms:
125 if vrm.senseVoltage is not None:
126 self._hasAtLeastOneSenseLine = True
127 if vrm.sourceType != 'PackagedVrm':
128 self._hasAtLeastOneSwitch = True
129 if self._hasAtLeastOneSenseLine and self._hasAtLeastOneSwitch:
130 break
131
132 for index, vrm in enumerate(self.results.vrms):
133 row = [vrm.name, vrm.sourceVoltage, vrm.outputVoltage ,abs(vrm.outputCurrent), abs(vrm.outputCurrent*vrm.outputVoltage), vrm.tolerance, self._milliVoltageFormat % (vrm.margin*1000.0)]
134 if self._hasAtLeastOneSenseLine and (self.results.resultAnalysisType == 1 or self.results.resultAnalysisType == 6):
135 voltage_diff = None
136 if vrm.senseVoltage is not None:
137 voltage_diff = self._milliVoltageFormat % ((vrm.senseVoltage-vrm.senseportVoltage)*1000.0)
138 row.append(vrm.senseVoltage)
139 row.append(vrm.senseportVoltage)
140 row.append(voltage_diff)
141 if self._hasAtLeastOneSwitch and (self.results.resultAnalysisType == 1 or self.results.resultAnalysisType == 6):
142 row.append(vrm.inputVoltage)
143 row.append(abs(vrm.upSwitchBunch.current) if vrm.upSwitchBunch else None)
144 row.append(abs(-vrm.lowSwitchBunch.current) if vrm.lowSwitchBunch else None)
145 row.append(abs(-vrm.inductorBunch.current) if vrm.inductorBunch else None)
146 if vrm.switchOutputVoltage and vrm.switchOutputCurrent:
147 row[2] = vrm.switchOutputVoltage
148 row[3] = abs(vrm.switchOutputCurrent)
149 row[4] = abs(vrm.switchOutputVoltage*vrm.switchOutputCurrent)
150 if not self._showDifference:
151 row.append(vrm.result)
152 self._vrmsTable.setRow(index, row)
153 if not self._showDifference:
154 icon = {True:self._failIcon, False:self._passIcon}["fail" in vrm.result.lower()]
155 self._vrmsTable.setDecoration(index,0, icon)
156 if "fail" in vrm.result.lower():
157 for i in range(len(row)):
158 self._vrmsTable.setData(index, i, (0.9,0.5,0.5,1.0),8)
159
160
161 for index, sink in enumerate(self.results.sinks):
162 irDrop = sink.vrmOutputVoltage-sink.inputVoltage
163 deltaV = sink.vrmVoltage - sink.inputVoltage
164 deltaVg = sink.maxVoltageGroundPins
165 deltaVp = sink.vrmVoltage-sink.minVoltagePowerPins
166 row = [sink.name, sink.vrmVoltage, sink.sourceCurrent, sink.inputVoltage,abs(sink.sourceCurrent*sink.inputVoltage), self._milliVoltageFormat % (irDrop*1000.0), self._milliVoltageFormat % (deltaV*1000.0), self._milliVoltageFormat % (deltaVp*1000.0), self._milliVoltageFormat % (deltaVg*1000.0), sink.tolerance, self._milliVoltageFormat % (sink.margin*1000.0),sink.resistance*1000.0]
167 if not self._showDifference:
168 row.append(sink.result)
169 self._sinksTable.setRow(index, row)
170 if not self._showDifference:
171 icon = {True:self._failIcon, False:self._passIcon}["fail" in sink.result.lower()]
172 self._sinksTable.setDecoration(index,0, icon)
173 if "fail" in sink.result.lower():
174 for i in range(len(row)):
175 self._sinksTable.setData(index, i, (0.9,0.5,0.5,1.0),8)
176
177
178 for index, source in enumerate(self.results.thermalComponents):
179 if hasattr(source,'heatDie'):
180 row = [source.name, source.heatDie, source.heatBoard, source.heatCase]
181 else:
182 row = [source.name, source.heat, '---', '---']
183 if hasattr(source,"temperature"):
184 row += [self._temperatureFormat % celsius.fromReferenceUnits(source.temperature), "---","---","---", source.bareBoardThermalResistance]
185 else:
186 row += ["---", self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureBoard), self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureDie), self._temperatureFormat % celsius.fromReferenceUnits(source.temperatureCase),source.bareBoardThermalResistance]
187 self._thermalComponentsTable.setRow(index, row)
188
189 if not self.results.vrms or not self.results.sinks:
190 self.tabWidget.setTabEnabled(self.powerGraphTabId,False)
191 if not self.results.sinks:
192 self.tabWidget.setTabEnabled(self.sinksTabId,False)
193 if not self.results.vrms:
194 self.tabWidget.setTabEnabled(self.vrmsTabId,False)
195 if not self.results.pins:
196 self.tabWidget.setTabEnabled(self.pinsTabId,False)
197 if not self.results.thermalComponents:
198 self.tabWidget.setTabEnabled(self.thermalComponentsTabId,False)
199
200 realIndex = 0
201 instanceCandidates = set()
202 for index, pin in enumerate(self.results.pins):
203 if pin.name!="---":
204 instanceName = ""
205 tokens = pin.name.split(".")
206 if len(tokens)==2:
207 instanceName=tokens[0]
208 instanceCandidates.add(instanceName)
209 row= [pin.name,pin.netName,pin.netType,pin.voltage,pin.current, celsius.fromReferenceUnits(pin.temperature)]
210 self._pinsTable.setRow(realIndex, row)
211 realIndex += 1
212 instanceCandidatesList = list(instanceCandidates)
213 instanceWithDesignatorList = []
214 for part in empro.activeProject.geometry().flatList(True):
215 if isinstance(part, empro.geometry.OaLayout):
216 for index in range(part._instanceCount()):
217 inst = part._instance(index)
218 if inst.name in instanceCandidates:
219 instanceWithDesignatorList.append(inst.name + " ( " + inst.libraryName + ":" + inst.cellName + " )")
220 self._instanceFilter.clear()
221 self._instanceFilter.addItem("All")
222 self._instanceFilter.addItem("Top Level Pins")
223 for instName in instanceWithDesignatorList:
224 self._instanceFilter.addItem(instName)
225
226
227 deltaSymbol = ""
228 if self._showDifference:
229 deltaSymbol = u"\u0394 "
230
231
232 self._layersTable.headers = ["Layer", deltaSymbol + u"Min T\n [\u00B0C]",deltaSymbol+u"Max T\n[\u00B0C]", deltaSymbol+"Min Current\nDensity [A/mm**2]", deltaSymbol+"Max Current\nDensity [A/mm**2]",deltaSymbol+"Min\nVoltage [V]", deltaSymbol+"Max\nVoltage [V]"]
233 self._layersTable.resizeColumnsToContents()
234 sinkHeaders = ["Name", deltaSymbol+"VRM\nVoltage [V]",deltaSymbol+"Input\nCurrent [A]", deltaSymbol+"Input\n Voltage [V]", deltaSymbol+"Input\nPower [W]", deltaSymbol+"IR Drop\n[mV]", u"\u0394V\n[mV]", u"\u0394Vp\n[mV]", u"\u0394Vg\n[mV]", deltaSymbol+"Tolerance", deltaSymbol+"Margin\n[mV]", deltaSymbol+"Resistance\n [mOhm]"]
235 self._sinksTable.headers = sinkHeaders
236 self._sinksTable.columnSizeHints = [(x,36) for x in [100,75,75,75,75,75,50,50,60,60]]
237 self._sinksTable.resizeColumnsToContents()
238 self._pinsTable.headers = ["Name","Net Name","Net Type", deltaSymbol+"Voltage [V]", deltaSymbol+"Current [A]", deltaSymbol+u"Temperature [\u00B0C]"]
239 self._pinsTable.resizeColumnsToContents()
240 vrmHeaders = ["Name", deltaSymbol+"Source\nVoltage [V]", deltaSymbol+"Output\nVoltage [V]", deltaSymbol+"Output\nCurrent [A]", deltaSymbol+"Output\nPower [W]", "Tolerance", deltaSymbol+"Margin\n[mV]"]
241 if self._hasAtLeastOneSenseLine:
242 vrmHeaders += ["Sense\nVoltage [V]", "Sense Port\nVoltage [V]", deltaSymbol+"Sense Diff.\n[mV]"]
243 if self._hasAtLeastOneSwitch:
244 vrmHeaders += ["Input\nVoltage [V]", "USwitch\nCurrent [A]", "LSwitch\nCurrent [A]", "Inductor\nCurrent [A]"]
245 self._vrmsTable.headers = vrmHeaders
246 self._vrmsTable.resizeColumnsToContents()
247 self._viasTable.headers = ["Id", deltaSymbol+"Current [A]", deltaSymbol+u"T [\u00B0C]", deltaSymbol+u"Radius [um]", deltaSymbol+u"Plating [um]", deltaSymbol+u"Area [um**2]"]
248 self._thermalComponentsTable.headers = ["Name", deltaSymbol+"Source [W]", deltaSymbol+"Heat To\nBoard [W]", deltaSymbol+"Heat To\nCase [W]", deltaSymbol+u"T\n[\u00B0C]",deltaSymbol+u"Case \nBottom T[\u00B0C]", deltaSymbol+u"Die T\n[\u00B0C]", deltaSymbol+u"Case \nTop T[\u00B0C]", deltaSymbol+"Thermal Resistance\nBare Board [K/W]"]
249 self._thermalComponentsTable.resizeColumnsToContents()
250
251 for table in [self._vrmsTable, self._sinksTable, self._pinsTable, self._viasTable, self._layersTable, self._thermalComponentsTable]:
252 table.selectionBehavior = TableView.SelectRows
253 table.selectionMode = TableView.ExtendedSelection
254 table.resizeRowsToContents()
255 table.resizeColumnsToContents()
256 table.alternatingRowColors = False
257 table.resizeColumnsToContents()
258 table.onLayoutChanged = lambda y=table: self.onSelectionChanged(y)
259 table.onSelectionChanged = lambda y=table: self.onSelectionChanged(y)
260 table.refresh()
261
262 pinNameToObj = {}
263 for part in empro.activeProject.geometry().flatList(True):
264 if isinstance(part, empro.geometry.OaLayout):
265 for index in range(part._instanceCount()):
266 inst = part._instance(index)
267 for pi in range(inst.instPinCount()):
268 pin = inst.instPin(pi)
269 name = "%s.%s" % (inst.name, pin.name)
270 pinNameToObj[name] = pin
271 self.pinNameToObj = pinNameToObj
272
273 import empro.toolkit.analysis.dc.output
274 empro.toolkit.analysis.dc.output._powerGraphSceneFromResults(self._powerGraphScene, self.results)
275 self._viaUpdate()
276
277
278 @_printexception
280 import empro
281 msg = { 'temperature' : 'Generating Temperature Plots',
282 'voltage' : 'Generating Voltage Plots',
283 'current' : 'Generating Current Plots',
284 'powerLossDensity' : 'Generating Power Loss Density Plots',
285 }.get(arg1,"Generating Report...")
286
287 prog = { 'temperature' : 0,
288 'voltage' : 1,
289 'current' : 2,
290 'powerLossDensity' : 3,
291 }.get(arg1,0)
292
293 self._progressInitDialog.value = prog
294 self._progressInitDialog.labelText = msg
295 empro.gui.processEvents()
296
297 @_printexception
299 self.alwaysExport = True
300 self.path = path
301
302 @_printexception
304 import empro
305 import empro.toolkit.analysis.dc.output
306 import os
307 if ( self.alwaysExport ):
308 path = os.path.join(self.path,self.results.resultName)
309 if not os.path.splitext(path)[1]:
310 path += ".html"
311 directory = os.path.split(path)[0]
312 if not (directory == ""):
313 html = empro.toolkit.analysis.dc.output.Html(self.results, self.tableInfo, self._maxCurrent.text, \
314 self._maxTemperature.text, self._showViolatingViasCurrentCheckBox.checked, self._showViolatingViasTCheckBox.checked)
315 html.templatesLocation = os.path.join(os.environ['EMPROHOME'],"empro","toolkit","sipi","dc","data","templates")
316 html.figuresLocation = directory
317 text = html.generate(path)
318 import codecs
319 with codecs.open(path,'w','utf-8') as f:
320 f.write(text)
321 else:
322 defaultPath = os.path.expanduser(".")
323 path = empro.gui.getSaveFileName("Export results_overview to Html", defaultPath, "*.html")
324 if not (path == ""):
325 if not os.path.splitext(path)[1]:
326 path += ".html"
327 directory = os.path.split(path)[0]
328 if not (directory == ""):
329 self._progressInitDialog = empro.gui.ProgressDialog("Generating HTML Report","","bla",0,1)
330 self._progressInitDialog.setCancelButtonText("Hide Progress Window")
331 html = empro.toolkit.analysis.dc.output.Html(self.results, self.tableInfo, self._maxCurrent.text, \
332 self._maxTemperature.text, self._showViolatingViasCurrentCheckBox.checked, self._showViolatingViasTCheckBox.checked)
333 html.templatesLocation = os.path.join(os.environ['EMPROHOME'],"empro","toolkit","sipi","dc","data","templates")
334 html.figuresLocation = directory
335 html.progressCallback = self._progressHtmlExport
336 self._progressInitDialog.minimumDuration = 0
337 self._progressInitDialog.setRange(0,4)
338 text = html.generate(path)
339 import codecs
340 with codecs.open(path,'w','utf-8') as f:
341 f.write(text)
342 self._progressInitDialog.close()
343 _openWebLink(path)
344 import platform
345 if platform.system() == "Windows":
346 path = path.replace('/','\\')
347 empro.gui.MessageBox.information("Export To Html", "File generated %s" % path, empro.gui.Ok, empro.gui.Ok)
348
349
350 @_printexception
352 import empro
353 import empro.toolkit.analysis.dc.output
354 import os
355 if ( self.alwaysExport ):
356 path = os.path.join(self.path,self.results.resultName)
357 if not os.path.splitext(path)[1]:
358 path += ".docx"
359 directory = os.path.split(path)[0]
360 if not (directory == ""):
361 docxinstance = empro.toolkit.analysis.dc.output.Docx(self.results, self.tableInfo,self._maxCurrent.text, \
362 self._maxTemperature.text,self._showViolatingViasCurrentCheckBox.checked, self._showViolatingViasTCheckBox.checked)
363 docxinstance.figuresLocation = directory
364 IOErrorflag = 0
365 try:
366 docxinstance.generate(path)
367 except IOError:
368 empro.gui.MessageBox.information("IOError: File can't be overwritten.", "File with the same name has been opened, it can't be overwritten. \nPlease close it firstly. \nFile is located at %s" % fn, empro.gui.Ok, empro.gui.Ok)
369 IOErrorflag = 1
370 else:
371 defaultPath = os.path.expanduser(".")
372 path = empro.gui.getSaveFileName("Export results_overview to Docx", defaultPath, "*.docx")
373 if not (path == ""):
374 if not os.path.splitext(path)[1]:
375 path += ".docx"
376 directory = os.path.split(path)[0]
377 if not (directory == ""):
378 self._progressInitDialog = empro.gui.ProgressDialog("Generating Docx Report","","bla",0,1)
379 self._progressInitDialog.setCancelButtonText("Hide Progress Window")
380 docxinstance = empro.toolkit.analysis.dc.output.Docx(self.results, self.tableInfo,self._maxCurrent.text, \
381 self._maxTemperature.text,self._showViolatingViasCurrentCheckBox.checked, self._showViolatingViasTCheckBox.checked)
382 docxinstance.figuresLocation = directory
383 docxinstance.progressCallback = self._progressHtmlExport
384 self._progressInitDialog.minimumDuration = 0
385 self._progressInitDialog.setRange(0,4)
386 IOErrorflag = 0
387 try:
388 docxinstance.generate(path)
389 except IOError:
390 empro.gui.MessageBox.information("IOError: File can't be overwritten.", "File with the same name has been opened, it can't be overwritten. \nPlease close it firstly. \nFile is located at %s" % fn, empro.gui.Ok, empro.gui.Ok)
391 IOErrorflag = 1
392 self._progressInitDialog.close()
393 if not (IOErrorflag == 1):
394 _openDocxFile(path)
395 import platform
396 if platform.system() == "Windows":
397 path = path.replace('/','\\')
398 empro.gui.MessageBox.information("Export To Docx", "File generated %s" % path, empro.gui.Ok, empro.gui.Ok)
399
400 @_printexception
403
404 @_printexception
406 import empro.gui
407 import empro
408 widget = empro.gui.Widget()
409 self._optionLayersTable = TableView(widget)
410 self._optionLayersTable.objectName = "Layers"
411 widget.layout = empro.gui.VBoxLayout()
412 widget.layout.addWidget(self._optionLayersTable)
413 self._optionLayersTable.headers = ["Layer","T", "V", "A", "P"]
414 index = 0
415 zSortedLayerNames = [ (k,v['zMax'],v['zMin']) for (k,v) in self.results.layerStatistics.iteritems()]
416 zSortedLayerNames = sorted(zSortedLayerNames, key=lambda x:(-x[2],-x[1]))
417 if self.acceptFlag == 0 :
418 row = []
419 plot1 = False
420 plot2 = False
421 plot3 = False
422 plot4 = False
423 for layer in zSortedLayerNames:
424 layerName = layer[0]
425 if(index == 0 or index == len(zSortedLayerNames)-1):
426 plot1 = True
427 else:
428 plot1 = False
429 row = [layerName, plot1, plot2, plot3, plot4]
430 self._optionLayersTable.setRow(index, row)
431 index += 1
432 for layerId in [-2,-3]:
433 layerName = {-2 : "top", -3 : "bottom"}[layerId]
434 plot1 = False
435 plot2 = plot3 = plot4 = True
436 row = [layerName, plot1, plot2, plot3, plot4]
437 self._optionLayersTable.setRow(index, row)
438 index += 1
439 else:
440 for row in self.tableInfo:
441 self._optionLayersTable.setRow(index, row)
442 index += 1
443 self._optionLayersTable.setUserCheckableColumns([1,2,3,4])
444 self._optionLayersTable.columnSizeHints = [(x,20) for x in [200,20,20,20]]
445 self._optionLayersTable.resizeColumnsToContents()
446 self._optionLayersTable.resizeRowsToContents()
447 self._optionsDialog = empro.gui.SimpleDialog(empro.gui.Ok | empro.gui.Cancel)
448 self._optionsDialog.setButtonText(empro.gui.Ok,'Accept')
449 self._optionsDialog.setButtonText(empro.gui.Cancel,'Cancel')
450 self._optionsDialog.title = "DC Results Overview Options"
451 self._optionsDialog.resize(535, 600)
452 self._optionsDialog.layout.add(empro.gui.Label("Select plots to be included in report:\n"))
453 self._optionsDialog.layout.add(self._optionLayersTable)
454 self._optionsDialog.layout.add(empro.gui.Label("Tips:\n\
455 For html plots, templates are being used.\n\
456 These are found from a predefined location.\n\
457 The filepath is <ads_installation>/fem/2017/win32_64/bin/empro/toolkit/sipi/dc/data/templates/\n"))
458 self._optionsDialog.windowFlags = empro.gui.WF_Window
459 self._optionsDialog.windowFlags &= ~empro.gui.WF_WindowStaysOnTopHint
460 self._optionsDialog.onClicked = self.onClicked
461 if self.orgTableInfo == []:
462 for i in range(self._optionLayersTable.rowCount()):
463 self.orgTableInfo.append(self._optionLayersTable.row(i))
464 self._optionsDialog.show(True)
465 return self.tableInfo
466
467 @_printexception
469 if iButtonClicked.text == "Accept":
470 self._accept()
471 if iButtonClicked.text == "Cancel":
472 self._cancel()
473
474 @_printexception
476 if self.tableInfo == []:
477 self.tableInfo = self.orgTableInfo
478
479 @_printexception
481 if not self.tableInfo == []:
482 self.tableInfo = []
483 for i in range(self._optionLayersTable.rowCount()):
484 self.tableInfo.append(self._optionLayersTable.row(i))
485 self.acceptFlag = 1
486
487 @_printexception
494
495 @_printexception
497 curText = self._instanceFilter.currentText()
498 if curText == "All":
499 self._pinsTable.clear()
500 pinData = [(i) for i in self.results.pins]
501 realIndex = 0
502 for pin in pinData:
503 row = [pin.name,pin.netName,pin.netType,pin.voltage,pin.current]
504 self._pinsTable.setRow(realIndex, row)
505 realIndex += 1
506 self._pinsTable.resizeRowsToContents()
507 elif curText == "Top Level Pins":
508 self._pinsTable.clear()
509 pinData = [(i) for i in self.results.pins if not i.name.count(".")]
510 realIndex = 0
511 for pin in pinData:
512 row = [pin.name,pin.netName,pin.netType,pin.voltage,pin.current]
513 self._pinsTable.setRow(realIndex, row)
514 realIndex += 1
515 self._pinsTable.resizeRowsToContents()
516 else:
517 tokens = curText.split("(")
518 targetInstName = tokens[0]
519 targetInstName = targetInstName.strip()
520 self._pinsTable.clear()
521 pinData = [(i) for i in self.results.pins if (i.name.split(".")[0] == targetInstName)]
522 realIndex = 0
523 for pin in pinData:
524 row = [pin.name,pin.netName,pin.netType,pin.voltage,pin.current]
525 self._pinsTable.setRow(realIndex, row)
526 realIndex += 1
527 self._pinsTable.resizeRowsToContents()
528
529 @_printexception
531 maxCurrent = 1e15
532 maxCurrentFormula = self._maxCurrent.text
533
534 showViolatingCurrent = self._showViolatingViasCurrentCheckBox.checked
535 showViolatingT = self._showViolatingViasTCheckBox.checked
536 index = 0
537 self._numberOfViolatingVias = 0
538 self._numberOfViolatingViasT = 0
539
540 import empro
541 lengthUnit = empro.units.unitByAbbreviation("um")
542 areaUnit = empro.units.unitByAbbreviation("squm")
543 celsius = empro.units.unitByAbbreviation("degC")
544 if self._showDifference:
545 celsius = empro.units.unitByAbbreviation("K")
546
547 maxT = 1e15
548 maxTemperatureFormula = self._maxTemperature.text
549
550 self._viasTable.clear()
551 localParamList = empro.activeProject.parameters().clone()
552 localParamList.append("Radius",0.0)
553 localParamList.append("Plating",0.0)
554 localParamList.append("Area",0.0)
555 import math
556
557 for key, via in self.results.viaCurrents.iteritems():
558 viaCurrent = float(via[0])
559 viaTemperature = celsius.fromReferenceUnits(self.results.viaMaxTemperatures.get(key,298.15))
560 radius, plating = self.results.viaRadiusThickness.get(key,(-1,-1))
561 localParamList.setFormula("Radius",radius)
562 localParamList.setFormula("Plating",plating)
563 area = math.pi*radius*radius
564 if plating>0.0:
565 area -= math.pi*(radius-plating)*(radius-plating)
566 localParamList.setFormula("Area",area)
567 maxCurrent = empro.core.Expression(maxCurrentFormula).evaluate(localParamList)
568 maxT = celsius.fromReferenceUnits(empro.core.Expression(maxTemperatureFormula).evaluate(localParamList))
569
570
571 currentIsPassed = False
572 if float(via[0]) < maxCurrent:
573 currentIsPassed = True
574 else:
575 self._numberOfViolatingVias += 1
576
577 tempIsPassed = viaTemperature < maxT
578 if not tempIsPassed:
579 self._numberOfViolatingViasT += 1
580
581 hideRow = (showViolatingCurrent and currentIsPassed) or (showViolatingT and tempIsPassed)
582 radiusStr = lengthUnit.fromReferenceUnits(radius)
583 platingStr = lengthUnit.fromReferenceUnits(plating)
584 areaStr = areaUnit.fromReferenceUnits(area)
585
586 if not hideRow:
587 self._viasTable.setRow(index, [str(key), viaCurrent, self._temperatureFormat % viaTemperature, radiusStr, platingStr, areaStr])
588 self._viasTable.setDecoration(index,1,{True : self._passIcon, False:self._failIcon}[currentIsPassed] )
589 self._viasTable.setDecoration(index,2,{True : self._passIcon, False:self._failIcon}[tempIsPassed] )
590 index += 1
591 self._viasTable.resizeRowsToContents()
592 self.refreshTableLayout(self._viasTable)
593 currentViolations = self._numberOfViolatingVias
594 temperatureViolations = self._numberOfViolatingViasT
595 self._currentViolationCount.text = "(%(currentViolations)d Violations)" % vars()
596 self._temperatureViolationCount.text = "(%(temperatureViolations)d Violations)" % vars()
597
598
599 @_printexception
601 w,h = table.size()
602 table.resize((w+1,h))
603 table.resize((w,h))
604
605 @_printexception
607 import empro.gui
608 w = empro.gui.Widget()
609 self._layersTable = TableView(w)
610 self._layersTable .objectName = "layers"
611 w.layout = empro.gui.VBoxLayout()
612 w.layout.addWidget(self._layersTable)
613 self._layersTable.headers = []
614 return w
615
616 @_printexception
618 import empro.gui
619 w = empro.gui.Widget()
620 w.layout = empro.gui.VBoxLayout()
621 self._powerGraphScene = empro.gui.GraphicsScene()
622 self._powerGraphView = empro.gui.GraphicsView(self._powerGraphScene, w)
623 self._powerGraphView.scale(1,-1)
624 self._powerGraphView.allowDragging = True
625 self._powerGraphView.autoFitScene = False
626 w.layout.addWidget(self._powerGraphView)
627 return w
628
629 @_printexception
631 import empro.gui
632 w = empro.gui.Widget()
633 self._sinksTable = TableView(w)
634 self._sinksTable.objectName = "sinks"
635 w.layout = empro.gui.VBoxLayout()
636 w.layout.addWidget(self._sinksTable)
637 self._sinksTable.headers = []
638 return w
639
640 @_printexception
642 import empro.gui
643 w = empro.gui.Widget()
644 self._thermalComponentsTable = TableView(w)
645 self._thermalComponentsTable.objectName = "thermalComponents"
646 w.layout = empro.gui.VBoxLayout()
647 w.layout.addWidget(self._thermalComponentsTable)
648 self._thermalComponentsTable.headers = []
649 return w
650
651 @_printexception
654
655 @_printexception
657 self._viaUpdate()
658 self._evaluateVias.enabled = False
659
660 @_printexception
662 self._evaluateVias.enabled = True
663
664
665 @_printexception
667 self._evaluateVias.enabled = True
668
669 @_printexception
672
673 @_printexception
675 import empro.gui
676 w = empro.gui.Widget()
677
678 self._viasTable = TableView(w)
679 self._maxCurrent = empro.gui.LineEdit("1 + 0*Area A")
680 self._maxCurrent.onUpdate = self._maxCurrentUpdated
681 self.label = Label("Maximum Current:")
682 self._numberOfViolatingVias = 0
683 self._currentViolationCount = Label("(0 Violations)")
684 self._viasTable.objectName = "vias"
685 self._displayViasResultChckBox = empro.gui.CheckBox("Display Results in Layout" )
686 self._displayViasResultChckBox.checked = True
687 self._displayViasResultChckBox.onToggled = lambda x : self.onCheckBoxClick()
688 self._maxTempLabel = empro.gui.Label("Maximum Temperature")
689 self._maxTemperature = empro.gui.LineEdit("100 degC")
690 self._maxTemperature.onUpdate = self._maxTemperatureUpdated
691 self._temperatureViolationCount = Label("(0 Violations)")
692 self._numberOfViolatingViasT = 0
693 self._showViolatingViasCurrentCheckBox = empro.gui.CheckBox("Only Show Violating Vias (Current)")
694 self._showViolatingViasCurrentCheckBox.onToggled = lambda x : self.onShowViolatingViasOnlyClicked()
695 self._showViolatingViasTCheckBox = empro.gui.CheckBox("Only Show Violating Vias (T)")
696 self._showViolatingViasTCheckBox.onToggled = lambda x : self.onShowViolatingViasOnlyClicked()
697 self._evaluateVias = empro.gui.PushButton("Re-Evaluate")
698 self._evaluateVias.onClicked = lambda x:self._evaluateViolations()
699 self._evaluateVias.enabled = False
700 self._viaUpdate()
701
702
703 filterWidget = empro.gui.Widget()
704 filterWidget.layout = empro.gui.HBoxLayout()
705 filterWidget.layout.contentsMargin = [0, 0, 0, 0]
706 filterWidget.layout.addWidget(self.label)
707 filterWidget.layout.addWidget(self._maxCurrent,1)
708 filterWidget.layout.addWidget(self._currentViolationCount,0,20)
709 filterWidget2 = empro.gui.Widget()
710 filterWidget2.layout = empro.gui.HBoxLayout()
711 filterWidget2.layout.contentsMargin = [0, 0, 0, 0]
712 filterWidget2.layout.addWidget(self._maxTempLabel)
713 filterWidget2.layout.addWidget(self._maxTemperature,1)
714 filterWidget2.layout.addWidget(self._temperatureViolationCount,0,20)
715 filterWidget3 = empro.gui.Widget()
716 filterWidget3.layout = empro.gui.HBoxLayout()
717 filterWidget3.layout.contentsMargin = [0, 0, 0, 0]
718 filterWidget3.layout.addWidget(self._evaluateVias)
719 filterWidget3.layout.addWidget(self._displayViasResultChckBox)
720 filterWidget3.layout.addWidget(self._showViolatingViasCurrentCheckBox)
721 filterWidget3.layout.addWidget(self._showViolatingViasTCheckBox)
722 filterWidget3.layout.addStretch(1)
723
724 w.layout = empro.gui.VBoxLayout()
725 w.layout.addWidget(filterWidget)
726 w.layout.addWidget(filterWidget2)
727 w.layout.addWidget(filterWidget3)
728 w.layout.addWidget(self._viasTable)
729 self._viasTable.headers = []
730 self._viasTable.resizeColumnsToContents()
731 return w
732
733 @_printexception
737
738 @_printexception
740
741
742 import empro
743 w, h = table.size()
744 table.resize(w + 2, h)
745 table.resize(w, h)
746 if table.objectName=="pins":
747 selectedPins = [table.data(x,0) for x in table.selectedRows()]
748 points = []
749 results = []
750 if self._selectInTreeChckBox.checked:
751 gv = empro.gui.activeProjectView().geometryView()
752 import empro.gui
753 gs = empro.gui.SelectionList.globalSelectionList()
754 gs.clear()
755 gs.insertList([self.pinNameToObj[x] for x in selectedPins])
756
757 if not self._selectInTreeChckBox.checked:
758 import empro.gui
759 gs = empro.gui.SelectionList.globalSelectionList()
760 gs.clear()
761
762 if self._displayPinsResultChckBox.checked:
763 for pinName in selectedPins:
764 for pin in self.results.pins:
765 if pinName == pin.name:
766 name = pin.name
767 voltage = str(pin.voltage)+" V"
768 current = str(pin.current)+" A"
769 temperature = str(pin.temperature) + " K"
770 pin = self.pinNameToObj[pinName]
771 position = pin.dotPosition
772 data = name+"\n"+voltage+"\n"+current+"\n"+temperature
773 points.append(position)
774 results.append(data)
775
776 gv = empro.gui.activeProjectView().geometryView()
777 key = gv.insertTexts(points,results,self._pinResultHighlightSegment)
778 gv.setRenderingOptions( key, "general displacement = -20")
779 gv.updateView()
780
781 if not self._displayPinsResultChckBox.checked:
782 gv = empro.gui.activeProjectView().geometryView()
783 key = gv.insertTexts([],[],self._pinResultHighlightSegment)
784 gv.updateView()
785
786 if table.objectName=="vias":
787 import empro
788 import time
789 celsius = empro.units.unitByAbbreviation("degC")
790 if self._showDifference:
791 celsius = empro.units.unitByAbbreviation("K")
792
793 ids = [table.data(x,0) for x in table.selectedRows()]
794 cellCoords = []
795 lineCoords = []
796 results = []
797 points = []
798
799 for id in ids:
800 current, faces = self.results.viaCurrents.get(int(id),0.0)
801 temperature = celsius.fromReferenceUnits(self.results.viaMaxTemperatures.get(int(id),298.15))
802 cellCoords.extend(faces)
803 results.append(str(current)+" A\n" + (self._temperatureFormat % temperature) + " " + celsius.abbreviation())
804 points.append(faces[0][0])
805 for face in faces:
806 lineCoords += [(face[0], face[1]), (face[0], face[2]), (face[2], face[1])]
807
808 gv = empro.gui.activeProjectView()
809 gv = gv.geometryView()
810 key = gv.insertPolygons(cellCoords, self._viaHighlightSegment, self._viaHighlightColor)
811 gv.setRenderingOptions( key, "general displacement = -20")
812 key = gv.insertWeightedLines(lineCoords, self._viaHighlightSegmentLines, 4, self._viaHighlightColor)
813 gv.setRenderingOptions( key, "general displacement = -20")
814 if self._displayViasResultChckBox.checked:
815 key = gv.insertTexts(points,results,self._viaHighlightSegment)
816 gv.setRenderingOptions( key, "general displacement = -20")
817 else:
818 key = gv.insertTexts([],[],self._viaHighlightSegment)
819 gv.updateView()
820
821 @_printexception
823 import empro.gui
824 w = empro.gui.Widget()
825 self._vrmsTable = TableView(w)
826 self._vrmsTable.objectName = "vrms"
827 w.layout = empro.gui.VBoxLayout()
828 w.layout.addWidget(self._vrmsTable)
829 self._vrmsTable.headers = []
830 return w
831
832 @_printexception
834 import empro.gui
835 w = empro.gui.Widget()
836 self._pinsTable = TableView(w)
837 self._pinsTable.objectName = "pins"
838
839
840 self._instanceFilterLbl = empro.gui.Label("Select Pins:")
841 self._instanceFilter = empro.gui.ComboBox(w)
842 self._instanceFilter.objectName = "filterCombo"
843 self._instanceFilter.onActivated = self.updateInstanceTableVisibility
844 instanceFilterWidget = empro.gui.Widget()
845 instanceFilterWidget.layout = empro.gui.HBoxLayout()
846 instanceFilterWidget.layout.contentsMargin = [0, 0, 0, 0]
847 instanceFilterWidget.layout.addWidget(self._instanceFilterLbl)
848 instanceFilterWidget.layout.addWidget(self._instanceFilter)
849 instanceFilterWidget.layout.addStretch(1)
850
851 self._selectInTreeChckBox = empro.gui.CheckBox("Select Pins in Project Tree" )
852 self._selectInTreeChckBox.checked = True
853 self._selectInTreeChckBox.onToggled = lambda x : self.onCheckBoxClick()
854 self._displayPinsResultChckBox = empro.gui.CheckBox("Display Results in Layout" )
855 self._displayPinsResultChckBox.checked = True
856 self._displayPinsResultChckBox.onToggled = lambda x : self.onCheckBoxClick()
857 pinsDisplayFilterWidget = empro.gui.Widget()
858 pinsDisplayFilterWidget.layout = empro.gui.HBoxLayout()
859 pinsDisplayFilterWidget.layout.contentsMargin = [0, 0, 0, 0]
860 pinsDisplayFilterWidget.layout.addWidget(self._selectInTreeChckBox)
861 pinsDisplayFilterWidget.layout.addWidget(self._displayPinsResultChckBox)
862 pinsDisplayFilterWidget.layout.addStretch(1)
863
864 pinsTableWidget = empro.gui.Widget()
865 pinsTableWidget.layout = empro.gui.HBoxLayout()
866 pinsTableWidget.layout.contentsMargin = [0, 0, 0, 0]
867 pinsTableWidget.layout.addWidget(self._pinsTable)
868 self._pinsTable.headers = []
869
870 w.layout = empro.gui.VBoxLayout()
871 w.layout.addWidget(instanceFilterWidget)
872 w.layout.addWidget(pinsDisplayFilterWidget)
873 w.layout.addWidget(pinsTableWidget)
874 return w
875
877 self.dialog.show(False)
878
879 @_printexception
881
882 import empro
883 gv = empro.gui.activeProjectView()
884 gv = gv.geometryView()
885 key = gv.insertPolygons([], self._viaHighlightSegment, self._viaHighlightColor)
886 key = gv.insertWeightedLines([], self._viaHighlightSegmentLines, 1, self._viaHighlightColor)
887 key = gv.insertTexts([],[],self._pinResultHighlightSegment)
888 key = gv.insertTexts([],[],self._viaHighlightSegment)
889 gv.updateView()
890
891 if False:
892 import empro.toolkit.analysis.dc.results
893 result1 = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[-1])
894 result2 = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[-2])
895 diff = empro.toolkit.analysis.dc.results.DCResultsDiff(result1,result2)
896 resultsDiffView = ResultsOverview(diff)
897 resultsDiffView.show()
898
899 if False:
900 import empro.toolkit.analysis.dc.results
901 result1 = empro.toolkit.analysis.dc.results.DCResults(empro.activeProject.analyses[-2])
902 resultsDiffView = ResultsOverview(result1)
903 resultsDiffView.show()
904