fixed purposes for gdsMill

This commit is contained in:
Joey Kunzler 2020-02-15 15:00:30 -08:00
parent 87b5a48f9e
commit 125bcafb3e
3 changed files with 114 additions and 109 deletions

View File

@ -12,14 +12,14 @@ class Gds2reader:
self.fileHandle = None
self.layoutObject = layoutObject
self.debugToTerminal=debugToTerminal
#do we dump debug data to the screen
def print64AsBinary(self,number):
for index in range(0,64):
print((number>>(63-index))&0x1,eol='')
print("\n")
def stripNonASCII(self,bytestring):
string = bytestring.decode('utf-8')
return string
@ -29,20 +29,20 @@ class Gds2reader:
#(1)sign (7)exponent (56)mantissa
#exponent is excess 64, mantissa has no implied 1
#a normal IEEE double is like this:
#(1)sign (11)exponent (52)mantissa
#(1)sign (11)exponent (52)mantissa
data = struct.unpack('>q',ibmData)[0]
sign = (data >> 63)&0x01
exponent = (data >> 56) & 0x7f
mantissa = data<<8 #chop off sign and exponent
if mantissa == 0:
newFloat = 0.0
else:
else:
exponent = ((exponent-64)*4)+1023 #convert to double exponent
#re normalize
while mantissa & 0x8000000000000000 == 0:
while mantissa & 0x8000000000000000 == 0:
mantissa<<=1
exponent-=1
exponent-=1
mantissa<<=1 #remove the assumed high bit
exponent-=1
#check for underflow error -- should handle these properly!
@ -56,7 +56,7 @@ class Gds2reader:
#convert back to double
newFloat = struct.unpack('>d',asciiDouble)[0]
return newFloat
def ieeeFloatCheck(self,aFloat):
asciiDouble = struct.pack('>d',aFloat)
data = struct.unpack('>q',asciiDouble)[0]
@ -70,12 +70,12 @@ class Gds2reader:
asciiDouble = struct.pack('>q',(sign<<63)|(exponent+1023<<52)|(mantissa>>12))
newFloat = struct.unpack('>d',asciiDouble)[0]
print("Check:"+str(newFloat))
def readNextRecord(self):
global offset
recordLengthAscii = self.fileHandle.read(2) #first 2 bytes tell us the length of the record
if len(recordLengthAscii)==0:
return
return
recordLength = struct.unpack(">h",recordLengthAscii) #gives us a tuple with a short int inside
offset_int = int(recordLength[0]) # extract length
offset += offset_int # count offset
@ -96,20 +96,20 @@ class Gds2reader:
else:
print("Invalid GDSII Header")
return -1
#read records until we hit the UNITS section... this is the last part of the header
while 1:
record = self.readNextRecord()
idBits = record[0:2]
## Modified Date
if idBits==b'\x01\x02' and len(record)==26:
modYear = struct.unpack(">h",record[2:4])[0]
modYear = struct.unpack(">h",record[2:4])[0]
modMonth = struct.unpack(">h",record[4:6])[0]
modDay = struct.unpack(">h",record[6:8])[0]
modHour = struct.unpack(">h",record[8:10])[0]
modMinute = struct.unpack(">h",record[10:12])[0]
modSecond = struct.unpack(">h",record[12:14])[0]
lastAccessYear = struct.unpack(">h",record[14:16])[0]
lastAccessYear = struct.unpack(">h",record[14:16])[0]
lastAccessMonth = struct.unpack(">h",record[16:18])[0]
lastAccessDay = struct.unpack(">h",record[18:20])[0]
lastAccessHour = struct.unpack(">h",record[20:22])[0]
@ -169,14 +169,14 @@ class Gds2reader:
if(self.debugToTerminal==1):
print("Units: 1 user unit="+str(userUnits)+" database units, 1 database unit="+str(dbUnits)+" meters.")
break;
if(self.debugToTerminal==1):
if(self.debugToTerminal==1):
print("End of GDSII Header Found")
return 1
def readBoundary(self):
##reads in a boundary type structure = a filled polygon
if(self.debugToTerminal==1):
print("\t\t\tBeginBoundary")
print("\t\t\tBeginBoundary")
thisBoundary=GdsBoundary()
while 1:
record = self.readNextRecord()
@ -198,9 +198,9 @@ class Gds2reader:
self.layoutObject.layerNumbersInUse += [drawingLayer]
if(self.debugToTerminal==1):
print("\t\tDrawing Layer: "+str(drawingLayer))
elif(idBits==b'\x16\x02'): #Purpose
elif(idBits==b'\x0E\x02'): #Purpose DATATYPE
purposeLayer = struct.unpack(">h",record[2:4])[0]
thisBoundary.purposeLayer=purposeLayer
thisBoundary.purposeLayer=purposeLayer
if(self.debugToTerminal==1):
print("\t\tPurpose Layer: "+str(purposeLayer))
elif(idBits==b'\x10\x03'): #XY Data Points
@ -217,11 +217,11 @@ class Gds2reader:
print("\t\t\tEndBoundary")
break;
return thisBoundary
def readPath(self): #reads in a path structure
if(self.debugToTerminal==1):
print("\t\t\tBeginPath")
thisPath=GdsPath()
while 1:
record = self.readNextRecord()
@ -245,7 +245,7 @@ class Gds2reader:
print("\t\t\tDrawing Layer: "+str(drawingLayer))
elif(idBits==b'\x16\x02'): #Purpose
purposeLayer = struct.unpack(">h",record[2:4])[0]
thisPath.purposeLayer=purposeLayer
thisPath.purposeLayer=purposeLayer
if(self.debugToTerminal==1):
print("\t\tPurpose Layer: "+str(purposeLayer))
elif(idBits==b'\x21\x02'): #Path type
@ -277,7 +277,7 @@ class Gds2reader:
print("\t\t\tEndPath")
break;
return thisPath
def readSref(self): #reads in a reference to another structure
if(self.debugToTerminal==1):
print("\t\t\tBeginSref")
@ -318,7 +318,7 @@ class Gds2reader:
print("\t\t\tMagnification:"+str(magFactor))
elif(idBits==b'\x1C\x05'): #Rotate Angle
rotateAngle=self.ieeeDoubleFromIbmData(record[2:10])
thisSref.rotateAngle=rotateAngle
thisSref.rotateAngle=rotateAngle
if(self.debugToTerminal==1):
print("\t\t\tRotate Angle (CCW):"+str(rotateAngle))
elif(idBits==b'\x10\x03'): #XY Data Points
@ -333,11 +333,11 @@ class Gds2reader:
print("\t\t\tEndSref")
break;
return thisSref
def readAref(self): #an array of references
if(self.debugToTerminal==1):
print("\t\t\tBeginAref")
thisAref = GdsAref()
while 1:
record = self.readNextRecord()
@ -374,7 +374,7 @@ class Gds2reader:
print("\t\t\tMagnification:"+str(magFactor))
elif(idBits==b'\x1C\x05'): #Rotate Angle
rotateAngle=self.ieeeDoubleFromIbmData(record[2:10])
thisAref.rotateAngle=rotateAngle
thisAref.rotateAngle=rotateAngle
if(self.debugToTerminal==1):
print("\t\t\tRotate Angle (CCW):"+str(rotateAngle))
elif(idBits==b'\x10\x03'): #XY Data Points
@ -393,11 +393,11 @@ class Gds2reader:
print("\t\t\tEndAref")
break;
return thisAref
def readText(self):
if(self.debugToTerminal==1):
print("\t\t\tBeginText")
thisText=GdsText()
while 1:
record = self.readNextRecord()
@ -419,9 +419,9 @@ class Gds2reader:
self.layoutObject.layerNumbersInUse += [drawingLayer]
if(self.debugToTerminal==1):
print("\t\tDrawing Layer: "+str(drawingLayer))
elif(idBits==b'\x16\x02'): #Purpose
elif(idBits==b'\x16\x02'): #Purpose TEXTTYPE
purposeLayer = struct.unpack(">h",record[2:4])[0]
thisText.purposeLayer=purposeLayer
thisText.purposeLayer=purposeLayer
if(self.debugToTerminal==1):
print("\t\tPurpose Layer: "+str(purposeLayer))
elif(idBits==b'\x1A\x01'): #Transformation
@ -497,11 +497,11 @@ class Gds2reader:
print("\t\t\tEndText")
break;
return thisText
def readNode(self):
if(self.debugToTerminal==1):
print("\t\t\tBeginNode")
##reads in a node type structure = an electrical net
thisNode = GdsNode()
while 1:
@ -543,11 +543,11 @@ class Gds2reader:
print("\t\t\tEndNode")
break;
return thisNode
def readBox(self):
if(self.debugToTerminal==1):
print("\t\t\tBeginBox")
##reads in a gds BOX structure
thisBox = GdsBox()
while 1:
@ -570,9 +570,9 @@ class Gds2reader:
self.layoutObject.layerNumbersInUse += [drawingLayer]
if(self.debugToTerminal==1):
print("\t\tDrawing Layer: "+str(drawingLayer))
elif(idBits==b'\x16\x02'): #Purpose
elif(idBits==b'\x16\x02'): #Purpose TEXTYPE
purposeLayer = struct.unpack(">h",record[2:4])[0]
thisBox.purposeLayer=purposeLayer
thisBox.purposeLayer=purposeLayer
if(self.debugToTerminal==1):
print("\t\tPurpose Layer: "+str(purposeLayer))
elif(idBits==b'\x2D\x00'): #Box
@ -594,14 +594,14 @@ class Gds2reader:
print("\t\t\tEndBox")
break;
return thisBox
def readNextStructure(self):
thisStructure = GdsStructure()
thisStructure = GdsStructure()
record = self.readNextRecord()
idBits = record[0:2]
# Begin structure
if(idBits==b'\x05\x02' and len(record)==26):
createYear = struct.unpack(">h",record[2:4])[0]
createYear = struct.unpack(">h",record[2:4])[0]
createMonth = struct.unpack(">h",record[4:6])[0]
createDay = struct.unpack(">h",record[6:8])[0]
createHour = struct.unpack(">h",record[8:10])[0]
@ -628,7 +628,7 @@ class Gds2reader:
idBits = record[0:2]
if idBits==b'\x07\x00': break; #we've reached the end of the structure
elif(idBits==b'\x06\x06'):
structName = self.stripNonASCII(record[2::])
structName = self.stripNonASCII(record[2::])
thisStructure.name = structName
if(self.debugToTerminal==1):
print("\tStructure Name: "+structName)
@ -646,11 +646,11 @@ class Gds2reader:
thisStructure.nodes+=[self.readNode()]
elif(idBits==b'\x2E\x02'):
thisStructure.boxes+=[self.readBox()]
if(self.debugToTerminal==1):
if(self.debugToTerminal==1):
print("\tEnd of Structure.")
self.layoutObject.structures[structName]=thisStructure #add this structure to the layout object
return 1
def readGds2(self):
if(self.readHeader()): #did the header read ok?
record = self.readNextStructure()
@ -667,7 +667,7 @@ class Gds2reader:
print("There was an error reading the structure list.")
else:
print("There was an error parsing the GDS header. Aborting...")
def loadFromFile(self, fileName):
self.fileHandle = open(fileName,"rb")
self.readGds2()
@ -695,11 +695,11 @@ class Gds2reader:
def findStruct_readNextStruct(self,findStructName):
self.debugToTerminal=0
thisStructure = GdsStructure()
thisStructure = GdsStructure()
record = self.readNextRecord()
idBits = record[0:2]
if(idBits==('\x05','\x02') and len(record)==26):
createYear = struct.unpack(">h",record[2]+record[3])[0]
createYear = struct.unpack(">h",record[2]+record[3])[0]
createMonth = struct.unpack(">h",record[4]+record[5])[0]
createDay = struct.unpack(">h",record[6]+record[7])[0]
createHour = struct.unpack(">h",record[8]+record[9])[0]
@ -743,7 +743,7 @@ class Gds2reader:
thisStructure.nodes+=[self.readNode()]
elif(idBits==('\x2E','\x02')):
thisStructure.boxes+=[self.readBox()]
if(self.debugToTerminal==1):
if(self.debugToTerminal==1):
print("\tEnd of Structure.")
self.layoutObject.structures[structName]=thisStructure #add this structure to the layout object
if(wantedStruct == 0):
@ -771,11 +771,11 @@ class Gds2reader:
def findLabel_readNextStruct(self,findLabelName):
self.debugToTerminal=0
thisStructure = GdsStructure()
thisStructure = GdsStructure()
record = self.readNextRecord()
idBits = record[0:2]
if(idBits==('\x05','\x02') and len(record)==26):
createYear = struct.unpack(">h",record[2]+record[3])[0]
createYear = struct.unpack(">h",record[2]+record[3])[0]
createMonth = struct.unpack(">h",record[4]+record[5])[0]
createDay = struct.unpack(">h",record[6]+record[7])[0]
createHour = struct.unpack(">h",record[8]+record[9])[0]
@ -825,7 +825,7 @@ class Gds2reader:
thisStructure.nodes+=[self.readNode()]
elif(idBits==('\x2E','\x02')):
thisStructure.boxes+=[self.readBox()]
if(self.debugToTerminal==1):
if(self.debugToTerminal==1):
print("\tEnd of Structure.")
self.layoutObject.structures[structName]=thisStructure #add this structure to the layout object
if(wantedLabel == 0):
@ -833,4 +833,3 @@ class Gds2reader:
else:
#print("\tDone with collectting bound. Return")
return [0,wantedtexts]

View File

@ -5,37 +5,37 @@ from .gdsPrimitives import *
class Gds2writer:
"""Class to take a populated layout class and write it to a file in GDSII format"""
## Based on info from http://www.rulabinsky.com/cavd/text/chapc.html
def __init__(self,layoutObject):
self.fileHandle = 0
self.layoutObject = layoutObject
self.debugToTerminal=0 #do we dump debug data to the screen
def print64AsBinary(self,number):
#debugging method for binary inspection
for index in range(0,64):
print((number>>(63-index))&0x1,eol='')
print("\n")
def ieeeDoubleFromIbmData(self,ibmData):
#the GDS double is in IBM 370 format like this:
#(1)sign (7)exponent (56)mantissa
#exponent is excess 64, mantissa has no implied 1
#a normal IEEE double is like this:
#(1)sign (11)exponent (52)mantissa
#(1)sign (11)exponent (52)mantissa
data = struct.unpack('>q',ibmData)[0]
sign = (data >> 63)&0x01
exponent = (data >> 56) & 0x7f
mantissa = data<<8 #chop off sign and exponent
if mantissa == 0:
newFloat = 0.0
else:
exponent = ((exponent-64)*4)+1023 #convert to double exponent
#re normalize
while mantissa & 0x8000000000000000 == 0:
while mantissa & 0x8000000000000000 == 0:
mantissa<<=1
exponent-=1
exponent-=1
mantissa<<=1 #remove the assumed high bit
exponent-=1
#check for underflow error -- should handle these properly!
@ -49,12 +49,12 @@ class Gds2writer:
#convert back to double
newFloat = struct.unpack('>d',asciiDouble)[0]
return newFloat
def ibmDataFromIeeeDouble(self,ieeeDouble):
asciiDouble = struct.pack('>d',ieeeDouble)
data = struct.unpack('>q',asciiDouble)[0]
sign = (data >> 63) & 0x01
exponent = ((data >> 52) & 0x7ff)-1023
exponent = ((data >> 52) & 0x7ff)-1023
mantissa = data << 12 #chop off sign and exponent
if(ieeeDouble == 0):
mantissa = 0
@ -70,14 +70,14 @@ class Gds2writer:
for index in range (0,-exponent&3):
mantissa >>= 1
mantissa = mantissa & 0x7fffffffffffffff
exponent = (exponent+3) >> 2
exponent = (exponent+3) >> 2
exponent+=64
newFloat =(sign<<63)|(exponent<<56)|((mantissa>>8)&0xffffffffffffff)
asciiDouble = struct.pack('>q',newFloat)
newFloat =(sign<<63)|(exponent<<56)|((mantissa>>8)&0xffffffffffffff)
asciiDouble = struct.pack('>q',newFloat)
return asciiDouble
def ieeeFloatCheck(self,aFloat):
#debugging method for float construction
asciiDouble = struct.pack('>d',aFloat)
@ -90,7 +90,7 @@ class Gds2writer:
asciiDouble = struct.pack('>q',(sign<<63)|(exponent+1023<<52)|(mantissa>>12))
newFloat = struct.unpack('>d',asciiDouble)[0]
print("Check:"+str(newFloat))
def writeRecord(self,record):
recordLength = len(record)+2 #make sure to include this in the length
recordLengthAscii=struct.pack(">h",recordLength)
@ -127,7 +127,7 @@ class Gds2writer:
libraryName = self.layoutObject.info["libraryName"].encode() + "\0"
else:
libraryName = self.layoutObject.info["libraryName"].encode()
self.writeRecord(idBits+libraryName)
self.writeRecord(idBits+libraryName)
## reference libraries
if("referenceLibraries" in self.layoutObject.info):
idBits=b'\x1F\x06'
@ -158,11 +158,11 @@ class Gds2writer:
mask = self.layoutObject.info["mask"]
self.writeRecord(idBits+mask)
if("units" in self.layoutObject.info):
idBits=b'\x03\x05'
idBits=b'\x03\x05'
userUnits=self.ibmDataFromIeeeDouble(self.layoutObject.info["units"][0])
dbUnits=self.ibmDataFromIeeeDouble((self.layoutObject.info["units"][0]*1e-6/self.layoutObject.info["units"][1])*self.layoutObject.info["units"][1])
#User Units are hardcoded, since the floating point implementation of gdsMill is not adequate,
#User Units are hardcoded, since the floating point implementation of gdsMill is not adequate,
#resulting in a different value being written in output stream. Hardcoded to sram compiler's outputed gds units.
#db="39225c17d04dad2a"
#uu="3e20c49ba5e353f8"
@ -172,17 +172,17 @@ class Gds2writer:
#dbUnits="39225c17d04dad2a".decode("hex")
#db=39225c17d04dad2a
self.writeRecord(idBits+userUnits+dbUnits)
if(self.debugToTerminal==1):
if(self.debugToTerminal==1):
print("writer: userUnits %s"%(userUnits.encode("hex")))
print("writer: dbUnits %s"%(dbUnits.encode("hex")))
#self.ieeeFloatCheck(1.3e-6)
print("End of GDSII Header Written")
return 1
def writeBoundary(self,thisBoundary):
idBits=b'\x08\x00' #record Type
self.writeRecord(idBits)
@ -216,7 +216,7 @@ class Gds2writer:
idBits=b'\x11\x00' #End Of Element
coordinateRecord = idBits
self.writeRecord(coordinateRecord)
def writePath(self,thisPath): #writes out a path structure
idBits=b'\x09\x00' #record Type
self.writeRecord(idBits)
@ -260,7 +260,7 @@ class Gds2writer:
idBits=b'\x11\x00' #End Of Element
coordinateRecord = idBits
self.writeRecord(coordinateRecord)
def writeSref(self,thisSref): #reads in a reference to another structure
idBits=b'\x0A\x00' #record Type
self.writeRecord(idBits)
@ -296,7 +296,7 @@ class Gds2writer:
magFactor=self.ibmDataFromIeeeDouble(thisSref.magFactor)
self.writeRecord(idBits+magFactor)
if(thisSref.rotateAngle!=""):
idBits=b'\x1C\x05'
idBits=b'\x1C\x05'
rotateAngle=self.ibmDataFromIeeeDouble(thisSref.rotateAngle)
self.writeRecord(idBits+rotateAngle)
if(thisSref.coordinates!=""):
@ -312,7 +312,7 @@ class Gds2writer:
idBits=b'\x11\x00' #End Of Element
coordinateRecord = idBits
self.writeRecord(coordinateRecord)
def writeAref(self,thisAref): #an array of references
idBits=b'\x0B\x00' #record Type
self.writeRecord(idBits)
@ -348,7 +348,7 @@ class Gds2writer:
magFactor=self.ibmDataFromIeeeDouble(thisAref.magFactor)
self.writeRecord(idBits+magFactor)
if(thisAref.rotateAngle!=""):
idBits=b'\x1C\x05'
idBits=b'\x1C\x05'
rotateAngle=self.ibmDataFromIeeeDouble(thisAref.rotateAngle)
self.writeRecord(idBits+rotateAngle)
if(thisAref.coordinates):
@ -363,7 +363,7 @@ class Gds2writer:
idBits=b'\x11\x00' #End Of Element
coordinateRecord = idBits
self.writeRecord(coordinateRecord)
def writeText(self,thisText):
idBits=b'\x0C\x00' #record Type
self.writeRecord(idBits)
@ -379,9 +379,8 @@ class Gds2writer:
idBits=b'\x0D\x02' #drawing layer
drawingLayer = struct.pack(">h",thisText.drawingLayer)
self.writeRecord(idBits+drawingLayer)
# TextType is always a 0 per GDS specification
idBits=b'\x16\x02' #purpose layer
purposeLayer = struct.pack(">h",0)
idBits=b'\x16\x02' #purpose layer TEXTTYPE
purposeLayer = struct.pack(">h",thisText.purposeLayer)
self.writeRecord(idBits+purposeLayer)
if(thisText.transFlags != ""):
idBits=b'\x1A\x01'
@ -400,7 +399,7 @@ class Gds2writer:
magFactor=self.ibmDataFromIeeeDouble(thisText.magFactor)
self.writeRecord(idBits+magFactor)
if(thisText.rotateAngle!=""):
idBits=b'\x1C\x05'
idBits=b'\x1C\x05'
rotateAngle=self.ibmDataFromIeeeDouble(thisText.rotateAngle)
self.writeRecord(idBits+rotateAngle)
if(thisText.pathType !=""):
@ -412,12 +411,12 @@ class Gds2writer:
pathWidth = struct.pack(">i",thisText.pathWidth)
self.writeRecord(idBits+pathWidth)
if(thisText.presentationFlags!=""):
idBits=b'\x1A\x01'
idBits=b'\x1A\x01'
font = thisText.presentationFlags[0]<<4
verticalFlags = int(thisText.presentationFlags[1])<<2
horizontalFlags = int(thisText.presentationFlags[2])
presentationFlags = struct.pack(">H",font|verticalFlags|horizontalFlags)
self.writeRecord(idBits+transFlags)
self.writeRecord(idBits+transFlags)
if(thisText.coordinates!=""):
idBits=b'\x10\x03' #XY Data Points
coordinateRecord = idBits
@ -431,11 +430,11 @@ class Gds2writer:
idBits=b'\x19\x06'
textString = thisText.textString
self.writeRecord(idBits+textString.encode())
idBits=b'\x11\x00' #End Of Element
coordinateRecord = idBits
self.writeRecord(coordinateRecord)
def writeNode(self,thisNode):
idBits=b'\x15\x00' #record Type
self.writeRecord(idBits)
@ -450,11 +449,11 @@ class Gds2writer:
if(thisNode.drawingLayer!=""):
idBits=b'\x0D\x02' #drawig layer
drawingLayer = struct.pack(">h",thisNode.drawingLayer)
self.writeRecord(idBits+drawingLayer)
self.writeRecord(idBits+drawingLayer)
if(thisNode.nodeType!=""):
idBits=b'\x2A\x02'
nodeType = struct.pack(">h",thisNode.nodeType)
self.writeRecord(idBits+nodeType)
self.writeRecord(idBits+nodeType)
if(thisText.coordinates!=""):
idBits=b'\x10\x03' #XY Data Points
coordinateRecord = idBits
@ -464,11 +463,11 @@ class Gds2writer:
coordinateRecord+=x
coordinateRecord+=y
self.writeRecord(coordinateRecord)
idBits=b'\x11\x00' #End Of Element
coordinateRecord = idBits
self.writeRecord(coordinateRecord)
def writeBox(self,thisBox):
idBits=b'\x2E\x02' #record Type
self.writeRecord(idBits)
@ -491,7 +490,7 @@ class Gds2writer:
if(thisBox.boxValue!=""):
idBits=b'\x2D\x00'
boxValue = struct.pack(">h",thisBox.boxValue)
self.writeRecord(idBits+boxValue)
self.writeRecord(idBits+boxValue)
if(thisBox.coordinates!=""):
idBits=b'\x10\x03' #XY Data Points
coordinateRecord = idBits
@ -501,11 +500,11 @@ class Gds2writer:
coordinateRecord+=x
coordinateRecord+=y
self.writeRecord(coordinateRecord)
idBits=b'\x11\x00' #End Of Element
coordinateRecord = idBits
self.writeRecord(coordinateRecord)
def writeNextStructure(self,structureName):
#first put in the structure head
thisStructure = self.layoutObject.structures[structureName]
@ -532,7 +531,7 @@ class Gds2writer:
structureName = structureName + '\x00'
self.writeRecord(idBits+structureName.encode())
#now go through all the structure elements and write them in
for boundary in thisStructure.boundaries:
self.writeBoundary(boundary)
for path in thisStructure.paths:
@ -550,7 +549,7 @@ class Gds2writer:
#put in the structure tail
idBits=b'\x07\x00'
self.writeRecord(idBits)
def writeGds2(self):
self.writeHeader(); #first, put the header in
#go through each structure in the layout and write it to the file
@ -559,7 +558,7 @@ class Gds2writer:
#at the end, put in the END LIB record
idBits=b'\x04\x00'
self.writeRecord(idBits)
def writeToFile(self,fileName):
self.fileHandle = open(fileName,"wb")
self.writeGds2()

View File

@ -1,5 +1,12 @@
import math
from globals import OPTS
# default purpose layer is used for addText() in vlsiLayout.py
if OPTS.tech_name == "s8":
purposeLayer=20
else:
purposeLayer=0
class GdsStructure:
"""Class represent a GDS Structure Object"""
def __init__(self):
@ -9,7 +16,7 @@ class GdsStructure:
#these are the primitives defined in GDS2, and we will maintain lists of them all
self.boundaries=[]
self.paths=[]
self.srefs=[]
self.srefs=[]
self.arefs=[]
self.texts=[]
self.nodes=[]
@ -23,7 +30,7 @@ class GdsBoundary:
self.drawingLayer=""
self.purposeLayer=0
self.coordinates=""
class GdsPath:
"""Class represent a GDS Path Object"""
def __init__(self):
@ -35,7 +42,7 @@ class GdsPath:
self.dataType=None
self.pathWidth=""
self.coordinates=""
def equivalentBoundaryCoordinates(self):
"""Convert the path to a set of boundary coordinates that define it"""
halfWidth = (self.pathWidth/2)
@ -62,7 +69,7 @@ class GdsPath:
nextX = None;
nextY = None;
if lastX==None: #start of the path
if nextX>x:#moving right
if nextX>x:#moving right
boundaryEquivalent+=[(x,y+halfWidth)]
if nextX<x:#moving left
boundaryEquivalent+=[(x,y-halfWidth)]
@ -96,9 +103,9 @@ class GdsPath:
boundaryEquivalent+=[(x-halfWidth,y+halfWidth)]
if(y < lastY and x > nextX):
boundaryEquivalent+=[(x+halfWidth,y-halfWidth)]
if nextX == None: #end of path, put in the last 2 points
if lastX<x:#moving right
if nextX == None: #end of path, put in the last 2 points
if lastX<x:#moving right
boundaryEquivalent+=[(x,y+halfWidth)]
if lastX>x:#moving left
boundaryEquivalent+=[(x,y-halfWidth)]
@ -140,7 +147,7 @@ class GdsText:
self.elementFlags=""
self.plex=""
self.drawingLayer=""
self.purposeLayer=0
self.purposeLayer=purposeLayer
self.transFlags=[0,0,0]
self.magFactor=""
self.rotateAngle=""
@ -149,7 +156,7 @@ class GdsText:
self.presentationFlags=""
self.coordinates=""
self.textString = ""
class GdsNode:
"""Class represent a GDS Node Object"""
def __init__(self):
@ -158,7 +165,7 @@ class GdsNode:
self.drawingLayer=""
self.nodeType=""
self.coordinates=""
class GdsBox:
"""Class represent a GDS Box Object"""
def __init__(self):