mirror of https://github.com/VLSIDA/OpenRAM.git
fixed purposes for gdsMill
This commit is contained in:
parent
87b5a48f9e
commit
125bcafb3e
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Reference in New Issue