1
2
3
4
5
6
7
8
9
10 import string
11 import re
12 import os
13 import sys
14 import subprocess
15 import logging
16
17 if __name__=="__main__":
18
19
20 logfile = './eemAdfiParse.log'
21 else:
22
23
24 import tempfile
25 file_h, logfile = tempfile.mkstemp("_eemAdfiParse.log")
26 os.close(file_h)
27
28
29 hversion=sys.hexversion
30 if hversion >= 0x20401F0:
31
32 logging.basicConfig(level=logging.DEBUG,
33 format='%(asctime)s %(levelname)-8s %(message)s',
34 datefmt='%a, %d %b %Y %H:%M:%S',
35 filename=logfile,
36 filemode='w')
37 console = logging.StreamHandler()
38 console.setLevel(logging.INFO)
39 formatter = logging.Formatter('ADFI parser: %(levelname)-8s %(message)s')
40 console.setFormatter(formatter)
41 logging.getLogger('').addHandler(console)
42 console.flush()
43
44 eemWriteError=logging.error
45 eemWriteWarn=logging.warn
46 eemWriteInfo=logging.info
47 eemWriteDebug=logging.debug
48 else:
50 sys.stderr.write('%s: %s\n' % (iType,iMessage))
59 eemWriteWarn('Using stderr for log output')
60
61 if hversion < 0x20401F0:
62 eemWriteError('Python version not recent enough')
63 sys.exit(1)
64
65
66
67
68
69 import xml.dom.pulldom
70 import xml.dom.minidom
71 import xml.sax
72 import xml.sax.handler
73
75 elements = iNode.getElementsByTagName(iTag)
76 value = None
77 if elements and len(elements)==1:
78 value = getInnerText(elements[0])
79 return value
80
82 elements = iNode.getElementsByTagName(iTag)
83 for el in elements:
84 if el.hasAttribute(attrKeyName) and el.getAttribute(attrKeyName).upper() == attrKeyValue.upper():
85 if el.hasAttribute(attrValueName):
86 return el.getAttribute(attrValueName)
87 return None
88
89 -def contentOfNode(node):
90 if node.nodeType == node.TEXT_NODE:
91 return node.data
92 elif node.nodeType==node.ELEMENT_NODE:
93 return getInnerText(node)
94 elif node.nodeType==node.CDATA_SECTION_NODE:
95 return node.data
96 else:
97
98 pass
99
100 -def getInnerText(oNode):
101 rc = ""
102 nodelist = oNode.childNodes
103 rc = ''.join([contentOfNode(node) for node in nodelist])
104 return rc
105
106
107 -def eemFixName(iName, iMapChar='[^a-zA-Z0-9_@`#&$%^=+-]'):
108 return re.sub(iMapChar, '_', iName)
109
110
113 self.version=None
114 self.mainVersion=-1
115 self.minorVersion=None
116 self.revision=0
117 self.tool=None
118 self.target=None
119 self.drawing_units=None
120 self.drawing_resolution=None
121
123 if event==xml.dom.pulldom.START_ELEMENT and nodeAdfiToAds.localName=='AdfiToAds':
124 if nodeAdfiToAds.hasAttribute('adfiVersion'):
125 self.version=nodeAdfiToAds.getAttribute('adfiVersion')
126 vl=self.version.split('.')
127 self.mainVersion=int(vl[0])
128 if len(vl)==3:
129 self.minorVersion=int(vl[1])
130 self.minorVersion=int(vl[-1])
131 if nodeAdfiToAds.hasAttribute('tool'):
132 self.tool=nodeAdfiToAds.getAttribute('tool')
133 if nodeAdfiToAds.hasAttribute('adfiTarget'):
134 self.target=nodeAdfiToAds.getAttribute('adfiTarget')
135
139
141
142 factorMap = {'m':1,'mm':1e-3,'um':1e-6,'nm':1e-9,'pm':1e-12,'mil':2.54e-5,'inch':2.54e-2,'in':2.54e-2}
143 conversionFactor = 1
144 unit=self.drawing_units
145 if unit in factorMap.keys():
146 conversionFactor = factorMap[unit]
147 else:
148 raise Exception('Unknown unit %s' % unit)
149 return conversionFactor
150
161
162
164 """This class is used to write out .egs file."""
165 - def __init__(self, fileName,useSolderBalls=False):
166 self.fileName = fileName
167 self.file = None
168 self.useSolderBalls=useSolderBalls
169 self.filterEgs={}
170
172 if self.file==None:
173 return
174 self.file.close()
175
177 try:
178 if self.file==None:
179 self.file = open(self.fileName,'w')
180 self.file.write(egsHeader)
181 self.file.write("\n\n")
182 except:
183 raise Exception("Failed to write egs header in %s!" % self.fileName)
184
185
186 - def writeBody(self, iEgsData='', iId='', iName='', top=None, maskNameNbMap={}):
187 if self.file==None:
188 raise Exception("Failed to write into egs file")
189
190 refDes = eemFixName(iId)
191 egsData = iEgsData
192 egsBody = ''
193 name = iName
194 if top:
195 refDes += "_adfi"
196 if iId in self.filterEgs.keys():
197
198
199 (bumpLayer, pinLayer)=self.filterEgs[iId]
200 bumpLayerNb = maskNameNbMap[bumpLayer]
201 pinLayerNb = maskNameNbMap[pinLayer]
202 egsData = re.sub('ADD [A-Z]%s \:W.+;\n*'% bumpLayerNb,'', egsData)
203 egsData = re.sub('ADD [A-Z]%s \:W.+;\n*'% pinLayerNb,'', egsData)
204
205 pass
206 egsBody += "EDIT " + refDes + ";\n"
207 egsBody += "$$ component " + name + " instance " + refDes + ";\n"
208 egsBody += egsData + "\nSAVE;\n\n"
209 self.file.write(egsBody)
210
212 parameters = getComponentParms(cmpParmsNode)
213
214 if self.useSolderBalls and parameters:
215 if parameters.has_key('ICPKG_TYPE') and parameters['ICPKG_TYPE'] == 'DIE_FLIPCHIP':
216 bumpLayer = parameters['ICPKG_BUMP_LAYER']
217 pinLayer = parameters['ICPKG_PIN_LAYER']
218 self.filterEgs[iId]=tuple([bumpLayer,pinLayer])
219 eemWriteDebug("Found flipchip component with solder balls on layer %s to be excluded from egs." % bumpLayer)
220 elif parameters.has_key('PKG_TYPE') and parameters['PKG_TYPE'] == 'BGA':
221 filterEgs = True
222 bumpLayer = parameters['PKG_BALL_LAYER']
223 pinLayer = parameters['PKG_PIN_LAYER_ATPKG']
224 self.filterEgs[iId]=tuple([bumpLayer,pinLayer])
225 eemWriteDebug("Found BGA component with solder balls on layer %s to be excluded from egs." % bumpLayer)
226
227
229
230 ltdFile = iStacks.getLtdFileName(None)
231 ltdFp = open( ltdFile, "r" )
232 maskNameNbMap = {}
233 for line in ltdFp.readlines():
234 words = line.split()
235 if len(words) < 3:
236 continue
237 if (words[0].upper() != 'MASK'):
238 continue
239 maskNb = words[1]
240 for w in words[2:]:
241 subwords=w.split('=')
242 if len(subwords) < 2:
243 continue
244 if (subwords[0].upper() != 'NAME'):
245 continue
246 maskName = subwords[1]
247 maskNameNbMap[maskName]=maskNb
248 ltdFp.close()
249 return maskNameNbMap
250
251
253 """This class is used to write out .hdef file."""
254 - def __init__(self, fprefix, iAdfiInfo, iAblPresent=False, iUseAblRoot=False):
255 fName = fprefix + '_adfi.ahdf'
256 eemWriteDebug("ADFI Hierarchical Definition Filename is: %s" % fName)
257 self.dirName=os.path.dirname(fName)
258 self.hasAbl=iAblPresent
259 self.useAblRoot=iUseAblRoot
260 self.file = open(fName, "w")
261 self.file.write("\"ADFISTARTINFO|VERSION|%s|TOOL|%s\",\n" %(iAdfiInfo.version, iAdfiInfo.tool))
262
265
267 if self.hasAbl:
268 return
269 refDesName=None
270 slmFile=None
271 ltdFile=None
272 if iStacks:
273 refDesName = iStacks.getTopDesignName()
274 slmFile = iStacks.getSlmFileName(refDesName)
275 ltdFile = iStacks.getLtdFileName(refDesName)
276 if slmFile!=None:
277 if ltdFile==None:
278 self.file.write("\"ADFILIBRARYSUBSTRATE|DESIGN|%s|%s\",\n" % (eemFixName(refDesName),slmFile))
279 else:
280 self.file.write("\"ADFILIBRARYSUBSTRATE|DESIGN|%s|%s|%s\",\n" % (eemFixName(refDesName + "_adfi"),slmFile,ltdFile))
281
282 - def writeCmpInfo(self, adfiVersion, tool, refDes, name, cmpType, topLevel, mainLevel, viewName):
283 if viewName == None or viewName == '':
284 self.file.write("\"ADFICMPINFO|VERSION|%s|TOOL|%s|DESIGN|%s|CMPNAME|%s|TYPE|%s|TOP|%s|MAIN|%s\",\n" %
285 (adfiVersion, tool, eemFixName(refDes), eemFixName(name), cmpType, topLevel, mainLevel))
286 else:
287 self.file.write("\"ADFICMPINFO|VERSION|%s|TOOL|%s|DESIGN|%s|CMPNAME|%s|TYPE|%s|TOP|%s|MAIN|%s|VIEW|%s\",\n" %
288 (adfiVersion, tool, eemFixName(refDes), eemFixName(name), cmpType, topLevel, mainLevel, eemFixName(viewName)))
289
292
301
309
324
326 layerName = eemGetElNodeValByTag(p, 'LayerName')
327 layerNumber= eemGetElNodeValByTag(p, 'LayerNumber')
328 outline = p.getElementsByTagName('Outline')
329 verts = getInnerText(outline[0].getElementsByTagName('Vertices')[0])
330 verts = verts.strip('\n')
331 bulges = getInnerText(outline[0].getElementsByTagName('Bulges')[0])
332 bulges = bulges.strip('\n')
333 holes = p.getElementsByTagName('Hole')
334 nrOfHoles = len(holes)
335 eemWriteDebug("Polygon %s with holes %d: %s" % (str(p),nrOfHoles,str(holes)))
336 self.file.write("\"ADFIFIGURESPOLYGONDEF|%s|%s|%d\"\n" % (layerNumber,layerName,nrOfHoles))
337 self.file.write("\"ADFIFIGURESPOLYGONOUTLV|%s\"\n" % verts)
338 self.file.write("\"ADFIFIGURESPOLYGONOUTLB|%s\"\n" % bulges)
339 for hole in holes:
340 vertsHole = getInnerText(hole.getElementsByTagName('Vertices')[0])
341 vertsHole = vertsHole.strip('\n').replace(',',' ')
342 bulgesHole = getInnerText(hole.getElementsByTagName('Bulges')[0])
343 bulgesHole = bulgesHole.strip('\n').replace(',',' ')
344 self.file.write("\"ADFIFIGURESPOLYGONHOLEV|%s\"\n" % vertsHole)
345 self.file.write("\"ADFIFIGURESPOLYGONHOLEB|%s\"\n" % bulgesHole)
346 self.file.write("\"ADFIFIGURESPOLYGONEND\"\n")
347
357
359 shapesName = iRefDes + '_shapes.xml'
360 fName = os.path.join(self.dirName, shapesName)
361 curString = "<abl:Shapes "
362 if self.useAblRoot:
363 curString += "xmlns:abl=\"http://keysight.com/eesof/abl\">\n"
364 else:
365 curString += "xmlns:abl=\"http://agilent.com/abl\">\n"
366 nrOfNodes = 0
367 shapeFile = None
368 for (event,node) in shapesEvents:
369 if (event==xml.dom.pulldom.START_ELEMENT
370 and ( node.tagName in ('abl:Trace', 'abl:Path', "abl:oaEllipse", "abl:oaPolygon", "abl:oaLine") ) ):
371 shapesEvents.expandNode(node)
372 curString += node.toxml() + '\n'
373 nrOfNodes+=1
374 if ( nrOfNodes > 10 ):
375 if shapeFile==None:
376 shapeFile = open(fName, "w")
377 shapeFile.write( curString )
378 curString = ''
379 elif (event==xml.dom.pulldom.END_ELEMENT
380 and node.tagName=='abl:Shapes'):
381 break
382
383 if ( nrOfNodes<=10):
384 self.file.write("\"ADFIABL_SHAPES_START\",\n")
385 self.file.write(curString)
386 self.file.write("</abl:Shapes>\n\"ADFIABL_SHAPES_END\",\n")
387 else:
388 if ( len(curString)>0 ):
389 shapeFile.write(curString)
390 shapeFile.write("</abl:Shapes>\n")
391 shapeFile.close()
392 self.file.write("\"ADFIABL_SHAPES_FILE|%s\",\n" % shapesName)
393
394
397
398 - def writeParmsToFile(self, iParms, iType, iRefDes, iTool, iVersion, iParmsFromFile):
399 if (iParms or iParmsFromFile):
400 self.file.write("\"ADFI%sPARMSINFO|VERSION|%s|TOOL|%s|DESIGN|%s\",\n" %
401 (iType, iVersion, iTool, eemFixName(iRefDes)))
402 self.file.write("\"ADFI%sPARMSFORMAT|Key|Value\",\n" % iType)
403
404 eemWriteDebug("parameters %s" % str(iParms))
405 parms = iParms[0].getElementsByTagName('Parameter')
406 parmMap = {}
407 if iParmsFromFile != None:
408 parmMap = iParmsFromFile
409
410
411 for parm in parms:
412 key = parm.getAttribute('key')
413 value = parm.getAttribute('value')
414 if key == 'VALUE':
415 value = eemAdfiWriteConvertToADSValues(iRefDes,value)
416 value = re.sub('[Ss]iemens','S',value)
417 value = re.sub('[oO][hH][mM]','Ohm',value)
418 if key not in parmMap.keys():
419 parmMap[key] = value
420
421
422 for key,value in parmMap.iteritems():
423 self.file.write("\"ADFI%sPARM|%s|%s\",\n" % (iType, key, value))
424
425 self.file.write("\"ADFI%sPARMSEND|%d\",\n" % (iType, len(parms)))
426
428 self.file.write("\"ADFIPININFO|VERSION|%s|TOOL|%s|DESIGN|%s\",\n" % (iVersion, iTool, eemFixName(iRefDes)))
429 self.file.write("\"ADFIPINFORMAT|PINNAME|LAYERNUMBER|LAYERNAME|PORTNUMBER|PINNUMBER|"+
430 "NETNAME|XLOC|YLOC|PINTYPE|REPORTZ|IMPORTZ|PORTOFFSET|PORTNAME|POSNEG\",\n")
431 self.file.write("\"ADFIPINFORMATAREA|PINNAME[|x|y]+\",\n")
432
434 self.file.write("\"ADFIPINEND|%d\",\n" % nrOfPins)
435
436 - def writePinDef(self,pinName,layerNumber,layerName,portNumber,pinNumber,netName,
437 xLoc,yLoc,pinType,rePortZ,imPortZ,portOffset,portName,posNeg):
438 self.file.write("\"ADFIPINDEF|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\",\n" %
439 (pinName,layerNumber,layerName,portNumber,pinNumber,netName,
440 xLoc,yLoc,pinType,rePortZ,imPortZ,portOffset,portName,posNeg))
441
443 if phi != 0.0 or diffPair != None or isMultiPortRef or usage != None:
444 self.file.write("\"ADFIPINEXTRA")
445 if phi != 0.0:
446 self.file.write("|ANGLE|%s" % phi)
447 if diffPair != None:
448 self.file.write("|DIFFPAIR|%s" % diffPair)
449 if isMultiPortRef == True:
450 self.file.write("|MULTIPORTREF|TRUE")
451 if usage != None:
452 self.file.write("|USAGE|%s" % usage)
453 self.file.write("\"\n")
454
456 self.file.write("\"ADFIPINAREA|%s|%s|%s|%s|%s\",\n" % (pinName,'CR',x,y,r))
457
459 self.file.write("\"ADFIPINAREA|%s|%s|%s|%s|%s\",\n" % (pinName,'CR',x,y,r))
460
462 self.file.write("\"ADFIPINAREA|%s|%s|%s|%s\",\n" % (pinName,'PP',verts,bulges))
463
465 self.file.write("\"ADFIPINAREA|%s|%s\",\n" % (pinName,pinString))
466
468 self.file.write("\"ADFIINSTSINFO|VERSION|%s|TOOL|%s|DESIGN|%s\",\n" % (iVersion, iTool, eemFixName(iRefDes)))
469 self.file.write("\"ADFIINSTDATAFORMAT|REFDES|CMPNAME|XLOC|YLOC|ROTATION[|VIEW]\",\n")
470
471 - def writeInstData(self, refDes, cmpName, viewName,xLoc, yLoc, rot):
472 if viewName != None:
473 self.file.write("\"ADFIINSTDATA|%s|%s|%s|%s|%s|%s\",\n" %
474 (eemFixName(refDes), eemFixName(cmpName), xLoc, yLoc, rot, eemFixName(viewName)))
475 else:
476 self.file.write("\"ADFIINSTDATA|%s|%s|%s|%s|%s\",\n" %
477 (eemFixName(refDes), eemFixName(cmpName), xLoc, yLoc, rot))
478
480 self.file.write("\"ADFIINSTSEND|%d\",\n" % nrOfInstances)
481
483 self.file.write("\"ADFICMPREFLOCATION|X|%s|Y|%s\",\n" % refLocation)
484
486 if self.hasAbl:
487 return
488 slmFile = iStacks.getSlmFileName(refDesName)
489 ltdFile = iStacks.getLtdFileName(refDesName)
490 if slmFile!=None:
491 if ltdFile==None:
492 self.file.write("\"ADFICMPSUBSTRATE|%s\",\n" % slmFile)
493 else:
494 self.file.write("\"ADFICMPSUBSTRATE|%s|%s\",\n" % (slmFile,ltdFile))
495
498
500 self.file.write("\"ADFIEND|%d\"\n\n" % nrOfComponent)
501
502
503 -def eemAdfiProcessHDefEgsFile(iAdfiDoc, iAdfiInfo, iHDefWriter, iEgsWriter, iBondWireWriter,
504 iStacks, iParmMap, iMaskNameNbMap={}):
505 """extract and write pin/port/comp info"""
506
507 eemWriteDebug("Writing hierarchical design data")
508 tool = iAdfiInfo.tool
509 adfiVersion = iAdfiInfo.version
510
511 parser=xml.sax.make_parser()
512
513 parser.setFeature(xml.sax.handler.feature_external_ges,0)
514
515 events = xml.dom.pulldom.parse(iAdfiDoc,parser,1024*1024*16)
516
517 iHDefWriter.writeLibrarySubstrate(iStacks)
518
519 cmpName=''
520 refDes=''
521 refDesName=''
522 viewName=''
523 inComponent=None
524 topLevel='FALSE'
525 top=False
526 mainLevel='FALSE'
527 addedParameters = None
528 nrOfComponent=0
529 egsData=''
530 name=''
531 drawingConversionFactor=iAdfiInfo.getDrawingUnitConversionFactor()
532 for (event,node) in events:
533 if (event!=xml.dom.pulldom.START_ELEMENT
534 and event!=xml.dom.pulldom.END_ELEMENT):
535 continue
536 elif (event==xml.dom.pulldom.START_ELEMENT
537 and node.localName=="AdfiComponent"):
538 cmpName = (node.getAttribute('id')).strip()
539 inComponent=True
540 viewName=''
541 name=''
542 if node.getAttribute('top') == 'true':
543 topLevel = 'TRUE'
544 top=True
545 else:
546 topLevel = 'FALSE'
547 top=False
548 if node.hasAttribute('main') and node.getAttribute('main') == 'true':
549 mainLevel = 'TRUE'
550 else:
551 mainLevel = 'FALSE'
552 elif (inComponent
553 and event==xml.dom.pulldom.START_ELEMENT
554 and node.localName=="Name"):
555 events.expandNode(node)
556 name=(getInnerText(node)).strip()
557 if cmpName==None or cmpName=='':
558 cmpName=name
559 refDes = cmpName
560 refDesName = refDes
561 if top:
562 refDes = refDes + "_adfi"
563 elif (inComponent
564 and event==xml.dom.pulldom.START_ELEMENT
565 and node.localName=="View"):
566 events.expandNode(node)
567 viewNameString=(getInnerText(node)).strip()
568 if viewName==None or viewName=='':
569 viewName = viewNameString
570 refDes = cmpName
571 refDesName = refDes
572 if top:
573 refDes = refDes + "_adfi"
574 elif (inComponent
575 and event==xml.dom.pulldom.START_ELEMENT
576 and node.localName=="Units"):
577 events.expandNode(node)
578 drawingConversionFactor=getDrawingUnitConversionFactor(node)
579 if drawingConversionFactor==None:
580 drawingConversionFactor=iAdfiInfo.getDrawingUnitConversionFactor()
581 elif (inComponent
582 and event==xml.dom.pulldom.START_ELEMENT
583 and node.localName=="Type"):
584 events.expandNode(node)
585 cmpType=getInnerText(node)
586 iHDefWriter.writeCmpInfo(adfiVersion, tool, refDes, name, cmpType, topLevel, mainLevel, viewName)
587 elif (inComponent
588 and event==xml.dom.pulldom.START_ELEMENT
589 and node.localName=="Geometry2D"
590 and node.hasAttribute('geometry2DType')
591 and node.getAttribute('geometry2DType')=='egs'
592 and (not node.hasAttribute('geometry2DOp') or
593 node.getAttribute('geometry2DOp')!='process')):
594 events.expandNode(node)
595 egsData=getInnerText(node)
596 iEgsWriter.writeBody(egsData,cmpName,name,top,iMaskNameNbMap)
597 elif (inComponent
598 and event==xml.dom.pulldom.START_ELEMENT
599 and node.localName=="Geometry2D"
600 and node.hasAttribute('geometry2DType')
601 and node.getAttribute('geometry2DType')=='direct'):
602 eemAdfiWriteCmpFiguresToFile(events, iHDefWriter, refDes, tool, adfiVersion)
603 elif (inComponent
604 and event==xml.dom.pulldom.START_ELEMENT
605 and node.localName=="ComponentParms"):
606 events.expandNode(node)
607 eemAdfiWriteCmpParmsToFile(iHDefWriter, node, refDes, tool, adfiVersion, addedParameters)
608 elif (inComponent
609 and event==xml.dom.pulldom.START_ELEMENT
610 and node.localName=="Ports"):
611 events.expandNode(node)
612 eemAdfiWriteCmpPinsToFile(iHDefWriter, node, refDes, tool, adfiVersion)
613 elif (inComponent
614 and event==xml.dom.pulldom.START_ELEMENT
615 and node.localName=="Instances"):
616 events.expandNode(node)
617 eemAdfiWriteCmpInstToFile(iHDefWriter, node, refDes, tool, adfiVersion, iParmMap)
618 iBondWireWriter.writeCmptBondwires(node,refDes,drawingConversionFactor)
619 elif (inComponent
620 and event==xml.dom.pulldom.START_ELEMENT
621 and node.localName=="RefLocation"):
622 events.expandNode(node)
623 eemAdfiWriteCmpRefLocationToFile(iHDefWriter, node)
624 elif event==xml.dom.pulldom.END_ELEMENT and node.localName=="AdfiComponent":
625 iHDefWriter.writeCmpSubstrate(refDes,refDesName,iStacks)
626 iHDefWriter.writeCmpEnd(refDes)
627 nrOfComponent+=1
628
629 cmpName=''
630 refDes=''
631 refDesName=''
632 inComponent=None
633 topLevel='FALSE'
634 top=False
635 addedParameters = None
636 egsData=''
637 name=''
638 iHDefWriter.writeEnd(nrOfComponent)
639 eemWriteDebug("Writing hierarchical design data done")
640
641
694
695
707
721
723 phi = '0.0'
724 rot = iNode.getElementsByTagName('Rotation')
725 if rot:
726 phi = rot[0].getAttribute('phi')
727 return phi
728
730 r = '0.0'
731 rad = iNode.getElementsByTagName('Radius')
732 if rad:
733 r = rad[0].getAttribute('r')
734 return r
735
742
744 refLocation = eemAdfiGetLocation(iNode,'RefLocation')
745 if refLocation!=('0.0','0.0'):
746 eemWriteDebug("Ref location found: %s,%s" % refLocation)
747 iHDefWriter.writeRefLocation(refLocation)
748
750 pinName = eemGetElNodeValByTag(iPin, 'PinName')
751 eemWriteDebug("Process pin %s" % pinName)
752 pinNumber = eemGetElNodeValByTag(iPin, 'PinNumber')
753 portNumber = eemGetElNodeValByTag(iPin, 'PortNumber')
754 if portNumber == None:
755 portNumber = pinNumber
756 layerName = eemGetElNodeValByTag(iPin, 'LayerName')
757 layerNumber= eemGetElNodeValByTag(iPin, 'LayerNumber')
758 netName = eemGetElNodeValByTag(iPin, 'NetName')
759 if netName == None:
760 netName = '__NONE__'
761 (xLoc,yLoc)= eemAdfiGetLocation(iPin)
762 phi = eemAdfiGetRotation(iPin)
763 pinType = eemGetElNodeValByTag(iPin, 'PinType')
764 if pinType == None:
765 pinType = '0'
766 rePortZ = eemGetElNodeValByTag(iPin, 'RePortZ')
767 if rePortZ == None:
768 rePortZ = '50.0'
769 imPortZ = eemGetElNodeValByTag(iPin, 'ImPortZ')
770 if imPortZ == None:
771 imPortZ = '0.0'
772 portOffset = eemGetElNodeValByTag(iPin, 'PortOffset')
773 if portOffset == None:
774 portOffset = '0.0'
775 portName = eemGetElNodeValByTag(iPin, 'PortName')
776 if portName == None:
777 portName = pinName
778 posNeg = eemGetElNodeValByTag(iPin, 'PosNeg')
779 if posNeg == None:
780 posNeg = '0'
781 diffPair = eemGetElNodeValByTag(iPin, 'DifferentialPair')
782 usage = eemGetElNodeValByTag(iPin, 'Usage')
783
784 iHDefWriter.writePinDef(pinName,layerNumber,layerName,portNumber,pinNumber,netName,
785 xLoc,yLoc,pinType,rePortZ,imPortZ,portOffset,portName,posNeg)
786 pinId = pinName
787 isMultiPortRef = False
788 if pinId in pinSet:
789 isMultiPortRef = True
790 else:
791 pinSet.add(pinId)
792
793 iHDefWriter.writePinExtra(phi,diffPair,isMultiPortRef,usage)
794
795
797 pinName = eemGetElNodeValByTag(iPin, 'PinName')
798 pinArea = iPin.getElementsByTagName('PinArea')
799 if pinArea:
800
801 pinAreaType = pinArea[0].getAttribute('pinAreaType')
802 if pinAreaType=='direct':
803 circle = pinArea[0].getElementsByTagName('Circle')
804 if circle:
805 r = eemAdfiGetRadius(circle[0])
806 (x,y) = eemAdfiGetLocation(circle[0],'XY')
807 iHDefWriter.writePinAreaCircle(pinName,x,y,r)
808 else:
809 polygon = pinArea[0].getElementsByTagName('Polygon')
810 if polygon:
811
812 outline = polygon[0].getElementsByTagName('Outline')
813 verts = getInnerText(outline[0].getElementsByTagName('Vertices')[0])
814 verts = verts.strip('\n')
815
816 bulges = getInnerText(outline[0].getElementsByTagName('Bulges')[0])
817 bulges = bulges.strip('\n')
818
819 iHDefWriter.writePinAreaPolygon(pinName,verts,bulges)
820 else:
821 pinString = str(getInnerText(pinArea[0]))
822
823 if len(pinString)>5:
824
825 pinString = re.sub('ADD ([CPLR])[0-9]+ \:W[0-9.]+ ',r'\1 ', pinString)
826 pinString = pinString.strip('\n \t;')
827 pinString = re.sub('[ ,]+','|', pinString)
828 iHDefWriter.writePinAreaString(pinName,pinString)
829
831 eemWriteDebug("Process Component parameters %s" % iRefDes)
832 addedParameters=None
833 if ((iParmMap != None) and (refDes in iParmMap.keys())):
834 addedParameters = iParmMap[refDes]
835 cmpParms=[]
836 if iCmp.localName=='ComponentParms':
837 cmpParms.append(iCmp)
838 else:
839 cmpParms = iCmp.getElementsByTagName('ComponentParms')
840 iHDefWriter.writeParmsToFile(cmpParms, 'CMP', iRefDes, iTool, iVersion, addedParameters)
841 eemWriteDebug("Process Component parameters %s done" % iRefDes)
842
843
844
846 m = re.match('([-+]?[0-9]*[\.,]?[0-9]+)([eE][-+]?[0-9]+)?([ \t]+)?([a-zA-Z]+)?',iValue)
847 if m!=None:
848 value = m.group(1)
849 if m.group(2)!=None:
850 value = value + m.group(2)
851 if ((m.group(4)!=None) and
852 (m.group(4)!='')):
853 value = value + ' '
854 if m.group(4) == 'MEG':
855 value = value + 'M'
856 elif len(m.group(4))==1:
857 if m.group(4) in ['A','F','K','N','P','U']:
858 value = value + m.group(4).lower()
859 else:
860 value = value + m.group(4)
861 elif len(m.group(4))==2:
862 if ((iRefDes[0] == 'L')
863 or (iRefDes[0] == 'C')
864 or (m.group(4)[1] in ['h','H','f','F'])):
865 if (m.group(4)[0] in ['A','F','K','M','N','P','U']):
866 value = value + m.group(4)[0].lower() + m.group(4)[1].upper()
867 else:
868 value = value + m.group(4)[0] + m.group(4)[1].upper()
869 else:
870 value = value + m.group(4)
871 else:
872 value = value + m.group(4)
873 else:
874 if (iRefDes[0] == 'L'):
875 value = value + ' nH'
876 if (iRefDes[0] == 'C'):
877 value = value + ' pF'
878 value = re.sub(',','.',value)
879 eemWriteDebug("Transformed ivalue: %s into value: %s" % (iValue,value))
880 return value
881 return iValue
882
883
884
886 eemWriteDebug("Process instances in component %s when present"% iRefDes)
887 instances = iCmp.getElementsByTagName('Instance')
888 if instances:
889 iHDefWriter.writeInstsInfo(iVersion, iTool, iRefDes)
890 for inst in instances:
891 refDes = inst.getAttribute('id')
892 cmpName = eemGetElNodeValByTag(inst, 'Component').strip()
893 viewName = eemGetElNodeValByTag(inst, 'View')
894 if viewName!=None:
895 viewName = viewName.strip()
896 eemWriteDebug("Process instance %s of component %s view %s" % (refDes, cmpName, viewName))
897 else:
898 eemWriteDebug("Process instance %s of component %s" % (refDes,cmpName))
899 (xLoc, yLoc) = eemAdfiGetLocation(inst)
900 rot = eemAdfiGetRotation(inst)
901 eemWriteDebug("Process instance location %s,%s rotation %s" % (xLoc,yLoc,rot))
902 iHDefWriter.writeInstData(refDes, cmpName, viewName, xLoc, yLoc, rot)
903
904 hInstName = iRefDes + '.' + refDes
905 addedParameters = None
906 if ((iParmMap != None) and (hInstName in iParmMap.keys())):
907 addedParameters = iParmMap[hInstName]
908 eemAdfiWriteInstParmsToFile(iHDefWriter, inst, refDes, iTool, iVersion, addedParameters)
909 eemWriteDebug("Processing instance %s of component %s done" % (refDes,cmpName))
910 iHDefWriter.writeInstsEnd(len(instances))
911
913 eemWriteDebug("Process instance parameters %s" % instName)
914 instParms = iInst.getElementsByTagName('InstanceParms')
915 iHDefWriter.writeParmsToFile(instParms, 'INST', instName, iTool, iVersion, iParmsFromFile)
916 eemWriteDebug("Processing instance parameters %s done" % instName)
917
918
920 fname = adfiNamePrefix + "_adfi_parms.csv"
921 if not os.path.isfile(fname):
922 eemWriteDebug("No additional/updated parameters for components found")
923 return None
924
925 try:
926 import csv
927 eemWriteDebug("Read additional/updated parameters for components: %s" % fname)
928 fp = open(fname,"rb")
929 reader = csv.reader(fp)
930 fp.close()
931 parmMap = {}
932 for row in reader:
933 instMap = {}
934 iName = row[0]
935 if iName in parmMap.keys():
936 instMap = parmMap[iName]
937 parmList = row[1:]
938 for i in range(0,len(parmList),2):
939 instMap[parmList[i]] = parmList[i+1]
940 parmMap[iName] = instMap
941 return parmMap
942 eemWriteDebug("Read additional and updated parameters done")
943 except:
944 eemWriteDebug("Can not read from ADS ADFI file: %s" % iAdfiFilename)
945 return None
946
948 unit = eemGetElNodeAttrByTagAttrValue(cInst, "Unit", 'key', 'drawing_units', 'value')
949
950 factorMap = {'m':1,'mm':1e-3,'um':1e-6,'nm':1e-9,'pm':1e-12,'mil':2.54e-5,'inch':2.54e-2,'in':2.54e-2}
951 conversionFactor = 1
952 if unit in factorMap.keys():
953 conversionFactor = factorMap[unit]
954 else:
955 raise Exception('Unknown unit %s' % unit)
956 return conversionFactor
957
959 pins=None
960 conversionFactor=None
961 try:
962 if(iPortsDom.nodeType==iPortsDom.DOCUMENT_NODE):
963 components = iPortsDom.getElementsByTagName('AdfiComponent')
964 for cInst in components:
965 if cInst.getAttribute('top') == 'true':
966 if iAdfiInfo==None and needUnit:
967 conversionFactor = getDrawingUnitConversionFactor(cInst)
968 pins = cInst.getElementsByTagName('PortDescription')
969 break
970 except:
971 pass
972
973 try:
974 if (pins==None
975 and iPortsDom.nodeType==iPortsDom.ELEMENT_NODE):
976
977 pins = iPortsDom.getElementsByTagName('PortDescription')
978 except:
979 pass
980
981 try:
982 if (pins==None
983 and len(iPortsDom)
984 and iPortsDom[0].nodeType==iPortsDom[0].ELEMENT_NODE):
985
986 pins=iPortsDom
987 except:
988 raise Exception('Unknown port/pin object %s' % str(iPortsDom))
989
990 if conversionFactor==None and needUnit:
991 conversionFactor = iAdfiInfo.getDrawingUnitConversionFactor()
992
993 return (pins,conversionFactor)
994
996 """This class is used to write out the .pin file of the top level of an adfi file."""
998 self.file = open( filename, "w" )
999 self.file.write(r'<?xml version="1.0" encoding="UTF-8"?>')
1000
1001
1002 - def writePin(self,name,net,layer,purpose,x,y):
1003 self.file.write("""
1004 <pin>
1005 <name>"""+name+"""</name>
1006 <net>"""+net+"""</net>
1007 <layout>
1008 <shape>
1009 <layer>"""+str(layer)+"""</layer>
1010 <purpose>"""+str(purpose)+"""</purpose>
1011 <point>
1012 <x>"""+str(x)+"""</x>
1013 <y>"""+str(y)+"""</y>
1014 </point>
1015 </shape>
1016 </layout>
1017 </pin>""")
1018
1020 pins=None
1021 conversionFactor=None
1022 try:
1023 (pins, conversionFactor) = getPinNodeListUnitInfo(iPortsDom,iAdfiInfo,True)
1024 except:
1025 raise
1026
1027 self.file.write("""
1028 <pin_list version="1.0">
1029 <!-- note: all coordinates are in meter -->""")
1030 for iPin in pins:
1031 pinName = eemGetElNodeValByTag(iPin, 'PinName')
1032 eemWriteDebug("Process pin %s" % pinName)
1033 pinNumber = eemGetElNodeValByTag(iPin, 'PinNumber')
1034 layerName = eemGetElNodeValByTag(iPin, 'LayerName')
1035 layerNumber= eemGetElNodeValByTag(iPin, 'LayerNumber')
1036 netName = eemGetElNodeValByTag(iPin, 'NetName')
1037 if netName == None:
1038 netName = ""
1039 (xLoc,yLoc)= eemAdfiGetLocation(iPin)
1040 phi = eemAdfiGetRotation(iPin)
1041
1042
1043 self.writePin(pinName,netName,layerNumber,-1,
1044 conversionFactor*float(xLoc),
1045 conversionFactor*float(yLoc))
1046 self.file.write('\n'+r'</pin_list>'+'\n')
1047
1050
1052 """write out top level pins in .pin file"""
1053 writer = pinWriter(fName)
1054 writer.writePinList(iDom,iAdfiInfo)
1055 writer.close()
1056
1059 self.file = open( filename, "w" )
1060 self.file.write(r'<?xml version="1.0" encoding="UTF-8"?>'+'\n')
1061
1063 self.file.write(""" <calibration_group_list>
1064 <calibration_group id="1">
1065 <type>TML</type>
1066 <auto_split>true</auto_split>
1067 </calibration_group>
1068 </calibration_group_list>
1069 """)
1070
1071 - def writePort(self,id,name,plusPinList,minusPinList,impedanceR,impedanceI):
1072 self.file.write(" <port id=\""+str(id)+"\">\n")
1073 self.file.write(" <name>"""+name+"</name>\n")
1074 for plusPin in plusPinList:
1075 self.file.write(" <plus_pin>"+plusPin+"</plus_pin>\n")
1076 for minusPin in minusPinList:
1077 self.file.write(" <minus_pin>"+minusPin+"</minus_pin>\n")
1078 self.file.write(" <impedance>\n")
1079 self.file.write(" <real>"+str(impedanceR)+"</real>\n")
1080 self.file.write(" <imag>"+str(impedanceI)+"</imag>\n")
1081 self.file.write(" </impedance>\n")
1082 self.file.write(" <calibration_group_ref ref=\"1\" />\n")
1083 self.file.write(" </port>\n")
1084
1090
1092 pins=None
1093 conversionFactor=None
1094 try:
1095 (pins, conversionFactor) = getPinNodeListUnitInfo(iPortsDom)
1096 except:
1097 raise
1098
1099 self.file.write(" <port_list>\n")
1100 portList = {}
1101 for iPin in pins:
1102
1103 pinName = eemGetElNodeValByTag(iPin, 'PinName')
1104 pinNumber = eemGetElNodeValByTag(iPin, 'PinNumber')
1105 portNumber = int(eemGetElNodeValByTag(iPin, 'PortNumber'))
1106 if portNumber == None:
1107 portNumber = pinNumber
1108 pinType = eemGetElNodeValByTag(iPin, 'PinType')
1109 if pinType == None:
1110 pinType = '+1'
1111 rePortZ = eemGetElNodeValByTag(iPin, 'RePortZ')
1112 if rePortZ == None:
1113 rePortZ = '50.0'
1114 imPortZ = eemGetElNodeValByTag(iPin, 'ImPortZ')
1115 if imPortZ == None:
1116 imPortZ = '0.0'
1117 portOffset = eemGetElNodeValByTag(iPin, 'PortOffset')
1118 if portOffset == None:
1119 portOffset = '0.0'
1120 portName = eemGetElNodeValByTag(iPin, 'PortName')
1121 eemWriteDebug("Process pin %s in port %s" % (pinName,portName))
1122 if portName == None:
1123 portName = pinName
1124 posNeg = eemGetElNodeValByTag(iPin, 'PosNeg')
1125 if posNeg == None:
1126 posNeg = '0'
1127 diffPair = eemGetElNodeValByTag(iPin, 'DifferentialPair')
1128
1129 if portList.has_key(portNumber):
1130 thisPort = portList[portNumber]
1131 else:
1132 newPort = dict(name=portName,plusPinList=[],minusPinList=[],rePortZ=rePortZ,imPortZ=imPortZ)
1133 thisPort = newPort
1134 portList[portNumber]=thisPort
1135
1136 if pinType == '+1':
1137 thisPort['plusPinList'].append(pinName)
1138 else:
1139 thisPort['minusPinList'].append(pinName)
1140
1141 keys = portList.keys()
1142 keys.sort()
1143 for id in keys:
1144 port = portList[id]
1145 self.writePort(id,port['name'],port['plusPinList'],port['minusPinList'],port['rePortZ'],port['imPortZ'])
1146 self.file.write(' </port_list>\n')
1147
1150
1156
1157
1159 - def __init__(self, filename,maskNameNbMap):
1160 self.maskNameNbMap = maskNameNbMap
1161 self.file = open( filename, "w" )
1162 self.file.write(
1163 """# bondwire file format version 2.0
1164
1165 # uses mks units
1166 #
1167 # wire
1168 # name "<bondwire name>";
1169 # netname "<bondwire net name>";
1170 # resistivity <resistivity in Ohm*m>
1171 # radius <bondwire radius in m>;
1172 # points <nr of points n>,
1173 # <x1 y1 mask z1 [top|bottom]>,
1174 # <x2 y2 [(mask [z1|zn] [top|bottom] delta)|absolute] z2>,
1175 # ...
1176 # <xn yn mask zn [top|bottom]>;
1177 # end_wire
1178 # ...
1179 """)
1180
1183
1184 - def writeBondWire(self,iCmp,inst,iCmpId=None,iDrawConversionFactor=None):
1185 cmpId=iCmpId
1186 if cmpId==None:
1187 cmpId = iCmp.getAttribute('id')
1188
1189 if iDrawConversionFactor!=None:
1190 drawingConversionFactor = iDrawConversionFactor
1191 else:
1192 drawingConversionFactor = getDrawingUnitConversionFactor(iCmp)
1193
1194 bondId = inst.getAttribute('id')
1195 self.file.write('\nwire\n')
1196
1197
1198 self.file.write(' name "%s_%s";\n' % (cmpId.replace('-','_'),bondId.replace('-','_')))
1199
1200 conductivityString = eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'Conductivity', 'value')
1201 condV,condUnit = conductivityString.split()
1202
1203
1204 factorMap = {'GS':1e9,'MS':1e6,'kS':1e3,'S':1,'mS':1e-3,'uS':1e-6,'nS':1e-9,'pS':1e-12}
1205 conversionFactor = 1
1206 if condUnit in factorMap.keys():
1207 conversionFactor = factorMap[condUnit]
1208 else:
1209 raise Exception('Unknown unit %s' % condUnit)
1210 self.file.write(' resistivity %s;\n' % (1/(float(condV)*conversionFactor)))
1211
1212 radius = eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'Radius', 'value')
1213 self.file.write(' radius %s;\n' % (float(radius)*drawingConversionFactor))
1214
1215 startLocation = inst.getElementsByTagName('Location')[0]
1216 xStart = drawingConversionFactor*float(startLocation.getAttribute('x'))
1217 yStart = drawingConversionFactor*float(startLocation.getAttribute('y'))
1218 xEnd = drawingConversionFactor*float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'xEnd', 'value'))
1219 yEnd = drawingConversionFactor*float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'yEnd', 'value'))
1220 maskNameStart = eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'Layer1', 'value')
1221 maskNameEnd = eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'Layer2', 'value')
1222 if maskNameStart in self.maskNameNbMap.keys():
1223 maskNbStart = self.maskNameNbMap[maskNameStart]
1224 else:
1225 eemWriteWarn("Mask number not found start mask for %s of bondwire %s.\nUsing \"0\" instead." % (str(maskNameStart),str(bondId)))
1226 maskNbStart = '0'
1227 if maskNameEnd in self.maskNameNbMap.keys():
1228 maskNbEnd = self.maskNameNbMap[maskNameEnd]
1229 else:
1230 eemWriteWarn("Mask number not found end mask for %s of bondwire %s.\nUsing \"0\" instead." % (str(maskNameEnd),str(bondId)))
1231 maskNbEnd = '0'
1232 import math
1233 dX = xEnd - xStart
1234 dY = yEnd - yStart
1235 length = math.sqrt(dX * dX + dY * dY)
1236 wireAbove = (eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'RelToSubstrate', 'value') == 'ABOVE')
1237 if (wireAbove):
1238 onSide = 'top'
1239 else:
1240 onSide = 'bot'
1241 NumberOfLengthsSpecified = int(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'NumberOfLengthsSpecified', 'value'))
1242 lList = []
1243 zList = []
1244 for ind in range(1,NumberOfLengthsSpecified+1):
1245 li = drawingConversionFactor*float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'l'+str(ind), 'value'))
1246 zi = drawingConversionFactor*float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'z'+str(ind), 'value'))
1247 lList.append(li)
1248 zList.append(zi)
1249 self.file.write(' points %s,\n' % (NumberOfLengthsSpecified + 2))
1250 self.file.write(' %s %s mask %s %s,\n' % (xStart,yStart,maskNbStart,onSide))
1251 xi = xStart
1252 yi = yStart
1253 for li,zi in zip(lList,zList):
1254 dXi = li/length * dX
1255 dYi = li/length * dY
1256 xi += dXi
1257 yi += dYi
1258 self.file.write(' %s %s mask %s %s delta %s,\n' % (xi,yi,maskNbStart,onSide,zi))
1259 self.file.write(' %s %s mask %s %s;\n' % (xEnd,yEnd,maskNbEnd,onSide))
1260 self.file.write('end_wire\n')
1261
1263 self.file.write('\nwire\n')
1264
1265 self.file.write(' name "%s";\n' % name)
1266
1267 self.file.write(' resistivity %s;\n' % paramMap['resistivity'])
1268
1269 radius = float(paramMap['radius'])
1270 self.file.write(' radius %s;\n' % (radius/10))
1271
1272 xStart = float(paramMap['x']) - radius/4
1273 yStart = float(paramMap['y']) - radius/4
1274 xEnd = xStart + radius/2
1275 yEnd = yStart + radius/2
1276 maskNameStart = paramMap['mask_top']
1277 maskNameEnd = paramMap['mask_bottom']
1278 maskNbStart = self.maskNameNbMap[maskNameStart]
1279 maskNbEnd = self.maskNameNbMap[maskNameEnd]
1280 self.file.write(' points %s,\n' % (3))
1281 self.file.write(' %s %s mask %s %s,\n' % (xStart,yStart,maskNbStart,'bot'))
1282 self.file.write(' %s %s mask %s %s delta %s,\n' % (xStart,yStart,maskNbStart,'bot', radius))
1283 self.file.write(' %s %s mask %s %s;\n' % (xEnd,yEnd,maskNbEnd,'top'))
1284 self.file.write('end_wire\n')
1285
1295
1305
1318
1323
1326
1328 if len(unit) == 1:
1329 return 1
1330
1331 if unit == 'MO':
1332 return 1e6
1333 factorPrefix = unit.upper()[:-1]
1334
1335
1336 factorMapWithCase = {'T':1e12,'G':1e9,'MEG':1e6,'k':1e3,'m':1e-3,'u':1e-6,'n':1e-9,'p':1e-12,'f':1e-15,'a':1e-18}
1337
1338 factorMap = {}
1339 for k,v in factorMapWithCase.iteritems():
1340 factorMap[k.upper()]=v
1341 conversionFactor = 1
1342 if factorPrefix in factorMap.keys():
1343 conversionFactor = factorMap[factorPrefix]
1344 else:
1345 msg = 'Unknown unit %s.' % unit
1346 eemWriteDebug(msg)
1347 raise UnitException(msg)
1348 return conversionFactor
1349
1351 if above:
1352 varName = "mask_%s_Zmax" % layerName
1353 else:
1354 varName = "mask_%s_Zmin" % layerName
1355 if addQuotes:
1356 return '"%s"' % varName
1357 else:
1358 return varName
1359
1361
1362 condV,condUnit = conductivityString.split()
1363
1364
1365 factorMap = {'GS':1e9,'MS':1e6,'kS':1e3,'S':1,'mS':1e-3,'uS':1e-6,'nS':1e-9,'pS':1e-12,'SIEMENS':1}
1366 conversionFactor = 1
1367 if condUnit in factorMap.keys():
1368 conversionFactor = factorMap[condUnit]
1369 else:
1370 if condUnit[-2:].upper()=='/M':
1371 condUnit = condUnit[:-2]
1372 if condUnit in factorMap.keys():
1373 conversionFactor = factorMap[condUnit]
1374 elif condUnit.upper() in factorMap.keys():
1375 conversionFactor = factorMap[condUnit.upper()]
1376 else:
1377 raise Exception('Unknown unit %s' % condUnit)
1378 resistivity = 1/(float(condV)*conversionFactor)
1379 return resistivity
1380
1384
1385
1386 - def _makeJedecDefinition(self,alpha="60 deg", beta="15 deg", h1="30 pct", radius="0.5 mil", numFaces=6, name=None):
1404
1406 profileName = eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', "ProfileName", 'value')
1407 height = float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', "JedecHeight", 'value'))
1408 alpha = float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', "JedecAlpha" , 'value'))
1409 beta = float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', "JedecBeta" , 'value'))
1410 radius = float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'Radius', 'value'))
1411
1412 drawingConversionFactor = getDrawingUnitConversionFactor(iCmp)
1413 radius = radius*drawingConversionFactor
1414 height = height*drawingConversionFactor
1415
1416 import empro
1417 bwDefs = empro.activeProject.bondwireDefinitions()
1418 for i in range(len(bwDefs)):
1419 bwDef = bwDefs[i]
1420 if bwDef.name != profileName:
1421 continue
1422 eemWriteDebug(" This bondwire matches definition with name '%s'" % profileName)
1423 return bwDef
1424
1425 eemWriteDebug(" Creating new bondwire definition '%s'" % profileName)
1426 created_bonddef = self._makeJedecDefinition(alpha = str(alpha)+" deg",beta = str(beta)+" deg", radius=radius,h1 = height,name=profileName)
1427 empro.activeProject.bondwireDefinitions().append(created_bonddef)
1428
1429
1430 bwDefs = empro.activeProject.bondwireDefinitions()
1431 bonddef_to_use = bwDefs[len(bwDefs)-1]
1432 return bonddef_to_use
1433
1435 cmpId = iCmp.getAttribute('id')
1436 bondId = inst.getAttribute('id')
1437
1438 name = "%s_%s" % (cmpId.replace('-','_'),bondId.replace('-','_'))
1439
1440 conductivityString = eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'Conductivity', 'value')
1441 resistivity = getResistivityFromConductivityString(conductivityString)
1442
1443 drawingConversionFactor = getDrawingUnitConversionFactor(iCmp)
1444 startLocation = inst.getElementsByTagName('Location')[0]
1445 xStart = drawingConversionFactor*float(startLocation.getAttribute('x'))
1446 yStart = drawingConversionFactor*float(startLocation.getAttribute('y'))
1447 xEnd = drawingConversionFactor*float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'xEnd', 'value'))
1448 yEnd = drawingConversionFactor*float(eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'yEnd', 'value'))
1449 maskNameStart = eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'Layer1', 'value')
1450 maskNameEnd = eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'Layer2', 'value')
1451 wireAbove = (eemGetElNodeAttrByTagAttrValue(inst, "Parameter", 'key', 'RelToSubstrate', 'value') == 'ABOVE')
1452
1453 eemWriteDebug("Found bondwire with name %s" % (name))
1454 bondwireDef = self.createOrGetBondwireProfileDefinition(iCmp,inst)
1455 zStart = _layerNameToVariable(maskNameStart,wireAbove,False)
1456 zEnd = _layerNameToVariable(maskNameEnd,wireAbove,False)
1457 import empro
1458 V=empro.geometry.Vector3d
1459 beginP = V(xStart,yStart,zStart)
1460 endP = V(xEnd,yEnd,zEnd)
1461 bw = empro.geometry.Bondwire(beginP,endP,None)
1462 bw.definition = bondwireDef
1463 model = empro.geometry.Model()
1464 model.name = name
1465 model.recipe.append(bw)
1466 if not wireAbove:
1467
1468 import math
1469 model.coordinateSystem.rotate(math.pi,0,0)
1470
1471 parameters = getInstanceParms(inst,toUpper=False)
1472 if parameters:
1473 for key,value in parameters.iteritems():
1474 try:
1475 model.addAttribute(key,str(value))
1476 except TypeError:
1477 model.addAttribute(key,"dummy_value")
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488 return model
1489
1507
1520
1522 return getParms(iCmp,toUpper,"ComponentParms")
1523
1524 -def getParms(iCmp,toUpper=True,groupName="ComponentParms"):
1525 keyValuePairs = {}
1526 if (iCmp.localName == groupName):
1527 cmpParms=iCmp
1528 else:
1529 cmpParms = iCmp.getElementsByTagName(groupName)
1530 if cmpParms and len(cmpParms)==1:
1531 cmpParms = cmpParms[0]
1532 else:
1533 return None
1534 parameterNodes = cmpParms.getElementsByTagName('Parameter')
1535 for pNodes in parameterNodes:
1536 key = pNodes.getAttribute('key')
1537 value = pNodes.getAttribute('value')
1538 if toUpper:
1539 key = key.upper()
1540 value = value.upper()
1541 keyValuePairs[key] = value
1542 eemWriteDebug(" Parameter %s : %s" % (key,value))
1543 return keyValuePairs
1544
1546 return getParms(iCmp,toUpper,"InstanceParms")
1547 InstanceParms
1548 InstanceParms
1549
1553
1555 R = 0
1556 L = 0
1557 C = 0
1558 if value.upper()[-3:]=='OHM':
1559 value = value[:-2]
1560 if value.upper()[-3:]=='MHO':
1561 value = value[:-3]+'S'
1562 try:
1563
1564 valueWithoutUnit = float(re.sub('[^0-9.]+','',value))
1565 except ValueError:
1566 return (R,L,C)
1567 unit = re.sub('[0-9.]+','',value)
1568 mainUnit = unit.upper()[-1:]
1569 if mainUnit in ['O','H','F','S']:
1570 if mainUnit == 'O':
1571 R = valueWithoutUnit * getRLCUnitConversionFactor(unit)
1572 elif mainUnit == 'H':
1573 L = valueWithoutUnit * getRLCUnitConversionFactor(unit)
1574 elif mainUnit == 'F':
1575 C = valueWithoutUnit * getRLCUnitConversionFactor(unit)
1576 elif mainUnit == 'S':
1577 R = 1/(valueWithoutUnit * getRLCUnitConversionFactor(unit))
1578 else:
1579 if partName in ['R','L','C']:
1580 if partName == 'R':
1581 unit += 'O'
1582 R = valueWithoutUnit * getRLCUnitConversionFactor(unit)
1583 elif partName == 'L':
1584 unit += 'H'
1585 L = valueWithoutUnit * getRLCUnitConversionFactor(unit)
1586 elif partName == 'C':
1587 unit += 'F'
1588 C = valueWithoutUnit * getRLCUnitConversionFactor(unit)
1589 else:
1590 eemWriteDebug('Found no unit in value %s. Taking Ohm as default' % value)
1591 unit += 'O'
1592 R = valueWithoutUnit * getRLCUnitConversionFactor(unit)
1593 return (R,L,C)
1594
1596 if not value:
1597 return None
1598
1599 try:
1600 (R,L,C) = self.valueToRLC(value,partName)
1601 except UnitException:
1602 return None
1603 if (R,L,C) == (0,0,0):
1604 return None
1605 eemWriteDebug(" Component with (R,L,C) = (%s,%s,%s)" % (R,L,C))
1606 import empro
1607 cdefs = empro.activeProject.circuitComponentDefinitions()
1608 for i in range(len(cdefs)):
1609 cmp = cdefs[i]
1610 if (cmp.impedance.resistance != R or cmp.impedance.inductance != L or cmp.impedance.capacitance != C) :
1611 continue
1612 if cmp.impedance.elementArrangement != "Series":
1613 continue
1614 eemWriteDebug(" This component matches definition with name '%s'" % cmp.name)
1615 return cmp
1616
1617 name = "%s Passive Load"%value
1618 newCmp = empro.components.PassiveLoad(name)
1619 newCmp.impedance.resistance = R
1620 newCmp.impedance.inductance = L
1621 newCmp.impedance.capacitance = C
1622 newCmp.impedance.elementArrangement = "Series"
1623 newCmp.name = "%s Passive Load"%value
1624 empro.activeProject.circuitComponentDefinitions().append(newCmp)
1625 cdefs = empro.activeProject.circuitComponentDefinitions()
1626 newCmp = cdefs[len(cdefs)-1]
1627 return newCmp
1628
1629
1631
1632 ports = iCmp.getElementsByTagName('PortDescription')
1633 cmpName = (eemGetElNodeValByTag(iCmp, 'Name')).strip()
1634 if len(ports) > 2:
1635 eemWriteWarn(" Components with more than 2 pins not supported! Only using pin 1 and 2 of %s." % cmpName)
1636 if len(ports) == 1:
1637 eemWriteWarn(" Components with only 1 pin not supported!")
1638 tailDef = None
1639 headDef = None
1640 for p in ports:
1641 pinName = eemGetElNodeValByTag(p, 'PinName')
1642 pinNumber = int(eemGetElNodeValByTag(p, 'PinNumber'))
1643 pinLayerName = eemGetElNodeValByTag(p, 'LayerName')
1644 netName = eemGetElNodeValByTag(p, 'NetName')
1645 if netName == None:
1646 netName = ''
1647 (xLoc,yLoc)= eemAdfiGetLocation(p)
1648 eemWriteDebug(" Port %s (nb %s) on %s at (%s,%s) on net %s" % (pinName,pinNumber,pinLayerName,xLoc,yLoc,netName))
1649 pin = {}
1650 pin['x' ] = float(xLoc)
1651 pin['y' ] = float(yLoc)
1652 pin['zLayer' ] = pinLayerName
1653 pin['name' ] = pinName
1654 pin['number' ] = pinNumber
1655 pin['netName'] = netName
1656 if pinNumber == 1:
1657 tailDef = pin
1658 elif pinNumber == 2:
1659 headDef = pin
1660 else:
1661 if tailDef == None:
1662 tailDef = pin
1663 elif headDef == None:
1664 headDef = pin
1665 if not headDef or not tailDef:
1666 includeInvalidComponents = False
1667 if includeInvalidComponents:
1668 if headDef or tailDef:
1669 headDef = tailDef or headDef
1670 tailDef = tailDef or headDef
1671 eemWriteWarn(" Colocating pins of %s since only one found in .adfi file!"%cmpName)
1672 return (tailDef,headDef)
1673
1675 cmpName = eemGetElNodeValByTag(iCmp, 'Name')
1676 if iCmp.hasAttribute('id'):
1677 id = iCmp.getAttribute('id')
1678 else:
1679 id = 'Unknown component'
1680 eemWriteDebug("Found component with name %s and id %s" % (cmpName,id))
1681 parameters = getComponentParms(iCmp)
1682 above = True
1683 compDef = None
1684 if (parameters and parameters.has_key('VALUE')):
1685 CmpValue = parameters['VALUE']
1686 try:
1687 compDef = self.createOrGetComponentDefinition(CmpValue,partName=parameters['PART_NAME'])
1688 except KeyError:
1689 compDef = self.createOrGetComponentDefinition(CmpValue)
1690 if (parameters and parameters.has_key('RELATIVE_TO_SUBSTRATE')):
1691 relToSub = parameters['RELATIVE_TO_SUBSTRATE']
1692 if relToSub.upper() == 'BELOW':
1693 above = False
1694 conversionFactor = getDrawingUnitConversionFactor(iCmp)
1695 tailDef,headDef = self.getPins(iCmp)
1696 if not tailDef or not headDef:
1697 eemWriteWarn(" Component %s not imported due to incorrect or unsupported pin setup!"%cmpName)
1698 return None
1699
1700 import empro
1701 newCmp=empro.components.CircuitComponent()
1702 newCmp.name= "%s %s" % (cmpName,id)
1703 newCmp.definition=compDef
1704 newCmp.port = False
1705 newCmp.notes = "Component imported from .adfi file.\nParameter values: \n%s\nDrawing unit conversion factor %s" % (str(parameters),conversionFactor)
1706 V=empro.geometry.Vector3d
1707 if headDef:
1708 newCmp.head=V(conversionFactor*headDef['x'],conversionFactor*headDef['y'],_layerNameToVariable(headDef['zLayer'],above,False))
1709 if tailDef:
1710 newCmp.tail=V(conversionFactor*tailDef['x'],conversionFactor*tailDef['y'],_layerNameToVariable(tailDef['zLayer'],above,False))
1711 return newCmp
1712
1713
1725
1726
1729 self.sbMaterials={}
1730 self.pkgLayer = ""
1731 self.compType = "flipchip"
1732
1734 conversionFactor = getDrawingUnitConversionFactor(iCmp)
1735 try:
1736 if self.compType == "flipchip":
1737 pinLayer = self.parameters['ICPKG_PIN_LAYER']
1738 else:
1739 pinLayer = self.parameters['PKG_PIN_LAYER_ATPKG']
1740 pins = iCmp.getElementsByTagName('PortDescription')
1741 sbLocs = []
1742 for pin in pins:
1743 layerName = eemGetElNodeValByTag(pin, 'LayerName')
1744 if layerName != pinLayer:
1745 if self.pkgLayer != layerName:
1746 eemWriteDebug("Found package layer %s" % (layerName))
1747 self.pkgLayer = layerName
1748 continue
1749 pinName = eemGetElNodeValByTag(pin, 'PinName')
1750 (x,y) = eemAdfiGetLocation(pin)
1751 x = float(x) * conversionFactor
1752 y = float(y) * conversionFactor
1753 eemWriteDebug("Found ball on location %s,%s" % (x,y))
1754 sbLocs.append((x,y,pinName))
1755 return sbLocs
1756 except:
1757 return []
1758
1760 if sbComps == None:
1761 sbComps = {}
1762 components = iDom.getElementsByTagName('AdfiComponent')
1763 import empro
1764 for iCmp in components:
1765 self.parameters = getComponentParms(iCmp)
1766 if (self.parameters):
1767 if self.parameters.has_key('ICPKG_TYPE') and self.parameters['ICPKG_TYPE'] == 'DIE_FLIPCHIP':
1768 self.compType = "flipchip"
1769 elif self.parameters.has_key('PKG_TYPE') and self.parameters['PKG_TYPE'] == 'BGA':
1770 self.compType = "bga"
1771 else:
1772 continue
1773 else:
1774 continue
1775 eemWriteDebug("Found component with solder balls.")
1776 id = iCmp.getAttribute('id')
1777 if self.compType == "flipchip":
1778 h = self.parameters["ICPKG_BUMP_HEIGHT"].lower()
1779 widthMax = self.parameters["ICPKG_BUMP_DIAMETER_MAX"].lower()
1780 widthFaceNear = self.parameters["ICPKG_BUMP_DIAMETER_ATDIE"].lower()
1781 widthFaceFar = self.parameters["ICPKG_BUMP_DIAMETER_ATPKG"].lower()
1782 bumpLayer = self.parameters['ICPKG_BUMP_LAYER']
1783 pinLayer = self.parameters['ICPKG_PIN_LAYER']
1784 relToSub = self.parameters['RELATIVE_TO_SUBSTRATE']
1785 conductivityString = self.parameters["ICPKG_BUMP_CONDUCTIVITY"]
1786 else:
1787 h = self.parameters["PKG_BALL_HEIGHT"].lower()
1788 try:
1789 widthMax = self.parameters["PKG_BALL_DIAMETER"].lower()
1790 except:
1791 widthMax = self.parameters["PKG_BALL_DIAMETER_MAX"].lower()
1792 widthFaceNear = self.parameters["PKG_BALL_DIAMETER_ATPKG"].lower()
1793 widthFaceFar = self.parameters["PKG_BALL_DIAMETER_ATBRD"].lower()
1794 bumpLayer = self.parameters['PKG_BALL_LAYER']
1795 pinLayer = self.parameters['PKG_PIN_LAYER_ATPKG']
1796
1797 relToSub = 'ABOVE'
1798
1799 conductivityString = "6.897e+006 Siemens/m"
1800 widthFace = "((%s)+(%s))/2.0" % (widthFaceNear,widthFaceFar)
1801
1802 resistivity = getResistivityFromConductivityString(conductivityString)
1803
1804 import re
1805 value = widthFaceNear
1806 valueWithoutUnit = float(re.sub('[A-Z]+','',value.upper()))
1807 unit = re.sub('[0-9. ]+','',value)
1808 radius = valueWithoutUnit * getRLCUnitConversionFactor(unit)
1809 above = True
1810 if relToSub.upper() == 'BELOW':
1811 above = False
1812 divisions = 3
1813 import math
1814 arcRes = "45 deg"
1815 portList = self.findPorts(iCmp)
1816 V=empro.geometry.Vector3d
1817 z = _layerNameToVariable(bumpLayer,above,addQuotes=False)
1818 if above:
1819 z = "(%s) - (%s)" % (z,h)
1820 eemWriteDebug ("z dim = %s" %(z))
1821 session=empro.toolkit.ads_import.Import_session(units="um", wall_boundary="Radiation")
1822 arcResParName = "solderBall_%s_arcRes"%id
1823 divisionsParName = "solderBall_%s_divisions"%id
1824 session.create_parameter(divisionsParName,str(divisions),"Nb of divisions of solderBalls of %s"%id,True)
1825 session.create_parameter(arcResParName,str(arcRes),"Arc resolution of solderBalls of %s"%id,True)
1826 sb = empro.geometry.SolderBall(h,widthFace,widthMax,divisionsParName,arcResParName)
1827 for (x,y,name) in portList:
1828 eemWriteDebug ("Creating ball with h=%s, wFace=%s, wMax=%s" %(h,widthFace,widthMax))
1829 model = empro.geometry.Model()
1830
1831 for key,value in self.parameters.iteritems():
1832 try:
1833 model.addAttribute(key,str(value))
1834 except TypeError:
1835 model.addAttribute(key,"dummy_value")
1836 model.name = id+"_"+name
1837 model.recipe.append(sb.clone())
1838 anchorPoint = empro.geometry.CoordinateSystemPositionExpression(V(x,y,z))
1839 eemWriteDebug ("anchorPoint z %s" %( anchorPoint.position))
1840 model.coordinateSystem.anchorPoint = anchorPoint
1841 paramMap = {}
1842 paramMap['comp_id'] = id
1843 paramMap['radius'] = radius
1844 paramMap['resistivity'] = resistivity
1845 paramMap['x'] = x
1846 paramMap['y'] = y
1847 paramMap['above'] = above
1848 paramMap['mask_top'] = pinLayer
1849 paramMap['mask_bottom'] = self.pkgLayer
1850 paramMap['material_name'] = bumpLayer
1851 sbComps[model.name]=(id,model,paramMap)
1852 return sbComps
1853
1875
1890
1891
1892
1893
1894
1895
1896
1897
1900 self.fPrefix = fPrefix
1901 self.ltdMap = {}
1902 self.ltdRevMap = {}
1903 self.ltds = {}
1904 self.instMergeMap = {'main':{'idx':-1},
1905 'top':{'idx':-1},
1906 'bottom':{'idx':-1}}
1907 self.top = None
1908 self.topInstancesMap = {}
1909 self.topSlmData = None
1910 self.topSlmDataFileName = None
1911 self.topLtdData = None
1912 self.topSlmFile = None
1913 self.topLtdFile = None
1914 self.topSubName = None
1915 self.topTypeLtdOrSlm = None
1916
1918 eemWriteDebug("Process layer stack informations")
1919
1920 self.__minimizeLtds()
1921 try:
1922 self.__writeTopSlmFile()
1923 except:
1924 eemWriteError("Problem writing top slm technology file output: need to exit")
1925 raise
1926 try:
1927 self.__writeLtdFiles()
1928 except:
1929 eemWriteError("Problem with ltd technology file output: need to exit")
1930 raise
1931 try:
1932 if self.__mergeLtdFiles()!=0:
1933 raise ValueError
1934 except:
1935 eemWriteError("Problem with ltd technology file merge: need to exit")
1936 raise
1937 try:
1938 self.__convertLtdToSlm()
1939 except:
1940 eemWriteError("Problem with ltd to slm file conversion")
1941 raise
1942 eemWriteDebug("Process layer stack informations done")
1943
1944
1949
1951 eemWriteDebug("Add component with layer stack information")
1952
1953 subName = eemGetElNodeValByTag(iDocNode, 'SubstrateName')
1954 if subName == None:
1955 subName=cmpName
1956
1957 subData = iDocNode.getElementsByTagName('SubstrateData')
1958 if (subData):
1959 ltdOrSlm = getInnerText(subData[0])
1960 typeLtdOrSlm = subData[0].getAttribute('substrateDataType')
1961 if typeLtdOrSlm=='ltd':
1962 ltd = ltdOrSlm
1963 v=None
1964 if ltd in self.ltdMap.keys():
1965 v = self.ltdMap[ltd]
1966 else:
1967 v = len(self.ltdMap)
1968 self.ltds[v]=ltd
1969 self.ltdMap[ltd]=v
1970 self.ltdRevMap[subName]=v
1971 self.ltdRevMap[cmpName]=v
1972 if (top):
1973 eemWriteDebug("Top components %s with layer stack information identified %s" % (self.top,str(typeLtdOrSlm)))
1974 self.topTypeLtdOrSlm=typeLtdOrSlm
1975 self.topSubName=subName
1976 if typeLtdOrSlm=='ltd':
1977 self.topLtdData=ltdOrSlm
1978 elif typeLtdOrSlm=='slm':
1979 self.topSlmData=ltdOrSlm
1980 elif typeLtdOrSlm=='ltdFile':
1981 self.topLtdFile==ltdOrSlm
1982 elif typeLtdOrSlm=='slmFile':
1983 self.topSlmFile==ltdOrSlm
1984 eemWriteDebug("Component with layer stack information identified")
1985
1987 eemWriteDebug("Add component instances with layer stack information")
1988 instances = iDocNode.getElementsByTagName('Instance')
1989 for inst in instances:
1990 instName = inst.getAttribute('id')
1991 side = 'main'
1992 layer = None
1993 instMap= {}
1994 direct = None
1995 instMap['cmpName']=(eemGetElNodeValByTag(inst, 'Component')).strip()
1996 subMerge = inst.getElementsByTagName('MergeAtInterface')
1997 if subMerge:
1998 direct = subMerge[0].getAttribute('mergeDirection')
1999 layer = (getInnerText(subMerge[0])).strip()
2000 if direct == 'up':
2001 side = 'top'
2002 elif direct == 'down':
2003 side = 'bottom'
2004 instMap['direct'] = direct
2005 instMap['side'] = side
2006 instMap['layer'] = layer
2007 self.topInstancesMap[instName] = instMap
2008
2009 eemWriteDebug("Component instances with layer stack information identified")
2010
2012 eemWriteDebug("Find duplicate layer stacks")
2013 instances = self.topInstancesMap
2014
2015 if self.topLtdData!=None:
2016 cmap=self.instMergeMap['main']
2017 cmap['idx'] = self.ltdRevMap[self.top]
2018 cmap['instNames'] = [self.top]
2019 cmap['layer'] = None
2020 self.instMergeMap['main']=cmap
2021
2022 for instName,instMap in instances.iteritems():
2023 cmpName = instMap['cmpName']
2024 if not(instName in self.ltdRevMap.keys()
2025 or cmpName in self.ltdRevMap.keys()):
2026 continue
2027
2028
2029
2030 side = instMap['side']
2031 layer = instMap['layer']
2032 cmap = self.instMergeMap[side]
2033 if cmap['idx']<0:
2034 cmap['idx'] = self.ltdRevMap[instName]
2035 aList = []
2036 aList.append(instName)
2037 cmap['instNames'] = aList
2038 if layer:
2039 cmap['layer'] = layer
2040 else:
2041 if ((cmap['idx'] != self.ltdRevMap[instName])
2042 or (cmap['idx'] != self.ltdRevMap[cmpName])
2043 or (layer != None
2044 and 'layer' in cmap.keys()
2045 and cmap['layer'] != layer)):
2046 eemWriteWarn("Found different %s substrate definitions: keep first." % side)
2047 aList = cmap['instNames']
2048 aList.append(instName)
2049 cmap['instNames'] = aList
2050
2051 self.instMergeMap[side] = cmap
2052
2053
2054 idxMap = {}
2055 instFound = []
2056 for wLtd in self.instMergeMap.keys():
2057 aList=[]
2058 cmap = self.instMergeMap[wLtd]
2059 idx = cmap['idx']
2060 if idx >= 0:
2061 idxMap[idx] = wLtd
2062 aList = cmap['instNames']
2063 instFound.extend(aList)
2064
2065 for iKey in self.ltdRevMap.keys():
2066 if iKey in instFound:
2067 continue
2068 ltdIdx = self.ltdRevMap[iKey]
2069 a = []
2070 if ltdIdx not in idxMap.keys():
2071 cmap = {'idx':ltdIdx}
2072 a.append(iKey)
2073 cmap['instNames'] = a
2074 self.instMergeMap[iKey] = cmap
2075 idxMap[ltdIdx] = iKey
2076 else:
2077 cmap = self.instMergeMap[idxMap[ltdIdx]]
2078 a = cmap['instNames']
2079 a.append(iKey)
2080 cmap['instNames']= a
2081 self.instMergeMap[idxMap[ltdIdx]] = cmap
2082 eemWriteDebug("Duplicates in layer stacks identified")
2083
2085 eemWriteDebug("Write the found layer stacks")
2086 fPrefix=self.fPrefix
2087 for ltdName,ltdMap in self.instMergeMap.iteritems():
2088 if ltdMap['idx']<0:
2089 continue
2090 fName = fPrefix + "_" + str(ltdName) + ".ltd"
2091 ltdMap['ltdFile'] = fName
2092 fp = open(fName, 'w')
2093 fp.write(self.ltds[ltdMap['idx']])
2094 fp.close()
2095 self.instMergeMap[ltdName]=ltdMap
2096 eemWriteDebug("Writing layer stacks done")
2097
2099 fPrefix=self.fPrefix
2100 if self.topSlmData!=None:
2101 eemWriteDebug("Write top slm file")
2102 fName = fPrefix + "_" + self.topSubName + ".slm"
2103 self.topSlmDataFileName=fName
2104 fp = open(fName, 'w')
2105 fp.write(self.topSlmData)
2106 fp.close()
2107
2109 topComponent=self.top
2110 fPrefix=self.fPrefix
2111 eemWriteDebug("Start merge with %s for %s" % (fPrefix,topComponent))
2112 bottom = self.instMergeMap['bottom']
2113 main = self.instMergeMap['main']
2114 top = self.instMergeMap['top']
2115 r = 0
2116 fIn1 = ''
2117 fIn2 = ''
2118 fOut = ''
2119 insts=[]
2120 insts.append(topComponent)
2121 verOk = eemIsValidSubedVersion()
2122 if (main['idx']<0
2123 or (bottom['idx']<0 and top['idx']<0)
2124 or not verOk):
2125 eemWriteDebug("No merge needed or can not merge: use main substrate")
2126 fOut = main['ltdFile']
2127 elif bottom['idx']>0 and top['idx']<0:
2128 fIn1 = bottom['ltdFile']
2129 fIn2 = main['ltdFile']
2130 fOut = fPrefix + '_bottom_main.ltd'
2131 r=eemMergeLtdFile(fIn1, fIn2, fOut)
2132 elif bottom['idx']<0 and top['idx']>0:
2133 fIn1 = main['ltdFile']
2134 fIn2 = top['ltdFile']
2135 fOut = fPrefix + '_main_top.ltd'
2136 r=eemMergeLtdFile(fIn1, fIn2, fOut)
2137 else:
2138 fIn1 = bottom['ltdFile']
2139 fIn2 = main['ltdFile']
2140 fOut = fPrefix + '_bottom_main.ltd'
2141 r=eemMergeLtdFile(fIn1, fIn2, fOut)
2142 if r==0:
2143 fIn1 = fOut
2144 fIn2 = top['ltdFile']
2145 fOut = fPrefix + '_bottom_main_top.ltd'
2146 r=eemMergeLtdFile(fIn1, fIn2, fOut)
2147 merge = {}
2148 merge['idx']=len(self.ltds)
2149 if r == 0:
2150 merge['ltdFile']=fOut
2151 else:
2152 merge['ltdFile']=main['ltdFile']
2153 merge['instNames']=insts
2154 self.instMergeMap['merge'] = merge
2155 eemWriteDebug("Merge of layerstacks %s for %s done" % (fPrefix,topComponent))
2156 return r
2157
2159 eemWriteDebug("Convert ltd to slm and lay files")
2160 fOutNames = []
2161 r=0
2162 for mapName,mergeMap in self.instMergeMap.iteritems():
2163 if 'ltdFile' in mergeMap.keys():
2164 fIn = mergeMap['ltdFile']
2165 fInSplit = os.path.splitext(fIn)
2166 fOut = fInSplit[0] + '.slm'
2167 if fOut not in fOutNames:
2168 fOutNames.append(fOut)
2169 r=eemConverLtdToSlmFile(fIn, fOut)
2170 mergeMap['slmFile']=fOut
2171 self.instMergeMap[mapName]=mergeMap
2172 eemWriteDebug("Conversion ltd to slm and lay files done")
2173
2176
2178 eemWriteDebug("Check for stack info of %s" % iName)
2179 name = self.top
2180 if iName:
2181 name = iName
2182 if (not((name == self.top)
2183 or (name in self.ltdRevMap.keys()))):
2184 return None
2185
2186 if self.topSlmDataFileName!=None :
2187 return self.topSlmDataFileName
2188 if self.topSlmFile!=None :
2189 return self.topSlmFile
2190
2191 slmName=None
2192 for mapName,mergeMap in self.instMergeMap.iteritems():
2193 if (('slmFile' in mergeMap.keys())
2194 and ('instNames' in mergeMap.keys())
2195 and (name in mergeMap['instNames'])):
2196 slmName = mergeMap['slmFile']
2197 break
2198 if ((name == None) or
2199 (slmName == None)):
2200 slmName = self.instMergeMap['main']['slmFile']
2201 eemWriteDebug("No valid slm file found: return main substrate instead")
2202 return slmName
2203
2205 eemWriteDebug("Check for stack info of %s ltd version" % iName)
2206 name = self.top
2207 if iName:
2208 name = iName
2209 if ((name != self.top)
2210 and (name not in self.ltdRevMap.keys())):
2211 return None
2212
2213 if self.topLtdFile!=None :
2214 return self.topLtdFile
2215
2216 for mapName,mergeMap in self.instMergeMap.iteritems():
2217 if (('ltdFile' in mergeMap.keys())
2218 and ('instNames' in mergeMap.keys())
2219 and (name in mergeMap['instNames'])):
2220 ltdFile = mergeMap['ltdFile']
2221 break
2222 if ((name == None) or
2223 (ltdFile == None)):
2224 ltdFile = self.instMergeMap['main']['ltdFile']
2225 eemWriteDebug("No valid ltd file found: return main substrate instead")
2226 return ltdFile
2227
2229 import subprocess
2230 try:
2231 startupinfo = subprocess.STARTUPINFO()
2232 startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
2233 except AttributeError:
2234 startupinfo = None
2235 return startupinfo
2236
2243
2245 import subprocess,re,os,string
2246 envVars = subedRemoveFromEnviron_QtQpaPluginPlatform()
2247 subedCmd = ['eesofsubed','--version']
2248
2249 eemWriteDebug("Check subed version: %s" % subedCmd)
2250 myProcess = subprocess.Popen(args=subedCmd,
2251 executable=None,
2252 stdin=None,
2253 stdout=subprocess.PIPE,
2254 stderr=subprocess.PIPE,
2255 universal_newlines=True,
2256 startupinfo=subProcessStartupInfo(),
2257 shell=False,
2258 env=envVars)
2259
2260 if 'wait' in dir(os):
2261 cmdStatus=os.wait()
2262
2263 res=''.join(myProcess.stdout.readlines())
2264 rMatch=re.search('Substrate Editor v(?P<version>[0-9]+\.[0-9]+)',res,re.M)
2265 val=0.0
2266 if rMatch!=None:
2267 val=float(rMatch.group(1))
2268 valNeeded = 2.1
2269 if val < valNeeded:
2270 eemWriteInfo("No valid EESof Substrate Editor found: needs version %s or higher (should be available in ADS 2009 / EMPro 2011.07 or later)" % valNeeded)
2271 print sys.path
2272 print os.environ['PATH']
2273 return False
2274 eemWriteDebug("Found valid EESof Substrate Editor")
2275 return True
2276
2277
2279 envVars = subedRemoveFromEnviron_QtQpaPluginPlatform()
2280 subedCmd = 'eesofsubed -M --stack --pos2=top1 --out='
2281 subedCmd = subedCmd + fOut
2282 subedCmd = ' '.join([subedCmd, fIn1, fIn2])
2283
2284 eemWriteDebug("Ltd merge operation: %s" % subedCmd)
2285
2286 myProcess = subprocess.Popen(args=subedCmd,
2287 executable=None,
2288 stdin=None,
2289 stdout=subprocess.PIPE,
2290 stderr=subprocess.PIPE,
2291 universal_newlines=True,
2292 startupinfo=subProcessStartupInfo(),
2293 shell=True,
2294 env=envVars)
2295
2296 if 'wait' in dir(os):
2297 cmdStatus=os.wait()
2298
2299 res=''.join(myProcess.stdout.readlines())
2300 if re.search('(Merged stack saved)',res,re.M) == None:
2301 errorString = "Problem merging ltd files: %s and %s into %s\n" % (fIn1, fIn2,fOut)
2302 errorString = errorString + "Process output:\n%s" % res
2303 eemWriteDebug(errorString)
2304 raise Exception(errorString)
2305
2306 eemWriteDebug("Success merging ltd files: %s and %s into %s" % (fIn1, fIn2,fOut))
2307 return 0
2308
2309
2311 envVars = subedRemoveFromEnviron_QtQpaPluginPlatform()
2312 subedCmd = 'eesofsubed -C --ltd2slm'
2313 fIn = '\"' + ifIn + '\"'
2314 fOut = '\"' + ifOut + '\"'
2315 subedCmd = ' '.join([subedCmd, fIn, fOut])
2316
2317 eemWriteDebug("Ltd to slm conversion: %s" % subedCmd)
2318
2319 myProcess = subprocess.Popen(args=subedCmd,
2320 executable=None,
2321 stdin=None,
2322 stdout=subprocess.PIPE,
2323 stderr=subprocess.PIPE,
2324 universal_newlines=True,
2325 startupinfo=subProcessStartupInfo(),
2326 shell=True,
2327 env=envVars)
2328
2329 if 'wait' in dir(os):
2330 cmdStatus=os.wait()
2331
2332 res=''.join(myProcess.stdout.readlines())
2333 if re.search('(Export successful)',res,re.M) == None:
2334 errorString = "Converting ltd to slm file failed for: %s to %s\n" % (fIn, fOut)
2335 errorString = errorString + "Process output:\n%s" % res
2336 eemWriteDebug(errorString)
2337 raise Exception(errorString)
2338
2339 eemWriteDebug("Ltd to slm file conversion success: %s to %s\n" % (fIn, fOut))
2340
2341
2344 self.layName = adfiPrefix + '.lay'
2345 self.layDisplayPrefName = adfiPrefix + '.lyrprf'
2346 self.lineTypes = {'solid':0,
2347 'dotted':1,
2348 'double dotted':2,
2349 'short dash':3,
2350 'short dot dash':4,
2351 'long dash':5,
2352 'long dot dash':6}
2353 self.layerData=[]
2354 self.egsProcess=None
2355
2357 if (iLayerDataNode!=None
2358 and self.layerData==[]):
2359 substrateLayerDataNode=iLayerDataNode.getElementsByTagName('SubstrateLayerData')
2360 if substrateLayerDataNode:
2361 clNode=substrateLayerDataNode[0].cloneNode(True)
2362 self.layerData=clNode.getElementsByTagName('SubstrateLayer')
2363
2365 self.egsProcess=iEgsHeader
2366
2368 eemWriteDebug("Extract the lay file from adfi elements")
2369
2370 if (self.egsProcess==""
2371 and self.layerData==[]):
2372 raise Exception('Both SubstrateLayerData and egs process data are missing')
2373
2374 outFormat='%s\tnumber = %s stream = %s iges = %s color = %s fill = %s line = %s, %s %s %s, \"%s\", type = %s, dxf = \"%s\" trans = %s\n'
2375
2376 try:
2377 fName = self.layName
2378 layerData = self.layerData
2379 lineTypes = self.lineTypes
2380 eemWriteDebug("Layer filename is: %s" % fName)
2381 eemWriteDebug("version and layerdata is: %d, %s" % (mainVersion, layerData))
2382 layFp = open(fName,"w")
2383 if not ((mainVersion < 4) or (layerData==[])):
2384 eemWriteDebug("Version 4 or higher and SubstrateLayer data for this to work.")
2385 first=True
2386 for i in layerData:
2387 layerName = i.getElementsByTagName('LayerName')[0].childNodes[0].nodeValue
2388 layerNum = i.getAttribute('id')
2389 if first:
2390 layFp.write( 'CurrentLayer number = ' + str(layerNum) + '\n' )
2391 first=None
2392
2393 layerColor = i.getElementsByTagName('LayerColor')
2394 color='1'
2395 if layerColor!=[]:
2396 color=layerColor[0].getAttribute('id')
2397
2398 line='0'
2399 fill='1'
2400 pattern='18'
2401 trans='50'
2402 layerParms = i.getElementsByTagName('Parameter')
2403 for parm in layerParms:
2404 key = parm.getAttribute('key')
2405 value = parm.getAttribute('value')
2406 eemWriteDebug('%s %s'%( key, value))
2407 if key == 'fill':
2408 val=1
2409 if value == 'outline':
2410 val=0
2411 elif value == 'both':
2412 val=2
2413 fill = str(val)
2414 elif key == 'line':
2415 line = str(lineTypes[value])
2416 elif key == 'trans':
2417 trans = str(value)
2418 elif key == 'pattern':
2419 pattern = str(value)
2420 layFp.write( outFormat % (layerName, layerNum, layerNum, layerNum, color,
2421 pattern, line, fill, '0', '1', '', '1', layerName, trans) )
2422 else:
2423 eemWriteDebug("do it from egs process data if necessary")
2424 layers=re.findall('EQU\s+(\w+).*?[:Cc](\d+)\s+:[P]\d+\s+(\d+);', process, re.M)
2425 first=True
2426 for layerName, color, layerNum in layers:
2427 if layerName!='default':
2428 if first:
2429 layFp.write( 'CurrentLayer number = ' + str(layerNum) + '\n' )
2430 first=None
2431 line='0'
2432 fill='1'
2433 pattern='1'
2434 trans='50'
2435 layFp.write( outFormat % (layerName, layerNum, layerNum, layerNum, color,
2436 pattern, line, fill, '0', '1', '', '1', layerName, trans) )
2437
2438 layFp.close()
2439 eemWriteDebug("Done: Extract the lay file from adfi elements")
2440
2441 except:
2442 eemWriteError("Can not write lay file info from ADS ADFI file.")
2443 raise
2444
2446 eemWriteDebug("Extract the layer preference setting and put them into the output")
2447
2448 try:
2449 lineTypes = self.lineTypes
2450 fName = self.layDisplayPrefName
2451 eemWriteDebug("Layer preference filename is: %s" % fName)
2452 lyrFp = open(fName,"w")
2453 if mainVersion<4:
2454
2455 lyrFp.close()
2456 raise Exception('Main version needs to be >= 4')
2457
2458 layerData = self.layerData
2459
2460 if layerData==[]:
2461 lyrFp.close()
2462 raise Exception('No layer data found')
2463
2464 for i in layerData:
2465 line = ""
2466 layerName = i.getElementsByTagName('LayerName')[0].childNodes[0].nodeValue
2467 eemWriteDebug("layer name %s" % layerName)
2468
2469 line = "layer|" + layerName
2470 layerColor = i.getElementsByTagName('LayerColor')
2471 eemWriteDebug("layer name %s" % str(layerColor))
2472 if layerColor!=[]:
2473 r=layerColor[0].getAttribute('r')
2474 g=layerColor[0].getAttribute('g')
2475 b=layerColor[0].getAttribute('b')
2476 line = line + '|red|' + r + '|green|' + g + '|blue|' + b
2477 eemWriteDebug("layer %s color r=%s g=%s b=%s" % (layerName,r,g,b))
2478
2479 layerParms = i.getElementsByTagName('Parameter')
2480 eemWriteDebug("layer parms %s" % str(layerParms))
2481 fillVal=1
2482 lineVal=0
2483 otherLine=''
2484 for parm in layerParms:
2485 key = parm.getAttribute('key')
2486 value = parm.getAttribute('value')
2487 if key == 'fill':
2488 if value == 'outline':
2489 fillVal=0
2490 elif value == 'both':
2491 fillVal=2
2492 elif key == 'line':
2493 lineVal = value
2494 else:
2495 otherLine = otherLine + "|" + str(key) + "|" + str(value)
2496
2497 line = line + "|fill|" + str(fillVal)
2498 line = line + "|line|" + str(lineTypes[lineVal])
2499 line = line + otherLine
2500 line = line + "\n"
2501 lyrFp.write(line)
2502 lyrFp.close()
2503 eemWriteDebug("Done: Extract the layer preference setting and put them into the output")
2504
2505 except Exception, err:
2506 errorString = "Cannot write display preference info from ADS ADFI file.\n%s" % str(err)
2507 eemWriteDebug(errorString)
2508 raise Exception(errorString)
2509
2511 - def __init__( self, targetDir, adfiPrefix, iLibName=''):
2512 self.present_ = False
2513 self.useAblRoot_ = False
2514 self.targetDir = targetDir
2515 self.fPrefix = adfiPrefix
2516 self.name = iLibName
2517 self.libName = ''
2518 self.refTechnologies = []
2519 self.userUnits = None
2520 self.DBUperUU = None
2521 self.instTextHeight='0.'
2522 self.portSize='0.'
2523 self.processTypes = {'Not defined':'PROCESS_ROLE_NONE',
2524 'Conductor':'PROCESS_ROLE_CONDUCTOR',
2525 'Dielectric':'PROCESS_ROLE_DIELECTRIC'}
2526
2527 self.lineTypes = {'solid':0,
2528 'dotted':1,
2529 'double dotted':2,
2530 'short dash':3,
2531 'short dot dash':4,
2532 'long dash':5,
2533 'long dot dash':6,
2534 'Solid':0,
2535 'Dotted':1,
2536 'Double Dotted':2,
2537 'Short Dash':3,
2538 'Short Dot Dash':4,
2539 'Long Dash':5,
2540 'Long Dot Dash':6}
2541 self.patternTypes = {'solid':18,'Solid':18,'18':18 }
2542 self.fillTypes = {'Outlined':0,'outline':0,
2543 'Filled':1,'filled':1,
2544 'Both':2,'both':2}
2545 self.unitsMap = {'um':'micron',
2546 'micron':'micron',
2547 'mm':'millimeter',
2548 'millimeter':'millimeter',
2549 'cm':'centimeter',
2550 'centimeter':'centimeter',
2551 'meter':'meter',
2552 'mil':'mil',
2553 'inch':'inch'}
2554 self.maskNameNbMap = {}
2555 self.layers = []
2556 self.layerIds = []
2557 self.defaultSubstrate = None
2558 self.substrateList = []
2559 self.ebondsList = []
2560
2561 - def present( self, status=None ):
2562 if status!=None:
2563 self.present_=status
2564 return self.present_
2565
2567 return self.useAblRoot_
2568
2570 return self.maskNameNbMap
2571
2573 eemWriteDebug("Process ABL library data")
2574 self.present_=True
2575 if ablNode.tagName == 'abl:ABLRoot':
2576 self.useAblRoot_=True
2577 libraryNode=ablNode.getElementsByTagName('abl:Library')[0]
2578 if libraryNode.hasAttribute('name') and (self.libName=='' or self.libName==None):
2579 self.libName = libraryNode.getAttribute('name')
2580 else:
2581 self.libName = self.name
2582
2583 techNode=ablNode.getElementsByTagName('abl:Technology')[0]
2584 self.getRefTechnologies( techNode )
2585 self.getUnits( techNode )
2586 self.getLayers( techNode )
2587 self.getLayerIds( techNode )
2588 self.getMaterials( techNode )
2589 self.getSubstrates( techNode )
2590 self.getPreferences( ablNode )
2591 self.getEBondProfiles( ablNode )
2592 if self.libName != self.name:
2593 libraryNode.setAttribute('name', self.name)
2594
2595 nestedSubstrateNodes=techNode.getElementsByTagName('abl:NestedSubstrate')
2596 for nestedSubstrate in nestedSubstrateNodes:
2597 nestedSubstrate.setAttribute('library', self.name)
2598 nestedSubstrate.setAttribute('layerMapLib', self.name)
2599
2600 if not ablNode.hasAttribute('xmlns:abl'):
2601 if self.useAblRoot_:
2602 ablNode.setAttribute("xmlns:abl", "http://keysight.com/eesof/abl")
2603 else:
2604 ablNode.setAttribute("xmlns:abl", "http://agilent.com/abl")
2605 self.writeAblLibXml(ablNode)
2606 self.writeAblLibInfo()
2607 eemWriteDebug("Done: processing ABL library data")
2608
2610 fileName = self.fPrefix + '_abl.xml'
2611 fp = open(fileName, 'w')
2612 fp.write( '<?xml version="1.0" encoding="UTF-8"?>\n' )
2613 xmlString = ablNode.toxml()
2614 fp.write(xmlString)
2615 fp.write('\n')
2616 fp.close()
2617
2618
2620 fileName = self.fPrefix + '_abl.aldf'
2621 fp = open(fileName, 'w')
2622 fp.write( 'ABLLIBRARY|%s|UU|%s|DBUTOUU|%s\n' %
2623 ( self.name, self.unitsMap[self.userUnits], self.DBUperUU ) )
2624 fp.write( 'ABLLAYOUTPREFERENCES|PORT_SIZE|%s|ANNOTATION_HEIGHT|%s\n' %
2625 ( self.portSize, self.instTextHeight ) )
2626 for tech in self.refTechnologies:
2627 fp.write( 'ABLREFTECH|%s\n' % tech )
2628 fp.write( 'ABLREFTECHEND\n' )
2629 fp.write( 'ABLLAYERSSTART|layername|layernumber|process_role\n' )
2630 for layer in self.layers:
2631 fp.write( 'ABLLAYERS|%s|%s|%s\n' % layer )
2632 fp.write( 'ABLLAYERSEND\n' )
2633 fp.write( 'ABLLAYERIDSTART|layer|purpose\n' )
2634 for layerId in self.layerIds:
2635 data='ABLLAYERID'
2636 for (key,value) in layerId.iteritems():
2637 data += '|' + str(key) + '|' + str(value)
2638 data += '\n'
2639 fp.write( data )
2640 fp.write( 'ABLLAYERIDEND\n' )
2641 fp.write( 'ABLMATERIALS|materials.matdb|%s\n' % os.path.join( self.targetDir, 'materials.matdb' ))
2642 for substrate in self.substrateList:
2643 substrateName = substrate + '.subst'
2644 fp.write( 'ABLSUBSTRATEFILE|%s|%s\n' % (substrateName, os.path.join( self.targetDir, substrateName )))
2645 fp.write( 'ABLLIBRARYDEFAULTSUBSTRATE|%s\n' % self.defaultSubstrate )
2646 fp.write( 'ABLEBONDSTART\n' )
2647 for ebond in self.ebondsList:
2648 fp.write( '%s' % ebond )
2649 fp.write( 'ABLEBONDEND\n' )
2650 fp.write( 'ABLLIBRARYEND\n' )
2651 fp.close()
2652
2654 refTechNodes =[]
2655 if techNode:
2656 refTechNodes = techNode.getElementsByTagName( 'abl:ReferencedTechnology' )
2657 for node in refTechNodes:
2658 if node.hasAttribute( 'referencedLibraryName' ):
2659 self.refTechnologies.append(node.getAttribute( 'referencedLibraryName' ))
2660
2662 techUnitsNode = techNode.getElementsByTagName( 'abl:TechUnits' )[0]
2663 if techUnitsNode == None:
2664 return
2665 layoutUnitNode = techUnitsNode.getElementsByTagName( 'abl:LayoutUnits' )[0]
2666 if layoutUnitNode != None:
2667 self.userUnits=layoutUnitNode.getAttribute( 'oaUserUnits' )
2668 self.DBUperUU=layoutUnitNode.getAttribute( 'DBUperUU' )
2669
2671 layersNode = techNode.getElementsByTagName( 'abl:Layers' )[0]
2672 if layersNode==None:
2673 return
2674 layerNodes = layersNode.getElementsByTagName('abl:Layer' )
2675 for node in layerNodes:
2676 name = node.getAttribute('name')
2677 number = node.getAttribute('number')
2678 self.maskNameNbMap[name] = number
2679 processRole = self.processTypes[node.getAttribute('processRole')]
2680 layerEntry = tuple([name, number, processRole])
2681 self.layers.append( layerEntry )
2682
2684 layerIdsNode = techNode.getElementsByTagName( 'abl:DisplayProperties' )[0]
2685 if layerIdsNode==None:
2686 return
2687 layerIdNodes = layerIdsNode.getElementsByTagName( 'abl:DisplayProperty' )
2688 for node in layerIdNodes:
2689 layerId={}
2690 layerId['layer'] = node.getAttribute('layer')
2691 layerId['purpose'] = node.getAttribute('purpose')
2692 layerId['r'] = node.getAttribute('r')
2693 layerId['g'] = node.getAttribute('g')
2694 layerId['b'] = node.getAttribute('b')
2695 layerId['alpha'] = node.getAttribute('alpha')
2696 layerId['fill'] = self.fillTypes[node.getAttribute('displayMode')]
2697 layerId['line'] = self.lineTypes[node.getAttribute('lineType')]
2698 layerId['pattern'] = self.patternTypes[node.getAttribute('fillType')]
2699 layerId['visible'] = '1'
2700 layerId['protected'] = '0'
2701 self.layerIds.append(layerId)
2702
2704 materialsNode = techNode.getElementsByTagName( 'abl:Materials' )[0]
2705 if materialsNode==None:
2706 return
2707 eemAdfiAblMaterialWriting( materialsNode, self.targetDir )
2708
2710 substratesNode = techNode.getElementsByTagName( 'abl:Substrates' )[0]
2711 if substratesNode==None:
2712 return
2713 defaultsNode = substratesNode.getElementsByTagName( 'abl:DefaultSubstrate' )[0]
2714 defaultLib = defaultsNode.getAttribute('library')
2715 defaultSubstrateName = defaultsNode.getAttribute('name')
2716 if defaultLib=='__CURRENT__':
2717 defaultLib = self.name
2718 defaultsNode.setAttribute('library', self.name)
2719 self.defaultSubstrate = defaultLib + '|' + defaultSubstrateName
2720 self.substrateList = writeSubstrates( substratesNode, self.name, self.targetDir )
2721
2723 libPrefNodes = ablNode.getElementsByTagName( 'abl:LibraryPreferences' )
2724 if libPrefNodes==[]:
2725 return
2726 libPrefNodes = ablNode.getElementsByTagName( 'abl:LayoutPreferences' )
2727 if libPrefNodes==[]:
2728 return
2729 prefNodes = libPrefNodes[0].getElementsByTagName( 'abl:FileContents' )
2730 if prefNodes==[]:
2731 return
2732 preferences=getInnerText(prefNodes[0]).splitlines()
2733 for i in preferences:
2734 lst=i.split(' ')
2735 if len(lst)==2:
2736 name = lst[0]
2737 value = lst[1]
2738 if name == 'instTextHeight':
2739 self.instTextHeight = value
2740 elif name == 'portSize':
2741 self.portSize = value
2742
2744 ebondNodes = ablNode.getElementsByTagName( 'abl:Instance' )
2745 if ebondNodes==[]:
2746 return
2747 for ebondNode in ebondNodes:
2748 if ebondNode.getAttribute('cellName')!='EBOND_Shape':
2749 continue
2750 ebondEntry = 'ABLEBOND|' + ebondNode.getAttribute('instanceName')
2751 parmNodes = ebondNode.getElementsByTagName( 'abl:Parameter' )
2752 for parmNode in parmNodes:
2753 name = parmNode.getAttribute('name')
2754 value = parmNode.getAttribute('value')
2755 if name.startswith(('rT','tT','vT','rZ','tZ','vZ')):
2756 ebondEntry+= '|' + str(name) + '|' + str(value)
2757 ebondEntry += '\n'
2758 self.ebondsList.append(ebondEntry)
2759
2760
2761
2763 filename = os.path.join( targetDir, 'materials.matdb')
2764 file = open( filename, "w" )
2765 file.write( '<!DOCTYPE Materials>\n' )
2766 xmlString = iMaterialsNode.toxml()
2767 xmlString = xmlString.replace( 'abl:', '' )
2768 file.write(xmlString)
2769 file.write('\n')
2770 file.close()
2771
2772
2774 - def __init__( self, iLibName='', iStackName=None, iTargetDir=None ):
2775 self.name = iStackName
2776 self.libName = iLibName
2777 targetDir = iTargetDir
2778 if targetDir==None or targetDir=='':
2779 targetDir='.'
2780 filename = os.path.join( targetDir, iStackName + '.subst' )
2781 self.file = open( filename, "w" )
2782 self.file.write( '<!DOCTYPE Substrate>\n<SubstrateModel>\n' )
2783
2785 self.file.write( '</SubstrateModel>\n' )
2786 self.file.close()
2787
2789 xmlString = iStackNode.toxml()
2790 xmlString = xmlString.replace( 'abl:', '' )
2791 xmlString = xmlString.replace( 'SubStack', 'stack' )
2792 xmlString = xmlString.replace( 'SubMaterial', 'material' )
2793 xmlString = xmlString.replace( 'SubInterface', 'interface' )
2794 self.file.write( xmlString )
2795 self.file.write( '\n' )
2796
2798 xmlString = iLayersNode.toxml()
2799 xmlString = xmlString.replace('abl:SubLayer', 'layer')
2800 self.file.write( xmlString )
2801 self.file.write( '\n' )
2802
2804 xmlString = iViaNode.toxml()
2805 xmlString = xmlString.replace( 'abl:SubVia', 'via' )
2806 self.file.write( xmlString )
2807 self.file.write( '\n' )
2808
2810 xmlString = iNestedSubstrates.toxml()
2811 xmlString = xmlString.replace('abl:NestedSubstrate', 'substrate')
2812 xmlString = xmlString.replace('__CURRENT__', self.libName)
2813 self.file.write( xmlString )
2814 self.file.write( '\n' )
2815
2817 stackList=[]
2818 elements = iSubstratesNode.getElementsByTagName('abl:Substrate')
2819 for el in elements:
2820 if el.hasAttribute('name'):
2821 stackName = el.getAttribute('name')
2822 currentStack = eemAdfiAblSubstWriter( iLibName, stackName, targetDir )
2823 stackNode = el.getElementsByTagName( 'abl:SubStack' )[0]
2824 currentStack.writeStack( stackNode )
2825 layersNode = el.getElementsByTagName( 'abl:SubLayers' )[0]
2826 currentStack.writeLayers( layersNode )
2827 viasNode = el.getElementsByTagName( 'abl:SubVias' )[0]
2828 currentStack.writeVias( viasNode )
2829 nestedSubstratesNode = el.getElementsByTagName( 'abl:NestedSubstrates' )
2830 if nestedSubstratesNode:
2831 currentStack.writeNestedSubstrates( nestedSubstratesNode[0] )
2832 currentStack.close()
2833 stackList.append(stackName)
2834 return stackList
2835
2836
2837
2838
2839
2840
2841
2842
2844
2845 try:
2846 eemWriteDebug("Filename is: %s" % iAdfiFilename)
2847 f = open(iAdfiFilename,"r")
2848 content = ''.join(f.readlines())
2849 f.close()
2850 except:
2851 eemWriteError("Can not read from ADS ADFI file: %s" % iAdfiFilename)
2852 raise
2853
2854
2855 content = re.sub('>\s+<','><',content)
2856
2857
2858 eemWriteDebug("Parse ADS ADFI file document")
2859 try:
2860 eemAdfiDom = xml.dom.minidom.parseString(content)
2861 except:
2862 eemWriteError("Problem with xml.dom.minidom parser: need to exit")
2863 raise
2864 return eemAdfiDom
2865
2866
2867
2868 -def eemAdfiProcessCollect(iAdfiDoc, iFprefix, iAdfiInfo, iAdfiTechData, iAdfiEgsWriter, iAdfiLayers, iAblLibInfo,targetPlatform='ads'):
2869 """ First pass through file using pulldom mechanism """
2870
2871 parser=xml.sax.make_parser()
2872
2873 parser.setFeature(xml.sax.handler.feature_external_ges,0)
2874
2875 events = xml.dom.pulldom.parse(iAdfiDoc,parser,1024*1024*16)
2876
2877 inComponent=None
2878 top=None
2879 cmpName=None
2880 name=None
2881 egsHeader=''
2882 for (event,node) in events:
2883 if (event==xml.dom.pulldom.START_ELEMENT
2884 and node.localName=='AdfiToAds'):
2885 iAdfiInfo.setAdfiToAdsAttributes(event,node)
2886 try:
2887 iAdfiInfo.checkTargetPlatform(targetPlatform)
2888 except Exception, err:
2889 eemWriteWarn(str(err))
2890 if targetPlatform=='empro':
2891 eemWriteWarn("!!! This may result in loss of objects during the import.")
2892 eemWriteWarn("!!! Please regenerate your .adfi file with EMPro as target platform.")
2893 pass
2894 elif event==xml.dom.pulldom.START_ELEMENT and ( node.tagName=='abl:AgilentBoardLink' or node.tagName=='abl:ABLRoot' ):
2895 events.expandNode(node)
2896 iAblLibInfo.buildAblData(node)
2897
2898 elif event==xml.dom.pulldom.START_ELEMENT and node.localName=="AdfiComponent":
2899 cmpName = node.getAttribute('id')
2900 top = (node.getAttribute('top')=='true')
2901 if top:
2902 iAdfiTechData.topName(cmpName)
2903 inComponent = True
2904 elif event==xml.dom.pulldom.END_ELEMENT and node.localName=="AdfiComponent":
2905 cmpName = None
2906 top = None
2907 inComponent = None
2908 name= None
2909
2910 elif inComponent and event==xml.dom.pulldom.START_ELEMENT and node.localName=='Name':
2911 events.expandNode(node)
2912 name = eemFixName(getInnerText(node))
2913
2914 elif (inComponent
2915 and event==xml.dom.pulldom.START_ELEMENT
2916 and node.localName=='ComponentParms'):
2917 events.expandNode(node)
2918 iAdfiEgsWriter.updateFilterEgsMap(node,cmpName)
2919
2920 elif (inComponent and top
2921 and event==xml.dom.pulldom.START_ELEMENT
2922 and node.localName=='Units'):
2923 events.expandNode(node)
2924 iAdfiInfo.setUnits(node)
2925
2926 elif (inComponent
2927 and event==xml.dom.pulldom.START_ELEMENT
2928 and node.localName=='Substrate'):
2929 events.expandNode(node)
2930 iAdfiTechData.addLtdSlmMap(node,cmpName,top)
2931 iAdfiLayers.addSubstrateLayerData(node)
2932
2933 elif inComponent and top and event==xml.dom.pulldom.START_ELEMENT and node.localName=='Instances':
2934 events.expandNode(node)
2935 iAdfiTechData.addSubstrateInstanceMap(node)
2936
2937 elif (inComponent and top
2938 and event==xml.dom.pulldom.START_ELEMENT
2939 and node.localName=='Geometry2D'
2940 and node.hasAttribute('geometry2DType')
2941 and node.getAttribute('geometry2DType')=='egs'
2942 and node.hasAttribute('geometry2DOp')
2943 and node.getAttribute('geometry2DOp')=='process'):
2944 events.expandNode(node)
2945 egsHeader+=getInnerText(node)
2946 iAdfiLayers.addEgsProcess(egsHeader)
2947 iAdfiEgsWriter.writeHeader(egsHeader)
2948
2949 elif (inComponent and top
2950 and event==xml.dom.pulldom.START_ELEMENT
2951 and node.localName=='Ports'):
2952 events.expandNode(node)
2953 try:
2954 fName = iFprefix + '_top.prt'
2955 eemWriteDebug("Port Filename is: %s" % fName)
2956 eemAdfiWritePortFile(fName, node)
2957 except Exception, err:
2958 eemWriteError("Problem processing definitions of ports on top level: need to exit")
2959 eemWriteError('ERROR: %s\n' % str(err))
2960 raise
2961
2962 try:
2963 fName = iFprefix + '_top.pin'
2964 eemWriteDebug("Pin Filename is: %s" % fName)
2965 eemAdfiWritePinFile(fName, node, iAdfiInfo)
2966 except Exception, err:
2967 eemWriteError("Problem processing definitions of pins on top level: need to exit")
2968 eemWriteError('ERROR: %s\n' % str(err))
2969 raise
2970
2971
2972
2973
2974
2975
2976 -def eemAdfiProcessFile(iAdfiFilename,targetDir=None,useJedecBondwires=False,useSolderBalls=False,bwMap=None,sbMap=None,targetPlatform='ads', oaLibName=None ):
2977 """Load and parse adfi file for use in ADS and EMPro"""
2978
2979 fprefix = os.path.splitext(iAdfiFilename)[0]
2980 if (targetDir != None):
2981 fprefix = os.path.join(targetDir,os.path.basename(fprefix))
2982 adfiPrefix = fprefix + '_adfi'
2983 if oaLibName==None:
2984 oaLibName=os.path.basename(fprefix)+ '_lib'
2985
2986 eemAdfiInfo=AdfiInfo()
2987 eemAdfiTechData=AdfiLtds(fprefix)
2988 eemAdfiEgsWriter=AdfiEgsWriter( adfiPrefix + '_egs',
2989 useSolderBalls )
2990 eemAdfiLayers=AdfiLayers(adfiPrefix)
2991 eemAblLibInfo=AdfiAblLibInfo(targetDir, adfiPrefix, oaLibName)
2992
2993 try:
2994 eemAdfiProcessCollect(iAdfiFilename, fprefix, eemAdfiInfo, eemAdfiTechData, eemAdfiEgsWriter, eemAdfiLayers, eemAblLibInfo, targetPlatform)
2995 except:
2996 eemWriteError("Problem with initial doc parsing: need to exit")
2997 raise
2998
2999 maskNameNbMap={}
3000 hasAbl=eemAblLibInfo.present()
3001 useAblRoot=eemAblLibInfo.useAblRoot()
3002 if hasAbl:
3003 maskNameNbMap = eemAblLibInfo.getMaskMap()
3004 else:
3005
3006 try:
3007 eemAdfiTechData.assembleLtdSlmMaps()
3008 except:
3009 eemWriteError("Problem with stack processing: need to exit")
3010 raise
3011 maskNameNbMap = getMaskNames(eemAdfiTechData)
3012 eemWriteDebug("maskNameNbMap : %s" % (str(maskNameNbMap)))
3013
3014
3015 try:
3016 eemAdfiLayers.writeLayFile(eemAdfiInfo.mainVersion)
3017 except:
3018 pass
3019 try:
3020 eemAdfiLayers.writeDisplayPreferenceFile(eemAdfiInfo.mainVersion)
3021 except:
3022 pass
3023
3024 eemAdfiHdefWriter=None
3025 try:
3026 eemAdfiHdefWriter=AdfiHdefWriter(fprefix,eemAdfiInfo,hasAbl,useAblRoot)
3027 except:
3028 eemWriteError("Problem creating hierachical processing file: need to exit")
3029 raise
3030
3031 eemAdfiBondWireWriter=None
3032 try:
3033 fName = fprefix + '_adfi.dbw'
3034 eemWriteDebug("Bondwire Filename is: %s" % fName)
3035 eemAdfiBondWireWriter = bondWireWriter(fName,maskNameNbMap)
3036 except:
3037 eemWriteError("Problem creating bondwire file: need to exit")
3038 raise
3039
3040 try:
3041 eemAdditionalParms = eemAdfiReadOptParmFile(os.path.splitext(iAdfiFilename)[0])
3042 except:
3043 eemAdditionalParms = None
3044 pass
3045
3046
3047 try:
3048 eemWriteDebug("ADFI Process Hierarchical Definition")
3049 eemAdfiProcessHDefEgsFile(iAdfiFilename, eemAdfiInfo,
3050 eemAdfiHdefWriter, eemAdfiEgsWriter,
3051 eemAdfiBondWireWriter, eemAdfiTechData,
3052 eemAdditionalParms, maskNameNbMap)
3053 eemAdfiHdefWriter.close()
3054 eemAdfiEgsWriter.close()
3055 except Exception, err:
3056 eemWriteError("Problem Hierarchical Definition output processing: need to exit")
3057 eemWriteError('ERROR: %s\n' % str(err))
3058 raise
3059
3060
3061 if (useSolderBalls or
3062 (useJedecBondwires and bwMap != None)):
3063
3064 adfiDom=None
3065
3066 try:
3067 eemAdfiDom = eemAdfiReadFile(iAdfiFilename)
3068 except:
3069 raise
3070
3071 if useSolderBalls:
3072 try:
3073 eemAdfiBondWireWriter.writeSBDummyBondWires(eemAdfiDom,useSolderBalls,sbMap=sbMap)
3074 except Exception, err:
3075 eemWriteError("Problem processing definitions of bondwires: need to exit")
3076 eemWriteError('ERROR: %s\n' % str(err))
3077 raise
3078 if useJedecBondwires and bwMap != None:
3079 importer = bondwireImporter()
3080 importer.getBondwireMap(eemAdfiDom,bwComps=bwMap)
3081
3082 eemAdfiBondWireWriter.close()
3083 eemWriteDebug("ADFI Hierarchical Definition File processed")
3084
3085 return 1
3086
3087
3088
3089 if __name__=="__main__":
3090 try:
3091 if len(sys.argv)==2:
3092 eemAdfiProcessFile( sys.argv[1] )
3093 elif len(sys.argv)==3:
3094 eemAdfiProcessFile( sys.argv[1],sys.argv[2] )
3095 elif len(sys.argv)==4:
3096 eemAdfiProcessFile( sys.argv[1], sys.argv[2], oaLibName=sys.argv[3] )
3097 else:
3098 print "usage: python $IMPORT_ADFI_ADD_ON/scripts/eemAdfiParse.py <file> [<targetDir> [<oalibName>]]"
3099 sys.exit(2)
3100 sys.exit(0)
3101 except Exception, err:
3102 eemWriteError('%s\n' % str(err))
3103 sys.exit(1)
3104