1
2 import io
3
4 from empro.toolkit import _printexception, Bunch
21
23 @_printexception
25 import os
26 import collections
27 import empro
28 self.sipiData = sipiData
29 self.resultName = sipiData.name
30 self.resultAnalysisType = sipiData.analysisType
31 simLocation = sipiData.simulationPath
32 if not simLocation:
33 raise Exception("Simulation Results Not Found")
34 simInpData = os.path.join(simLocation, "design.sti")
35 pinHashToName = {}
36 pinHashToName[0] = "---"
37 instancePinHashToName = {}
38
39 netNameDict = {}
40 netNameDict[0] = "---"
41 pinNameToNetName = _pinNameToNetNameDict()
42 netList = empro.activeProject.geometry()[0]._netList()
43 powerNets = list(netList.getPowerNetNames())
44 groundNets = list(netList.getGroundNetNames())
45 signalNets = list(netList.getSignalNetNames())
46 vrms = {}
47 sinks = {}
48 thermalComponents = {}
49 vrmsPlusNets = {}
50 sinksPlusNets = {}
51 components = {}
52 cmptNameToTolerance = {}
53 nbVrms = len(sipiData.getVrmList())
54 diagonalLoadsOnly = os.environ.has_key("SIPI_DC_DIAGONAL_LOADS_ONLY")
55 if diagonalLoadsOnly:
56 print "Warning: only diagonal loads are considered and off-diagonal loads are neglected"
57
58 with open(simInpData,"r") as inp:
59 lines = inp.readlines()
60 for index, line in enumerate(lines):
61 line = line.strip()
62 if not line.startswith('#'):
63 continue
64 cols = line[1:].split(";")
65 key = cols[0].strip()
66 if key=="AvailablePin":
67 pinHashToName[int(cols[1])]=cols[2]
68 netNameDict[int(cols[1])] = pinNameToNetName[cols[2]]
69 if key=="AvailableInstancePin":
70 instancePinHashToName[int(cols[1])]=cols[2]
71 if key=="Vrm":
72 for vrm in sipiData.getVrmList():
73 cmptNameToTolerance[vrm.name] = vrm.tolerance
74 nr = int(cols[1])
75 name = cols[2]
76 voltage = float(cols[3])
77 tolerance = float(cols[4])
78 plusPins = [x.strip() for x in map(str,lines[index+1].split(";")[2:])]
79 minPins = [x.strip() for x in map(str,lines[index+2].split(";")[2:])]
80 plusNets = []
81 if "NetPlus" in lines[index+3]:
82 plusNets = map(str,lines[index+3].split(";")[2:])
83 vrmsPlusNets[nr] = plusNets
84 vrms[nr] = [name, voltage, "?", "?", tolerance, "?", "?", plusPins, minPins]
85 if key=="ComponentModel":
86 nr = int(cols[1])
87 name = cols[2]
88 if "ComponentModelPlus1" in lines[index+1]:
89
90 counter = 0
91 plusPins = []
92 minPins= []
93 while "ComponentModelPlus" in lines[index+1+counter] or "ComponentModelMinus" in lines[index+1+counter]:
94 if "ComponentModelPlus" in lines[index+1+counter]:
95 plusPins += [x.strip() for x in map(str,lines[index+1+counter].split(";")[2:])]
96 else:
97 minPins += [x.strip() for x in map(str,lines[index+1+counter].split(";")[2:])]
98 counter += 1
99 else:
100 plusPins = [x.strip() for x in map(str,lines[index+1].split(";")[2:])]
101 minPins = [x.strip() for x in map(str,lines[index+2].split(";")[2:])]
102 components[nr] = Bunch(name=name,plusPinNames=plusPins,minusPinNames=minPins)
103 if key=="ThermalComponent":
104 nr = int(cols[1])
105 name = cols[2]
106 heatSource = float(cols[3])
107 pins = [x.strip() for x in map(str,lines[index+1].split(";")[2:])]
108 thermalComponent = Bunch(name=name, heatSource=heatSource, pins=pins)
109 thermalComponents[nr] = thermalComponent
110 if key=="Sink":
111 for sink in sipiData.getSinkList():
112 cmptNameToTolerance[sink.name] = sink.tolerance
113 nr = int(cols[1])
114 name = cols[2]
115 current = float(cols[3])
116 tolerance = float(cols[4])
117 plusPins = [x.strip() for x in map(str,lines[index+1].split(";")[2:])]
118 instanceCandidate = ""
119 for pinName in plusPins:
120 tokens = pinName.split(".")
121 if len(tokens)==2:
122 instanceCandidate=tokens[0]
123 minPins = [x.strip() for x in map(str,lines[index+2].split(";")[2:])]
124 plusNets = []
125 if "NetPlus" in lines[index+3]:
126 plusNets = map(str,lines[index+3].split(";")[2:])
127 sinksPlusNets[nr] = plusNets
128 sinks[nr] = [name, current, "?", "?", tolerance, "?", "?", plusPins, minPins, instanceCandidate]
129 if diagonalLoadsOnly:
130 loadsSeenFromSinks = []
131 else:
132 matrixLoadsSeenFromSinks = []
133 for index, line in enumerate(lines):
134 line = line.strip()
135 if line.startswith('#'):
136 continue
137 if line.startswith("Electric") or line.startswith("Lumped"):
138 words = line.replace(':','').split()
139 id = int(words[1])
140 if not sinks.has_key(id):
141 found = False
142 lookAhead = 250
143
144 words = lines[index+1].strip().split()
145 nrOfPorts = 1
146 if words[0].startswith("nrOfPorts"):
147 nrOfPorts = int(words[1])
148 lookAhead = 250 + nrOfPorts * 3
149
150 for incr in range(lookAhead):
151 if index+incr>=len(lines):
152 break
153 words = lines[index+incr].strip().split()
154 if nrOfPorts==1 and (words[0].startswith("portNr") or words[0].startswith("port")):
155 id = int(words[1])
156 if nrOfPorts>1 and (words[0].startswith("portNr[1]") or words[0].startswith("port[1]")):
157 id = int(words[1])
158 if words[0].startswith("load"):
159 if words[1].startswith("open"):
160 if diagonalLoadsOnly:
161 loadsSeenFromSinks.append([id-1,1e9])
162 else:
163 matrixLoadsSeenFromSinks.append([id-1,id-1,1e9])
164 elif words[1].startswith("short"):
165 if diagonalLoadsOnly:
166 loadsSeenFromSinks.append([id-1,0.0])
167 else:
168 matrixLoadsSeenFromSinks.append([id-1,id-1,0.0])
169 elif words[1] == "resistor":
170 if nrOfPorts==1:
171 if len(words)==4:
172 R = float(words[3])
173 else:
174 words = words[2].split('=')
175 R = float(words[1])
176 if diagonalLoadsOnly:
177 loadsSeenFromSinks.append([id-1,R])
178 else:
179 matrixLoadsSeenFromSinks.append([id-1,id-1,R])
180 else:
181 line = lines[index+incr].strip()
182 filteredLine = line[line.find("R=")+2:]
183 values = map(float,filteredLine.split())
184 if diagonalLoadsOnly:
185
186 def diagonalElements(nbPorts):
187 elements = [0]
188 index = 0
189 for i in range(nbPorts-1):
190 index += nbPorts-i
191 elements.append(index)
192 return elements
193 diagonalValues = []
194 for index in diagonalElements(nrOfPorts):
195 diagonalValues.append(values[index])
196 for index, value in enumerate(diagonalValues):
197 loadsSeenFromSinks.append([id-1+index,value])
198 else:
199
200 assert(len(values) == nrOfPorts*(nrOfPorts+1)/2)
201 cnt = 0
202 for r in range(id-1, id+nrOfPorts-1):
203 for c in range(r, id+nrOfPorts-1):
204 matrixLoadsSeenFromSinks.append([r,c,values[cnt]])
205 cnt = cnt + 1
206
207 break
208
209 def buildMatrixLoad(matrixLoadsSeenFromSinks):
210 import empro.enparams
211 loadIds = set([])
212 for load in matrixLoadsSeenFromSinks:
213 loadIds.add(load[0])
214 loadIds.add(load[1])
215 g2l = {}
216 lid = 0
217 loadIdsVec = []
218 for gid in loadIds:
219 loadIdsVec.append(gid)
220 g2l[gid] = lid
221 lid = lid + 1
222 matrixLoad = empro.enparams.SquareComplexMatrix(len(g2l))
223 for load in matrixLoadsSeenFromSinks:
224 r = g2l[load[0]]
225 c = g2l[load[1]]
226 v = load[2]
227 matrixLoad.setValue(r, c, v)
228 if r != c: matrixLoad.setValue(c, r, v)
229 return loadIdsVec, matrixLoad
230
231 self.pins = []
232 self.thermalPins = []
233 lumpNrToVI = {}
234 lumpNrToTH = {}
235 electricNameTolumpNr = {}
236 simOutpData = os.path.join(simLocation, "design.out.sti")
237 import re
238 posintRe = r"\d+"
239 floatRe = r"[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?"
240 pinRe = r"((plus)|(min))pin[\[" + posintRe + r"\]]*:"
241 extractPinVI = re.compile(r"\s*" + pinRe + r"\s*(?P<pinId>"+ posintRe +r")\s+voltage:\s*(?P<V>" + floatRe + r")\s+current:\s*(?P<I>" + floatRe + r")")
242 extractPinTH = re.compile(r"\s*" + pinRe + r"\s*(?P<pinId>"+ posintRe +r")\s+temperature:\s*(?P<T>" + floatRe + r")\s+heat:\s*(?P<H>" + floatRe + r")")
243 lastThermalLumpNr = None
244 lastElectricLumpNr = None
245
246 if not os.path.exists(simOutpData):
247 raise RuntimeError("Cannot find output file. Simulations results are incomplete.\nSearched for file: %(simOutpData)s" % vars())
248
249 with io.open(simOutpData) as inp:
250 lines = inp.readlines()
251 for index, line in enumerate(lines):
252 if line.startswith("StiFile"):
253 continue
254 matchVI = extractPinVI.match(line)
255 matchTH = extractPinTH.match(line)
256 if matchVI:
257 pinHash = int(matchVI.groupdict()["pinId"])
258 voltage = float(matchVI.groupdict()["V"])
259 current = float(matchVI.groupdict()["I"])
260 if pinHash in netNameDict:
261 netName = netNameDict[pinHash]
262 if netName in powerNets:
263 netType = "Power"
264 elif netName in groundNets:
265 netType = "Ground"
266 elif netName in signalNets:
267 netType = "Signal"
268 else:
269 netType = "Undefined"
270 pinName = pinHashToName[pinHash]
271 else:
272 pinName = ""
273 netName = ""
274 netType = "Virtual"
275 pinInfo = [pinName,netName,netType, voltage, current]
276 self.pins.append(pinInfo)
277 lumpNrToVI.get(lastElectricLumpNr,[0.0,0.0,[]])[2].append( Bunch(name=pinName,netName=netName,netType=netType,voltage=voltage,current=current) )
278 elif matchTH:
279 pinHash = int(matchTH.groupdict()["pinId"])
280 temperature = float(matchTH.groupdict()["T"])
281 heat = float(matchTH.groupdict()["H"])
282 if pinHash in netNameDict:
283 netName = netNameDict[pinHash]
284 if netName in powerNets:
285 netType = "Power"
286 elif netName in groundNets:
287 netType = "Ground"
288 elif netName in signalNets:
289 netType = "Signal"
290 else:
291 netType = "Undefined"
292 pinName = pinHashToName[pinHash]
293 else:
294 pinName = ""
295 netName = ""
296 if pinHash==0:
297 netType = "Virtual"
298 else:
299 netType = "ThermalPad"
300 pinInfo = Bunch(name=pinName,netName=netName,netType=netType,temperature=temperature,heat=heat)
301 self.thermalPins.append(pinInfo)
302 lumpNrToTH.get(lastThermalLumpNr,Bunch(temperature=298.15, heat=0.0, pins=[])).pins.append( Bunch(name=pinName,netName=netName,netType=netType,temperature=temperature,heat=heat) )
303 continue
304 elif line.startswith("Lumped") or line.startswith("Electric"):
305 if line.startswith("Lumped"):
306 lumpNr = int(line.replace("Lumped","").replace(":",""))
307 else:
308 lumpNr = int(line.replace("Electric","").replace(":",""))
309 lastElectricLumpNr = lumpNr
310 nextIndex = index + 1
311 if "name:" in lines[nextIndex]:
312 electricName = lines[nextIndex].replace("name","").replace(":","").lstrip(" ").rstrip("\n")
313 electricNameTolumpNr[electricName] = lumpNr
314 nextIndex += 1
315 parts = lines[nextIndex].split(":")
316 if "nrOfPorts" in parts[0]:
317 if int(parts[1]) > 1:
318 continue
319 else:
320 nextIndex = nextIndex + 1
321 parts = lines[nextIndex].split(":")
322 if not "voltage" in parts[0]:
323 raise Exception("parsing error at line %d: voltage expected" % nextIndex)
324 voltage = float(parts[1])
325 nextIndex = nextIndex + 1
326 parts = lines[nextIndex].split(":")
327 if not "current" in parts[0]:
328 raise Exception("parsing error at line %d: current expected" % nextIndex)
329 current = float(parts[1])
330 lumpNrToVI[lumpNr] = [voltage,current,[]]
331 elif line.startswith("Thermal"):
332 lumpNr = int(line.replace("Thermal","").replace(":",""))
333 lastThermalLumpNr = lumpNr
334 nextIndex = index + 1
335 if "name:" in lines[nextIndex]:
336 nextIndex += 1
337 parts = lines[nextIndex].split(":")
338 if "nrOfPorts" in parts[0]:
339 if int(parts[1]) > 1:
340 continue
341 else:
342 nextIndex = nextIndex + 1
343 parts = lines[nextIndex].split(":")
344 if not "temperature" in parts[0]:
345 raise Exception("parsing error at line %d: temperature expected" % nextIndex)
346 tempDescr = parts[1].strip().split(" ")
347 temperature = float(tempDescr[0])
348 nextIndex = nextIndex + 1
349 parts = lines[nextIndex].split(":")
350 if not "heat" in parts[0]:
351 raise Exception("parsing error at line %d: heat expected" % nextIndex)
352
353 heatDescr = parts[1].strip().split(" ")
354 heatBoard, heatDie, heatCase = float(heatDescr[0]),float(heatDescr[1]),float(heatDescr[2])
355 if len(tempDescr)==3:
356 temperatureBoard, temperatureDie, temperatureCase = float(tempDescr[0]),float(tempDescr[1]),float(tempDescr[2])
357 temperatureResult = Bunch(temperatureBoard=temperatureBoard, temperatureDie=temperatureDie, temperatureCase=temperatureCase, heatBoard=heatBoard,heatDie=heatDie, heatCase=heatCase, pins=[])
358 lumpNrToTH[lumpNr] = temperatureResult
359 else:
360 temperatureResult = Bunch(temperature=temperature, heatBoard=heatBoard,heatDie=heatDie, heatCase=heatCase, pins=[])
361 lumpNrToTH[lumpNr] = temperatureResult
362
363 import empro.enparams
364 thermalZ = None
365 if os.path.exists(os.path.join(simLocation, "design.out.thermal.cti")):
366 thermalCtiEvaluator = empro.enparams.CitiEvaluator(os.path.join(simLocation, "design.out.thermal.cti"), False)
367 thermalZ = thermalCtiEvaluator.Zmatrix(0)
368
369 thermalPinMap = {}
370 for thermalPin in self.thermalPins:
371 thermalPinMap[thermalPin.name] = thermalPin
372
373 self.thermalComponents = []
374 for sourceNr, sourceDescr in thermalComponents.iteritems():
375 if sourceNr not in lumpNrToTH:
376 continue
377 source = sourceDescr
378 source.merge(lumpNrToTH[sourceNr])
379 if thermalZ:
380 source.bareBoardThermalResistance = abs(thermalZ(sourceNr-1,sourceNr-1))
381 else:
382 source.bareBoardThermalResistance = '---'
383 source.heatToBoard = 0.0
384 for pin in source.pins:
385 if pin.netType!="Virtual":
386 source.heatToBoard -= pin.heat
387 self.thermalComponents.append(source)
388
389 def _vrmSenseportVoltageDict():
390 vrmSenseportVoltageDict = {}
391 vrmList = self.sipiData.getVrmList()
392 for vrm in vrmList:
393 if vrm.hasSenseLine:
394 senseName = "sense_"+vrm.name
395 try:
396 lumpNr = electricNameTolumpNr[senseName]
397 v,i,pins = lumpNrToVI[lumpNr]
398 except KeyError:
399 v = None
400 i = None
401 pins = []
402 sensePort = vrm.sensePort
403 plusPinNames = [x.name for x in sensePort.plusPins()]
404 plusPinVoltages = [x.voltage for x in pins if x.name in plusPinNames]
405 if plusPinVoltages:
406 minPlusPinVoltage = min(plusPinVoltages)
407 else:
408 minPlusPinVoltage = 0.0
409 vrmSenseportVoltageDict[vrm.name]=[float(vrm.senseVoltage),v,i,minPlusPinVoltage]
410 return vrmSenseportVoltageDict
411
412 def _vrmSwitchPortDict():
413 vrmSwitchPortDict = {}
414 vrmList = self.sipiData.getVrmList()
415 for vrm in vrmList:
416 if vrm.sourceType != 'PackagedVrm':
417 upSwitchName = "upSwitch_"+vrm.name
418 try:
419 lumpNr = electricNameTolumpNr[upSwitchName]
420 v_upSwitch,i_upSwitch,pins_upSwitch = lumpNrToVI[lumpNr]
421 except KeyError:
422 v_upSwitch = None
423 i_upSwitch = None
424 pins_upSwitch = []
425 upSwitch = vrm.upSwitch
426 lowSwitchName = "lowSwitch_"+vrm.name
427 try:
428 lumpNr = electricNameTolumpNr[lowSwitchName]
429 v_lowSwitch,i_lowSwitch,pins_lowSwitch = lumpNrToVI[lumpNr]
430 except KeyError:
431 v_lowSwitch = None
432 i_lowSwitch = None
433 pins_lowSwitch = []
434 lowSwitch = vrm.lowSwitch
435 inductorName = "inductor_" + vrm.name
436 try:
437 lumpNr = electricNameTolumpNr[inductorName]
438 v_inductor,i_inductor,pins_inductor = lumpNrToVI[lumpNr]
439 except KeyError:
440 v_inductor = None
441 i_inductor = None
442 pins_inductor = []
443 inductor = vrm.inductor
444
445 upPlusPinNames = set(y.name for y in upSwitch.plusPins())
446 upMinusPinNames = set(y.name for y in upSwitch.minusPins())
447 try:
448 upSwitchPlusPinVoltage = min(x.voltage for x in pins_upSwitch if x.name in upPlusPinNames)
449 upSwitchMinusPinVoltage = max(x.voltage for x in pins_upSwitch if x.name in upMinusPinNames)
450 except ValueError:
451 upSwitchPlusPinVoltage = 0.0
452 upSwitchMinusPinVoltage = 0.0
453 upSwitchBunch = Bunch(plusVoltage=upSwitchPlusPinVoltage, minusVoltage=upSwitchMinusPinVoltage,current=i_upSwitch)
454
455 lowPlusPinNames = set(y.name for y in lowSwitch.plusPins())
456 lowMinusPinNames = set(y.name for y in lowSwitch.minusPins())
457 try:
458 lowSwitchPlusPinVoltage = min(x.voltage for x in pins_lowSwitch if x.name in lowPlusPinNames)
459 lowSwitchMinusPinVoltage = max(x.voltage for x in pins_lowSwitch if x.name in lowMinusPinNames)
460 except ValueError:
461 lowSwitchPlusPinVoltage = 0.0
462 lowSwitchMinusPinVoltage = 0.0
463 lowSwitchBunch = Bunch(plusVoltage=lowSwitchPlusPinVoltage, minusVoltage=lowSwitchMinusPinVoltage,current=i_lowSwitch)
464
465 inductorPlusPinNames = set(y.name for y in inductor.plusPins())
466 inductorMinusPinNames = set(y.name for y in inductor.minusPins())
467 try:
468 inductorPlusPinVoltage = min(x.voltage for x in pins_inductor if x.name in inductorPlusPinNames)
469 inductorMinusPinVoltage = max(x.voltage for x in pins_inductor if x.name in inductorMinusPinNames)
470 except ValueError:
471 inductorPlusPinVoltage = 0.0
472 inductorMinusPinVoltage = 0.0
473 inductorBunch = Bunch(plusVoltage=inductorPlusPinVoltage, minusVoltage=inductorMinusPinVoltage,current=i_inductor)
474
475 switchOutputVoltage = inductorPlusPinVoltage
476 switchOutputCurrent = i_inductor
477 switchInputVoltage = upSwitchMinusPinVoltage
478 switchInputCurrent = i_upSwitch
479 if vrm.sourceType != 'DiscreteBuck':
480 switchOutputVoltage = lowSwitchPlusPinVoltage
481 switchOutputCurrent = i_lowSwitch
482 if vrm.sourceType =='DiscreteBoost':
483 switchInputVoltage = inductorMinusPinVoltage
484 switchInputCurrent = i_inductor
485 vrmSwitchPortDict[vrm.name]=[float(vrm.inputVoltage),vrm.sourceType,upSwitchBunch,lowSwitchBunch,inductorBunch,switchOutputVoltage,switchOutputCurrent,switchInputVoltage,switchInputCurrent]
486
487 return vrmSwitchPortDict
488
489 vrmVoltage = 0.0
490 self.failedVrms = []
491 vrm = None
492 vrmSenseportVoltageDict = _vrmSenseportVoltageDict()
493 vrmSwitchDict = _vrmSwitchPortDict()
494 for vrmNr, vrm in vrms.iteritems():
495 v,i,pins = lumpNrToVI.get(vrmNr,[0.0,0.0,[]])
496 for pin in pins:
497 temperature = thermalPinMap.get(pin.name,Bunch(temperature=298.15)).temperature
498 pin.temperature = temperature
499 vrm[2] = v
500 vrm[3] = i
501 vrmVoltage = vrm[1]
502
503 try:
504 senseVoltage, senseportVoltage, senseportCurrent, minSensePlusPinVoltage = vrmSenseportVoltageDict[vrm[0]]
505 except KeyError:
506 senseVoltage = None
507 senseportVoltage = None
508 senseportCurrent = None
509 minSensePlusPinVoltage = None
510 vrm.append(senseVoltage)
511 vrm.append(senseportVoltage)
512 vrm.append(senseportCurrent)
513 vrm.append(minSensePlusPinVoltage)
514
515 try:
516 inputVoltage, sourceType, upSwitchBunch,lowSwitchBunch,inductorBunch,switchOutputVoltage,switchOutputCurrent,switchInputVoltage,switchInputCurrent = vrmSwitchDict[vrm[0]]
517 except KeyError:
518 inputVoltage = None
519 sourceType = 'PackagedVrm'
520 upSwitchBunch = None
521 lowSwitchBunch = None
522 inductorBunch = None
523 switchOutputVoltage = None
524 switchOutputCurrent = None
525 switchInputVoltage = None
526 switchInputCurrent = None
527 vrm.append(inputVoltage)
528 vrm.append(sourceType)
529 vrm.append(upSwitchBunch)
530 vrm.append(lowSwitchBunch)
531 vrm.append(inductorBunch)
532 vrm.append(switchOutputVoltage)
533 vrm.append(switchOutputCurrent)
534 vrm.append(switchInputVoltage)
535 vrm.append(switchInputCurrent)
536 vrm.append(pins)
537
538 margin = self._calculateMargin(vrmVoltage, switchOutputVoltage if switchOutputVoltage else v, cmptNameToTolerance[vrm[0]])
539 vrm[5] = margin
540 if margin<0.0:
541 vrm[6] = "fail"
542 else:
543 vrm[6] = "pass"
544 if vrm[6] == "fail":
545 self.failedVrms.append(vrm[0])
546
547
548 def _vrmsConnectedToSinks():
549 setup = self.sipiData
550 layout = empro.activeProject.geometry()[0]
551 layoutObj = empro.activeProject.layout
552 allowedNets = [x.name for x in setup.getNetList() if x.type in [1,2,4]]
553 foundConnections = {}
554 vrms = {}
555 compInsts = []
556 for vrm in setup.getVrmList():
557 instList = []
558 for pin in vrm.plusPins():
559 instList.append((pin.getInstanceName(),pin.getPinName()))
560 break
561 instList = set(instList)
562 vrms[vrm.name] = instList
563 if vrm.sourceType == 'DiscreteBuck':
564 for pin in vrm.inductor.plusPins():
565 compInsts.append(pin.getInstanceName())
566 break
567 elif vrm.sourceType != 'PackagedVrm':
568 for pin in vrm.lowSwitch.plusPins():
569 compInsts.append(pin.getInstanceName())
570 break
571 sinks = {}
572 for sink in setup.getSinkList():
573 instList = []
574 for pin in sink.plusPins():
575 instList.append((pin.getInstanceName(),pin.getPinName()))
576 break
577 instList = set(instList)
578 sinks[sink.name] = instList
579
580 for compGroup in setup.getComponentModelGroupList():
581 for inst in compGroup.instances():
582 compInsts.append(inst.name)
583 limitInstances = True
584 for sinkName, sinkInstances in sinks.iteritems():
585 sinkInstance, firstPinName = list(sinkInstances)[0]
586 for vrmName, vrmInstances in vrms.iteritems():
587 connections = layout._connectionsFromInstance((sinkInstance,firstPinName),list(vrmInstances),[1,2,4],allowedNets, limitInstances, compInsts, 0, lambda x:None)
588 if connections:
589 if sinkName in foundConnections:
590 vrmsFound = foundConnections[sinkName]
591 vrmsFound.append(vrmName)
592 foundConnections[sinkName] = vrmsFound
593 else:
594 foundConnections[sinkName] = [vrmName]
595 return foundConnections
596 vrmsConnectedToSink = _vrmsConnectedToSinks()
597
598 vrmMap = dict( (vrm[0], vrm) for index, vrm in vrms.iteritems())
599 vrmVoltageOfSink = {}
600 for sinkNr, sink in sinks.iteritems():
601 allVrmVoltages = [vrmMap.get(vrmName,[None,None,0.0])[1] for vrmName in vrmsConnectedToSink.get(sink[0],[])]
602 if allVrmVoltages:
603 vrmVoltageOfSink[sinkNr] = max(allVrmVoltages)
604 else:
605 vrmVoltageOfSink[sinkNr] = 0.0
606 if sinksPlusNets[sinkNr]:
607
608 sinkPlusNets = sinksPlusNets[sinkNr]
609 for vrmNr, vrmNets in vrmsPlusNets.iteritems():
610 for plusNet in sinkPlusNets:
611 if plusNet in vrmNets:
612 vrmVoltageOfSink[sinkNr] = vrms[vrmNr][1]
613
614 vrmOutputVoltageOfSink = {}
615 for sinkNr, sink in sinks.iteritems():
616 allVrmVoltages = [vrmMap.get(vrmName,[None,None,0.0])[2] for vrmName in vrmsConnectedToSink.get(sink[0],[])]
617 if allVrmVoltages:
618 vrmOutputVoltageOfSink[sinkNr] = max(allVrmVoltages)
619 else:
620 vrmOutputVoltageOfSink[sinkNr] = 0.0
621 if sinksPlusNets[sinkNr]:
622
623 sinkPlusNets = sinksPlusNets[sinkNr]
624 for vrmNr, vrmNets in vrmsPlusNets.iteritems():
625 for plusNet in sinkPlusNets:
626 if plusNet in vrmNets:
627 vrmOutputVoltageOfSink[sinkNr] = vrms[vrmNr][2]
628
629 self.failedSinks = []
630 for sinkNr, sink in sinks.iteritems():
631 v,i,pins = lumpNrToVI.get(sinkNr,[0.0,0.0,[]])
632 for pin in pins:
633 temperature = thermalPinMap.get(pin.name,Bunch(temperature=298.15)).temperature
634 pin.temperature = temperature
635 tolerance = float(sink[4])
636 vrmVoltage = vrmVoltageOfSink[sinkNr]
637
638 sink[2] = vrmVoltage
639 sink[3] = v
640 sink[5] = None
641 sink[6] = None
642 sink.append(pins)
643
644
645 vrmsList =[]
646 sinksList=[]
647 pinsList=[]
648
649 for vrmNr, vrm in vrms.iteritems():
650 vrm[4] = self._toleranceToString(cmptNameToTolerance[vrm[0]])
651 vVrm = vrm[:-1]
652 vrmTemperature, tempB, tempD, tempC = [298.15,298.15,298.15,298.15]
653 if thermalZ:
654 vVrm.insert(4, abs(thermalZ(vrmNr,vrmNr)))
655 else:
656 vVrm.insert(4, 0.0)
657 vVrm.insert(5, 0.0)
658 vVrm.insert(6, vrmTemperature)
659 vVrm.insert(7, tempD)
660 vVrm.insert(8, tempB)
661 vVrm.insert(9, tempC)
662 vVrm.append(vrm[-1])
663
664
665
666 plusSenseNetName = self._vrmNameToPlusSenseNet(vVrm[0])
667 vrmObj = Bunch(name=vVrm[0],
668 sourceVoltage=vVrm[1],
669 outputVoltage=vVrm[2],
670 outputCurrent=vVrm[3],
671 thermalResistanceBareBoard=vVrm[4],
672 thermalResistance=vVrm[5],
673 temperature=vVrm[6],
674 temperatureDie=vVrm[7],
675 temperatureBoard=vVrm[8],
676 temperatureCase=vVrm[9],
677 tolerance=vVrm[10],
678 margin=vVrm[11],
679 result=vVrm[12],
680 plusPins = vVrm[13],
681 minusPins = vVrm[14],
682 senseVoltage = vVrm[15],
683 senseportVoltage = vVrm[16],
684 senseportCurrent = vVrm[17],
685 minSensePlusPinVoltage = vVrm[18],
686 senseNetName = plusSenseNetName,
687 inputVoltage = vVrm[19],
688 sourceType = vVrm[20],
689 upSwitchBunch = vVrm[21],
690 lowSwitchBunch = vVrm[22],
691 inductorBunch = vVrm[23],
692 switchOutputVoltage = vVrm[24],
693 switchOutputCurrent = vVrm[25],
694 switchInputVoltage = vVrm[26],
695 switchInputCurrent = vVrm[27],
696 pins=vVrm[-1])
697 vrmsList.append(vrmObj)
698
699 electricCtiFile = os.path.join(simLocation, "design.out.electric.cti")
700 electricCtiBckFile = os.path.join(simLocation, "design.out.cti")
701
702 ctiEvaluator = None
703 if os.path.exists(electricCtiFile):
704 ctiEvaluator = empro.enparams.CitiEvaluator(electricCtiFile, False)
705 elif os.path.exists(electricCtiBckFile):
706 ctiEvaluator = empro.enparams.CitiEvaluator(electricCtiBckFile, False)
707 electricCtiFile = electricCtiBckFile
708
709 if ctiEvaluator:
710 Z = ctiEvaluator.Zmatrix(0)
711 if diagonalLoadsOnly:
712 if Z.size() != len(sinks) + len(loadsSeenFromSinks):
713 raise Exception("invalid #ports in cti-file <%s>: expected %d, found %d" % (electricCtiFile, len(sinks) + len(loadsSeenFromSinks), Z.size()))
714 else:
715 loadIds, matrixLoad = buildMatrixLoad(matrixLoadsSeenFromSinks)
716 if Z.size() != len(sinks) + len(loadIds):
717 raise Exception("invalid #ports in cti-file <%s>: expected %d, found %d" % (electricCtiFile, len(sinks) + len(loadIds), Z.size()))
718
719
720 import os
721 useOldRsink = os.environ.has_key("SIPI_DC_USE_OLD_R_SINK")
722 if useOldRsink:
723 print "Using old formula for calculation of R seen from sinks"
724
725 self.failedSinks = []
726 for sinkKey, sink in sinks.iteritems():
727 if useOldRsink:
728 R = float((sink[2]-sink[3])/sink[1])
729 else:
730 if diagonalLoadsOnly:
731 R = Z.param_loaded(sinkKey-1,sinkKey-1,loadsSeenFromSinks).real
732 else:
733 R = Z.param_schur(sinkKey-1, sinkKey-1, loadIds, matrixLoad).real
734 sink.insert(4,round(R,4))
735 if thermalZ:
736 sink.insert(5, abs(thermalZ(sinkKey-1, sinkKey-1)))
737 else:
738 sink.insert(5, 0.0)
739 sink.insert(6, 0.0)
740 sink[7] = self._toleranceToString(cmptNameToTolerance[sink[0]])
741 sSink = sink[:]
742 sinkTemperature, tempB, tempD, tempC = [298.15,298.15,298.15,298.15]
743 sSink.insert(7, sinkTemperature)
744 sSink.insert(8, tempD)
745 sSink.insert(9, tempB)
746 sSink.insert(10, tempC)
747
748
749 sinkObj = Bunch(name=sSink[0],
750 sourceCurrent=sSink[1],
751 vrmVoltage=sSink[2],
752 inputVoltage=sSink[3],
753 resistance=sSink[4],
754 thermalResistanceBareBoard=sSink[5],
755 thermalResistance=sSink[6],
756 temperature=sSink[7],
757 temperatureDie=sSink[8],
758 temperatureBoard=sSink[9],
759 temperatureCase=sSink[10],
760 tolerance=sSink[11],
761 margin=sSink[12],
762 result=sSink[13],
763 plusPins=sSink[14],
764 minusPins=sSink[15],
765 instNameCandidate=sSink[16],
766 vrmOutputVoltage = vrmOutputVoltageOfSink[sinkKey],
767 pins=sSink[-1])
768
769
770 plusPinNames = set(sinkObj.plusPins)
771 minusPinNames = set(sinkObj.minusPins)
772 minPinVoltages = [x.voltage for x in sinkObj.pins if x.name in minusPinNames]
773 plusPinVoltages = [x.voltage for x in sinkObj.pins if x.name in plusPinNames]
774 if minPinVoltages and plusPinVoltages:
775 sinkObj.inputVoltage = min(plusPinVoltages)-max(minPinVoltages)
776
777 sinkObj.margin = self._calculateMargin(sinkObj.vrmVoltage, sinkObj.inputVoltage, cmptNameToTolerance[sinkObj.name])
778 sinkPass = self._calculateSinkPass(sinkObj.vrmVoltage, sinkObj.inputVoltage, cmptNameToTolerance[sinkObj.name])
779 sinkObj.result = { False : 'fail', True : 'pass'}[sinkPass]
780 if not sinkPass:
781 self.failedSinks.append(sinkObj.name)
782
783 sinksList.append(sinkObj)
784
785 self.vrms = vrmsList
786 self.sinks = sinksList
787 self.pins = sorted(self.pins, key=lambda x:x[0])
788 for pin in self.pins:
789 Pins= collections.namedtuple('Pin',['name', 'netName','netType','voltage', 'current','temperature'])
790 pPin = pin[:]
791 pPin.append( thermalPinMap.get(pPin[0], Bunch(temperature=298.15)).temperature )
792 pins = Pins(*pPin)
793 pinsList.append(pins)
794 self.pins = pinsList
795 else:
796 self.vrms = []
797 self.sinks = []
798 self.pins = []
799
800 pinMap = {}
801 for pin in self.pins:
802 pinMap[pin.name] = pin
803
804 self.components = []
805 for componentNr, component in components.iteritems():
806 comp = component
807 v,i,pins = lumpNrToVI.get(componentNr,[0.0,0.0,[]])
808 comp.voltage = v
809 comp.current = i
810 comp.pins = [x for x in [pinMap.get(name,None) for name in comp.minusPinNames] if x!=None]
811 comp.pins += [x for x in [pinMap.get(name,None) for name in comp.plusPinNames] if x!=None]
812 self.components.append(comp)
813
814 for vrm in self.vrms:
815 plusPinNames = set(vrm.plusPins)
816 plusPinVoltages = [x.voltage for x in vrm.pins if x.name in plusPinNames]
817 if plusPinVoltages:
818 plusPinVoltage = min(plusPinVoltages)
819 else:
820 plusPinVoltage = 0.0
821
822 vrm.minVoltagePowerPins = plusPinVoltage
823
824 for sink in self.sinks:
825 plusPinNames = set(sink.plusPins)
826 minusPinNames = set(sink.minusPins)
827
828
829 plusPinVoltages = [x.voltage for x in sink.pins if x.name in plusPinNames]
830 if plusPinVoltages:
831 plusPinVoltage = min(plusPinVoltages)
832 else:
833 plusPinVoltage = 0.0
834 minPinVoltages = [x.voltage for x in sink.pins if x.name in minusPinNames]
835 if minPinVoltages:
836 minPinVoltage = max(minPinVoltages)
837 else:
838 minPinVoltage = 0.0
839
840 sink.minVoltagePowerPins = plusPinVoltage
841 sink.maxVoltageGroundPins = minPinVoltage
842
843 self.layerStatistics = {}
844 self._extractLayerData(sipiData)
845
846
847
848 try:
849 self.viaCurrents = sipiData.vias()
850 except:
851 self.viaCurrents = {}
852 try:
853 self.viaMaxTemperatures = sipiData.viasMaxTemperature()
854 except:
855 self.viaMaxTemperatures = {}
856 try:
857 self.viaRadiusThickness = sipiData._viasRadiiThickness()
858 except:
859 self.viaRadiusThickness = {}
860
861 @_printexception
863 import os
864 import collections
865 import empro
866 simLocation = sipiData.simulationPath
867 if not simLocation:
868 raise Exception("Simulation Results Not Found")
869 layerStatistics = sipiData._perLayerStatistics()
870 import empro.toolkit.analysis as sipi
871 layerMapping = sipi._filterData(sipiData)
872 self.layerStatistics = {}
873 for index, name in layerMapping.iteritems():
874 if index in layerStatistics:
875 self.layerStatistics[name] = layerStatistics[index]
876 newDict = {}
877 for k,v in self.layerStatistics[name].iteritems():
878 newDict[k] = v
879 newDict['layerId'] = index
880 self.layerStatistics[name] = newDict
881
883 toleranceVoltage = None
884 if tolerance.unitClass()=="ELECTRIC_POTENTIAL":
885
886 toleranceVoltage = float(tolerance)
887 elif tolerance.unitClass()=="SCALAR":
888
889 toleranceVoltage = float(tolerance)*vrmVoltage
890 deltaVoltage = vrmVoltage-inputVoltage
891 return abs(toleranceVoltage)-deltaVoltage
892
894 toleranceVoltage = None
895 if tolerance.unitClass()=="ELECTRIC_POTENTIAL":
896
897 toleranceVoltage = float(tolerance)
898 elif tolerance.unitClass()=="SCALAR":
899
900 toleranceVoltage = float(tolerance)*vrmVoltage
901 deltaVoltage = inputVoltage-vrmVoltage
902 return abs(deltaVoltage) < abs(toleranceVoltage)
903
905 result = None
906 if value.is_integer():
907 result = "%d %s" % (value, unit)
908 else:
909 if value < 1e-6:
910 result = "%s %s" % (value, unit)
911 else:
912 result = "%.6f %s" % (value, unit)
913 return result
914
926
928 plusSenseNetName = None
929 vrmList = self.sipiData.getVrmList()
930 for vrm in vrmList:
931 if vrm.name == name and vrm.hasSenseLine:
932 sensePort = vrm.sensePort
933 for plusPin in sensePort.plusPins():
934 plusSenseNetName = plusPin.getNetName()
935 break
936 break
937 return plusSenseNetName
938
940 @_printexception
942 def diff(a,b):
943 if a==b:
944 if a=="---":
945 return a
946 return 0.0
947 try:
948 return a-b
949 except:
950 return "???"
951
952 def diffPins(a,b):
953 difference = []
954 pinsA = {}
955 pinsB = {}
956 for pin in a:
957 pinsA[pin.name] = pin
958 for pin in b:
959 pinsB[pin.name] = pin
960 for name, pinA in pinsA.iteritems():
961 if name in pinsB:
962 pinB = pinsB[name]
963 pin = Bunch(name=name,netType=pinA.netType,netName=pinA.netName,voltage=pinA.voltage-pinB.voltage,current=pinA.current-pinB.current,temperature=pinA.temperature-pinB.temperature)
964 difference.append(pin)
965 return difference
966
967 self.resultNames = [result1.sipiData.name, result2.sipiData.name]
968 self.sipiDatas = [result1.sipiData, result2.sipiData]
969 self.resultAnalysisType = result1.sipiData.analysisType
970
971 sinks1 = sorted(result1.sinks,key=lambda x:x.name)
972 sinks2 = sorted(result2.sinks,key=lambda x:x.name)
973 self.sinks = []
974 if [x.name for x in sinks1]==[x.name for x in sinks2]:
975 for sink1,sink2 in zip(sinks1,sinks2):
976 self.sinks.append(Bunch(name=sink1.name,
977 sourceCurrent=sink1.sourceCurrent-sink2.sourceCurrent,
978 vrmVoltage=sink1.vrmVoltage-sink2.vrmVoltage,
979 vrmOutputVoltage=sink1.vrmOutputVoltage-sink2.vrmOutputVoltage,
980 inputVoltage=sink1.inputVoltage-sink2.inputVoltage,
981 resistance=sink1.resistance-sink2.resistance,
982 tolerance=diff(sink1.tolerance,sink2.tolerance),
983 margin=sink1.margin-sink2.margin,
984 minVoltagePowerPins = sink1.minVoltagePowerPins-sink2.minVoltagePowerPins,
985 maxVoltageGroundPins = sink1.maxVoltageGroundPins-sink2.maxVoltageGroundPins,
986 pins=diffPins(sink1.pins,sink2.pins)))
987
988 vrms1 = sorted(result1.vrms,key=lambda x:x.name)
989 vrms2 = sorted(result2.vrms,key=lambda x:x.name)
990 self.vrms = []
991 if [x.name for x in vrms1]==[x.name for x in vrms2]:
992 for vrm1,vrm2 in zip(vrms1,vrms2):
993 vrmObj = Bunch(name=vrm1.name,
994 sourceVoltage=vrm1.sourceVoltage-vrm2.sourceVoltage,
995 outputVoltage=vrm1.outputVoltage-vrm2.outputVoltage,
996 outputCurrent=vrm1.outputCurrent-vrm2.outputCurrent,
997 tolerance=diff(vrm1.tolerance,vrm2.tolerance),
998 margin=vrm1.margin-vrm2.margin,
999 minVoltagePowerPins = vrm1.minVoltagePowerPins-vrm2.minVoltagePowerPins,
1000 pins=diffPins(vrm1.pins,vrm2.pins))
1001 if vrm1.senseVoltage and vrm2.senseVoltage:
1002 vrmObj.senseVoltage = vrm1.senseVoltage - vrm2.senseVoltage
1003 vrmObj.senseportVoltage = vrm1.senseportVoltage - vrm2.senseportVoltage
1004 vrmObj.senseportCurrent = vrm1.senseportCurrent - vrm2.senseportCurrent
1005 vrmObj.minSensePlusPinVoltage = vrm1.minSensePlusPinVoltage - vrm2.minSensePlusPinVoltage
1006 vrmObj.senseNetName = vrm1.senseNetName if vrm1.senseNetName==vrm2.senseNetName else ""
1007 else:
1008 vrmObj.senseVoltage = None
1009 vrmObj.senseportVoltage = None
1010 vrmObj.senseportCurrent = None
1011 vrmObj.minSensePlusPinVoltage = None
1012 vrmObj.senseNetName = None
1013 if vrm1.sourceType !='PackagedVrm' and (vrm1.sourceType==vrm2.sourceType):
1014 vrmObj.inputVoltage = vrm1.inputVoltage - vrm2.inputVoltage
1015 vrmObj.sourceType = vrm1.sourceType
1016 vrmObj.upSwitchBunch = Bunch(plusVoltage=vrm1.upSwitchBunch.plusVoltage-vrm2.upSwitchBunch.plusVoltage, minusVoltage=vrm1.upSwitchBunch.minusVoltage-vrm2.upSwitchBunch.minusVoltage,current=vrm1.upSwitchBunch.current-vrm2.upSwitchBunch.current)
1017 vrmObj.lowSwitchBunch = Bunch(plusVoltage=vrm1.lowSwitchBunch.plusVoltage-vrm2.lowSwitchBunch.plusVoltage, minusVoltage=vrm1.lowSwitchBunch.minusVoltage-vrm2.lowSwitchBunch.minusVoltage,current=vrm1.lowSwitchBunch.current-vrm2.lowSwitchBunch.current)
1018 vrmObj.inductorBunch = Bunch(plusVoltage=vrm1.inductorBunch.plusVoltage-vrm2.inductorBunch.plusVoltage, minusVoltage=vrm1.inductorBunch.minusVoltage-vrm2.inductorBunch.minusVoltage,current=vrm1.inductorBunch.current-vrm2.inductorBunch.current)
1019 vrmObj.switchOutputVoltage = vrm1.switchOutputVoltage - vrm2.switchOutputVoltage
1020 vrmObj.switchOutputCurrent = vrm1.switchOutputCurrent - vrm2.switchOutputCurrent
1021 vrmObj.switchInputVoltage = vrm1.switchInputVoltage - vrm2.switchInputVoltage
1022 vrmObj.switchInputCurrent = vrm1.switchInputCurrent - vrm2.switchInputCurrent
1023 else:
1024 vrmObj.inputVoltage = None
1025 vrmObj.sourceType = 'PackagedVrm'
1026 vrmObj.upSwitchBunch = None
1027 vrmObj.lowSwitchBunch = None
1028 vrmObj.inductorBunch = None
1029 vrmObj.switchOutputVoltage = None
1030 vrmObj.switchOutputCurrent = None
1031 vrmObj.switchInputVoltage = None
1032 vrmObj.switchInputCurrent = None
1033 self.vrms.append(vrmObj)
1034
1035 comps1 = sorted(result1.components,key=lambda x:x.name)
1036 comps2 = sorted(result2.components,key=lambda x:x.name)
1037 self.components = []
1038 if [x.name for x in comps1]==[x.name for x in comps2]:
1039 for comp1,comp2 in zip(comps1,comps2):
1040 self.components.append(Bunch(name=comp1.name,
1041 voltage=comp1.voltage-comp2.voltage,
1042 current=comp1.current-comp2.current,
1043 pins=diffPins(comp1.pins,comp2.pins)))
1044
1045 pins1 = sorted(result1.pins,key=lambda x:x[0])
1046 pins2 = sorted(result2.pins,key=lambda x:x[0])
1047 self.pins = []
1048 if [x[0] for x in pins1]==[x[0] for x in pins2]:
1049 for pin1,pin2 in zip(pins1,pins2):
1050 self.pins.append(Bunch(name=pin1[0],netType=pin1.netType,netName=pin1.netName,voltage=pin1[3]-pin2[3],current=pin1[4]-pin2[4],temperature=pin1[5]-pin2[5],))
1051
1052 thermalComponents1 = sorted(result1.thermalComponents,key=lambda x:x.name)
1053 thermalComponents2 = sorted(result2.thermalComponents,key=lambda x:x.name)
1054 self.thermalComponents = []
1055 if len(thermalComponents1)==len(thermalComponents2):
1056 for comp1,comp2 in zip(thermalComponents1,thermalComponents2):
1057 if hasattr(comp1, "temperatureBoard"):
1058 self.thermalComponents.append(Bunch(name=comp1.name,
1059 heatSource = comp1.heatSource-comp2.heatSource,
1060 heatToBoard = comp1.heatToBoard-comp2.heatToBoard,
1061 temperatureBoard=comp1.temperatureBoard-comp2.temperatureBoard,
1062 temperatureDie=comp1.temperatureDie-comp2.temperatureDie,
1063 temperatureCase=comp1.temperatureCase-comp2.temperatureCase,
1064 heatBoard=comp1.heatBoard-comp2.heatBoard,
1065 heatDie=comp1.heatDie-comp2.heatDie,
1066 heatCase=comp1.heatCase-comp2.heatCase,
1067 bareBoardThermalResistance=diff(comp1.bareBoardThermalResistance,comp2.bareBoardThermalResistance),
1068 ))
1069 else:
1070 self.thermalComponents.append(Bunch(name=comp1.name,
1071 heatSource = comp1.heatSource-comp2.heatSource,
1072 heatToBoard = comp1.heatToBoard-comp2.heatToBoard,
1073 temperature=comp1.temperature-comp2.temperature,
1074 heatBoard=comp1.heatBoard-comp2.heatBoard,
1075 heatDie=comp1.heatDie-comp2.heatDie,
1076 heatCase=comp1.heatCase-comp2.heatCase,
1077 bareBoardThermalResistance=diff(comp1.bareBoardThermalResistance,comp2.bareBoardThermalResistance),
1078 ))
1079
1080
1081 layers1 = result1.layerStatistics
1082 layers2 = result2.layerStatistics
1083 self.layerStatistics = {}
1084 for layerName,layer1 in layers1.iteritems():
1085 if layerName not in layers2:
1086 continue
1087 layer2 = layers2[layerName]
1088 newDict = {}
1089 for k,v in layer1.iteritems():
1090 if k not in ["zMax","zMin","layerId"]:
1091 newDict[k] = v-layer2[k]
1092 else:
1093 newDict[k] = v
1094 newDict['layerId'] = layer1['layerId']
1095 self.layerStatistics[layerName] = newDict
1096
1097 viaCurrs1 = result1.viaCurrents
1098 viaCurrs2 = result2.viaCurrents
1099 self.viaCurrents = {}
1100 if len(list(viaCurrs1.keys()))==len(list(viaCurrs2.keys())):
1101 for id, via1 in viaCurrs1.iteritems():
1102 via2 = viaCurrs2[id]
1103 viaDiff = (via1[0]-via2[0], via1[1])
1104 self.viaCurrents[id] = viaDiff
1105
1106 viaMaxTemps1 = result1.viaMaxTemperatures
1107 viaMaxTemps2 = result2.viaMaxTemperatures
1108 self.viaMaxTemperatures = {}
1109 for id, via1 in viaMaxTemps1.iteritems():
1110 via2 = viaMaxTemps2[id]
1111 self.viaMaxTemperatures[id] = via1-via2
1112
1113 viaRadiiThick1 = result1.viaRadiusThickness
1114 viaRadiiThick2 = result2.viaRadiusThickness
1115 self.viaRadiusThickness = {}
1116 for id, via1 in viaRadiiThick1.iteritems():
1117 via2 = viaRadiiThick2[id]
1118 self.viaRadiusThickness[id] = (via1[0]-via2[0],via1[1]-via2[1])
1119
1120
1121
1122 if False:
1123 try:
1124 del empro.internal.__tempResults
1125 pass
1126 except:
1127 pass
1128 if True or not hasattr(empro.internal,'__tempResults'):
1129
1130
1131
1132 results = DCResults(empro.activeProject.analyses[-1])
1133 empro.internal.__tempResults = results
1134 results = empro.internal.__tempResults
1135 """
1136 for vrm in results.vrms:
1137 print vrm
1138 print
1139 """
1140 for sink in results.sinks:
1141 print sink.name, sink.vrmVoltage, sink.margin
1142 print
1143 """
1144 for comp in results.thermalComponents:
1145 print comp
1146 print
1147 for comp in results.components:
1148 print comp
1149 print
1150 """
1151 """
1152 for via in results.viaMaxTemperatures.iteritems():
1153 print via
1154 """
1155