1
2 import empro
3 from empro.gui import SimpleDialog, TableView, Cancel, Ok, ComboBox, Label, GridLayout, MessageBox, Yes, No
4
5 from empro.toolkit.analysis import _createPinHash
6 from empro.toolkit.analysis import _createPinHashNetName
7 from empro.toolkit.analysis import _getNetTypesForUsedNets
8 from empro.toolkit import long_path_util
9
10 _immediately_ = 'At least one port is required to generate the test bench.'
11
22
24 import re
25 return re.sub(iMapChar, '_', iName)
26
28 import re
29 name = re.sub(r'%+', 'pct', iName)
30 name = name.replace('___','_UUU_')
31 name = name.replace('__','_UU_')
32 name = name.replace('+', '_p_')
33 name = name.replace('-', '_n_')
34 name = name.replace('#', '_x_')
35 name = name.replace('!', '_b_')
36 name = re.sub(r'[^a-zA-Z0-9_]', '_', name)
37 name = re.sub(r'_+', '_', name)
38 name = name.replace('_UU_','__')
39 name = name.replace('_UUU_','___')
40 if name[0] in tuple('0123456789_'):
41 if name[0] == '_':
42 name = 'X' + name
43 else:
44 name = 'X_' + name
45 return name
46
48 import re
49 special = {'*' :'_a_',
50 '(' :'_ob_',
51 ')' :'_cb_',
52 '[' :'_os_',
53 ']' :'_cs_',
54 '{' :'_oa_',
55 '}' :'_ca_',
56 '/' :'_fs_',
57 '\\':'_bs_',
58 '<' :'_lt_',
59 '>' :'_gt_',
60 '?' :'_qm_',
61 '!' :'_e_',
62 ',' :'_k_',
63 ';' :'_s_',
64 ':' :'_c_',
65 '\'':'_sq_',
66 '`' :'_bq_',
67 '"' :'_dq_',
68 '#' :'_lb_',
69 '|' :'_vb_',
70 '$' :'_ud_',
71 '%' :'_pct_',
72 ' ' :'_'
73 }
74
75 name = iName
76 for k,v in special.iteritems():
77 name = name.replace(k, v)
78 name = re.sub(r'_+', '_', name)
79 return name
80
82 import re
83 special = {'/' :'_fs_',
84 '\\':'_bs_',
85 '.' :'_d_',
86 ',' :'_k_',
87 ';' :'_s_',
88 ':' :'_c_',
89 '\'':'_sq_',
90 '`' :'_bq_',
91 '"' :'_dq_',
92 '#' :'_lb_',
93 '|' :'_vb_',
94 '$' :'_ud_',
95 ' ' :'_'
96 }
97
98 name = iName
99 for k,v in special.iteritems():
100 name = name.replace(k, v)
101 name = re.sub(r'_+', '_', name)
102 name = _fixADSSimulationNames(name)
103 return name
104
106
107
108
109 if "#7c" in iName or "#23" in iName:
110 name = iName.replace("#", "#23")
111 else:
112 name = iName
113 return name.replace("|", "#7c")
114
115
117
118
119
120 if "#" in iName:
121 name = iName.replace("#7c", "|")
122 return name.replace("#23", "#")
123 return iName
124
125
126
128 if freq < 1.e3:
129 return str(freq) + " Hz"
130 elif freq < 1.e6:
131 return str(freq/1.e3) + " kHz"
132 elif freq < 1.e9:
133 return str(freq/1.e6) + " MHz"
134 else:
135 return str(freq/1.e9) + " GHz"
136
138 if resValue == None:
139 resValue = 0.
140 if indValue == None:
141 indValue = 0.
142 if capValue == None:
143 capValue = 0.
144 return ( resValue, indValue, capValue )
145
147 import os
148 fileNames = ["%s.snp" % partNbr, "%s.s%dp" % (partNbr, nbrOfPorts)]
149 snpFileLocation = None
150 for fileName in fileNames:
151 snpFile = os.path.join(empro.liboa.getLibDefsDirPath(), "simulation", "eemSipi",
152 empro.activeProject.location.lib, "measSnp_%s" % partNbr, fileName)
153 if os.path.isfile(snpFile):
154 snpFileLocation = "%s" % snpFile
155 break
156 return snpFileLocation
157
158 _noSimulationModel = '__NOMODEL__'
159
160
161
163 import os
164 simulationPath = sipiData.simulationPath
165 if simulationPath==None:
166 return _noSimulationModel
167
168 analysisType = sipiData.analysisType
169
170 path = os.path.join(simulationPath, "emds_dsn", "design")
171
172 if analysisType == sipiData.DCAnalysisType or analysisType == sipiData.ETHAnalysisType :
173 path = simulationPath
174 fileNames = ['design.out.electric.cti', 'design.out.cti']
175 elif analysisType == sipiData.ACAnalysisType:
176 fileNames = ['design.cti', 'design_ffs.cti', 'design_dfs.cti', 'design.sio']
177 elif analysisType == sipiData.PASIAnalysisType:
178 fileNames = ['design_ffs.cti', 'design_dfs.cti', 'design.sio']
179 elif analysisType in [sipiData.EMFUAnalysisType,sipiData.EMUDAnalysisType,sipiData.EMSMAnalysisType,sipiData.EMFUAnalysisType,sipiData.EMFUPEAnalysisType,sipiData.EMUDPEAnalysisType]:
180 path = simulationPath
181 fileNames = ['emds_dsn/design/design.sio', 'work/proj.sio']
182 else:
183 print "Unexpected analysisType %s" % analysisType
184 return _noSimulationModel
185
186 for simulationModel in [os.path.join(path, fileName) for fileName in fileNames]:
187 if os.path.exists(long_path_util.resolveLongPath(simulationModel)):
188 return simulationModel
189
190 print "Model data file not found at ", simulationModel
191 return _noSimulationModel
192
194 import os
195 vrmOutputVoltageDict = {}
196 if not sipiData.analysisType == sipiData.DCAnalysisType:
197 return vrmOutputVoltageDict
198 simLocation = sipiData.simulationPath
199 if not simLocation:
200 return vrmOutputVoltageDict
201 simOutpData = os.path.join(simLocation, "design.out.sti")
202 if not os.path.exists(simOutpData):
203 return vrmOutputVoltageDict
204 electricNameToVI = {}
205 with open(simOutpData,"r") as inp:
206 lines = inp.readlines()
207 for index, line in enumerate(lines):
208 if line.startswith("StiFile"):
209 continue
210 elif line.startswith("Lumped") or line.startswith("Electric"):
211 if line.startswith("Lumped"):
212 lumpNr = int(line.replace("Lumped","").replace(":",""))
213 else:
214 lumpNr = int(line.replace("Electric","").replace(":",""))
215 lastElectricLumpNr = lumpNr
216 nextIndex = index + 1
217 if "name:" in lines[nextIndex]:
218 electricName = lines[nextIndex].replace("name","").replace(":","").lstrip(" ").rstrip("\n")
219 nextIndex += 1
220 parts = lines[nextIndex].split(":")
221 if "nrOfPorts" in parts[0]:
222 if int(parts[1]) > 1:
223 continue
224 else:
225 nextIndex = nextIndex + 1
226 parts = lines[nextIndex].split(":")
227 if not "voltage" in parts[0]:
228 raise Exception("DC Vrm output voltage parsing error in file %s at line %d: voltage expected" % (nextIndex,simOutpData))
229 voltage = float(parts[1])
230 nextIndex = nextIndex + 1
231 parts = lines[nextIndex].split(":")
232 if not "current" in parts[0]:
233 raise Exception("DC Vrm output voltage parsing error in file %s at line %d: voltage expected" % (nextIndex,simOutpData))
234 current = float(parts[1])
235 electricNameToVI[electricName] = [voltage,current]
236
237 for vrm in vrmList:
238 name = vrm.name
239 if not vrm.hasSenseLine:
240 vrmOutputVoltageDict[name]=float(vrm.voltage)
241 else:
242 resistance = float(vrm.resistance)
243 try:
244 v,i = electricNameToVI[name]
245 except KeyError:
246 continue
247 outputVoltage = v - resistance*i
248 vrmOutputVoltageDict[name]=outputVoltage
249 return vrmOutputVoltageDict
250
252 import os
253 switchVrmDict = {}
254 if not sipiData.analysisType == sipiData.DCAnalysisType:
255 return switchVrmDict
256 simLocation = sipiData.simulationPath
257 if not simLocation:
258 return switchVrmDict
259 simOutpData = os.path.join(simLocation, "design.out.sti")
260 if not os.path.exists(simOutpData):
261 return switchVrmDict
262 electricNameToVI = {}
263 with open(simOutpData,"r") as inp:
264 lines = inp.readlines()
265 for index, line in enumerate(lines):
266 if line.startswith("StiFile"):
267 continue
268 elif line.startswith("Lumped") or line.startswith("Electric"):
269 if line.startswith("Lumped"):
270 lumpNr = int(line.replace("Lumped","").replace(":",""))
271 else:
272 lumpNr = int(line.replace("Electric","").replace(":",""))
273 lastElectricLumpNr = lumpNr
274 nextIndex = index + 1
275 if "name:" in lines[nextIndex]:
276 electricName = lines[nextIndex].replace("name","").replace(":","").lstrip(" ").rstrip("\n")
277 nextIndex += 1
278 parts = lines[nextIndex].split(":")
279 if "nrOfPorts" in parts[0]:
280 if int(parts[1]) > 1:
281 continue
282 else:
283 nextIndex = nextIndex + 1
284 parts = lines[nextIndex].split(":")
285 if not "voltage" in parts[0]:
286 raise Exception("DC Vrm output voltage parsing error in file %s at line %d: voltage expected" % (nextIndex,simOutpData))
287 voltage = float(parts[1])
288 nextIndex = nextIndex + 1
289 parts = lines[nextIndex].split(":")
290 if not "current" in parts[0]:
291 raise Exception("DC Vrm output current parsing error in file %s at line %d: current expected" % (nextIndex,simOutpData))
292 current = float(parts[1])
293 electricNameToVI[electricName] = [voltage,current]
294
295 for vrm in vrmList:
296 name = vrm.name
297 if vrm.sourceType == 'PackagedVrm':
298 continue
299 upSwitchName = 'upSwitch_' + vrm.name
300 lowSwitchName = 'lowSwitch_' + vrm.name
301 inductorName = 'inductor_' + vrm.name
302 try:
303 voltage_1 = electricNameToVI[name][0]
304 current_2 = -electricNameToVI[inductorName][1] if vrm.sourceType == 'DiscreteBoost' else -electricNameToVI[upSwitchName][1]
305 current_3 = -electricNameToVI[lowSwitchName][1] if vrm.sourceType == 'DiscreteBuck' else -electricNameToVI[inductorName][1]
306 if vrm.sourceType == 'DiscreteBoost':
307 current_3 = -electricNameToVI[upSwitchName][1]
308 voltage_4 = electricNameToVI[lowSwitchName][0]
309 if vrm.sourceType == 'DiscreteBuck':
310 voltage_4 = electricNameToVI[inductorName][0]
311 current_4 = electricNameToVI[inductorName][1]
312 resValue = float(vrm.resistance)
313 voltage_4 = voltage_4 - resValue*current_4
314 switchVrmDict[name]=[voltage_1, current_2, current_3, voltage_4]
315 except KeyError:
316 raise Exception("DC switching Vrm parsing error in file %s" % (nextIndex,simOutpData))
317
318 return switchVrmDict
319
321 if line and line.strip:
322 maxStimulusLine = 256
323 lineLen = len(line)
324 if lineLen < maxStimulusLine:
325 stimulusLines.append(line)
326 else:
327 maxStimulusLine = lineLen // (1+(lineLen // maxStimulusLine))
328 pieces = iter(line.split('|'))
329 lines, current = [], next(pieces)
330 for piece in pieces:
331 if len(current) + len(piece) > maxStimulusLine:
332 if len(piece) > (maxStimulusLine//2):
333 splitchar=';'
334 nplPieces = piece.split(splitchar)
335 if len(nplPieces)<=1:
336 splitchar=','
337 nplPieces = piece.split(splitchar)
338 if len(nplPieces)>1:
339 current += "|" + nplPieces[0]
340 for nplPiece in nplPieces[1:]:
341 if len(current) + len(nplPiece) > maxStimulusLine:
342 lines.append(current + '|+++')
343 current = '+%s+|' % splitchar + nplPiece
344 else:
345 current += splitchar + nplPiece
346 continue
347 else:
348 lines.append(current + '|+++')
349 current = '+++|' + piece
350 else:
351 lines.append(current + '|+++')
352 current = '+++|' + piece
353 else:
354 current += '|' + piece
355 lines.append(current)
356 stimulusLines.extend(lines)
357
361
362 -def generateSchematicFile( workingDirectory, sipiData, libName, cellName, destinationCellName='', schematicType=1,
363 useLumped=False, missingInAds=[], suppressDialog=False, keepPinNames=False ):
364
365 import datetime
366 import os
367 import string
368 import re
369 import empro.core
370
371 parentPlatformIsVirtuoso = empro.core.CommunicationWithParent.communicationParent() == empro.core.CommunicationWithParent.VIRTUOSO
372
373 header = "# SipiSchFile 3.0\n"
374 header+= "# Generated " + str(datetime.datetime.now()) + "\n"
375
376 lumped = 0
377 stimulusLines = []
378
379 analysisType = sipiData.analysisType
380 analysisName = sipiData.name
381 analysisName = _fixSetupName(analysisName)
382
383 analysisLine = "SipiSchematic|Libname|%(libName)s|Name|%(cellName)s|AnalysisType|%(analysisType)s|AnalysisName|%(analysisName)s|SchematicType|%(schematicType)s" % vars()
384 layoutLibName = empro.activeProject.location.lib
385 layoutCellName = empro.activeProject.location.cell
386 if not layoutCellName:
387 layoutCellName = cellName
388 layoutViewName = empro.activeProject.geometry()[0].name
389 analysisLine += "|LayoutLibName|%(layoutLibName)s|LayoutCellName|%(layoutCellName)s|LayoutViewName|%(layoutViewName)s|End" % vars()
390 _appendToStimulusLines(stimulusLines, analysisLine)
391
392 pinHash = _createPinHash()
393 pinNetNames = _createPinHashNetName()
394 def _getPinNetName(pinName):
395 try:
396 return pinNetNames[ pinHash[pinName] ]
397 except KeyError:
398 raise Exception("Referring to nonexistent pin '%s'" % pinName)
399
400 netTypesUsedNets = dict(_getNetTypesForUsedNets(sipiData))
401 signalRefZ = float(empro.core.ApplicationPreferences.getPreference( "SiPro/GenerateSchematic/SignalRefImpedance", 50.0 ))
402 supplyRefZ = float(empro.core.ApplicationPreferences.getPreference( "SiPro/GenerateSchematic/SupplyRefImpedance", 0.1 ))
403
404 simulationModel = getSimulationModel(sipiData)
405
406
407
408
409
410
411
412
413
414 portsReduction = empro.analysis.TouchingPortsReduction(sipiData)
415 if portsReduction.isApplicable:
416 originalPortsReduction = portsReduction.originalPortsReduction
417 uniquePortNames = set()
418 def _uniquifyPortName(name):
419 candidate = name
420 suffix = 0
421 while True:
422 if candidate not in uniquePortNames:
423 uniquePortNames.add(candidate)
424 return candidate
425 suffix = suffix + 1
426 candidate = "%(name)s_%(suffix)d" % vars()
427
428 sortedPortNames = []
429 def _registerPort(name, exactName=False):
430 if not portsReduction.isApplicable or originalPortsReduction[_registerPort.portIdx] >= len(sortedPortNames):
431 if not exactName:
432 name = _fixADSSimulationNames(name)
433 resultingPortName = _uniquifyPortName(name)
434 sortedPortNames.append(resultingPortName)
435 else:
436 resultingPortName = sortedPortNames[originalPortsReduction[_registerPort.portIdx]]
437 _registerPort.portIdx = _registerPort.portIdx + 1
438 return resultingPortName
439 _registerPort.portIdx = 0
440 ioPortList = []
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456 if analysisType in [sipiData.PASIAnalysisType, sipiData.EMFUAnalysisType,
457 sipiData.EMUDAnalysisType, sipiData.EMSMAnalysisType,
458 sipiData.EMFUPEAnalysisType, sipiData.EMUDPEAnalysisType
459 ]:
460 ioPortList = sipiData.getPortList()
461 useSymbolGroups = (analysisType == sipiData.PASIAnalysisType)
462
463 if keepPinNames == True:
464 displayPinNameList = set()
465
466 ioPortNetNames = set()
467 for ioPort in ioPortList:
468 lumped += 1
469 port = ioPort
470 if schematicType == 2 and parentPlatformIsVirtuoso:
471
472 name = _fixCdsIoPortNames(ioPort.name)
473 else:
474 name = _fixADSVarNames(ioPort.name)
475 plusNetName = next(iter(set([ _getPinNetName(x.name) for x in port.plusPins()])), 'Gnd')
476 minusNetName = next(iter(set([ _getPinNetName(x.name) for x in port.minusPins()])), 'Gnd')
477 portName = _registerPort(name, exactName=True)
478 referenceImpedance = str(port.referenceImpedance.evaluate())
479 portLine = "IOPort|%(lumped)d|Name|%(name)s|Z|%(referenceImpedance)s|Port|%(portName)s" % vars()
480
481 if keepPinNames == True and netTypesUsedNets.get(plusNetName) == 16:
482 displayPinNameList.add(portName)
483
484 if portName in ioPortNetNames:
485 shortedNetName = _uniquifyPortName(portName)
486 portLine += "|Short|%(shortedNetName)s" % vars()
487 ioPortNetNames.add(shortedNetName)
488 else:
489 ioPortNetNames.add(portName)
490
491 if useSymbolGroups:
492 instPrtGrouping = list(set([ ((x.getInstanceName() == '' and 'None') or x.getInstanceName()) for x in port.plusPins() ]))
493 instPrtGroupString = '_'.join(instPrtGrouping)
494 portLine += "|SymbolGroup|%(instPrtGroupString)s" % vars()
495 portLine += "|End"
496 _appendToStimulusLines(stimulusLines, portLine)
497
498 vrmList=[]
499 if analysisType != sipiData.PASIAnalysisType:
500 vrmList = sipiData.getVrmList()
501 vrmOutputVoltageDict = _generateDCVrmOutputVoltageDict(sipiData, vrmList)
502 switchVrmDict = _generateSwitchVrmDict(sipiData, vrmList)
503 for vrm in vrmList:
504 lumped += 1
505 port = vrm
506 name = _fixADSVarNames(vrm.name)
507 if vrm.hasSenseLine and analysisType == 1 :
508 sensePort = vrm.sensePort
509 sensePlusNames = '_'.join([x.name for x in sensePort.plusPins()]).replace('.', '_').replace(',', '_')
510 senseMinusNames = '_'.join([x.name for x in sensePort.minusPins()]).replace('.', '_').replace(',', '_')
511 sensePlusNetName = next(iter(set([ _getPinNetName(x.name) for x in sensePort.plusPins()])), 'Gnd')
512 senseMinusNetName = next(iter(set([ _getPinNetName(x.name) for x in sensePort.minusPins()])), 'Gnd')
513 sensePortName = _registerPort('_'.join([name, sensePlusNetName, sensePlusNames, senseMinusNetName, senseMinusNames]))
514 sensePortRefImpedance = str(sensePort.referenceImpedance.evaluate())
515 vrmSensePortLine = "VrmSensePort|%(lumped)d|Name|%(name)s|Z|%(sensePortRefImpedance)s|Port|%(sensePortName)s|End" % vars()
516 _appendToStimulusLines(stimulusLines, vrmSensePortLine)
517
518 voltage = float(vrm.voltage)
519 tolerance = float(vrm.tolerance)
520 plusNetName = next(iter(set([ _getPinNetName(x.name) for x in port.plusPins()])), 'Gnd')
521 minusNetName = next(iter(set([ _getPinNetName(x.name) for x in port.minusPins()])), 'Gnd')
522 portName = _registerPort('_'.join([name, plusNetName, minusNetName]))
523 referenceImpedance = str(port.referenceImpedance.evaluate())
524
525 hasVrmInSwitchVrmDict = (switchVrmDict!={}) and (vrm.name in switchVrmDict.keys())
526 if vrm.sourceType == 'PackagedVrm':
527 resValue = float(vrm.resistance)
528 indValue = float(vrm.inductance)
529 capValue = 0.0
530 else:
531 if hasVrmInSwitchVrmDict:
532 voltage = switchVrmDict[vrm.name][0]
533 resValue = 0.0
534 indValue = 0.0
535 capValue = 0.0
536
537 vrmLine = "Vrm|%(lumped)d|Name|%(name)s|Voltage|%(voltage)g|Tolerance|%(tolerance)g" % vars()
538 vrmLine += "|R|%(resValue)g|L|%(indValue)g|C|%(capValue)g|Z|%(referenceImpedance)s" % vars()
539 vrmLine += "|Port|%(portName)s" % vars()
540 if analysisType == 1 and vrm.name:
541 if (vrmOutputVoltageDict!={}) and (vrm.name in vrmOutputVoltageDict.keys()):
542 if vrm.sourceType == 'PackagedVrm':
543 vrmLine += "|OutputVoltage|%g" % vrmOutputVoltageDict[vrm.name]
544
545 if vrm.sourceType != 'PackagedVrm':
546 highPort = vrm.upSwitch
547 highPortName = 'upSwitch_' + vrm.name
548 lowPort = vrm.lowSwitch
549 lowPortName = 'lowSwitch_' + vrm.name
550 outPort = vrm.inductor
551 outPortName = 'inductor_' + vrm.name
552 outPortRvalue = None
553 if vrm.sourceType == 'DiscreteBuck':
554 outPortRvalue = float(vrm.resistance)
555 elif vrm.sourceType == 'DiscreteBoost':
556 highPort = vrm.inductor
557 highPortName = 'inductor_' + vrm.name
558 lowPort = vrm.upSwitch
559 lowPortName = 'upSwitch_' + vrm.name
560 outPort = vrm.lowSwitch
561 outPortName = 'lowSwitch_' + vrm.name
562 else:
563 lowPort = vrm.inductor
564 lowPortName = 'inductor_' + vrm.name
565 outPort = vrm.lowSwitch
566 outPortName = 'lowSwitch_' + vrm.name
567
568 highPlusNames = '_'.join([x.name for x in highPort.plusPins()]).replace('.', '_').replace(',', '_')
569 highMinusNames = '_'.join([x.name for x in highPort.minusPins()]).replace('.', '_').replace(',', '_')
570 highPlusNetName = next(iter(set([ _getPinNetName(x.name) for x in highPort.plusPins()])), 'Gnd')
571 highMinusNetName = next(iter(set([ _getPinNetName(x.name) for x in highPort.minusPins()])), 'Gnd')
572 highPortNetName = _registerPort('_'.join([highPortName, highPlusNetName, highPlusNames, highMinusNetName, highMinusNames]))
573 highPortRefImpedance = str(highPort.referenceImpedance.evaluate())
574 highPortCurrent = switchVrmDict[vrm.name][1] if hasVrmInSwitchVrmDict else 0.0
575 highPortName = _fixADSSimulationNames(highPortName)
576 vrmLine += "|hName|%(highPortName)s|hCurrent|%(highPortCurrent)s|hZ|%(highPortRefImpedance)s|hPort|%(highPortNetName)s" % vars()
577
578 lowPlusNames = '_'.join([x.name for x in lowPort.plusPins()]).replace('.', '_').replace(',', '_')
579 lowMinusNames = '_'.join([x.name for x in lowPort.minusPins()]).replace('.', '_').replace(',', '_')
580 lowPlusNetName = next(iter(set([ _getPinNetName(x.name) for x in lowPort.plusPins()])), 'Gnd')
581 lowMinusNetName = next(iter(set([ _getPinNetName(x.name) for x in lowPort.minusPins()])), 'Gnd')
582 lowPortNetName = _registerPort('_'.join([lowPortName, lowPlusNetName, lowPlusNames, lowMinusNetName, lowMinusNames]))
583 lowPortRefImpedance = str(lowPort.referenceImpedance.evaluate())
584 lowPortCurrent = switchVrmDict[vrm.name][2] if hasVrmInSwitchVrmDict else 0.0
585 lowPortName = _fixADSSimulationNames(lowPortName)
586 vrmLine += "|lName|%(lowPortName)s|lCurrent|%(lowPortCurrent)s|lZ|%(lowPortRefImpedance)s|lPort|%(lowPortNetName)s" % vars()
587
588 outPlusNames = '_'.join([x.name for x in outPort.plusPins()]).replace('.', '_').replace(',', '_')
589 outMinusNames = '_'.join([x.name for x in outPort.minusPins()]).replace('.', '_').replace(',', '_')
590 outPlusNetName = next(iter(set([ _getPinNetName(x.name) for x in outPort.plusPins()])), 'Gnd')
591 outMinusNetName = next(iter(set([ _getPinNetName(x.name) for x in outPort.minusPins()])), 'Gnd')
592 outPortNetName = _registerPort('_'.join([outPortName, outPlusNetName, outPlusNames, outMinusNetName, outMinusNames]))
593 outPortRefImpedance = str(outPort.referenceImpedance.evaluate())
594 outPortVoltage = switchVrmDict[vrm.name][3] if hasVrmInSwitchVrmDict else 0.0
595 outPortName = _fixADSSimulationNames(outPortName)
596 vrmLine += "|oName|%(outPortName)s|oVoltage|%(outPortVoltage)s|oZ|%(outPortRefImpedance)s|oPort|%(outPortNetName)s" % vars()
597 if outPortRvalue!=None:
598 vrmLine += "|oR|%(outPortRvalue)g" % vars()
599 vrmLine += "|End"
600 _appendToStimulusLines(stimulusLines, vrmLine)
601
602 sinkList=[]
603 if analysisType != sipiData.PASIAnalysisType:
604 sinkList = sipiData.getSinkList()
605 for sink in sinkList:
606 lumped += 1
607 port = sink
608 name = _fixADSVarNames(sink.name)
609 tolerance = float(sink.tolerance)
610 current = float(sink.current)
611 plusNetName = next(iter(set([ _getPinNetName(x.name) for x in port.plusPins()])), 'Gnd')
612 minusNetName = next(iter(set([ _getPinNetName(x.name) for x in port.minusPins()])), 'Gnd')
613 portName = _registerPort('_'.join([name, plusNetName, minusNetName]))
614
615 curNetTypes = set.union( set([ netTypesUsedNets.get( _getPinNetName(x.name) ) for x in port.plusPins()]),
616 set([ netTypesUsedNets.get( _getPinNetName(x.name) ) for x in port.minusPins()]) )
617
618 referenceImpedance = str(port.referenceImpedance.evaluate())
619
620 resValue = 1.e+15
621 try:
622 resValue = float(sink.resistance)
623 except:
624 pass
625 sinkLine = "Sink|%(lumped)d|Name|%(name)s|Current|%(current)g|Tolerance|%(tolerance)g|R|%(resValue)g|Z|%(referenceImpedance)s" % vars()
626 sinkLine += "|Port|%(portName)s" % vars()
627 sinkLine += "|End"
628 _appendToStimulusLines(stimulusLines, sinkLine)
629
630 if keepPinNames == True and netTypesUsedNets.get(plusNetName) == 16:
631 displayPinNameList.add(portName)
632
633 componentModelGroupList = []
634 if analysisType==sipiData.DCAnalysisType or sipiData.newSimulationData().componentsTreatedAsPorts:
635 componentModelGroupList = sipiData.getComponentModelGroupList()
636
637 lumpedTypes = {'Series':'SRLC', 'Parallel':'PRLC', 'RLpC':'C', 'R':'R', 'C':'C', 'L':'L'}
638
639 db = empro.VendorPartsDbList.instance()
640 groupNr = 0
641 varNr = 0
642 arrayNr = 0
643
644 includeUpdateableAfterSimulation = (analysisType == sipiData.ACAnalysisType or analysisType == sipiData.PASIAnalysisType)
645 for componentGroup in componentModelGroupList:
646 if includeUpdateableAfterSimulation and not componentGroup.updateableAfterSimulation:
647 continue
648 componentModels = componentGroup.models()
649 componentGroupName = componentGroup.name
650 adsGroupCmpName = _fixADSVarNames(analysisName + '_' + componentGroupName)
651
652 def _checkIfUseHierarchy(analysisType, componentModels):
653 if analysisType in [ sipiData.EMFUAnalysisType,
654 sipiData.EMUDAnalysisType,
655 sipiData.EMSMAnalysisType,
656 sipiData.EMFUPEAnalysisType,
657 sipiData.EMUDPEAnalysisType ]:
658 return False
659 if len(componentModels)<=1:
660 return False
661 return True
662
663 useHierarchy = _checkIfUseHierarchy(analysisType, componentModels)
664
665 varName = _fixADSVarNames(componentGroupName)
666 if len(componentModels)==0:
667 raise Exception("Components in group %s have no model(s)" % componentGroupName)
668 if len(componentModels)==0:
669 defaultModel = None
670 else:
671 defaultModel = componentModels[ componentGroup.defaultModelIndex ]
672 modelPartNbrs = []
673 modelADSSelectItems = []
674 modelPinPortMaps = []
675 modelCmpType = ""
676
677 pinPortMap = componentGroup.pinPortMap()
678 pinNamesForPorts = pinPortMap.getPinNamesForPortNumbers(True)
679 nrOfPorts = pinPortMap.nrPorts()
680
681 isArrayedComponent = componentGroup.arrayedComponent
682
683 capValue = None
684 capDefault = None
685 indValue = None
686 indDefault = None
687 isCustomDBLumpedOnly = False
688 defaultArraySelect = None
689 defaultArrayPinPortMap = None
690 resValue = None
691 resDefault = None
692 topologyValue = None
693 topologyDefault = None
694 idxName = None
695 componentModelType = ""
696
697 coverPinName = empro.geometry.OaLayout.getCoverPinName()
698
699 for model in componentModels:
700 modelPinPortMap='NULL'
701 modelName = model.name
702 modelPinPortDict = {}
703
704 if model.modelType == 1:
705 modelDefinition = model.getPassiveLoad().clone()
706 impedance = modelDefinition.impedance
707 resValue = float(impedance.resistance)
708 indValue = float(impedance.inductance)
709 capValue = float(impedance.capacitance)
710 topologyValue = impedance.elementArrangement
711 lumpedType = lumpedTypes[topologyValue]
712 if capValue==0. and topologyValue=='Series':
713 lumpedType='SRL'
714 elif topologyValue=='Parallel':
715 if indValue == 0. and resValue == 0. and capValue == 0.:
716 raise Exception("Component model %s with Parallel topology has invalid model" % modelName)
717 else:
718 if indValue == 0.:
719 if resValue == 0.:
720 lumpedType ='C'
721 else:
722 lumpedType ='PRC'
723 elif capValue == 0.:
724 if resValue == 0.:
725 lumpedType ='L'
726 else:
727 lumpedType ='PRL'
728
729 adsSelectItem = 'list("deemsipi_place_Lumped","%s","%s",%s,%s,%s)' % ( lumpedType,
730 topologyValue,
731 resValue,
732 indValue,
733 capValue )
734 componentModelType = lumpedType
735 modelPinPortDict = {'P1':'1','P2':'0'}
736 if defaultModel == model:
737 idxName = model.name
738 modelCmpType = componentModelType
739 topologyDefault = topologyValue
740 resDefault = resValue
741 indDefault = indValue
742 capDefault = capValue
743
744 elif model.modelType == 2:
745 if not db.hasPartWithNbr( model.partNbr ):
746 raise( "Component model group %s uses a model partnumber %s not present in the database" % (componentGroupName,model.partNbr) )
747
748 modelName = model.partNbr
749 vp = db.partWithNbr( model.partNbr )
750 adsSelectItem = vp.ADSSelectItem
751 componentModelType = vp.partType
752 modelPinPortMapString = vp.pinPortMap
753 modelPinPortDict = eval(modelPinPortMapString)
754 modelPinPortMapString = modelPinPortMapString.strip('{}').replace(',','),list(')
755 modelPinPortMapString = modelPinPortMapString.replace(':',',')
756 modelPinPortMap = 'list(list(' + modelPinPortMapString + '))'
757
758 useLumpedForModel = useLumped and (model.partNbr in missingInAds)
759 if componentModelType in ('R','L','C'):
760 if defaultModel == model:
761 modelCmpType = componentModelType
762 idxName = model.partNbr
763 topology = vp.topology
764 if topology:
765 topologyDefault = string.replace(topology,'All ','')
766 else:
767 topologyDefault = 'Series'
768 resDefault = vp.RModelValue
769 indDefault = vp.LModelValue
770 capDefault = vp.CModelValue
771 isCustomDBLumpedOnly = ((vp.id >= long("100000")) and vp.modelType == "Lumped" and adsSelectItem == "")
772 else:
773 if defaultModel == model:
774 modelCmpType = componentModelType
775 idxName = model.partNbr
776
777 if adsSelectItem == "" or useLumpedForModel:
778 if vp.modelType == "SNP":
779 numberOfPorts = vp.numberOfPorts
780 snpFile = _getSNPFileLocation(model.partNbr, numberOfPorts)
781 fileType='Touchstone'
782 twoPortFor1Port = None
783 m = re.search(r'\.S(\d+)P$',snpFile,re.I)
784 if m!=None:
785 twoPortFor1Port = ((numberOfPorts==2 or int(m.group(1))==2) and (nrOfPorts==1 or isArrayedComponent))
786 if twoPortFor1Port:
787 adsSelectItem = 'list("deemsipi_initSnPPCell_item", "%s", %d, "%s", "%s")' % ( model.partNbr, 2, fileType, snpFile)
788 else:
789 if isArrayedComponent:
790 adsSelectItem = 'list("deemsipi_initSnPPCell_item", "%s", %d, "%s", "%s")' % ( model.partNbr, 1, fileType, snpFile)
791 else:
792 adsSelectItem = 'list("deemsipi_initSnPPCell_item", "%s", %d, "%s", "%s")' % ( model.partNbr, numberOfPorts, fileType, snpFile )
793 elif vp.modelType == "Lumped" or useLumpedForModel:
794 adsSelectItem = 'list("deemsipi_place_Lumped","%s","%s",%s,%s,%s)' % ( vp.partType,
795 vp.topology,
796 vp.RModelValue,
797 vp.LModelValue,
798 vp.CModelValue )
799 elif model.modelType == 3:
800 componentModelType = 'SNP'
801 modelDefinition = model.getPassiveLoad().clone()
802 impedance = modelDefinition.impedance
803 snpFile = impedance.fileName
804 fileType = 'Citifile'
805 twoPortFor1Port = None
806 m = re.search(r'\.S(\d+)P$',snpFile,re.I)
807 if m!=None:
808 twoPortFor1Port = (int(m.group(1))==2 and (nrOfPorts==1 or isArrayedComponent))
809 fileType='Touchstone'
810 elif len(snpFile)>2 and snpFile[-2]=='ds':
811 fileType='Dataset'
812
813 if defaultModel == model:
814 modelCmpType = componentModelType
815 idxName = model.name
816
817 if twoPortFor1Port:
818 adsSelectItem = 'list("deemsipi_initSnPPCell_item", "%s", %d, "%s", "%s")' % (model.name, 2, fileType, snpFile)
819 else:
820 if isArrayedComponent:
821 adsSelectItem = 'list("deemsipi_initSnPPCell_item", "%s", %d, "%s", "%s")' % (model.name, 1, fileType, snpFile)
822 else:
823 adsSelectItem = 'list("deemsipi_initSnPPCell_item", "%s", %d, "%s", "%s")' % (model.name, nrOfPorts, fileType, snpFile)
824
825 modelPinPortMapList=[]
826 if twoPortFor1Port:
827 modelPinPortDict = {'1':'+1','2':'+2'}
828 modelPinPortMapList.append('list("1","+1")')
829 modelPinPortMapList.append('list("2","+2")')
830 elif isArrayedComponent:
831 modelPinPortDict = {'1':'+1','2':'0'}
832 modelPinPortMapList.append('list("1","+1")')
833 modelPinPortMapList.append('list("2","0")')
834 else:
835 for iPort in range(1,nrOfPorts+1):
836 modelPinPortDict['%(iPort)d'] = '+%(iPort)d'
837 modelPinPortMapList.append('list("%(iPort)d","+%(iPort)d")'%vars())
838 modelPinPortMapList.append('list("Ref","0")')
839 modelPinPortDict['Ref'] = '0'
840 modelPinPortMap='list('+ ','.join(modelPinPortMapList) + ')'
841 elif model.modelType == 4:
842 if isArrayedComponent:
843 raise("Arrayed component is not supported for Library Cell.")
844
845 componentModelType = 'LibCell'
846 componentGroupLibCellName = componentGroup.instances()[0]._libCellName
847 modelLcv = componentGroupLibCellName
848 if model.viewName:
849 modelLcv += ':' + model.viewName
850 firstInstanceName = 'NULL'
851 if componentGroup.instances()[0]:
852 firstInstanceName = componentGroup.instances()[0].instance().name
853 adsSelectItem = 'list("deemsipi_initLibCellView_item", "%s", "%s", "%s", "%s:%s:%s")' % (model.name, modelLcv, firstInstanceName,
854 layoutLibName, layoutCellName, layoutViewName)
855 modelPinPortMapList=[]
856 for pinName, portNum in pinPortMap.getPinNamePortNumberPairs(True, False):
857
858 if portNum == 0:
859 portNumS = '0'
860 elif portNum > 0:
861 portNumS = '+'+str(portNum)
862 else:
863 portNumS = str(portNum)
864 if pinName != coverPinName:
865 modelPinPortMapList.append('list("%(pinName)s","%(portNumS)s")'%vars())
866 modelPinPortMap='list('+ ','.join(modelPinPortMapList) + ')'
867 if defaultModel == model:
868 modelCmpType = componentModelType
869 idxName = model.name
870
871 if isArrayedComponent and len(modelPinPortDict)==2 and nrOfPorts>1 and model.modelType != 4 :
872 arrayNr += 1
873 adsArrayCmpName = _fixADSVarNames( analysisName + '_array%d' % arrayNr + '_' + modelName )
874 modelName = model.name
875 ppmPinNamesPortNumbers = pinPortMap.getPinNamePortNumberPairs(False,False)
876 ppmPinNamesPortNumString = 'list(' + ','.join( ['list("%s",%d)'% x for x in ppmPinNamesPortNumbers if x[0] != coverPinName] ) +')'
877 arrayLine = 'ArrayCmp|%(arrayNr)d|Name|%(adsArrayCmpName)s' % vars()
878 arrayLine += '|SelectItem|%(adsSelectItem)s' % vars()
879 arrayLine += '|NrOfPorts|%(nrOfPorts)d|PinToPort|%(ppmPinNamesPortNumString)s' % vars()
880 arrayLine += '|End'
881 _appendToStimulusLines(stimulusLines, arrayLine)
882
883 modelPinPortMap = 'list(' + ','.join(['list("%s","%+d")'% (pName,pNum) for pName,pNum in pinPortMap.getPinNamePortNumberPairs(True,True) if pName!=coverPinName]) +')'
884 if model.modelType==1:
885 cResValue, cIndValue, cCapValue = _setNoneToZeroRLCValues( resValue, indValue, capValue )
886 adsSelectItem = 'list("deemsipi_Arrayed_init_item", "%(adsArrayCmpName)s", "Lumped", %(cResValue)s, %(cIndValue)s, %(cCapValue)s )' % vars()
887 else:
888 adsSelectItem = 'list("deemsipi_Arrayed_init_item", "%(adsArrayCmpName)s", "Other", NULL, NULL, NULL )' % vars()
889
890 if defaultModel == model:
891 idxName = modelName
892 if componentModelType in ('R','L','C','SRL','SRLC','PRLC','PRL','PRC','PLC') :
893 if model.modelType==2:
894 arrayNr += 1
895 adsArrayCmpName = _fixADSVarNames( analysisName + '_array%d_tunable' % arrayNr + '_' + modelName )
896 lumpedType = lumpedTypes[topologyDefault]
897 arrayLine = 'ArrayCmp|%(arrayNr)d|Name|%(adsArrayCmpName)s' % vars()
898 arrayLine += '|SelectItem|list("deemsipi_place_Lumped","%(lumpedType)s","%(topologyDefault)s",%(resDefault)s,%(indDefault)s,%(capDefault)s)' % vars()
899 arrayLine += '|NrOfPorts|%(nrOfPorts)d|PinToPort|%(ppmPinNamesPortNumString)s' % vars()
900 arrayLine += '|End'
901 _appendToStimulusLines(stimulusLines, arrayLine)
902
903 defaultArrayPinPortMap = modelPinPortMap
904 if model.modelType==2 or model.modelType==1:
905 defaultArraySelectItem = 'list("deemsipi_Arrayed_init_item", "%(adsArrayCmpName)s", "Tunable", "var:R", "var:L", "var:C" )' % vars()
906
907 modelPartNbrs.append(modelName)
908 modelADSSelectItems.append(adsSelectItem)
909 modelPinPortMaps.append(modelPinPortMap)
910
911 if modelCmpType=="":
912 modelCmpType = componentModelType
913
914 if useHierarchy:
915 if modelCmpType in ('R','L','C','SRL','SRLC','PRLC','PRL','PRC','PLC'):
916 cResValue, cIndValue, cCapValue = _setNoneToZeroRLCValues( resDefault, indDefault, capDefault )
917 modelPartNbrs = ['Tunable Lumped'] + modelPartNbrs
918 if isArrayedComponent:
919 modelADSSelectItems.insert( 0, defaultArraySelectItem )
920 modelPinPortMaps.insert( 0, defaultArrayPinPortMap)
921 else:
922 modelPinPortMaps.insert( 0,'NULL')
923 modelADSSelectItems.insert( 0, 'list("deemsipi_place_Lumped","%(modelCmpType)s","%(topologyDefault)s", "var:R", "var:L", "var:C" )' % vars() )
924 modelPartNbrs = ['Open'] + modelPartNbrs
925 modelADSSelectItems.insert(0, 'NULL')
926 modelPinPortMaps.insert(0,'NULL')
927 partIdx = modelPartNbrs.index(idxName)
928 groupNr += 1
929 partNbrs = '","'.join(modelPartNbrs)
930 lastPartNbrsIdx = len(modelPartNbrs)-1
931 selectItems = ",".join(modelADSSelectItems)
932 pinPortMaps = ",".join(modelPinPortMaps)
933
934 groupLine = 'GroupCmp|%(groupNr)d|Name|%(adsGroupCmpName)s' % vars()
935 groupLine += '|Type|%(modelCmpType)s|PartNumbers|list("%(partNbrs)s")|SelectItems|list(%(selectItems)s)' % vars()
936 groupLine += '|Ports|%(nrOfPorts)d' % vars()
937 if modelCmpType not in ('R','L','C','SRL','SRLC','PRLC','PRL','PRC','PLC') or isArrayedComponent:
938 groupLine += '|PinPortMaps|list(%(pinPortMaps)s)' % vars()
939 groupLine += '|End'
940 _appendToStimulusLines(stimulusLines, groupLine)
941
942 varNr += 1
943 varLine = 'Var|%(varNr)d' % vars()
944 varLine += '|Name|%(varName)s_PartIdx%(varNr)d|Value|%(partIdx)d' % vars()
945 varLine += '|Name|%(varName)s_PartLimIdx%(varNr)d|Value|var:int(limit_warn(%(varName)s_PartIdx%(varNr)d,0,%(lastPartNbrsIdx)d,%(partIdx)d,"%(varName)s_PartIdx%(varNr)d"))' % vars()
946 varLine += '|Name|%(varName)s_PartNumber%(varNr)d|Value|var:%(adsGroupCmpName)s[%(varName)s_PartLimIdx%(varNr)d+1]' % vars()
947 if modelCmpType in ('R','L','C','SRL','SRLC','PRLC','PRL','PRC','PLC'):
948 cResValue, cIndValue, cCapValue = _setNoneToZeroRLCValues( resDefault, indDefault, capDefault )
949 varLine += '|Name|%(varName)s_R%(varNr)d|Value|%(cResValue)s' % vars()
950 varLine += '|Name|%(varName)s_L%(varNr)d|Value|%(cIndValue)s' % vars()
951 varLine += '|Name|%(varName)s_C%(varNr)d|Value|%(cCapValue)s' % vars()
952 varLine += '|End'
953 _appendToStimulusLines(stimulusLines, varLine)
954 else:
955 if defaultModel == None:
956 pass
957 elif defaultModel.modelType == 1:
958 varNr += 1
959 varLine = 'Var|%(varNr)d' % vars()
960 varLine += '|Name|%(varName)s_R%(varNr)d|Value|%(resValue)g' % vars()
961 varLine += '|Name|%(varName)s_L%(varNr)d|Value|%(indValue)g' % vars()
962 varLine += '|Name|%(varName)s_C%(varNr)d|Value|%(capValue)g' % vars()
963 varLine += '|End'
964 _appendToStimulusLines(stimulusLines, varLine)
965 elif ( len(modelPartNbrs)==1 ) and ( ( useLumped and modelPartNbrs[0] in missingInAds ) or isCustomDBLumpedOnly ):
966 cResValue, cIndValue, cCapValue = _setNoneToZeroRLCValues( resDefault, indDefault, capDefault )
967 varNr += 1
968 varLine = 'Var|%(varNr)d' % vars()
969 varLine += '|Name|%(varName)s_R%(varNr)d|Value|%(cResValue)g' % vars()
970 varLine += '|Name|%(varName)s_L%(varNr)d|Value|%(cIndValue)g' % vars()
971 varLine += '|Name|%(varName)s_C%(varNr)d|Value|%(cCapValue)g' % vars()
972 varLine += '|End'
973 _appendToStimulusLines(stimulusLines, varLine)
974
975
976 coverPinName = empro.geometry.OaLayout.getCoverPinName()
977 for componentInstance in componentGroup.instances():
978 instance = componentInstance.instance()
979 lumped +=1
980 name = instance.name
981 portsFrag = ""
982
983 refNeg = ()
984 portI=0
985 for portNum,port in pinNamesForPorts:
986 if portNum > nrOfPorts:
987 break
988 if portNum==0 and port[0]!=coverPinName:
989
990 refNeg = port[0]
991 continue
992 plusPinsPort = port[0]
993 minPinsPort = port[1]
994 if minPinsPort == () or minPinsPort == (coverPinName,):
995 minPinsPort = refNeg
996 plusNames = name + '_' + '_'.join(plusPinsPort).replace('.', '_').replace(',', '_')
997 minusNames = name + '_' + '_'.join(minPinsPort).replace('.', '_').replace(',', '_')
998 plusNetName = next(iter(set([ _getPinNetName(name + '.' + pinName) for pinName in plusPinsPort])), 'Gnd')
999 minusNetName = next(iter(set([ _getPinNetName(name + '.' + pinName) for pinName in minPinsPort])), 'Gnd')
1000 portName = _registerPort('_'.join([plusNames, plusNetName, minusNames, minusNetName]))
1001 portI += 1
1002 portsFrag += "|Port%(portI)d|%(portName)s" % vars()
1003
1004 if keepPinNames == True and netTypesUsedNets.get(plusNetName) == 16:
1005 displayPinNameList.add(portName)
1006
1007 if keepPinNames == True:
1008 continue
1009
1010
1011 compLine = ""
1012 fixedInstName = _fixADSInstNames(name)
1013 if useHierarchy:
1014 partIdxString = '"var:%(varName)s_PartLimIdx%(varNr)d"' % vars()
1015 if modelCmpType in ('R','L','C','SRL','SRLC','PRLC','PRL','PRC','PLC'):
1016 resVarString = '"var:%(varName)s_R%(varNr)d"' % vars()
1017 capVarString = '"var:%(varName)s_C%(varNr)d"' % vars()
1018 indVarString = '"var:%(varName)s_L%(varNr)d"' % vars()
1019 adsSelect = 'list("deemsipi_Indexed_init_item","%(adsGroupCmpName)s","Simple",%(resVarString)s,%(indVarString)s,%(capVarString)s,%(partIdxString)s)' % vars()
1020 else:
1021 adsSelect = 'list("deemsipi_Indexed_init_item","%(adsGroupCmpName)s","Other",NULL,NULL,NULL,%(partIdxString)s)' % vars()
1022 compLine += "Component|%(lumped)d|Name|%(fixedInstName)s" % vars()
1023 compLine += "|Type|ModelDB|SelectItem|%(adsSelect)s" % vars()
1024 else:
1025 if defaultModel.modelType == 4:
1026 origName = _encodeOriginalInstname(name)
1027 if defaultModel.viewName:
1028 compLine += 'Component|%(lumped)d|Name|%(fixedInstName)s|Type|LibCell' % vars() +'|OriginalInstName|'+origName+'|LibCellView|'+componentInstance._libCellName+":"+defaultModel.viewName
1029 else:
1030 compLine += 'Component|%(lumped)d|Name|%(fixedInstName)s|Type|LibCell' % vars() +'|OriginalInstName|'+origName+'|LibCellView|'+componentInstance._libCellName
1031 modelPinPortMap = modelPinPortMaps[0]
1032 compLine += "|Ports|%(nrOfPorts)d|PinPortMap|%(modelPinPortMap)s" % vars()
1033 elif defaultModel.modelType == 1 and (not isArrayedComponent or nrOfPorts<=1):
1034 resVarString = 'var:%(varName)s_R%(varNr)d' % vars()
1035 capVarString = 'var:%(varName)s_C%(varNr)d' % vars()
1036 indVarString = 'var:%(varName)s_L%(varNr)d' % vars()
1037 compLine += "Component|%(lumped)d|Name|%(fixedInstName)s" % vars()
1038 compLine += "|Type|Lumped|Arrangement|%(topologyValue)s:%(modelCmpType)s|R|%(resVarString)s|L|%(indVarString)s|C|%(capVarString)s" % vars()
1039 elif ((useLumped and modelPartNbrs[0] in missingInAds) or isCustomDBLumpedOnly) and len(modelPartNbrs)==1 and (not isArrayedComponent or nrOfPorts<=1):
1040 resVarString = 'var:%(varName)s_R%(varNr)d' % vars()
1041 capVarString = 'var:%(varName)s_C%(varNr)d' % vars()
1042 indVarString = 'var:%(varName)s_L%(varNr)d' % vars()
1043 compLine += "Component|%(lumped)d|Name|%(fixedInstName)s" % vars()
1044 compLine += "|Type|Lumped|Arrangement|%(topologyDefault)s:%(modelCmpType)s|R|%(resVarString)s|L|%(indVarString)s|C|%(capVarString)s" % vars()
1045 else:
1046 adsSelect = modelADSSelectItems[0]
1047 modelPinPortMap = modelPinPortMaps[0]
1048 compLine += "Component|%(lumped)d|Name|%(fixedInstName)s" % vars()
1049 compLine += "|Type|ModelDB|SelectItem|%(adsSelect)s" % vars()
1050 compLine += "|Ports|%(nrOfPorts)d|PinPortMap|%(modelPinPortMap)s" % vars()
1051 compLine += portsFrag
1052 if componentInstance.enabled:
1053 compLine += "|Enabled|TRUE"
1054 else:
1055 compLine += "|Enabled|FALSE"
1056 compLine += "|End"
1057 _appendToStimulusLines(stimulusLines, compLine)
1058
1059 if keepPinNames == True:
1060 return list(displayPinNameList)
1061
1062 if lumped==0:
1063 raise Exception(_immediately_)
1064
1065 if simulationModel==_noSimulationModel and not suppressDialog:
1066 if not ioPortList:
1067 empro.gui.MessageBox.warning("Generate Schematic", "Model data file not found and no port is created, generating schematic without a model file and no port.\n\nTip: To generate model data, run EM simulation first.", 0, 0)
1068 else:
1069 empro.gui.MessageBox.warning("Generate Schematic", "Model data file not found, generating schematic without a model file.\n\nTip: To generate model data, run EM simulation first.", 0, 0)
1070
1071 if destinationCellName:
1072 adsModelName = _fixADSSimulationNames(destinationCellName)
1073 else:
1074 adsModelName = _fixADSSimulationNames(analysisName)
1075
1076 resultsFileType = 'CitiFile'
1077 resultsLocationType = 'rDir'
1078 resultsLocationIdentifier = 'data'
1079 if simulationModel != _noSimulationModel:
1080 originalCtiOrSioFile = simulationModel
1081 fileExt = os.path.splitext(simulationModel)[1]
1082 if fileExt == '.sio':
1083 resultsFileType = 'SMatrixIO'
1084 simulationModel = _fixADSSimulationNames( cellName + '_' + analysisName ) + fileExt
1085 if parentPlatformIsVirtuoso:
1086
1087
1088 resultsLocationType = 'relDir'
1089 resultsLocationIdentifier = 'data'
1090 dataLocationPath = os.path.join(workingDirectory, resultsLocationIdentifier)
1091 if not os.path.isdir(dataLocationPath):
1092 if not os.path.exists(dataLocationPath):
1093 os.mkdir(dataLocationPath)
1094 else:
1095 raise Exception(dataLocationPath + " is not a directory")
1096 newCtiOrSioFile = os.path.join( dataLocationPath, simulationModel )
1097 try:
1098 copyFile(originalCtiOrSioFile, newCtiOrSioFile)
1099 except Exception as e:
1100 empro.gui.MessageBox.warning("Generate Schematic", "Copy results file failed: %s.\nGenerating schematic without a model file." % e, 0, 0)
1101 simulationModel = _noSimulationModel
1102 pass
1103
1104 if portsReduction.isApplicable:
1105 modelPortList = [sortedPortNames[i] for i in portsReduction.emModelReduction]
1106 else:
1107 modelPortList = sortedPortNames
1108 modelPorts = len(modelPortList)
1109 if modelPorts > 0:
1110 modelLine = "Model|%(modelPorts)d|Name|%(adsModelName)s|FileName|%(simulationModel)s|FileType|%(resultsFileType)s|LocationName|%(resultsLocationIdentifier)s|LocationType|%(resultsLocationType)s" % vars()
1111 modelLine += "|Ports|%(modelPorts)d" % vars()
1112 portI = 0
1113 for portName in modelPortList:
1114 portI += 1
1115 modelLine += "|Port%(portI)d|%(portName)s" % vars()
1116 modelLine += "|End"
1117 _appendToStimulusLines(stimulusLines, modelLine)
1118
1119 sipiSimData = sipiData.newSimulationData()
1120 startFreq = None
1121 endFreq = None
1122 for fpi in range(sipiSimData.femFrequencyPlanList().size()):
1123 fp = sipiSimData.femFrequencyPlanList().at(fpi)
1124 if not fp.enabled:
1125 continue
1126 beginFreq = float(fp.startFrequency)
1127 stopFreq = float(fp.stopFrequency)
1128 if not startFreq or startFreq > beginFreq:
1129 startFreq = beginFreq
1130 if not endFreq or endFreq < stopFreq:
1131 endFreq = stopFreq
1132
1133 pl = empro.activeProject.parameters()
1134 if not startFreq:
1135 startFreq = pl.formula("minFreq")
1136 else:
1137 startFreq = _freqWithUnits(startFreq)
1138 if not endFreq:
1139 endFreq = pl.formula("maxFreq")
1140 else:
1141 endFreq = _freqWithUnits(endFreq)
1142
1143 if analysisType != sipiData.PASIAnalysisType:
1144 stimulusLines.append('AnalysisSettings|StartFreq|%(startFreq)s|EndFreq|%(endFreq)s|Dec|50|End' % vars())
1145 else:
1146 stimulusLines.append('AnalysisSettings|StartFreq|%(startFreq)s|EndFreq|%(endFreq)s|Lin|250|End' % vars())
1147
1148 stimulusDesc = header + "\n".join(stimulusLines)
1149 if empro.core.ApplicationInfo.personality() == "rfpro":
1150 stimulusFileName = os.path.join(workingDirectory, "_rfproSchFile.txt")
1151 elif empro.core.ApplicationInfo.personality() == "pepro":
1152 stimulusFileName = os.path.join(workingDirectory, "_peproSchFile.txt")
1153 else:
1154 stimulusFileName = os.path.join(workingDirectory, "sipiSchFile.txt")
1155 with open(stimulusFileName,"w") as stimulusFile:
1156 stimulusFile.write(stimulusDesc)
1157 return stimulusFileName
1158
1159
1170
1172
1173 if not empro.core.CommunicationWithParent.wasActivated():
1174 return ""
1175
1176 isBusy = False
1177 try:
1178 isBusy = empro.toolkit.rpc.callIsShowingModalOrPopupWidget()
1179 except:
1180 isBusy = True
1181 if isBusy:
1182 parentTag = empro.core.CommunicationWithParent.communicationParentTag()
1183 if parentTag.startswith("Un"):
1184 parentTag = "Parent platform"
1185 message = parentTag + " is currently busy. Please close all active (modal) dialogs in this tool and retry."
1186 raise Exception(message)
1187
1188 fromParent = 0
1189
1190
1191
1192
1193
1194 try:
1195 while True:
1196 result = empro.toolkit.rpc.callParent('generateSchematic', [stimulusFileName, libName, cellName, fromParent, overWrite, whereToSave])
1197 if not result[0]:
1198 raise Exception('Schematic generation problem: \n' + result[1])
1199 elif result[0]==-2:
1200
1201 ret = empro.gui.MessageBox.question(empro.gui.activeProjectView(), "Schematic Generation", result[1], empro.gui.Yes | empro.gui.No | empro.gui.Cancel, empro.gui.Yes, ["Create View in Existing Cell", "Create new Cell/View", "Cancel"] )
1202 if ret == empro.gui.Yes:
1203 whereToSave=2
1204 elif ret == empro.gui.No:
1205 whereToSave=0
1206 else:
1207
1208 return ""
1209 elif result[0]==-1:
1210
1211 if empro.gui.MessageBox.question("Schematics already exist", result[1], empro.gui.Yes | empro.gui.No, empro.gui.No ) == empro.gui.Yes:
1212 overWrite = 1
1213 else:
1214
1215 return ""
1216 elif result[0]>0:
1217 inFront = empro.toolkit.rpc.callParent('showCellview', [ result[1], "schematic" ])
1218
1219 return result[1]
1220 else:
1221 raise Exception('Schematic generation problem: \n')
1222 except:
1223 raise
1224
1225
1227
1228 if not empro.core.CommunicationWithParent.wasActivated():
1229 return ""
1230
1231 isAdsBusy = False
1232 try:
1233 isAdsBusy = empro.toolkit.rpc.callIsShowingModalOrPopupWidget()
1234 except:
1235 isAdsBusy = True
1236 if isAdsBusy:
1237 raise Exception("ADS Schematic or Layout are currently busy. Please close all active (modal) dialogs in these tools and retry.")
1238
1239 fromADS = 0
1240
1241
1242
1243
1244
1245
1246 try:
1247 while True:
1248 result = empro.toolkit.rpc.callAEL('deemsipi_generateSchematic', [stimulusFileName, libName, cellName, fromADS, overWrite, whereToSave])
1249 if not result[0]:
1250 raise Exception('Schematic generation problem: \n' + result[1])
1251 elif result[0]==-2:
1252
1253 ret = empro.gui.MessageBox.question(empro.gui.activeProjectView(), "Schematic Generation", result[1], empro.gui.Yes | empro.gui.No | empro.gui.Cancel, empro.gui.Yes, ["Create View in Existing Cell", "Create new Cell/View", "Cancel"] )
1254 if ret == empro.gui.Yes:
1255 whereToSave=2
1256 elif ret == empro.gui.No:
1257 whereToSave=0
1258 else:
1259
1260 return ""
1261 elif result[0]==-1:
1262
1263 if empro.gui.MessageBox.question("Schematics already exist", result[1], empro.gui.Yes | empro.gui.No, empro.gui.No ) == empro.gui.Yes:
1264 overWrite = 1
1265 else:
1266
1267 return ""
1268 elif result[0]>0:
1269 empro.core.CommunicationWithParent.rpc().call("<call><method>bringToFront</method></call>")
1270 return result[1]
1271 else:
1272 raise Exception('Schematic generation problem: \n')
1273 except:
1274 empro.core.CommunicationWithParent.rpc().stopDialog()
1275 raise
1276
1277
1278
1279 -def generateSchematic(workingDirectory, sipiData, libName, cellName, schematicType=1, overwrite=0, noErrorMessageBox=False, whereToSave=1):
1280 missingInAds = []
1281 useLumped = False
1282 overwrite = overwrite
1283 try:
1284 if not noErrorMessageBox:
1285 missingListInfo = findMissingADSComponentsFromModelDB(sipiData, libName, cellName)
1286 if missingListInfo != None and missingListInfo[2] != None and len(missingListInfo[2])>0:
1287 missingText = missingListInfo[1]
1288 missingList = missingListInfo[2]
1289 missingTypesList = []
1290 missesOnlyRLC = True
1291 if len(missingListInfo)>=4:
1292 missingTypesList = missingListInfo[3]
1293 missingTypeSet = set(missingTypesList)
1294 rlcTypesSet = ['R','L','C']
1295 if len(missingTypeSet.difference(rlcTypesSet))>0:
1296 missesOnlyRLC=False
1297 missingInAds = [part for part, partType in zip(missingList, missingTypesList) if partType in rlcTypesSet]
1298 else:
1299 missingInAds=missingList
1300
1301 msg = ""
1302 if len(missingList)==1:
1303 msg += "The ADS component for part number: "
1304 msg += missingList[0]
1305 msg += " is not available for placement in the schematic."
1306 else:
1307 msg += "The ADS components for part numbers: "
1308 if len(missingList)<7:
1309 msg += ", ".join(missingList)
1310 else:
1311 msg += ", ".join(missingList[0:5])
1312 msg += ",..."
1313 msg += " are not available for placement in the schematic."
1314 if missesOnlyRLC:
1315 msg += "\n\nDo you want to simulate with an approximate lumped setup for R, L and Cs, check the incomplete design or cancel schematic generation and fix your ADS workspace setup first?\n"
1316 else:
1317 msg += "\n\nDo you want to check the incomplete design with or without approximate lumped models or cancel schematic generation and fix your ADS workspace setup first.\n"
1318 msg += "\nSee the details for further information."
1319
1320 messageBox = empro.gui.MessageBox()
1321 messageBox.title = "Use SIPro/PIPro's Lumped Approximation for Missing ADS R, L or C Components"
1322 messageBox.icon = empro.gui.MessageBox.Question
1323 messageBox.text = msg
1324 messageBox.detailedText = missingText
1325 if missesOnlyRLC:
1326 messageBoxLumpedText = "Use lumped DB values as fall-back"
1327 else:
1328 messageBoxLumpedText = "Incomplete with lumped DB values as fall-back"
1329 messageButtonLumped = messageBox.addButton(messageBoxLumpedText, empro.gui.MessageBox.YesRole)
1330 messageButtonIncomplete = messageBox.addButton("Incomplete without fall-back", empro.gui.MessageBox.NoRole)
1331 messageBox.standardButtons=empro.gui.Cancel
1332 messageBox.setDefaultButton(empro.gui.Cancel)
1333
1334 ret=messageBox.execute()
1335 if ret == empro.gui.Cancel:
1336 return
1337 elif messageBox.buttonRole(messageBox.clickedButton()) == empro.gui.MessageBox.YesRole:
1338 useLumped = True
1339 elif messageBox.buttonRole(messageBox.clickedButton()) == empro.gui.MessageBox.NoRole:
1340 missingInAds = []
1341 useLumped = False
1342 else:
1343 return
1344 else:
1345 overwrite = 1
1346
1347 schematicFileName = generateSchematicFile( workingDirectory, sipiData, libName, cellName,
1348 schematicType=schematicType,
1349 useLumped = useLumped,
1350 missingInAds = missingInAds,
1351 suppressDialog=noErrorMessageBox)
1352 lcvName = requestToCreateSchematic( schematicFileName, libName, cellName, overWrite=overwrite, whereToSave=whereToSave )
1353 return lcvName
1354 except:
1355 raise
1356
1357
1359
1360 if not empro.core.CommunicationWithParent.wasActivated():
1361 return ""
1362
1363 isAdsBusy = False
1364 try:
1365 isAdsBusy = empro.toolkit.rpc.callIsShowingModalOrPopupWidget()
1366 except:
1367 isAdsBusy = True
1368 if isAdsBusy:
1369 raise Exception("ADS Schematic or Layout are currently busy. Please close all active (modal) dialogs in these tools and retry.")
1370
1371 fromADS = 0
1372 try:
1373 result = empro.toolkit.rpc.callAEL('deemsipi_simulateSchematic', [lcvName, overWrite, closeDesign, fromADS])
1374 if not result[0]:
1375 raise Exception('Schematic simulation problem: \n' + result[1])
1376 elif result[0]==-1:
1377
1378 if empro.gui.MessageBox.question("Dataset already exists", result[1], empro.gui.Yes | empro.gui.No, empro.gui.No ) == empro.gui.Yes:
1379 overWrite = 1
1380 result = empro.toolkit.rpc.callAEL('deemsipi_simulateSchematic', [lcvName, overWrite, closeDesign, fromADS])
1381 if not result[0]:
1382 raise Exception('Schematic simulation problem: \n' + result[1])
1383 if result[0]>0:
1384 return result[1]
1385 except:
1386 raise
1387
1388 -def requestAdsRLCData( partNbr, typeRLC, adsSelectItem, nominalVal, libName="MyLibrary_lib", cellName="rlcMeasure", startFreq="10 kHz", stopFreq="100 GHz", pointsPerDec="50" ):
1389 import datetime
1390 import os
1391 import string
1392
1393 if not empro.core.CommunicationWithParent.wasActivated():
1394 raise Exception("ADS is not acting as parent application.")
1395
1396 isAdsBusy = False
1397 try:
1398 isAdsBusy = empro.toolkit.rpc.callIsShowingModalOrPopupWidget()
1399 except:
1400 isAdsBusy = True
1401 if isAdsBusy:
1402 raise Exception("ADS Schematic or Layout are currently busy. Please close all active (modal) dialogs in these tools and retry.")
1403
1404 try:
1405 result = empro.toolkit.rpc.callAEL('deemsipi_measureRLCData', [libName, cellName, partNbr, typeRLC, adsSelectItem, "", startFreq, stopFreq, pointsPerDec, nominalVal])
1406 if not result[0]:
1407 raise Exception('RLC extract problem: \n' + result[1])
1408 except:
1409 raise
1410 return result[2]
1411
1412 -def requestADSForSnPData( partNbr, libName="MyLibrary_lib", startFreq="10 kHz", stopFreq="100 GHz", pointsPerDec="50" ):
1413
1414 vendorPartsDb = empro.VendorPartsDbList.instance()
1415
1416 if not vendorPartsDb.hasPartWithNbr(partNbr):
1417 raise( "Partnumber %s missing in vendor database" % partNbr )
1418
1419 vp = vendorPartsDb.partWithNbr('GA242QR7E2471MW01')
1420 adsSelectItem = vp.ADSSelectItem
1421 modelPinPortMapString = vp.pinPortMap
1422 modelPinPortMapString = modelPinPortMapString.strip('{}').replace(',','),list(')
1423 modelPinPortMapString = modelPinPortMapString.replace(':',',')
1424 pinPortMap = 'list(list(' + modelPinPortMapString + '))'
1425
1426 if not empro.core.CommunicationWithParent.wasActivated():
1427 raise Exception("ADS is not acting as parent application.")
1428
1429 isAdsBusy = False
1430 try:
1431 isAdsBusy = empro.toolkit.rpc.callIsShowingModalOrPopupWidget()
1432 except:
1433 isAdsBusy = True
1434 if isAdsBusy:
1435 raise Exception("ADS Schematic or Layout are currently busy. Please close all active (modal) dialogs in these tools and retry.")
1436
1437 try:
1438 result = empro.toolkit.rpc.callAEL('deemsipi_measureSnpForPartNbr', [libName, partNbr, adsSelectItem, pinPortMap, startFreq, stopFreq, pointsPerDec])
1439 if not result[0]:
1440 raise Exception('SNP extract problem: \n' + result[1])
1441 except:
1442 raise
1443 return result[2]
1444
1445
1447 analysisList = ["","PI-DC","PI-AC","SI","PPR","THERMAL","ELECTRO_THERMAL", "FULL EM EXTRACTION"]
1448 analysisString = analysisList[setup.analysisType]
1449 if whereToSave ==2:
1450 viewName="schematic"+"_"+_fixSetupName(setup.name)
1451 return origCellName, viewName
1452 else:
1453 cellName=origCellName+"_"+analysisString
1454 if schematicType == 1:
1455 cellName=cellName+"_Ckt"
1456 cellName=cellName+"_"+_fixSetupName(setup.name)
1457 viewName="schematic"
1458 return cellName, viewName
1459
1460
1461
1463 isAdsBusy = False
1464 try:
1465 isAdsBusy = empro.toolkit.rpc.callIsShowingModalOrPopupWidget()
1466 except:
1467 isAdsBusy = True
1468 if isAdsBusy:
1469 raise Exception("ADS Schematic or Layout are currently busy. Please close all active (modal) dialogs in these tools and retry.")
1470 try:
1471 cellName, viewName = getDefaultCellViewName(origLibName, origCellName, setup, schematicType, whereToSave)
1472 if whereToSave == 2:
1473 viewNameTo= viewName + "_expected"
1474 result = empro.toolkit.rpc.callAEL('sipitest_renameViewName', [origLibName, cellName, viewName, viewNameTo])
1475 if not result[0]:
1476 raise Exception('SNP extract problem: \n' + result[1])
1477 else:
1478 cellNameTo = cellName + "_expected"
1479 result = empro.toolkit.rpc.callAEL('sipitest_renameDesignName', [origLibName, cellName, cellNameTo])
1480 if not result[0]:
1481 raise Exception('SNP extract problem: \n' + result[1])
1482 except:
1483 raise
1484 return result[2]
1485
1486
1488 isAdsBusy = False
1489 try:
1490 isAdsBusy = empro.toolkit.rpc.callIsShowingModalOrPopupWidget()
1491 except:
1492 isAdsBusy = True
1493 if isAdsBusy:
1494 raise Exception("ADS Schematic or Layout are currently busy. Please close all active (modal) dialogs in these tools and retry.")
1495 try:
1496 result = empro.toolkit.rpc.callAEL('sipitest_compareSchematic', [referenceDesignName, testDesignName])
1497 except:
1498 raise
1499 return result
1500
1503
1505 - def __init__(self, adsInstanceList, vendorDb=None):
1506
1507 self.dialog = SimpleDialog(Cancel+Ok)
1508 self.dialog.title = "Add ADS Schematic Instances as Parts to Component Database"
1509 self.dialog.resize(1400, 600)
1510 self.dialog.onClicked = self.onClicked
1511 w = empro.gui.Widget()
1512 w.layout = empro.gui.VBoxLayout()
1513 self.designName = ':'.join(adsInstanceList[0:3])
1514 self.label = Label( "Select instance entrie(s) from: " + self.designName)
1515 self.dialog.layout.add(self.label)
1516 self.instanceTable = TableView(w)
1517 self.instanceTable.objectName = "schem_instances"
1518 self.instanceTable.postEdit = self.afterEditCell
1519
1520 w.layout.addWidget(self.instanceTable)
1521 columns = [ '', "Vendor", "Part Number", "Instance(s)", "Instance Component Name", "Number of Ports", "Number of Pins", "Pin-Port Mapping","Use Instance"]
1522
1523 self.instanceTable.headers = []
1524 self.vendorDb = vendorDb
1525 self.adsLibName = adsInstanceList[0]
1526 self.adsCellName = adsInstanceList[1]
1527 self.adsViewName = adsInstanceList[2]
1528 self.adsInstances = adsInstanceList[3]
1529 for index, adsInstance in enumerate(adsInstanceList[3]):
1530 instD = dict(zip(['instLibName', 'instCellName', 'instName', 'nrOfPins', 'nrOfPorts', 'pinPortMapString'],adsInstance))
1531 partNbr = _fixADSVarNames(self.adsCellName + '_' + instD['instName'][0])
1532 cmpName = instD['instLibName'] + ':' + instD['instCellName']
1533 instNames = instD['instName'][0]
1534 nrOfInstances = len(instD['instName'])
1535 if(nrOfInstances<=5):
1536 instNames = ','.join(instD['instName'])
1537 else:
1538 instNames = ','.join(instD['instName'][0:4]) + ',...,' + instD['instName'][-1]
1539 row = [ False, self.adsLibName, partNbr, instNames, cmpName, instD['nrOfPorts'], instD['nrOfPins'], instD['pinPortMapString'], instD['instName'][0] ]
1540 self.instanceTable.setRow(index,row)
1541 self.instanceTable.setTooltip(index,0,'Enable checkbox to add entry to database')
1542 self.instanceTable.setTooltip(index,1,'User specified vendor value\n default = <ADS library>')
1543 self.instanceTable.setTooltip(index,2,'User specified unique Part Number\nIgnored when Part Number already exists\n default = <ADS schematic cell name>_<first instance from list>')
1544 self.instanceTable.setTooltip(index,3,'Abbreviated list of all instances of the same component with identical parameter values in selected ADS design')
1545 self.instanceTable.setTooltip(index,4,'Instance component name in ADS')
1546 self.instanceTable.setTooltip(index,5,'User specified numbers of ports (must match Pin-Port Mapping)')
1547 self.instanceTable.setTooltip(index,6,'Numbers of pins of the ADS component')
1548 self.instanceTable.setTooltip(index,7, \
1549 """User specified Pin-Port Mapping between {} brackets
1550 Syntax:
1551 \t"<pin name>":"number" pin is part of the plus of port indicated by number
1552 \t"<pin name>":"-number" pin is part of the minus of port indicated by number
1553 \t"<pin name>":"0" pin is part the single common reference for all the ports
1554 \tport numbers go from 1 to Number of Ports value
1555 \tno "-number" entries can occur when common reference "0" is in use
1556 \tunused pins can be omitted from pin-port mapping
1557 \tValue in "Number of Ports" column must match the port count in this mapping
1558 Default = {"<pin 1>":"1",..."<pin N-1>":"N-1","<pin N>":"0"}""")
1559 self.instanceTable.setEditableColumns([1, 2, 5, 7])
1560 self.instanceTable.setUserCheckableColumns([0])
1561 self.instanceTable.hideColumn(8)
1562 self.instanceTable.resizeColumnsToContents()
1563 self.dialog.layout.add(self.instanceTable)
1564 self.instanceTable.headers = columns
1565 self.instanceTable.resizeColumnsToContents()
1566 self.dialog.windowFlags = empro.gui.WF_Window
1567 self.dialog.windowFlags &= ~empro.gui.WF_WindowStaysOnTopHint
1568
1570 self.dialog.show(False)
1571
1573 db = self.vendorDb
1574 if db==None:
1575 db = empro.VendorPartsDbList.instance()
1576 skipped = []
1577 added = []
1578 pinPortMapError = []
1579 for i in range( self.instanceTable.rowCount() ):
1580 row = self.instanceTable.row(i)
1581 if not row[0]:
1582 continue
1583 partNbr = row[2]
1584 if db.hasPartWithNbr(partNbr):
1585 skipped.append(partNbr)
1586 continue
1587 vendor = row[1]
1588 nrOfPorts = row[5]
1589 nrOfPins = row[6]
1590 pinPortMap = row[7]
1591 expectedNrOfPorts = -1
1592 try:
1593 expectedNrOfPorts = self.validPinPortMap(i)
1594 except:
1595 pass
1596 if int(nrOfPorts) != expectedNrOfPorts:
1597 pinPortMapError.append(partNbr)
1598 continue
1599 usedInstance = row[8]
1600 if self.adsInstanceToVendorDB(vendor, partNbr, usedInstance, nrOfPorts, nrOfPins, pinPortMap):
1601 added.append(partNbr)
1602 msg = ""
1603 if added != []:
1604 msg += "Part Numbers: " + str(added) + " added to Components Database.\n"
1605 if skipped != []:
1606 msg += "Duplicate Part Numbers: " + str(skipped) + " not added to Components Database.\n"
1607 if pinPortMapError != []:
1608 msg += "Pin-Port Mapping incorrect for Part Numbers: " + str(pinPortMapError) + " not added to Components Database.\n"
1609 if msg=="":
1610 msg += "No changes to Components Database.\n"
1611 empro.gui.MessageBox.information("Database Update",msg,0,0)
1612
1628
1635
1637 inputPinPortMap = self.instanceTable.data(row,7)
1638 adsInstance = self.adsInstances[row]
1639 origPinPortMapString = adsInstance[5]
1640 try:
1641 inputPinPortDict = eval(inputPinPortMap)
1642 if not isinstance(inputPinPortDict, dict):
1643 raise ADSInstanceException("Error in pin-port mapping")
1644 except:
1645 self.instanceTable.setData(row,7,origPinPortMapString)
1646 raise ADSInstanceException("Error in pin-port mapping")
1647 origPinPortMap = eval(origPinPortMapString)
1648 inputPinNames = set( inputPinPortDict.keys() )
1649 origPinNames = set(origPinPortMap.keys())
1650 if not inputPinNames <= origPinNames:
1651 raise ADSInstanceException("Pin names in Pin-Port mapping don't match original ADS pin names")
1652
1653 inputPortPinDict = dict()
1654 for pin, port in inputPinPortDict.iteritems():
1655 neg=False
1656 if port[0]=='-':
1657 neg=True
1658 port = port[1:]
1659 if port in inputPortPinDict:
1660 pinList = inputPortPinDict[port]
1661 posPins = pinList[0]
1662 negPins = pinList[1]
1663 if neg:
1664 negPins.append(pin)
1665 else:
1666 posPins.append(pin)
1667 pinList = [posPins, negPins]
1668 inputPortPinDict[port] = pinList
1669 else:
1670 if neg:
1671 inputPortPinDict[port] = [[], [pin]]
1672 else:
1673 inputPortPinDict[port] = [[pin], []]
1674 portNums = [int(x) for x in inputPortPinDict.keys() ]
1675 portNums.sort()
1676 singleRef = False
1677 if portNums[0] == 0:
1678 expNum = 0
1679 singleRef = True
1680 else:
1681 expNum = 1
1682 for pn in portNums:
1683 if pn != expNum:
1684 raise ADSInstanceException("Port Numbers not in sequencial order %s" % str(portNums))
1685 expNum += 1
1686 for port,pins in inputPortPinDict.iteritems():
1687 if ( (singleRef and pins[1]!=[]) or
1688 (not singleRef and pins[1]==[]) ):
1689 raise ADSInstanceException("Mixing single reference with differential port configuration for port %s" % port)
1690 return portNums[-1]
1691
1693 selectedCells = self.instanceTable.selectedCells()
1694 try:
1695 for row, col in selectedCells:
1696 if col == 2:
1697 db = self.vendorDb
1698 partNbr = self.instanceTable.data(row,col)
1699 if db.hasPartWithNbr(partNbr):
1700 raise ADSInstanceException("Part Number %s already exists in database." % partNbr)
1701 elif col == 5 or col == 7:
1702 nrOfPorts = int(self.instanceTable.data(row,5))
1703 nrOfPortsFromPortMap = self.validPinPortMap(row)
1704 if nrOfPortsFromPortMap != nrOfPorts:
1705 if col == 5:
1706 raise ADSInstanceException("Number of Ports %d does not match the Pin-Port Mapping." % nrOfPorts)
1707 else:
1708 self.instanceTable.setData( row, 5, nrOfPortsFromPortMap )
1709 except ADSInstanceException as e:
1710 empro.gui.MessageBox.warning("Warning","Invalid input:\n" + str(e) + "\nInstance will be ignored without modification.",0,0)
1711 pass
1712 except:
1713 raise
1714
1741
1755
1757 componentModelGroupList = []
1758
1759 analysisType = sipiData.analysisType
1760 if analysisType==sipiData.DCAnalysisType or sipiData.newSimulationData().componentsTreatedAsPorts:
1761 componentModelGroupList = sipiData.getComponentModelGroupList()
1762 else:
1763 return None
1764
1765 db = empro.VendorPartsDbList.instance()
1766 adsSelectItemsDict = {}
1767 for componentGroup in componentModelGroupList:
1768 componentModels = componentGroup.models()
1769 for model in componentModels:
1770 if model.modelType == 2 and not model.partNbr in adsSelectItemsDict:
1771 if db.hasPartWithNbr( model.partNbr ):
1772 vp = db.partWithNbr( model.partNbr )
1773 if vp.ADSSelectItem != "":
1774 adsSelectItemsDict[model.partNbr] = [vp.ADSSelectItem, vp.partType]
1775
1776 if len(adsSelectItemsDict) == 0:
1777 return None
1778
1779 if not empro.core.CommunicationWithParent.wasActivated():
1780 raise Exception("No parent application active.")
1781
1782 if empro.core.CommunicationWithParent.communicationParent() != empro.core.CommunicationWithParent.ADS:
1783 parentTag = empro.core.CommunicationWithParent.communicationParentTag()
1784 print "Cannot check for missing ADSComponentsFromModelDB: platform is " + parentTag + " instead of ADS"
1785 return None
1786
1787 isAdsBusy = False
1788 try:
1789 isAdsBusy = empro.toolkit.rpc.callIsShowingModalOrPopupWidget()
1790 except:
1791 isAdsBusy = True
1792 if isAdsBusy:
1793 raise Exception("ADS Schematic or Layout are currently busy. Please close all active (modal) dialogs in these tools and retry.")
1794
1795 try:
1796 result = empro.toolkit.rpc.callAEL('is_function_defined',['deemsipi_checkForMissingComponentsInADS'])
1797 if not result:
1798 return None
1799 except:
1800 raise
1801
1802 try:
1803 usedPartsList = ['list("%s",%s,"%s")'%(k,v[0],v[1]) for (k,v) in adsSelectItemsDict.items()]
1804 result = empro.toolkit.rpc.callAEL('deemsipi_checkForMissingComponentsInADS', [libName, cellName, usedPartsList])
1805 except:
1806 raise
1807
1808 return result
1809
1811
1812 AnalysisName = sipiData.name
1813 AnalysisName = _fixSetupName(AnalysisName)
1814
1815 switchingFreq, rippleFreq, trise, tfall = getParamValuesFromSMPSFreqPlan(sipiData, noErrorMessageBox)
1816
1817 pinsOnSwitchingNets = getPinNamesForDisplay(sipiData)
1818 if not pinsOnSwitchingNets and not noErrorMessageBox:
1819 questionMsg = "To automatically generate voltage waveform plots, at least one net " \
1820 "should be set as Switching net and at least one component needs to be attached to it. " \
1821 "You may proceed, but you will have to manually add the plots you want to the data display " \
1822 "after running the testbench." \
1823 "\n\nDo you want to proceed with the testbench generation?"
1824
1825 wantDisplay = empro.gui.MessageBox.question("", questionMsg, empro.gui.Yes + empro.gui.No, empro.gui.Yes)
1826 if wantDisplay == empro.gui.No:
1827 raise Exception('\n\nUser cancelled test bench generation.')
1828
1829 cellFullName = cellName + "_VoltageSpikes_" + AnalysisName + "_testbench";
1830 schViewName = "schematic";
1831 exists = empro.toolkit.rpc.callAEL('de_cellview_exists', [libName, cellFullName, schViewName])
1832 if exists and not overWrite and not noErrorMessageBox:
1833 askMsg = ("The top level design and the associated sub designs for:\n" \
1834 + '"{libName}:{cellFullName}", already exist.\n\n' \
1835 + "Overwrite existing designs?").format(libName=libName, cellFullName=cellFullName)
1836
1837 answer = empro.gui.MessageBox.question("", askMsg, empro.gui.Yes + empro.gui.No, empro.gui.Yes)
1838 if answer == empro.gui.No:
1839 raise Exception("\n\nUser cancelled test bench generation.")
1840
1841 ddtFileName = "PEPro_Volt_Spike_Display"
1842 generateVoltageSpikesDisplayTemplate(ddtFileName, pinsOnSwitchingNets, switchingFreq)
1843 try:
1844
1845 str_sw = "{} MHz".format(switchingFreq*1e-6)
1846 str_ripple = "{} kHz".format(rippleFreq*1e-3)
1847 str_trise = "{} nsec".format(trise*1e9)
1848 str_tfall = "{} nsec".format(tfall*1e9)
1849
1850 result = empro.toolkit.rpc.callAEL('deempe_generate_testbench', ["VoltageSpikes", AnalysisName, libName, cellName, ddtFileName, overWrite, str_sw, str_ripple, str_trise, str_tfall])
1851 if not result[0]:
1852 raise Exception('Voltage spikes analysis testbench generation problem: \n' + result[1])
1853 else:
1854 return result[1]
1855 except:
1856 raise
1857 finally:
1858 empro.core.CommunicationWithParent.rpc().stopDialog()
1859
1861 AnalysisName = sipiData.name
1862 AnalysisName = _fixSetupName(AnalysisName)
1863 ddtFileName = "PEPro_ConductedEMI_Display"
1864
1865 switchingFreq, rippleFreq, trise, tfall = getParamValuesFromSMPSFreqPlan(sipiData, noErrorMessageBox)
1866
1867 cellFullName = cellName + "_ConductedEMI_" + AnalysisName + "_testbench";
1868 schViewName = "schematic";
1869 exists = empro.toolkit.rpc.callAEL('de_cellview_exists', [libName, cellFullName, schViewName])
1870 if exists and not overWrite and not noErrorMessageBox:
1871 askMsg = ("The top level design and the associated sub designs for:\n" \
1872 + '"{libName}:{cellFullName}", already exist.\n\n' \
1873 + "Overwrite existing designs?").format(libName=libName, cellFullName=cellFullName)
1874
1875 answer = empro.gui.MessageBox.question("", askMsg, empro.gui.Yes + empro.gui.No, empro.gui.Yes)
1876 if answer == empro.gui.No:
1877 raise Exception("\n\nUser cancelled test bench generation.")
1878
1879 try:
1880
1881 str_sw = "{} MHz".format(switchingFreq*1e-6)
1882 str_ripple = "{} kHz".format(rippleFreq*1e-3)
1883 str_trise = "{} nsec".format(trise*1e9)
1884 str_tfall = "{} nsec".format(tfall*1e9)
1885
1886 result = empro.toolkit.rpc.callAEL('deempe_generate_testbench', ["ConductedEMI", AnalysisName, libName, cellName, ddtFileName, overWrite, str_sw, str_ripple, str_trise, str_tfall])
1887 if not result[0]:
1888 raise Exception('Conducted EMI analysis testbench generation problem: \n' + result[1])
1889 else:
1890 return result[1]
1891 except:
1892 raise
1893 finally:
1894 empro.core.CommunicationWithParent.rpc().stopDialog()
1895
1905
1915
1916
1918 sipiSimData = sipiData.newSimulationData()
1919 switchingFreq = None
1920 rippleFreq = None
1921 trise = None
1922 tfall = None
1923 for fpi in range(sipiSimData.femFrequencyPlanList().size()):
1924 fp = sipiSimData.femFrequencyPlanList().at(fpi)
1925
1926 if not fp.enabled or not fp.type == "SMPS":
1927 continue
1928
1929 if not switchingFreq and fp.switchingFrequency.isValid():
1930 switchingFreq = float(fp.switchingFrequency)
1931 if not rippleFreq and fp.rippleFrequency.isValid():
1932 rippleFreq = float(fp.rippleFrequency)
1933 if not trise and fp.riseTime.isValid():
1934 trise = float(fp.riseTime)
1935 if not tfall and fp.fallTime.isValid():
1936 tfall = float(fp.fallTime)
1937
1938 if not rippleFreq:
1939 rippleFreq = 10000.0
1940 if not switchingFreq or not trise or not tfall:
1941 if not noErrorMessageBox:
1942 msg = "When you simulate the testbench, you will need to set:\n\n Switching Frequency\n Ripple Frequency\n Rise Time\n Fall Time\n\n" \
1943 "Tip: If you select an SMPS frequency plan, then these values would have been added automatically."
1944 empro.gui.MessageBox.information("", msg, empro.gui.Ok, empro.gui.Ok)
1945
1946 switchingFreq = -1.0
1947 rippleFreq = -1.0
1948 trise = -1.0
1949 tfall = -1.0
1950
1951 return switchingFreq, rippleFreq, trise, tfall
1952
1953
1954 if __name__=='__main__':
1955 testRLCextract = False
1956 if testRLCextract:
1957 print requestAdsRLCData(partNbr="GRM155R71A104KA01", typeRLC="C", adsSelectItem='list("murataWebLib_init_item","GRM15","GRM155R71A104KA01")', nominalVal="100e-9")
1958 print requestAdsRLCData(partNbr="MHQ0402P4N2BT000", typeRLC="L", adsSelectItem='list("TDK_Component_Library_init_item","TDK_MHQ0402P","MHQ0402P4N2BT000")', nominalVal="4.2e-9")
1959
1960
1961 vendorPartsDb = empro.VendorPartsDbList.instance()
1962
1963 partNbr = 'GA242QR7E2471MW01'
1964 if not vendorPartsDb.hasPartWithNbr(partNbr):
1965 raise( "Partnumber %s missing in vendor database" % partNbr )
1966
1967 vp = vendorPartsDb.partWithNbr( partNbr )
1968 adsSelectItem = vp.ADSSelectItem
1969 partType = vp.partType
1970 modelPinPortMapString = vp.pinPortMap
1971
1972 print adsSelectItem
1973 print requestAdsRLCData(partNbr=partNbr, typeRLC=partType, adsSelectItem=adsSelectItem, nominalVal="300 fF")
1974
1975 testSnPextract = False
1976 if testSnPextract:
1977 print requestADSForSnPData( partNbr="MCZ2010AH900L4", startFreq="10 kHz", stopFreq="100 GHz", pointsPerDec="50" )
1978 print requestADSForSnPData( partNbr="ACH4518-470-T", startFreq="10 kHz", stopFreq="100 GHz", pointsPerDec="50" )
1979
1980 if __name__=='__main__':
1981 testGenerateLocal = False
1982 if testGenerateLocal:
1983 analyses = empro.activeProject.analyses
1984 sipiData = analyses[0]
1985 workingDirectory = os.getcwd()
1986 oaLayout = empro.activeProject.geometry()[0]
1987 libName = empro.activeProject.location.lib
1988 cellName = empro.activeProject.location.cell
1989 lcvName = generateSchematic(workingDirectory, sipiData, libName, cellName, schematicType=2)
1990
1991 if __name__=='__main__':
1992 testGeneralGenerate = True
1993 if testGeneralGenerate:
1994 sipiData = empro.activeProject.analyses[0]
1995 oaLayout = empro.activeProject.geometry()[0]
1996 libName = empro.activeProject.location.lib
1997 cellName = empro.activeProject.location.cell
1998
1999 generateSchematic('.', sipiData, libName, cellName, schematicType=1, overwrite=0, noErrorMessageBox=False)
2000
2001
2002
2003 stimulusLines = []
2004
2005 if __name__=='__main__':
2006 testAddToVendorDB = False
2007 if testAddToVendorDB:
2008 addADSComponentInstancesToVendorDB()
2009