mirror of https://github.com/VLSIDA/OpenRAM.git
Found rotate bug in transformCoordinate. Cleaned up transFlags.
This commit is contained in:
parent
763f1e8dee
commit
378993ca22
|
|
@ -15,22 +15,27 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
necessary to import layouts into Magic which requires the select to be in the same GDS
|
necessary to import layouts into Magic which requires the select to be in the same GDS
|
||||||
hierarchy as the contact.
|
hierarchy as the contact.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
unique_id = 1
|
||||||
|
|
||||||
def __init__(self, layer_stack, dimensions=[1,1], implant_type=None, well_type=None):
|
def __init__(self, layer_stack, dimensions=[1,1], implant_type=None, well_type=None):
|
||||||
if implant_type or well_type:
|
if implant_type or well_type:
|
||||||
name = "{0}_{1}_{2}_{3}x{4}_{5}{6}".format(layer_stack[0],
|
name = "{0}_{1}_{2}_{3}x{4}_{5}{6}_{7}".format(layer_stack[0],
|
||||||
layer_stack[1],
|
layer_stack[1],
|
||||||
layer_stack[2],
|
layer_stack[2],
|
||||||
dimensions[0],
|
dimensions[0],
|
||||||
dimensions[1],
|
dimensions[1],
|
||||||
implant_type,
|
implant_type,
|
||||||
well_type)
|
well_type,
|
||||||
|
contact.unique_id)
|
||||||
else:
|
else:
|
||||||
name = "{0}_{1}_{2}_{3}x{4}".format(layer_stack[0],
|
name = "{0}_{1}_{2}_{3}x{4}_{5}".format(layer_stack[0],
|
||||||
layer_stack[1],
|
layer_stack[1],
|
||||||
layer_stack[2],
|
layer_stack[2],
|
||||||
dimensions[0],
|
dimensions[0],
|
||||||
dimensions[1])
|
dimensions[1],
|
||||||
|
contact.unique_id)
|
||||||
|
contact.unique_id += 1
|
||||||
hierarchy_design.hierarchy_design.__init__(self, name)
|
hierarchy_design.hierarchy_design.__init__(self, name)
|
||||||
debug.info(4, "create contact object {0}".format(name))
|
debug.info(4, "create contact object {0}".format(name))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,14 +34,14 @@ class geometry:
|
||||||
# coordinate += [(x, y)]
|
# coordinate += [(x, y)]
|
||||||
# return coordinate
|
# return coordinate
|
||||||
|
|
||||||
def transform_coords(self, coords, offset, mirr, angle):
|
# def transform_coords(self, coords, offset, mirr, angle):
|
||||||
"""Calculate coordinates after flip, rotate, and shift"""
|
# """Calculate coordinates after flip, rotate, and shift"""
|
||||||
coordinate = []
|
# coordinate = []
|
||||||
for item in coords:
|
# for item in coords:
|
||||||
x = item[0]*math.cos(angle) - item[1]*mirr*math.sin(angle) + offset[0]
|
# x = item[0]*math.cos(angle) - item[1]*mirr*math.sin(angle) + offset[0]
|
||||||
y = item[0]*math.sin(angle) + item[1]*mirr*math.cos(angle) + offset[1]
|
# y = item[0]*math.sin(angle) + item[1]*mirr*math.cos(angle) + offset[1]
|
||||||
coordinate += [[x, y]]
|
# coordinate += [[x, y]]
|
||||||
return coordinate
|
# return coordinate
|
||||||
|
|
||||||
def normalize(self):
|
def normalize(self):
|
||||||
""" Re-find the LL and UR points after a transform """
|
""" Re-find the LL and UR points after a transform """
|
||||||
|
|
@ -148,40 +148,40 @@ class instance(geometry):
|
||||||
|
|
||||||
debug.info(4, "creating instance: " + self.name)
|
debug.info(4, "creating instance: " + self.name)
|
||||||
|
|
||||||
def get_blockages(self, layer, top=False):
|
# def get_blockages(self, layer, top=False):
|
||||||
""" Retrieve rectangular blockages of all modules in this instance.
|
# """ Retrieve rectangular blockages of all modules in this instance.
|
||||||
Apply the transform of the instance placement to give absolute blockages."""
|
# Apply the transform of the instance placement to give absolute blockages."""
|
||||||
angle = math.radians(float(self.rotate))
|
# angle = math.radians(float(self.rotate))
|
||||||
mirr = 1
|
# mirr = 1
|
||||||
if self.mirror=="R90":
|
# if self.mirror=="R90":
|
||||||
angle += math.radians(90.0)
|
# angle += math.radians(90.0)
|
||||||
elif self.mirror=="R180":
|
# elif self.mirror=="R180":
|
||||||
angle += math.radians(180.0)
|
# angle += math.radians(180.0)
|
||||||
elif self.mirror=="R270":
|
# elif self.mirror=="R270":
|
||||||
angle += math.radians(270.0)
|
# angle += math.radians(270.0)
|
||||||
elif self.mirror=="MX":
|
# elif self.mirror=="MX":
|
||||||
mirr = -1
|
# mirr = -1
|
||||||
elif self.mirror=="MY":
|
# elif self.mirror=="MY":
|
||||||
mirr = -1
|
# mirr = -1
|
||||||
angle += math.radians(180.0)
|
# angle += math.radians(180.0)
|
||||||
elif self.mirror=="XY":
|
# elif self.mirror=="XY":
|
||||||
mirr = 1
|
# mirr = 1
|
||||||
angle += math.radians(180.0)
|
# angle += math.radians(180.0)
|
||||||
|
|
||||||
if self.mod.is_library_cell:
|
# if self.mod.is_library_cell:
|
||||||
# For lib cells, block the whole thing except on metal3
|
# # For lib cells, block the whole thing except on metal3
|
||||||
# since they shouldn't use metal3
|
# # since they shouldn't use metal3
|
||||||
if layer==tech.layer["metal1"] or layer==tech.layer["metal2"]:
|
# if layer==tech.layer["metal1"] or layer==tech.layer["metal2"]:
|
||||||
return [self.transform_coords(self.mod.get_boundary(), self.offset, mirr, angle)]
|
# return [self.transform_coords(self.mod.get_boundary(), self.offset, mirr, angle)]
|
||||||
else:
|
# else:
|
||||||
return []
|
# return []
|
||||||
else:
|
# else:
|
||||||
|
|
||||||
blockages = self.mod.get_blockages(layer)
|
# blockages = self.mod.get_blockages(layer)
|
||||||
new_blockages = []
|
# new_blockages = []
|
||||||
for b in blockages:
|
# for b in blockages:
|
||||||
new_blockages.append(self.transform_coords(b,self.offset, mirr, angle))
|
# new_blockages.append(self.transform_coords(b,self.offset, mirr, angle))
|
||||||
return new_blockages
|
# return new_blockages
|
||||||
|
|
||||||
def gds_write_file(self, new_layout):
|
def gds_write_file(self, new_layout):
|
||||||
"""Recursively writes all the sub-modules in this instance"""
|
"""Recursively writes all the sub-modules in this instance"""
|
||||||
|
|
|
||||||
|
|
@ -379,12 +379,10 @@ class layout(lef.lef):
|
||||||
dimensions=size,
|
dimensions=size,
|
||||||
implant_type=implant_type,
|
implant_type=implant_type,
|
||||||
well_type=well_type)
|
well_type=well_type)
|
||||||
|
|
||||||
debug.check(mirror=="R0","Use rotate to rotate vias instead of mirror.")
|
|
||||||
|
|
||||||
height = via.height
|
height = via.height
|
||||||
width = via.width
|
width = via.width
|
||||||
|
debug.check(mirror=="R0","Use rotate to rotate vias instead of mirror.")
|
||||||
|
|
||||||
if rotate==0:
|
if rotate==0:
|
||||||
corrected_offset = offset + vector(-0.5*width,-0.5*height)
|
corrected_offset = offset + vector(-0.5*width,-0.5*height)
|
||||||
elif rotate==90:
|
elif rotate==90:
|
||||||
|
|
@ -847,6 +845,7 @@ class layout(lef.lef):
|
||||||
"""
|
"""
|
||||||
Add a single power pin from M3 down to M1 at the given center location
|
Add a single power pin from M3 down to M1 at the given center location
|
||||||
"""
|
"""
|
||||||
|
debug.info(0,"Adding power pin {0} at {1} rotate={2}".format(name, loc, rotate))
|
||||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||||
offset=loc,
|
offset=loc,
|
||||||
rotate=rotate)
|
rotate=rotate)
|
||||||
|
|
|
||||||
|
|
@ -36,16 +36,14 @@ class pin_layout:
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
""" Check if these are the same pins for duplicate checks """
|
""" Check if these are the same pins for duplicate checks """
|
||||||
if isinstance(other, self.__class__):
|
if isinstance(other, self.__class__):
|
||||||
return (self.name==other.name and self.layer==other.layer and self.rect == other.rect)
|
return (self.layer==other.layer and self.rect == other.rect)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def overlaps(self, other):
|
def overlaps(self, other):
|
||||||
""" Check if a shape overlaps with a rectangle """
|
""" Check if a shape overlaps with a rectangle """
|
||||||
ll = self.rect[0]
|
(ll,ur) = self.rect
|
||||||
ur = self.rect[1]
|
(oll,our) = other.rect
|
||||||
oll = other.rect[0]
|
|
||||||
our = other.rect[1]
|
|
||||||
# Start assuming no overlaps
|
# Start assuming no overlaps
|
||||||
x_overlaps = False
|
x_overlaps = False
|
||||||
y_overlaps = False
|
y_overlaps = False
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,7 @@ class Gds2reader:
|
||||||
mirrorFlag = bool(transFlags&0x8000) ##these flags are a bit sketchy
|
mirrorFlag = bool(transFlags&0x8000) ##these flags are a bit sketchy
|
||||||
rotateFlag = bool(transFlags&0x0002)
|
rotateFlag = bool(transFlags&0x0002)
|
||||||
magnifyFlag = bool(transFlags&0x0004)
|
magnifyFlag = bool(transFlags&0x0004)
|
||||||
thisSref.transFlags=[mirrorFlag,rotateFlag,magnifyFlag]
|
thisSref.transFlags=[mirrorFlag,magnifyFlag,rotateFlag]
|
||||||
if(self.debugToTerminal==1):
|
if(self.debugToTerminal==1):
|
||||||
print("\t\t\tMirror X:"+str(mirrorFlag))
|
print("\t\t\tMirror X:"+str(mirrorFlag))
|
||||||
print( "\t\t\tRotate:"+str(rotateFlag))
|
print( "\t\t\tRotate:"+str(rotateFlag))
|
||||||
|
|
@ -345,7 +345,7 @@ class Gds2reader:
|
||||||
mirrorFlag = bool(transFlags&0x8000) ##these flags are a bit sketchy
|
mirrorFlag = bool(transFlags&0x8000) ##these flags are a bit sketchy
|
||||||
rotateFlag = bool(transFlags&0x0002)
|
rotateFlag = bool(transFlags&0x0002)
|
||||||
magnifyFlag = bool(transFlags&0x0004)
|
magnifyFlag = bool(transFlags&0x0004)
|
||||||
thisAref.transFlags=[mirrorFlag,rotateFlag,magnifyFlag]
|
thisAref.transFlags=[mirrorFlag,magnifyFlag,rotateFlag]
|
||||||
if(self.debugToTerminal==1):
|
if(self.debugToTerminal==1):
|
||||||
print("\t\t\tMirror X:"+str(mirrorFlag))
|
print("\t\t\tMirror X:"+str(mirrorFlag))
|
||||||
print("\t\t\tRotate:"+str(rotateFlag))
|
print("\t\t\tRotate:"+str(rotateFlag))
|
||||||
|
|
@ -408,7 +408,7 @@ class Gds2reader:
|
||||||
mirrorFlag = bool(transFlags&0x8000) ##these flags are a bit sketchy
|
mirrorFlag = bool(transFlags&0x8000) ##these flags are a bit sketchy
|
||||||
rotateFlag = bool(transFlags&0x0002)
|
rotateFlag = bool(transFlags&0x0002)
|
||||||
magnifyFlag = bool(transFlags&0x0004)
|
magnifyFlag = bool(transFlags&0x0004)
|
||||||
thisText.transFlags=[mirrorFlag,rotateFlag,magnifyFlag]
|
thisText.transFlags=[mirrorFlag,magnifyFlag,rotateFlag]
|
||||||
if(self.debugToTerminal==1):
|
if(self.debugToTerminal==1):
|
||||||
print("\t\t\tMirror X:"+str(mirrorFlag))
|
print("\t\t\tMirror X:"+str(mirrorFlag))
|
||||||
print("\t\t\tRotate:"+str(rotateFlag))
|
print("\t\t\tRotate:"+str(rotateFlag))
|
||||||
|
|
|
||||||
|
|
@ -280,15 +280,15 @@ class Gds2writer:
|
||||||
if(thisSref.transFlags!=""):
|
if(thisSref.transFlags!=""):
|
||||||
idBits=b'\x1A\x01'
|
idBits=b'\x1A\x01'
|
||||||
mirrorFlag = int(thisSref.transFlags[0])<<15
|
mirrorFlag = int(thisSref.transFlags[0])<<15
|
||||||
rotateFlag = int(thisSref.transFlags[1])<<1
|
rotateFlag = int(thisSref.transFlags[2])<<1
|
||||||
magnifyFlag = int(thisSref.transFlags[2])<<3
|
magnifyFlag = int(thisSref.transFlags[1])<<3
|
||||||
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
|
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
|
||||||
self.writeRecord(idBits+transFlags)
|
self.writeRecord(idBits+transFlags)
|
||||||
if(thisSref.magFactor!=""):
|
if(thisSref.transFlags[1]):
|
||||||
idBits=b'\x1B\x05'
|
idBits=b'\x1B\x05'
|
||||||
magFactor=self.ibmDataFromIeeeDouble(thisSref.magFactor)
|
magFactor=self.ibmDataFromIeeeDouble(thisSref.magFactor)
|
||||||
self.writeRecord(idBits+magFactor)
|
self.writeRecord(idBits+magFactor)
|
||||||
if(thisSref.rotateAngle!=""):
|
if(thisSref.transFlags[2]):
|
||||||
idBits=b'\x1C\x05'
|
idBits=b'\x1C\x05'
|
||||||
rotateAngle=self.ibmDataFromIeeeDouble(thisSref.rotateAngle)
|
rotateAngle=self.ibmDataFromIeeeDouble(thisSref.rotateAngle)
|
||||||
self.writeRecord(idBits+rotateAngle)
|
self.writeRecord(idBits+rotateAngle)
|
||||||
|
|
@ -327,15 +327,15 @@ class Gds2writer:
|
||||||
if(thisAref.transFlags):
|
if(thisAref.transFlags):
|
||||||
idBits=b'\x1A\x01'
|
idBits=b'\x1A\x01'
|
||||||
mirrorFlag = int(thisAref.transFlags[0])<<15
|
mirrorFlag = int(thisAref.transFlags[0])<<15
|
||||||
rotateFlag = int(thisAref.transFlags[1])<<1
|
rotateFlag = int(thisAref.transFlags[2])<<1
|
||||||
magnifyFlag = int(thisAref.transFlags[0])<<3
|
magnifyFlag = int(thisAref.transFlags[1])<<3
|
||||||
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
|
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
|
||||||
self.writeRecord(idBits+transFlags)
|
self.writeRecord(idBits+transFlags)
|
||||||
if(thisAref.magFactor):
|
if(thisAref.transFlags[1]):
|
||||||
idBits=b'\x1B\x05'
|
idBits=b'\x1B\x05'
|
||||||
magFactor=self.ibmDataFromIeeeDouble(thisAref.magFactor)
|
magFactor=self.ibmDataFromIeeeDouble(thisAref.magFactor)
|
||||||
self.writeRecord(idBits+magFactor)
|
self.writeRecord(idBits+magFactor)
|
||||||
if(thisAref.rotateAngle):
|
if(thisAref.transFlags[2]):
|
||||||
idBits=b'\x1C\x05'
|
idBits=b'\x1C\x05'
|
||||||
rotateAngle=self.ibmDataFromIeeeDouble(thisAref.rotateAngle)
|
rotateAngle=self.ibmDataFromIeeeDouble(thisAref.rotateAngle)
|
||||||
self.writeRecord(idBits+rotateAngle)
|
self.writeRecord(idBits+rotateAngle)
|
||||||
|
|
@ -374,15 +374,15 @@ class Gds2writer:
|
||||||
if(thisText.transFlags != ""):
|
if(thisText.transFlags != ""):
|
||||||
idBits=b'\x1A\x01'
|
idBits=b'\x1A\x01'
|
||||||
mirrorFlag = int(thisText.transFlags[0])<<15
|
mirrorFlag = int(thisText.transFlags[0])<<15
|
||||||
rotateFlag = int(thisText.transFlags[1])<<1
|
rotateFlag = int(thisText.transFlags[2])<<1
|
||||||
magnifyFlag = int(thisText.transFlags[0])<<3
|
magnifyFlag = int(thisText.transFlags[1])<<3
|
||||||
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
|
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
|
||||||
self.writeRecord(idBits+transFlags)
|
self.writeRecord(idBits+transFlags)
|
||||||
if(thisText.magFactor != ""):
|
if(thisText.transFlags[1]):
|
||||||
idBits=b'\x1B\x05'
|
idBits=b'\x1B\x05'
|
||||||
magFactor=self.ibmDataFromIeeeDouble(thisText.magFactor)
|
magFactor=self.ibmDataFromIeeeDouble(thisText.magFactor)
|
||||||
self.writeRecord(idBits+magFactor)
|
self.writeRecord(idBits+magFactor)
|
||||||
if(thisText.rotateAngle != ""):
|
if(thisText.transFlags[2]):
|
||||||
idBits=b'\x1C\x05'
|
idBits=b'\x1C\x05'
|
||||||
rotateAngle=self.ibmDataFromIeeeDouble(thisText.rotateAngle)
|
rotateAngle=self.ibmDataFromIeeeDouble(thisText.rotateAngle)
|
||||||
self.writeRecord(idBits+rotateAngle)
|
self.writeRecord(idBits+rotateAngle)
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ class GdsText:
|
||||||
self.plex=""
|
self.plex=""
|
||||||
self.drawingLayer=""
|
self.drawingLayer=""
|
||||||
self.purposeLayer = None
|
self.purposeLayer = None
|
||||||
self.transFlags=[0,00]
|
self.transFlags=[0,0,0]
|
||||||
self.magFactor=""
|
self.magFactor=""
|
||||||
self.rotateAngle=""
|
self.rotateAngle=""
|
||||||
self.pathType=""
|
self.pathType=""
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,11 @@ class VlsiLayout:
|
||||||
#helper method to rotate a list of coordinates
|
#helper method to rotate a list of coordinates
|
||||||
angle=math.radians(float(0))
|
angle=math.radians(float(0))
|
||||||
if(rotateAngle):
|
if(rotateAngle):
|
||||||
angle = math.radians(float(repr(rotateAngle)))
|
angle = math.radians(float(rotateAngle))
|
||||||
|
|
||||||
coordinatesRotate = [] #this will hold the rotated values
|
coordinatesRotate = [] #this will hold the rotated values
|
||||||
for coordinate in coordinatesToRotate:
|
for coordinate in coordinatesToRotate:
|
||||||
|
# This is the CCW rotation matrix
|
||||||
newX = coordinate[0]*math.cos(angle) - coordinate[1]*math.sin(angle)
|
newX = coordinate[0]*math.cos(angle) - coordinate[1]*math.sin(angle)
|
||||||
newY = coordinate[0]*math.sin(angle) + coordinate[1]*math.cos(angle)
|
newY = coordinate[0]*math.sin(angle) + coordinate[1]*math.cos(angle)
|
||||||
coordinatesRotate.extend((newX,newY))
|
coordinatesRotate.extend((newX,newY))
|
||||||
|
|
@ -274,8 +275,9 @@ class VlsiLayout:
|
||||||
Method to insert one layout into another at a particular offset.
|
Method to insert one layout into another at a particular offset.
|
||||||
"""
|
"""
|
||||||
offsetInLayoutUnits = (self.userUnits(offsetInMicrons[0]),self.userUnits(offsetInMicrons[1]))
|
offsetInLayoutUnits = (self.userUnits(offsetInMicrons[0]),self.userUnits(offsetInMicrons[1]))
|
||||||
if self.debug==1:
|
if self.debug:
|
||||||
debug.info(0,"DEBUG: GdsMill vlsiLayout: addInstance: type %s, nameOfLayout "%type(layoutToAdd),nameOfLayout)
|
debug.info(0,"DEBUG: GdsMill vlsiLayout: addInstance: type {0}, nameOfLayout {1}".format(type(layoutToAdd),nameOfLayout))
|
||||||
|
debug.info(0,"DEBUG: name={0} offset={1} mirror={2} rotate={3}".format(layoutToAdd.rootStructureName,offsetInMicrons, mirror, rotate))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -295,7 +297,7 @@ class VlsiLayout:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# If layoutToAdd is a unique object (not this), then copy heirarchy,
|
# If layoutToAdd is a unique object (not this), then copy hierarchy,
|
||||||
# otherwise, if it is a text name of an internal structure, use it.
|
# otherwise, if it is a text name of an internal structure, use it.
|
||||||
|
|
||||||
if layoutToAdd != self:
|
if layoutToAdd != self:
|
||||||
|
|
@ -316,9 +318,7 @@ class VlsiLayout:
|
||||||
if mirror or rotate:
|
if mirror or rotate:
|
||||||
|
|
||||||
layoutToAddSref.transFlags = [0,0,0]
|
layoutToAddSref.transFlags = [0,0,0]
|
||||||
# This is NOT the same as the order in the GDS spec!
|
# transFlags = (mirror around x-axis, magnification, rotation)
|
||||||
# It gets written out in gds2writer in the right order though.
|
|
||||||
# transFlags = (mirror around x-axis, rotation, magnification)
|
|
||||||
# If magnification or rotation is true, it is the flags are then
|
# If magnification or rotation is true, it is the flags are then
|
||||||
# followed by an amount in the record
|
# followed by an amount in the record
|
||||||
if mirror=="R90":
|
if mirror=="R90":
|
||||||
|
|
@ -328,17 +328,16 @@ class VlsiLayout:
|
||||||
if mirror=="R270":
|
if mirror=="R270":
|
||||||
rotate = 270.0
|
rotate = 270.0
|
||||||
if rotate:
|
if rotate:
|
||||||
#layoutToAddSref.transFlags = [0,1,0]
|
layoutToAddSref.transFlags[2] = 1
|
||||||
layoutToAddSref.rotateAngle = rotate
|
layoutToAddSref.rotateAngle = rotate
|
||||||
if mirror == "x" or mirror == "MX":
|
if mirror == "x" or mirror == "MX":
|
||||||
layoutToAddSref.transFlags = [1,0,0]
|
layoutToAddSref.transFlags[0] = 1
|
||||||
if mirror == "y" or mirror == "MY": #NOTE: "MY" option will override specified rotate angle
|
if mirror == "y" or mirror == "MY": #NOTE: "MY" option will override specified rotate angle
|
||||||
#layoutToAddSref.transFlags = [1,1,0]
|
layoutToAddSref.transFlags[0] = 1
|
||||||
layoutToAddSref.transFlags = [1,0,0]
|
layoutToAddSref.transFlags[2] = 1
|
||||||
layoutToAddSref.rotateAngle = 180.0
|
layoutToAddSref.rotateAngle = 180.0
|
||||||
if mirror == "xy" or mirror == "XY": #NOTE: "XY" option will override specified rotate angle
|
if mirror == "xy" or mirror == "XY": #NOTE: "XY" option will override specified rotate angle
|
||||||
#layoutToAddSref.transFlags = [0,1,0]
|
layoutToAddSref.transFlags[2] = 1
|
||||||
layoutToAddSref.transFlags = [0,0,0]
|
|
||||||
layoutToAddSref.rotateAngle = 180.0
|
layoutToAddSref.rotateAngle = 180.0
|
||||||
|
|
||||||
#add the sref to the root structure
|
#add the sref to the root structure
|
||||||
|
|
@ -405,10 +404,10 @@ class VlsiLayout:
|
||||||
if(len(text)%2 == 1):
|
if(len(text)%2 == 1):
|
||||||
text = text + '\x00'
|
text = text + '\x00'
|
||||||
textToAdd.textString = text
|
textToAdd.textString = text
|
||||||
textToAdd.transFlags = [0,0,1]
|
textToAdd.transFlags[1] = 1
|
||||||
textToAdd.magFactor = magnification
|
textToAdd.magFactor = magnification
|
||||||
if rotate:
|
if rotate:
|
||||||
textToAdd.transFlags = [0,1,1]
|
textToAdd.transFlags[2] = 1
|
||||||
textToAdd.rotateAngle = rotate
|
textToAdd.rotateAngle = rotate
|
||||||
#add the sref to the root structure
|
#add the sref to the root structure
|
||||||
self.structures[self.rootStructureName].texts.append(textToAdd)
|
self.structures[self.rootStructureName].texts.append(textToAdd)
|
||||||
|
|
@ -816,10 +815,10 @@ class VlsiLayout:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
(structureName,structureOrigin,structureuVector,structurevVector)=structure
|
(structureName,structureOrigin,structureuVector,structurevVector)=structure
|
||||||
|
#print(structureName,"u",structureuVector.transpose(),"v",structurevVector.transpose(),"o",structureOrigin.transpose())
|
||||||
boundaries = []
|
boundaries = []
|
||||||
for boundary in self.structures[str(structureName)].boundaries:
|
for boundary in self.structures[str(structureName)].boundaries:
|
||||||
# Pin enclosures only work on rectangular pins so ignore any non rectangle
|
# FIXME: Right now, this only supports rectangular shapes!
|
||||||
# This may report not finding pins, but the user should fix this by adding a rectangle.
|
|
||||||
if len(boundary.coordinates)!=5:
|
if len(boundary.coordinates)!=5:
|
||||||
continue
|
continue
|
||||||
if layer==boundary.drawingLayer:
|
if layer==boundary.drawingLayer:
|
||||||
|
|
@ -827,10 +826,11 @@ class VlsiLayout:
|
||||||
right_top=boundary.coordinates[2]
|
right_top=boundary.coordinates[2]
|
||||||
# Rectangle is [leftx, bottomy, rightx, topy].
|
# Rectangle is [leftx, bottomy, rightx, topy].
|
||||||
boundaryRect=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
|
boundaryRect=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
|
||||||
|
# perform the rotation
|
||||||
boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector)
|
boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector)
|
||||||
|
# add the offset
|
||||||
boundaryRect=[boundaryRect[0]+structureOrigin[0].item(),boundaryRect[1]+structureOrigin[1].item(),
|
boundaryRect=[boundaryRect[0]+structureOrigin[0].item(),boundaryRect[1]+structureOrigin[1].item(),
|
||||||
boundaryRect[2]+structureOrigin[0].item(),boundaryRect[3]+structureOrigin[1].item()]
|
boundaryRect[2]+structureOrigin[0].item(),boundaryRect[3]+structureOrigin[1].item()]
|
||||||
|
|
||||||
boundaries.append(boundaryRect)
|
boundaries.append(boundaryRect)
|
||||||
|
|
||||||
return boundaries
|
return boundaries
|
||||||
|
|
@ -858,8 +858,12 @@ class VlsiLayout:
|
||||||
"""
|
"""
|
||||||
Rotate a coordinate in space.
|
Rotate a coordinate in space.
|
||||||
"""
|
"""
|
||||||
x=coordinate[0]*uVector[0].item()+coordinate[1]*uVector[1].item()
|
# MRG: 9/3/18 Incorrect matrixi multiplication!
|
||||||
y=coordinate[1]*vVector[1].item()+coordinate[0]*vVector[0].item()
|
# This is fixed to be:
|
||||||
|
# |u[0] v[0]| |x| |x'|
|
||||||
|
# |u[1] v[1]|x|y|=|y'|
|
||||||
|
x=coordinate[0]*uVector[0].item()+coordinate[1]*vVector[0].item()
|
||||||
|
y=coordinate[0]*uVector[1].item()+coordinate[1]*vVector[1].item()
|
||||||
transformCoordinate=[x,y]
|
transformCoordinate=[x,y]
|
||||||
|
|
||||||
return transformCoordinate
|
return transformCoordinate
|
||||||
|
|
|
||||||
|
|
@ -115,11 +115,11 @@ class dff_inv_array(design.design):
|
||||||
def add_layout_pins(self):
|
def add_layout_pins(self):
|
||||||
for row in range(self.rows):
|
for row in range(self.rows):
|
||||||
for col in range(self.columns):
|
for col in range(self.columns):
|
||||||
# Continous vdd rail along with label.
|
# Adds power pin on left of row
|
||||||
vdd_pin=self.dff_insts[row,col].get_pin("vdd")
|
vdd_pin=self.dff_insts[row,col].get_pin("vdd")
|
||||||
self.add_power_pin("vdd", vdd_pin.lc())
|
self.add_power_pin("vdd", vdd_pin.lc())
|
||||||
|
|
||||||
# Continous gnd rail along with label.
|
# Adds gnd pin on left of row
|
||||||
gnd_pin=self.dff_insts[row,col].get_pin("gnd")
|
gnd_pin=self.dff_insts[row,col].get_pin("gnd")
|
||||||
self.add_power_pin("gnd", gnd_pin.lc())
|
self.add_power_pin("gnd", gnd_pin.lc())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,8 @@ class pinv(pgate.pgate):
|
||||||
offset=vector(0.5*self.width,self.height),
|
offset=vector(0.5*self.width,self.height),
|
||||||
width=self.width)
|
width=self.width)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_ptx(self):
|
def create_ptx(self):
|
||||||
"""
|
"""
|
||||||
Create the PMOS and NMOS netlist.
|
Create the PMOS and NMOS netlist.
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,6 @@ class grid:
|
||||||
def add_blockage_shape(self,ll,ur,z):
|
def add_blockage_shape(self,ll,ur,z):
|
||||||
debug.info(3,"Adding blockage ll={0} ur={1} z={2}".format(str(ll),str(ur),z))
|
debug.info(3,"Adding blockage ll={0} ur={1} z={2}".format(str(ll),str(ur),z))
|
||||||
|
|
||||||
if ll[0]<42 and ll[0]>38 and ll[1]<3 and ll[1]>0:
|
|
||||||
debug.info(0,"Adding blockage ll={0} ur={1} z={2}".format(str(ll),str(ur),z))
|
|
||||||
|
|
||||||
block_list = []
|
block_list = []
|
||||||
for x in range(int(ll[0]),int(ur[0])+1):
|
for x in range(int(ll[0]),int(ur[0])+1):
|
||||||
for y in range(int(ll[1]),int(ur[1])+1):
|
for y in range(int(ll[1]),int(ur[1])+1):
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,12 @@ class router:
|
||||||
""" If we want to route something besides the top-level cell."""
|
""" If we want to route something besides the top-level cell."""
|
||||||
self.top_name = top_name
|
self.top_name = top_name
|
||||||
|
|
||||||
|
def get_zindex(self,layer_num):
|
||||||
|
if layer_num==self.horiz_layer_number:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
|
|
||||||
def set_layers(self, layers):
|
def set_layers(self, layers):
|
||||||
"""Allows us to change the layers that we are routing on. First layer
|
"""Allows us to change the layers that we are routing on. First layer
|
||||||
is always horizontal, middle is via, and last is always
|
is always horizontal, middle is via, and last is always
|
||||||
|
|
@ -203,15 +209,20 @@ class router:
|
||||||
|
|
||||||
def add_blockages(self):
|
def add_blockages(self):
|
||||||
""" Add the blockages except the pin shapes """
|
""" Add the blockages except the pin shapes """
|
||||||
|
# Skip pin shapes
|
||||||
|
all_pins = [x[0] for x in list(self.pins.values())]
|
||||||
|
|
||||||
for blockage in self.blockages:
|
for blockage in self.blockages:
|
||||||
# Skip pin shapes
|
|
||||||
all_pins = [x[0] for x in list(self.pins.values())]
|
|
||||||
for pin in all_pins:
|
for pin in all_pins:
|
||||||
if blockage.overlaps(pin):
|
# If the blockage overlaps the pin and is on the same layer,
|
||||||
|
# it must be connected, so skip it.
|
||||||
|
if blockage==pin:
|
||||||
|
debug.info(1,"Skipping blockage for pin {}".format(str(pin)))
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
debug.info(2,"Adding blockage {}".format(str(blockage)))
|
||||||
[ll,ur]=self.convert_blockage_to_tracks(blockage.rect)
|
[ll,ur]=self.convert_blockage_to_tracks(blockage.rect)
|
||||||
zlayer = 0 if blockage.layer_num==self.horiz_layer_number else 1
|
zlayer = self.get_zindex(blockage.layer_num)
|
||||||
self.rg.add_blockage_shape(ll,ur,zlayer)
|
self.rg.add_blockage_shape(ll,ur,zlayer)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -227,37 +238,6 @@ class router:
|
||||||
rect = [ll,ur]
|
rect = [ll,ur]
|
||||||
new_pin = pin_layout("blockage{}".format(len(self.blockages)),rect,layer_num)
|
new_pin = pin_layout("blockage{}".format(len(self.blockages)),rect,layer_num)
|
||||||
self.blockages.append(new_pin)
|
self.blockages.append(new_pin)
|
||||||
|
|
||||||
# for boundary in self.layout.structures[sref].boundaries:
|
|
||||||
# coord_trans = self.translate_coordinates(boundary.coordinates, mirr, angle, xyShift)
|
|
||||||
# shape_coords = self.min_max_coord(coord_trans)
|
|
||||||
# shape = self.convert_shape_to_units(shape_coords)
|
|
||||||
|
|
||||||
# # only consider the two layers that we are routing on
|
|
||||||
# if boundary.drawingLayer in [self.vert_layer_number,self.horiz_layer_number]:
|
|
||||||
# # store the blockages as pin layouts so they are easy to compare etc.
|
|
||||||
# new_pin = pin_layout("blockage",shape,boundary.drawingLayer)
|
|
||||||
# # avoid repeated blockage pins
|
|
||||||
# if new_pin not in self.blockages:
|
|
||||||
# self.blockages.append(new_pin)
|
|
||||||
|
|
||||||
|
|
||||||
# # recurse given the mirror, angle, etc.
|
|
||||||
# for cur_sref in self.layout.structures[sref].srefs:
|
|
||||||
# sMirr = 1
|
|
||||||
# if cur_sref.transFlags[0] == True:
|
|
||||||
# sMirr = -1
|
|
||||||
# sAngle = math.radians(float(0))
|
|
||||||
# if cur_sref.rotateAngle:
|
|
||||||
# sAngle = math.radians(float(cur_sref.rotateAngle))
|
|
||||||
# sAngle += angle
|
|
||||||
# x = cur_sref.coordinates[0]
|
|
||||||
# y = cur_sref.coordinates[1]
|
|
||||||
# newX = (x)*math.cos(angle) - mirr*(y)*math.sin(angle) + xyShift[0]
|
|
||||||
# newY = (x)*math.sin(angle) + mirr*(y)*math.cos(angle) + xyShift[1]
|
|
||||||
# sxyShift = (newX, newY)
|
|
||||||
|
|
||||||
# self.get_blockages(cur_sref.sName, sMirr, sAngle, sxyShift)
|
|
||||||
|
|
||||||
|
|
||||||
def convert_point_to_units(self,p):
|
def convert_point_to_units(self,p):
|
||||||
|
|
@ -282,9 +262,11 @@ class router:
|
||||||
old_ur = ur
|
old_ur = ur
|
||||||
ll=ll.scale(self.track_factor)
|
ll=ll.scale(self.track_factor)
|
||||||
ur=ur.scale(self.track_factor)
|
ur=ur.scale(self.track_factor)
|
||||||
|
if ll[0]<45 and ll[0]>35 and ll[1]<46 and ll[1]>39:
|
||||||
|
print(ll,ur)
|
||||||
ll = ll.floor()
|
ll = ll.floor()
|
||||||
ur = ur.ceil()
|
ur = ur.ceil()
|
||||||
if ll[0]<45 and ll[0]>35 and ll[1]<10 and ll[1]>0:
|
if ll[0]<45 and ll[0]>35 and ll[1]<46 and ll[1]>39:
|
||||||
debug.info(0,"Converting [ {0} , {1} ]".format(old_ll,old_ur))
|
debug.info(0,"Converting [ {0} , {1} ]".format(old_ll,old_ur))
|
||||||
debug.info(0,"Converted [ {0} , {1} ]".format(ll,ur))
|
debug.info(0,"Converted [ {0} , {1} ]".format(ll,ur))
|
||||||
return [ll,ur]
|
return [ll,ur]
|
||||||
|
|
@ -296,9 +278,6 @@ class router:
|
||||||
If a pin has insufficent overlap, it returns the blockage list to avoid it.
|
If a pin has insufficent overlap, it returns the blockage list to avoid it.
|
||||||
"""
|
"""
|
||||||
(ll,ur) = pin.rect
|
(ll,ur) = pin.rect
|
||||||
#ll = snap_to_grid(ll)
|
|
||||||
#ur = snap_to_grid(ur)
|
|
||||||
|
|
||||||
#debug.info(1,"Converting [ {0} , {1} ]".format(ll,ur))
|
#debug.info(1,"Converting [ {0} , {1} ]".format(ll,ur))
|
||||||
|
|
||||||
# scale the size bigger to include neaby tracks
|
# scale the size bigger to include neaby tracks
|
||||||
|
|
@ -306,37 +285,40 @@ class router:
|
||||||
ur=ur.scale(self.track_factor).ceil()
|
ur=ur.scale(self.track_factor).ceil()
|
||||||
|
|
||||||
# width depends on which layer it is
|
# width depends on which layer it is
|
||||||
zindex = 0 if pin.layer_num==self.horiz_layer_number else 1
|
zindex=self.get_zindex(pin.layer_num)
|
||||||
if zindex==0:
|
if zindex:
|
||||||
width = self.horiz_layer_width
|
|
||||||
else:
|
|
||||||
width = self.vert_layer_width
|
width = self.vert_layer_width
|
||||||
|
else:
|
||||||
|
width = self.horiz_layer_width
|
||||||
|
|
||||||
track_list = []
|
track_list = []
|
||||||
block_list = []
|
block_list = []
|
||||||
# include +- 1 so when a shape is less than one grid
|
|
||||||
for x in range(ll[0]-1,ur[0]+1):
|
track_area = self.track_width*self.track_width
|
||||||
for y in range(ll[1]-1,ur[1]+1):
|
for x in range(ll[0],ur[0]):
|
||||||
|
for y in range(ll[1],ur[1]):
|
||||||
#debug.info(1,"Converting [ {0} , {1} ]".format(x,y))
|
#debug.info(1,"Converting [ {0} , {1} ]".format(x,y))
|
||||||
# get the rectangular pin at a track location
|
|
||||||
# if dimension of overlap is greater than min width in any dimension,
|
|
||||||
# it will be an on-grid pin
|
|
||||||
rect = self.convert_track_to_pin(vector3d(x,y,zindex))
|
|
||||||
max_overlap=max(self.compute_overlap(pin.rect,rect))
|
|
||||||
|
|
||||||
# however, if there is not enough overlap, then if there is any overlap at all,
|
# however, if there is not enough overlap, then if there is any overlap at all,
|
||||||
# we need to block it to prevent routes coming in on that grid
|
# we need to block it to prevent routes coming in on that grid
|
||||||
full_rect = self.convert_full_track_to_shape(vector3d(x,y,zindex))
|
full_rect = self.convert_track_to_shape(vector3d(x,y,zindex))
|
||||||
full_overlap=max(self.compute_overlap(pin.rect,full_rect))
|
overlap_rect=self.compute_overlap(pin.rect,full_rect)
|
||||||
|
overlap_area = overlap_rect[0]*overlap_rect[1]
|
||||||
#debug.info(1,"Check overlap: {0} {1} max={2}".format(shape,rect,max_overlap))
|
#debug.info(1,"Check overlap: {0} {1} max={2}".format(shape,rect,max_overlap))
|
||||||
if max_overlap >= width:
|
|
||||||
|
# Assume if more than half the area, it is occupied
|
||||||
|
overlap_ratio = overlap_area/track_area
|
||||||
|
if overlap_ratio > 0.5:
|
||||||
track_list.append(vector3d(x,y,zindex))
|
track_list.append(vector3d(x,y,zindex))
|
||||||
elif full_overlap>0:
|
# otherwise, the pin may not be accessible, so block it
|
||||||
|
elif overlap_ratio > 0:
|
||||||
block_list.append(vector3d(x,y,zindex))
|
block_list.append(vector3d(x,y,zindex))
|
||||||
else:
|
else:
|
||||||
debug.info(4,"No overlap: {0} {1} max={2}".format(pin.rect,rect,max_overlap))
|
debug.info(4,"No overlap: {0} {1} max={2}".format(pin.rect,rect,max_overlap))
|
||||||
|
print("H:",x,y)
|
||||||
|
if x>38 and x<42 and y>42 and y<45:
|
||||||
|
print(pin)
|
||||||
|
print(full_rect, overlap_rect, overlap_ratio)
|
||||||
#debug.warning("Off-grid pin for {0}.".format(str(pin)))
|
#debug.warning("Off-grid pin for {0}.".format(str(pin)))
|
||||||
#debug.info(1,"Converted [ {0} , {1} ]".format(ll,ur))
|
#debug.info(1,"Converted [ {0} , {1} ]".format(ll,ur))
|
||||||
return (track_list,block_list)
|
return (track_list,block_list)
|
||||||
|
|
@ -381,7 +363,7 @@ class router:
|
||||||
|
|
||||||
return [ll,ur]
|
return [ll,ur]
|
||||||
|
|
||||||
def convert_full_track_to_shape(self,track):
|
def convert_track_to_shape(self,track):
|
||||||
"""
|
"""
|
||||||
Convert a grid point into a rectangle shape that occupies the entire centered
|
Convert a grid point into a rectangle shape that occupies the entire centered
|
||||||
track.
|
track.
|
||||||
|
|
@ -447,9 +429,8 @@ class router:
|
||||||
grid_keys=self.rg.map.keys()
|
grid_keys=self.rg.map.keys()
|
||||||
partial_track=vector(0,self.track_width/6.0)
|
partial_track=vector(0,self.track_width/6.0)
|
||||||
for g in grid_keys:
|
for g in grid_keys:
|
||||||
continue # for now...
|
shape = self.convert_track_to_shape(g)
|
||||||
shape = self.convert_full_track_to_shape(g)
|
self.cell.add_rect(layer="text",
|
||||||
self.cell.add_rect(layer="boundary",
|
|
||||||
offset=shape[0],
|
offset=shape[0],
|
||||||
width=shape[1].x-shape[0].x,
|
width=shape[1].x-shape[0].x,
|
||||||
height=shape[1].y-shape[0].y)
|
height=shape[1].y-shape[0].y)
|
||||||
|
|
@ -481,7 +462,7 @@ class router:
|
||||||
zoom=0.05)
|
zoom=0.05)
|
||||||
|
|
||||||
for blockage in self.blockages:
|
for blockage in self.blockages:
|
||||||
self.cell.add_rect(layer="boundary",
|
self.cell.add_rect(layer="blockage",
|
||||||
offset=blockage.ll(),
|
offset=blockage.ll(),
|
||||||
width=blockage.width(),
|
width=blockage.width(),
|
||||||
height=blockage.height())
|
height=blockage.height())
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,14 @@ class no_blockages_test(openram_test):
|
||||||
globals.setup_paths()
|
globals.setup_paths()
|
||||||
from control_logic import control_logic
|
from control_logic import control_logic
|
||||||
cell = control_logic(16)
|
cell = control_logic(16)
|
||||||
|
#from pinv import pinv
|
||||||
|
#cell = pinv()
|
||||||
#gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),"control_logic")
|
#gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),"control_logic")
|
||||||
#cell = gds_cell(name, gds_file)
|
#cell = gds_cell(name, gds_file)
|
||||||
self.add_inst(name=name,
|
self.add_inst(name=name,
|
||||||
mod=cell,
|
mod=cell,
|
||||||
offset=[0,0])
|
offset=[0,0])
|
||||||
self.connect_inst(["csb","web","clk","s_en","w_en","clk_buf_bar","clk_buf","vdd","gnd"])
|
self.connect_inst(cell.pin_map.keys())
|
||||||
|
|
||||||
r=router(module=cell)
|
r=router(module=cell)
|
||||||
layer_stack =("metal3","via2","metal2")
|
layer_stack =("metal3","via2","metal2")
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ layer["via9"] = 28
|
||||||
layer["metal10"] = 29
|
layer["metal10"] = 29
|
||||||
layer["text"] = 239
|
layer["text"] = 239
|
||||||
layer["boundary"]= 239
|
layer["boundary"]= 239
|
||||||
|
layer["blockage"]= 239
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
##END GDS Layer Map
|
##END GDS Layer Map
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ layer["via2"] = 61
|
||||||
layer["metal3"] = 62
|
layer["metal3"] = 62
|
||||||
layer["text"] = 63
|
layer["text"] = 63
|
||||||
layer["boundary"] = 63
|
layer["boundary"] = 63
|
||||||
|
layer["blockage"] = 83
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
##END GDS Layer Map
|
##END GDS Layer Map
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue