1
2 import empro
3 from empro.toolkit import _printexception
4 from empro.toolkit import long_path_util
38
42
43 import datetime
44 import os
45 import empro.toolkit.analysis as sipi
46 pinHash = sipi._createPinHash()
47 instanceHash = sipi._createInstanceHash()
48 pinNetNames = sipi._createPinHashNetName()
49
50 simData = sipiData.newSimulationData()
51 generateThermalPorts = simData.sParametersEnabled
52
53 backGroundTemperature = float(simData.ambientConditions.backgroundTemperature)
54 zLowerEffHeatTransfer = max(1e-4,simData.ambientConditions._zLowerEvaluatedEffectiveHeatTransfer())
55 zUpperEffHeatTransfer = max(1e-4,simData.ambientConditions._zUpperEvaluatedEffectiveHeatTransfer())
56
57 stimulusLines = []
58 portNr = 0
59 thermalComponentGroupList = sipiData.getThermalComponentGroupList()
60 for group in thermalComponentGroupList:
61 for source in group:
62 portNr += 1
63 name = source.name
64 instance = source.instance()
65 instHash = instanceHash[instance.name]
66 thermalSource = float(source.heatSource)
67 pinNames = [instance.name + "." + pin.name for pin in instance.pins()]
68 stimulusLines.append("Thermal %(portNr)d:" % vars())
69 stimulusLines.append(" name: %(name)s" % vars())
70 if generateThermalPorts:
71 stimulusLines.append(" port: %(portNr)d" % vars())
72
73 generateR = isinstance(group.thermalResistance, empro.components.Package3RSpecification)
74 if generateR:
75 pinR = float(group.thermalResistance.pinResistance)
76 for pinName in pinNames:
77 pinNr = str(pinHash[pinName])
78 if generateR:
79 stimulusLines.append(" pluspin: %(pinNr)s R=%(pinR)f name=%(pinName)s" % vars())
80 else:
81 stimulusLines.append(" pluspin: %(pinNr)s name=%(pinName)s" % vars())
82
83 if isinstance(group.thermalResistance, empro.components.Package3RSpecification):
84 if group.thermalResistance.useCaseToBoardResistance:
85 padR = float(group.thermalResistance.caseToBoardResistance)
86 pinNr = str(instHash)
87 pinName = name + "..BOARD"
88 stimulusLines.append(" pluspin: %(pinNr)s R=%(padR)f name=%(pinName)s" % vars())
89
90 stimulusLines.append(" minpin: 0")
91
92 thermalSource = float(source.heatSource)
93 if source.sourceType in ["Disabled", "ElectricDissipation", "ElectricDissipationAndHeatSource","HeatSource"]:
94 if source.sourceType in ["Disabled", "ElectricDissipation"]:
95 thermalSource = 0.0
96 stimulusLines.append(" source: heat Q=%(thermalSource)f" % vars())
97 elif source.sourceType in ["TemperatureSource"]:
98 temperatureSource = float(source.temperatureSource)-backGroundTemperature
99 stimulusLines.append(" source: temperature T=%(temperatureSource)f" % vars())
100
101 if not (source.sourceType in ["TemperatureSource"] and isinstance(group.thermalResistance, empro.components.ToAmbientSpecification)):
102 stimulus = _generateThermalResistanceStimulus(group.thermalResistance, instance, zLowerEffHeatTransfer, zUpperEffHeatTransfer)
103 stimulusLines += stimulus
104
105
106 stimulusDesc = "\n".join(stimulusLines)
107 with open(long_path_util.resolveLongPath(fileName),"w") as stimulusFile:
108 stimulusFile.write(_generateStimulusHeader(sipiData))
109 stimulusFile.write(stimulusDesc)
110
113 componentModel = componentGroup.models()[componentGroup.defaultModelIndex]
114 impedanceSpecification = None
115 if componentModel.modelType == 2:
116 impedanceSpecification = componentModel.getPassiveLoadFromVendorPartsDb().impedance
117 elif componentModel.modelType == 4:
118 viewName = componentModel.viewName
119 firstInstance = None
120 libCellName = None
121 if componentGroup.instances()[0]:
122 firstInstance = componentGroup.instances()[0].instance().name
123 libCellName = componentGroup.instances()[0]._libCellName
124 else:
125 raise RuntimeError("Model <%s> has no instances" % componentGroup.models()[ componentGroup.defaultModelIndex ].name)
126 layoutLibName = empro.activeProject.location.lib
127 layoutCellName = empro.activeProject.location.cell
128 layoutViewName = empro.activeProject.geometry()[0].name
129 if not layoutViewName or layoutViewName=='':
130 layoutViewName='layout'
131 parentLCVLayout = layoutLibName + ':' + layoutCellName + ':' + layoutViewName
132 pinPortMap = componentGroup.pinPortMap()
133 nrOfPorts = pinPortMap.nrPorts()
134 pinNamePortNumberPairs = pinPortMap.getPinNamePortNumberPairs(True, True);
135 impedanceSpecification = componentModel.getPassiveLoadFromLibCell(libCellName, viewName, firstInstance,
136 parentLCVLayout, nrOfPorts,
137 pinNamePortNumberPairs).impedance
138 else:
139 impedanceSpecification = componentModel.getPassiveLoad().impedance
140 if isinstance(impedanceSpecification, empro.components.RLCSpecification):
141 resistance = float(impedanceSpecification.resistance)
142 capacitance = float(impedanceSpecification.capacitance)
143 inductance = float(impedanceSpecification.inductance)
144 arrangement = impedanceSpecification.elementArrangement
145 if arrangement=="Series" and capacitance>0.0:
146 resistance = 1e8
147 elif arrangement=="Parallel":
148 if inductance>0.0:
149 resistance = 0.0
150 elif capacitance>0.0 and resistance==0.0:
151 resistance = 1e8
152 result = (1, [resistance])
153 elif isinstance(impedanceSpecification, empro.components.SnPSpecification):
154 import empro.enparams as enparams
155 snpEvaluator = enparams.TouchstoneEvaluator(impedanceSpecification.fileName)
156 minFreq = snpEvaluator.storedFrequencies()[0]
157 if minFreq != 0.0:
158 message = "DC not available in <%s>, using %e Hz instead" % (impedanceSpecification.fileName, minFreq)
159 empro.gui.MessageBox.warning("Warning", message, 0, 0)
160
161 Z = snpEvaluator.Zmatrix(0)
162 resistance = []
163 nrOfPorts = snpEvaluator.nbPorts()
164 for r in range(nrOfPorts):
165 for c in range(r, nrOfPorts):
166 resistance.append(Z.param(r,c).real)
167 result = (snpEvaluator.nbPorts(), resistance)
168 else:
169 raise RuntimeError("Unknown impedance specification type", )
170 if componentGroup.arrayedComponent:
171 if result[0] != 1:
172 raise RuntimeError("Model <%s> for array component has invalid #ports=%s: should be 1"%(componentGroup.models()[ componentGroup.defaultModelIndex ].name, str(result[0])))
173 assert(len(result[1]) == 1)
174 R = result[1][0]
175 nbPorts = componentGroup.pinPortMap().nrPorts()
176 resistance = []
177 for r in range(nbPorts):
178 for c in range(r, nbPorts):
179 if r == c:
180 resistance.append(R)
181 else:
182
183 resistance.append(0)
184 result = (nbPorts, resistance)
185 return result
186
189
190 import datetime
191 import os
192 import empro.toolkit.analysis as sipi
193 pinHash = sipi._createPinHash()
194 instanceHash = sipi._createInstanceHash()
195 pinNetNames = sipi._createPinHashNetName()
196 pinNetTypes = sipi._createPinHashNetTypeString()
197
198 simData = sipiData.newSimulationData()
199 generateThermalPorts = simData.sParametersEnabled
200
201 stimulusLines = []
202
203 electricalNameToLump = {}
204 vrmList = sipiData.getVrmList()
205 sinkList = sipiData.getSinkList()
206
207 lumped = 0
208 portNr = 0
209 for vrm in vrmList:
210 port = vrm
211 if port.hasSenseLine:
212 senseLumped, sensePortNr, stimulusLines = _generateSensePortStimulusElectro(port, stimulusLines, lumped, portNr, pinHash, pinNetTypes, idealGround)
213 lumped += 1
214 portNr +=1
215 lumped += 1
216 portNr += 1
217 if port.sourceType != 'PackagedVrm':
218
219 switchLumped, switchStimulusLines, voltage = _generateAllSwitchPortStimulusElectro(port, lumped, portNr, pinHash, pinNetTypes, idealGround)
220 name = vrm.name
221 electricalNameToLump[vrm.name] = lumped
222 plusPinNames = [x.name for x in port.plusPins()]
223 minusPinNames = [x.name for x in port.minusPins()]
224 stimulusLines.append("Electric %(lumped)d:" % vars())
225 stimulusLines.append(" name: %(name)s" % vars())
226 stimulusLines.append(" port: %(portNr)d" % vars())
227
228 for pinName in plusPinNames:
229 pinHashNr = pinHash[pinName]
230 pinNetType = pinNetTypes[pinHashNr]
231 if idealGround and pinNetType=="gnd":
232 stimulusLines.append(" pluspin: 0")
233 else:
234 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
235
236 for pinName in minusPinNames:
237 pinHashNr = pinHash[pinName]
238 pinNetType = pinNetTypes[pinHashNr]
239 if idealGround and pinNetType=="gnd":
240 stimulusLines.append(" minpin: 0")
241 else:
242 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
243
244 if port.sourceType == 'PackagedVrm':
245 resValue = float(port.resistance)
246 if resValue>1e-12:
247 stimulusLines.append(" load: resistor R=%(resValue)f" % vars())
248 else:
249 stimulusLines.append(" load: short" % vars())
250 else:
251 stimulusLines.append(" load: short" % vars())
252
253 if port.sourceType == 'PackagedVrm':
254 voltage = float(port.voltage)
255 stimulusLines.append(" source: voltage V=%f" % (voltage))
256 if port.hasSenseLine:
257 senseVoltage = float(port.senseVoltage)
258 stimulusLines[-1]+= " sense %d %f" %(senseLumped,senseVoltage)
259 if port.sourceType != 'PackagedVrm':
260 inputVoltage = float(port.inputVoltage)
261 stimulusSourceType = port.sourceType.split("Discrete")[1]
262 stimulusLines[-1]+= " switch %s %d %d %d %f" %(stimulusSourceType,switchLumped[0],switchLumped[1],switchLumped[2],inputVoltage)
263 stimulusLines += switchStimulusLines
264 lumped += 3
265 portNr += 3
266
267 for sink in sinkList:
268 port = sink
269 lumped += 1
270 name = sink.name
271 electricalNameToLump[sink.name] = lumped
272 plusPinNames = [x.name for x in port.plusPins()]
273 minusPinNames = [x.name for x in port.minusPins()]
274
275 stimulusLines.append("Electric %(lumped)d:" % vars())
276 portNr += 1
277 stimulusLines.append(" name: %(name)s" % vars())
278 stimulusLines.append(" port: %(portNr)d" % vars())
279
280 if sink.pinCurrentModel=="EqualVoltage":
281 for pinName in plusPinNames:
282 pinHashNr = pinHash[pinName]
283 pinNetType = pinNetTypes[pinHashNr]
284 if idealGround and pinNetType=="gnd":
285 stimulusLines.append(" pluspin: 0")
286 else:
287 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
288
289 for pinName in minusPinNames:
290 pinHashNr = pinHash[pinName]
291 pinNetType = pinNetTypes[pinHashNr]
292 if idealGround and pinNetType=="gnd":
293 stimulusLines.append(" minpin: 0")
294 else:
295 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
296 resistance = float(sink.resistance)
297 stimulusLines.append(" load: resistor R=%(resistance)f" % vars())
298 current = -float(sink.current)
299 stimulusLines.append(" source: current I=%(current)f" % vars())
300 else:
301 current = -float(sink.current)
302 currentPerPin = current/max(1.0,len(plusPinNames))
303 resistancePerPin = len(plusPinNames) * float(sink.resistance)
304 for pinName in plusPinNames:
305 pinHashNr = pinHash[pinName]
306 pinNetType = pinNetTypes[pinHashNr]
307 if idealGround and pinNetType=="gnd":
308 stimulusLines.append(" pluspin: 0")
309 else:
310 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=%(resistancePerPin)f I=%(currentPerPin)f " % vars())
311 for pinName in minusPinNames:
312 pinHashNr = pinHash[pinName]
313 pinNetType = pinNetTypes[pinHashNr]
314 if idealGround and pinNetType=="gnd":
315 stimulusLines.append(" minpin: 0")
316 else:
317 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
318 stimulusLines.append(" load: resistor R=0" % vars())
319
320 for componentGroup in sipiData.getComponentModelGroupList():
321 nbPorts = 0
322 nbPorts, resistance = _getDCResistance(componentGroup)
323 pinPortMap = componentGroup.pinPortMap()
324 if pinPortMap.nrPorts() != nbPorts:
325 raise RuntimeError("nbPorts of component (=%d) and nbPorts of impedance model (=%d) must be identical" % (pinPortMap.nrPorts(), nbPorts))
326
327 if nbPorts == 1 and componentGroup.pinPortMap().nrPins()==2:
328 for componentInstance in componentGroup.instances():
329 plusPinNames = []
330 minusPinNames = []
331
332 lumped += 1
333 name = componentInstance.name
334 electricalNameToLump[componentInstance.name] = lumped
335
336 stimulusLines.append("Electric %(lumped)d:" % vars())
337 portNr += 1
338 stimulusLines.append(" name: %(name)s" % vars())
339 stimulusLines.append(" port: %(portNr)d" % vars())
340
341
342 component = componentInstance.instance()
343 pin1 = component.pins()[0]
344 pin2 = component.pins()[1]
345 pinName1 = component.name + "." + pin1.name
346 pinName2 = component.name + "." + pin2.name
347 plusPinNames = [pinName1]
348 minusPinNames = [pinName2]
349 for pinName in plusPinNames:
350 pinHashNr = pinHash[pinName]
351 pinNetType = pinNetTypes[pinHashNr]
352 if idealGround and pinNetType=="gnd":
353 stimulusLines.append(" pluspin: 0")
354 else:
355 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
356
357 for pinName in minusPinNames:
358 pinHashNr = pinHash[pinName]
359 pinNetType = pinNetTypes[pinHashNr]
360 if idealGround and pinNetType=="gnd":
361 stimulusLines.append(" minpin: 0")
362 else:
363 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
364
365 stimulusLines.append(" load: resistor R=%f" % resistance[0])
366 stimulusLines.append("\n")
367
368 else:
369 for componentInstance in componentGroup.instances():
370 lumped += 1
371 electricalNameToLump[componentInstance.name] = lumped
372 name = componentInstance.name
373
374 stimulusLines.append("Electric %(lumped)d:" % vars())
375 stimulusLines.append(" nrOfPorts: %(nbPorts)d" % vars())
376 stimulusLines.append(" name: %(name)s" % vars())
377
378
379 componentName = componentInstance.instance().name
380 for localPortId, pinNames in pinPortMap.getPinNamesForPortNumbers(True):
381 portNr += 1
382 stimulusLines.append( " port[%d]: %d" % (localPortId, portNr) )
383 plusPins = pinNames[0]
384 minPins = pinNames[1]
385 for pin in plusPins:
386 pinName = componentName + "." + pin
387 pinHashNr = pinHash[pinName]
388 pinNetType = pinNetTypes[pinHashNr]
389 if idealGround and pinNetType=="gnd":
390 stimulusLines.append(" pluspin[%(localPortId)d]: 0" % vars())
391 else:
392 stimulusLines.append(" pluspin[%(localPortId)d]: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
393
394 for pin in minPins:
395 pinName = componentName + "." + pin
396 pinHashNr = pinHash[pinName]
397 pinNetType = pinNetTypes[pinHashNr]
398 if idealGround and pinNetType=="gnd":
399 stimulusLines.append(" minpin[%(localPortId)d]: 0" % vars())
400 else:
401 stimulusLines.append(" minpin[%(localPortId)d]: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
402
403 stimulusLines.append(" load: resistor R= %s" % " ".join([str(x) for x in resistance]) )
404 stimulusLines.append("\n")
405
406
407 backGroundTemperature = float(simData.ambientConditions.backgroundTemperature)
408 zLowerEffHeatTransfer = max(1e-4,simData.ambientConditions._zLowerEvaluatedEffectiveHeatTransfer())
409 zUpperEffHeatTransfer = max(1e-4,simData.ambientConditions._zUpperEvaluatedEffectiveHeatTransfer())
410
411 portNr = 0
412 thermalComponentGroupList = sipiData.getThermalComponentGroupList()
413 for group in thermalComponentGroupList:
414 for source in group:
415 portNr += 1
416 name = source.name
417 instance = source.instance()
418 instHash = instanceHash[instance.name]
419
420 pinNames = [instance.name + "." + pin.name for pin in instance.pins()]
421 stimulusLines.append("Thermal %(portNr)d:" % vars())
422 stimulusLines.append(" name: %(name)s" % vars())
423 if generateThermalPorts:
424 stimulusLines.append(" port: %(portNr)d" % vars())
425
426 generateR = isinstance(group.thermalResistance, empro.components.Package3RSpecification)
427 if generateR:
428 pinR = float(group.thermalResistance.pinResistance)
429 for pinName in pinNames:
430 pinNr = str(pinHash[pinName])
431 if generateR:
432 stimulusLines.append(" pluspin: %(pinNr)s R=%(pinR)f name=%(pinName)s" % vars())
433 else:
434 stimulusLines.append(" pluspin: %(pinNr)s name=%(pinName)s" % vars())
435
436 if isinstance(group.thermalResistance, empro.components.Package3RSpecification):
437 if group.thermalResistance.useCaseToBoardResistance:
438 pinNr = str(instHash)
439 pinName = name + "..BOARD"
440 padR = float(group.thermalResistance.caseToBoardResistance)
441 stimulusLines.append(" pluspin: %(pinNr)s R=%(padR)f name=%(pinName)s" % vars())
442
443 stimulusLines.append(" minpin: 0")
444 thermalSource = float(source.heatSource)
445 if source.sourceType in ["Disabled", "ElectricDissipation", "ElectricDissipationAndHeatSource","HeatSource"]:
446 if source.sourceType in ["Disabled", "ElectricDissipation"]:
447 thermalSource = 0.0
448 stimulusLines.append(" source: heat Q=%(thermalSource)f" % vars())
449 elif source.sourceType in ["TemperatureSource"]:
450 temperatureSource = float(source.temperatureSource)-backGroundTemperature
451 stimulusLines.append(" source: temperature T=%(temperatureSource)f" % vars())
452
453 eff = []
454 for k,v in source.dissipationFactors.iteritems():
455 strippedName = k
456 if k.startswith("VRM:"):
457 strippedName = strippedName[4:]
458 elif k.startswith("Sink:"):
459 strippedName = strippedName[5:]
460 elif k.startswith("ComponentInstance:"):
461 strippedName = strippedName[18:]
462 eff.append( (electricalNameToLump[strippedName], float(v) ) )
463
464 if source.sourceType in ["ElectricDissipation", "ElectricDissipationAndHeatSource"]:
465 for es in eff:
466 electricSourceNr = es[0]
467 dissipationFactor = es[1]
468 stimulusLines.append(" electric: %(electricSourceNr)d %(dissipationFactor)f" % vars())
469
470 if not (source.sourceType in ["TemperatureSource"] and isinstance(group.thermalResistance, empro.components.ToAmbientSpecification)):
471 stimulus = _generateThermalResistanceStimulus(group.thermalResistance, instance, zLowerEffHeatTransfer, zUpperEffHeatTransfer)
472 stimulusLines += stimulus
473
474 stimulusDesc = "\n".join(stimulusLines)
475 with open(long_path_util.resolveLongPath(fileName),"w") as stimulusFile:
476 stimulusFile.write(_generateStimulusHeader(sipiData))
477 stimulusFile.write(stimulusDesc)
478
481 import datetime
482 import os
483 import empro.toolkit.analysis as sipi
484 stimulusLines = []
485 header = "StiFile 1.0\n"
486 header+= "# Generated " + str(datetime.datetime.now()) + "\n\n"
487
488 pinHash = sipi._createPinHash()
489 instanceHash = sipi._createInstanceHash()
490 pinNetNames = sipi._createPinHashNetName()
491 usedPins = sipi._pinsUsed(sipiData)
492 lumped = 0
493
494 vrmList = sipiData.getVrmList()
495 for vrm in vrmList:
496 if vrm.hasSenseLine:
497 lumped += 1
498 lumped += 1
499 port = vrm
500 name = vrm.name
501 voltage = float(vrm.voltage)
502 tolerance = float(vrm.tolerance)
503 plusNames = ";".join([x.name for x in port.plusPins()])
504 minusNames = ";".join([x.name for x in port.minusPins()])
505 plusNetNames = ";".join(list(set([ pinNetNames[ pinHash[x.name] ] for x in port.plusPins()])))
506 stimulusLines.append("# Vrm;%(lumped)d;%(name)s;%(voltage)f;%(tolerance)f" % vars())
507 stimulusLines.append("# VrmPlus;%(lumped)s;%(plusNames)s" % vars())
508 stimulusLines.append("# VrmMinus;%(lumped)s;%(minusNames)s" % vars())
509 stimulusLines.append("# VrmNetPlus;%(lumped)s;%(plusNetNames)s" % vars())
510 if vrm.sourceType != 'PackagedVrm':
511 lumped += 3
512
513 sinkList = sipiData.getSinkList()
514 for sink in sinkList:
515 lumped += 1
516 port = sink
517 name = sink.name
518 tolerance = float(sink.tolerance)
519 current = float(sink.current)
520 plusNames = ";".join([x.name for x in port.plusPins()])
521 minusNames = ";".join([x.name for x in port.minusPins()])
522 plusNetNames = ";".join(list(set([ pinNetNames[ pinHash[x.name] ] for x in port.plusPins()])))
523 stimulusLines.append("# Sink;%(lumped)d;%(name)s;%(current)f;%(tolerance)f" % vars())
524 stimulusLines.append("# SinkPlus;%(lumped)s;%(plusNames)s" % vars())
525 stimulusLines.append("# SinkMinus;%(lumped)s;%(minusNames)s" % vars())
526 stimulusLines.append("# SinkNetPlus;%(lumped)s;%(plusNetNames)s" % vars())
527
528 thermalLumped = 0
529 thermalComponentGroupList = sipiData.getThermalComponentGroupList()
530 for group in thermalComponentGroupList:
531 for source in group:
532 thermalLumped += 1
533 instance = source.instance()
534 heatSource = float(source.heatSource)
535 name = instance.name
536 plusNames = ";".join([x.name for x in instance.pins()])
537 stimulusLines.append("# ThermalComponent;%(thermalLumped)d;%(name)s;%(heatSource)f" % vars())
538 stimulusLines.append("# ThermalComponentPlus;%(thermalLumped)s;%(plusNames)s" % vars())
539
540 for componentGroup in sipiData.getComponentModelGroupList():
541 pinPortMap = componentGroup.pinPortMap()
542 if pinPortMap.nrPorts() == 1 and pinPortMap.nrPins()==2:
543 for componentInstance in componentGroup.instances():
544 lumped += 1
545 component = componentInstance.instance()
546 name = component.name
547 stimulusLines.append("# ComponentModel;%(lumped)d;%(name)s" % vars())
548 pinName1 = component.name + "." + component.pins()[0].name
549 pinName2 = component.name + "." + component.pins()[1].name
550 stimulusLines.append("# ComponentModelPlus;%(lumped)d;%(pinName1)s" % vars())
551 stimulusLines.append("# ComponentModelMinus;%(lumped)d;%(pinName2)s" % vars())
552 else:
553 for componentInstance in componentGroup.instances():
554 lumped += 1
555 name = componentInstance.instance().name
556 stimulusLines.append("# ComponentModel;%(lumped)d;%(name)s" % vars())
557 for localPortId, pinNames in pinPortMap.getPinNamesForPortNumbers(True):
558 plusPinNames = pinNames[0]
559 minusPinNames = pinNames[1]
560
561 for pin in plusPinNames:
562 pinName = name + "." + pin
563 stimulusLines.append("# ComponentModelPlus%(localPortId)d;%(lumped)d;%(pinName)s" % vars())
564 for pin in minusPinNames:
565 pinName = name + "." + pin
566 stimulusLines.append("# ComponentModelMinus%(localPortId)d;%(lumped)d;%(pinName)s" % vars())
567
568
569 stimulusLines.append("# Available Pins")
570 for k,v in pinHash.iteritems():
571 stimulusLines.append("# AvailablePin;%(v)d;%(k)s" % vars())
572
573 stimulusLines.append("# Available Instance Pins")
574 for k,v in instanceHash.iteritems():
575 stimulusLines.append("# AvailableInstancePin;%(v)d;%(k)s" % vars())
576
577 stimulusLines.append("# Used Pins")
578 for name in usedPins:
579 hash = pinHash[name]
580 stimulusLines.append("# UsedPin;%(hash)d;%(name)s" % vars())
581
582 return header+"\n".join(stimulusLines) + "\n"
583
585 lumped += 1
586 portNr += 1
587 sensePort = vrm.sensePort
588 name = 'sense_' + vrm.name
589 plusPinNames = [x.name for x in sensePort.plusPins()]
590 minusPinNames = [x.name for x in sensePort.minusPins()]
591 stimulusLines.append("Electric %(lumped)d:" % vars())
592 stimulusLines.append(" name: %(name)s" % vars())
593 stimulusLines.append(" port: %(portNr)d" % vars())
594 for pinName in plusPinNames:
595 pinHashNr = pinHash[pinName]
596 pinNetType = pinNetTypes[pinHashNr]
597 if idealGround and pinNetType=="gnd":
598 stimulusLines.append(" pluspin: 0")
599 else:
600 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
601
602 for pinName in minusPinNames:
603 pinHashNr = pinHash[pinName]
604 pinNetType = pinNetTypes[pinHashNr]
605 if idealGround and pinNetType=="gnd":
606 stimulusLines.append(" minpin: 0")
607 else:
608 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
609
610 stimulusLines.append(" load: open")
611
612 return lumped, portNr, stimulusLines
613
614 -def _generateSingleSwitchPortStimulusElectro(port, stimulusLines, lumped, portNr, pinHash, pinNetTypes, name, isBoostPort, sourceVal, idealGround = False, resValue = None):
615 lumped += 1
616 portNr += 1
617 plusPinNames = [x.name for x in port.plusPins()]
618 minusPinNames = [x.name for x in port.minusPins()]
619 stimulusLines.append("Electric %(lumped)d:" % vars())
620 stimulusLines.append(" name: %(name)s" % vars())
621 stimulusLines.append(" port: %(portNr)d" % vars())
622 for pinName in plusPinNames:
623 pinHashNr = pinHash[pinName]
624 pinNetType = pinNetTypes[pinHashNr]
625 if idealGround and pinNetType=="gnd":
626 stimulusLines.append(" pluspin: 0")
627 else:
628 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
629
630 for pinName in minusPinNames:
631 pinHashNr = pinHash[pinName]
632 pinNetType = pinNetTypes[pinHashNr]
633 if idealGround and pinNetType=="gnd":
634 stimulusLines.append(" minpin: 0")
635 else:
636 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
637
638 if resValue and resValue>1e-12:
639 stimulusLines.append(" load: resistor R=%(resValue)f" % vars())
640 stimulusLines.append(" source: voltage V=%f" %(sourceVal))
641 elif isBoostPort:
642 stimulusLines.append(" load: short")
643 stimulusLines.append(" source: voltage V=%f" %(sourceVal))
644 else:
645 stimulusLines.append(" load: open")
646 stimulusLines.append(" source: current I=%f" %(sourceVal))
647 return lumped, stimulusLines
648
651 stimulusLines= []
652 inputVoltage = float(vrm.inputVoltage)
653 dcVoltage = float(vrm.voltage)
654 R = None
655 if vrm.sourceType == 'DiscreteBuck':
656 R = float(vrm.resistance)
657 voltage = dcVoltage
658 boostVoltage = 0
659 ports = [vrm.upSwitch, vrm.lowSwitch, vrm.inductor]
660 names = ['upSwitch_' + vrm.name, 'lowSwitch_' + vrm.name, 'inductor_' + vrm.name]
661 elif vrm.sourceType == 'DiscreteBoost':
662 voltage = inputVoltage
663 boostVoltage = dcVoltage - inputVoltage
664 ports = [vrm.inductor, vrm.upSwitch, vrm.lowSwitch]
665 names = [ 'inductor_' + vrm.name, 'upSwitch_' + vrm.name, 'lowSwitch_' + vrm.name]
666 else:
667 voltage = 0
668 boostVoltage = dcVoltage
669 ports = [vrm.upSwitch, vrm.inductor, vrm.lowSwitch]
670 names = ['upSwitch_' + vrm.name, 'inductor_' + vrm.name, 'lowSwitch_' + vrm.name]
671
672 highLumped, stimulusLines = _generateSingleSwitchPortStimulusElectro(ports[0], stimulusLines, lumped, portNr, pinHash, pinNetTypes, names[0], False, 0, idealGround)
673 lowLumped, stimulusLines = _generateSingleSwitchPortStimulusElectro(ports[1], stimulusLines, lumped+1, portNr+1, pinHash, pinNetTypes, names[1], False, 0, idealGround)
674 outLumped, stimulusLines = _generateSingleSwitchPortStimulusElectro(ports[2], stimulusLines, lumped+2, portNr+2, pinHash, pinNetTypes, names[2], True, boostVoltage, idealGround, resValue = R)
675 switchLumped = [highLumped,lowLumped,outLumped]
676 return switchLumped, stimulusLines, voltage
677
680
681 import empro.toolkit.analysis as sipi
682 pinHash = sipi._createPinHash()
683 instanceHash = sipi._createInstanceHash()
684 simData = sipiData.newSimulationData()
685 generateThermalStimulus = False
686 generateElectroStimulus = True
687
688 lumped = 0
689 stimulusLines = []
690 portNr = 0
691
692 vrmList = sipiData.getVrmList()
693 sinkList = sipiData.getSinkList()
694 pinNetNames = sipi._createPinHashNetName()
695 pinNetTypes = sipi._createPinHashNetTypeString()
696
697
698 for vrm in vrmList:
699 port = vrm
700 if port.hasSenseLine:
701 senseLumped, sensePortNr, stimulusLines = _generateSensePortStimulusElectro(port, stimulusLines, lumped, portNr, pinHash, pinNetTypes, idealGround)
702 lumped += 1
703 portNr +=1
704 lumped += 1
705 portNr += 1
706 if port.sourceType != 'PackagedVrm':
707
708 switchLumped, switchStimulusLines, voltage = _generateAllSwitchPortStimulusElectro(port, lumped, portNr, pinHash, pinNetTypes, idealGround)
709 name = port.name
710 plusPinNames = [x.name for x in port.plusPins()]
711 minusPinNames = [x.name for x in port.minusPins()]
712
713 stimulusLines.append("Electric %(lumped)d:" % vars())
714 stimulusLines.append(" name: %(name)s" % vars())
715 stimulusLines.append(" port: %(portNr)d" % vars())
716 for pinName in plusPinNames:
717 pinHashNr = pinHash[pinName]
718 pinNetType = pinNetTypes[pinHashNr]
719 if idealGround and pinNetType=="gnd":
720 stimulusLines.append(" pluspin: 0")
721 else:
722 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
723
724 for pinName in minusPinNames:
725 pinHashNr = pinHash[pinName]
726 pinNetType = pinNetTypes[pinHashNr]
727 if idealGround and pinNetType=="gnd":
728 stimulusLines.append(" minpin: 0")
729 else:
730 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
731
732 if port.sourceType == 'PackagedVrm':
733 resValue = float(port.resistance)
734 if resValue>1e-12:
735 stimulusLines.append(" load: resistor R=%(resValue)f" % vars())
736 else:
737 stimulusLines.append(" load: short" % vars())
738 else:
739 stimulusLines.append(" load: short" % vars())
740
741
742 if port.sourceType == 'PackagedVrm':
743 voltage = float(port.voltage)
744 stimulusLines.append(" source: voltage V=%f" % (voltage))
745 if port.hasSenseLine:
746 senseVoltage = float(port.senseVoltage)
747 stimulusLines[-1]+= " sense %d %f" %(senseLumped,senseVoltage)
748 if port.sourceType != 'PackagedVrm':
749 inputVoltage = float(port.inputVoltage)
750 stimulusSourceType = port.sourceType.split("Discrete")[1]
751 stimulusLines[-1]+= " switch %s %d %d %d %f" %(stimulusSourceType,switchLumped[0],switchLumped[1],switchLumped[2],inputVoltage)
752 stimulusLines += switchStimulusLines
753 lumped += 3
754 portNr += 3
755
756 for sink in sinkList:
757 port = sink
758 lumped += 1
759 portNr += 1
760 name = sink.name
761
762 plusPinNames = [x.name for x in port.plusPins()]
763 minusPinNames = [x.name for x in port.minusPins()]
764
765 stimulusLines.append("Electric %(lumped)d:" % vars())
766 stimulusLines.append(" name: %(name)s" % vars())
767 stimulusLines.append(" port: %(portNr)d" % vars())
768
769 if sink.pinCurrentModel=="EqualVoltage":
770 for pinName in plusPinNames:
771 pinHashNr = pinHash[pinName]
772 pinNetType = pinNetTypes[pinHashNr]
773 if idealGround and pinNetType=="gnd":
774 stimulusLines.append(" pluspin: 0")
775 else:
776 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
777
778 for pinName in minusPinNames:
779 pinHashNr = pinHash[pinName]
780 pinNetType = pinNetTypes[pinHashNr]
781 if idealGround and pinNetType=="gnd":
782 stimulusLines.append(" minpin: 0")
783 else:
784 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
785
786 resistance = float(sink.resistance)
787 stimulusLines.append(" load: resistor R=%(resistance)f" % vars())
788 current = -float(sink.current)
789 stimulusLines.append(" source: current I=%(current)f" % vars())
790
791 else:
792 current = -float(sink.current)
793 currentPerPin = current/max(1.0,len(plusPinNames))
794 resistancePerPin = len(plusPinNames) * float(sink.resistance)
795 for pinName in plusPinNames:
796 pinHashNr = pinHash[pinName]
797 pinNetType = pinNetTypes[pinHashNr]
798 if idealGround and pinNetType=="gnd":
799 stimulusLines.append(" pluspin: 0")
800 else:
801 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=%(resistancePerPin)f I=%(currentPerPin)f " % vars())
802
803 for pinName in minusPinNames:
804 pinHashNr = pinHash[pinName]
805 pinNetType = pinNetTypes[pinHashNr]
806 if idealGround and pinNetType=="gnd":
807 stimulusLines.append(" minpin: 0")
808 else:
809 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
810
811 stimulusLines.append(" load: resistor R=0" % vars())
812
813
814 for componentGroup in sipiData.getComponentModelGroupList():
815 nbPorts = 0
816 if generateElectroStimulus:
817 nbPorts, resistance = _getDCResistance(componentGroup)
818 pinPortMap = componentGroup.pinPortMap()
819 if pinPortMap.nrPorts() != nbPorts:
820 raise RuntimeError("nbPorts of component (=%d) and nbPorts of impedance model (=%d) must be identical" % (pinPortMap.nrPorts(), nbPorts))
821
822
823 if nbPorts == 1 and componentGroup.pinPortMap().nrPins()==2:
824 for componentInstance in componentGroup.instances():
825 plusPinNames = []
826 minusPinNames = []
827 lumped += 1
828 portNr += 1
829 name = componentInstance.name
830 stimulusLines.append("Electric %(lumped)d:" % vars())
831 stimulusLines.append(" name: %(name)s" % vars())
832 stimulusLines.append(" port: %(portNr)d" % vars())
833
834 component = componentInstance.instance()
835 pin1 = component.pins()[0]
836 pin2 = component.pins()[1]
837 pinName1 = component.name + "." + pin1.name
838 pinName2 = component.name + "." + pin2.name
839
840 plusPinNames = [pinName1]
841 minusPinNames = [pinName2]
842 for pinName in plusPinNames:
843 pinHashNr = pinHash[pinName]
844 pinNetType = pinNetTypes[pinHashNr]
845 if idealGround and pinNetType=="gnd":
846 stimulusLines.append(" pluspin: 0")
847 else:
848 stimulusLines.append(" pluspin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
849
850 minPinIsAttachedToGndNet = True
851 groundNetNames = empro.activeProject.geometry()[0]._netList().getGroundNetNames()
852 minPinIsAttachedToGndNet = pinNetNames[ pinHash[pinName2] ] in groundNetNames
853
854 for pinName in minusPinNames:
855 pinHashNr = pinHash[pinName]
856 pinNetType = pinNetTypes[pinHashNr]
857 if idealGround and pinNetType=="gnd":
858 stimulusLines.append(" minpin: 0")
859 else:
860 stimulusLines.append(" minpin: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
861
862 stimulusLines.append(" load: resistor R=%f" % resistance[0])
863
864
865 else:
866 for componentInstance in componentGroup.instances():
867 lumped += 1
868 name = componentInstance.name
869
870 stimulusLines.append("Electric %(lumped)d:" % vars())
871 stimulusLines.append(" nrOfPorts: %(nbPorts)d" % vars())
872 stimulusLines.append(" name: %(name)s" % vars())
873
874
875 componentName = componentInstance.instance().name
876 for localPortId, pinNames in pinPortMap.getPinNamesForPortNumbers(True):
877 portNr += 1
878 stimulusLines.append( " port[%d]: %d" % (localPortId, portNr) )
879 plusPins = pinNames[0]
880 minPins = pinNames[1]
881 for pin in plusPins:
882 pinName = componentName + "." + pin
883 pinHashNr = pinHash[pinName]
884 pinNetType = pinNetTypes[pinHashNr]
885 if idealGround and pinNetType=="gnd":
886 stimulusLines.append(" pluspin[%(localPortId)d]: 0" % vars())
887 else:
888 stimulusLines.append(" pluspin[%(localPortId)d]: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
889
890 for pin in minPins:
891 pinName = componentName + "." + pin
892 pinHashNr = pinHash[pinName]
893 pinNetType = pinNetTypes[pinHashNr]
894 if idealGround and pinNetType=="gnd":
895 stimulusLines.append(" minpin[%(localPortId)d]: 0" % vars())
896 else:
897 stimulusLines.append(" minpin[%(localPortId)d]: %(pinHashNr)d %(pinNetType)s R=0 name=%(pinName)s" % vars())
898
899
900 stimulusLines.append(" load: resistor R= %s" % " ".join([str(x) for x in resistance]) )
901
902 stimulusDesc = "\n".join(stimulusLines)
903 with open(long_path_util.resolveLongPath(fileName),"w") as stimulusFile:
904 stimulusFile.write(_generateStimulusHeader(sipiData))
905 stimulusFile.write(stimulusDesc)
906
917