Found rotate bug in transformCoordinate. Cleaned up transFlags.

This commit is contained in:
Matt Guthaus 2018-09-04 16:35:40 -07:00
parent 763f1e8dee
commit 378993ca22
15 changed files with 156 additions and 166 deletions

View File

@ -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
hierarchy as the contact.
"""
unique_id = 1
def __init__(self, layer_stack, dimensions=[1,1], implant_type=None, well_type=None):
if implant_type or well_type:
name = "{0}_{1}_{2}_{3}x{4}_{5}{6}".format(layer_stack[0],
layer_stack[1],
layer_stack[2],
dimensions[0],
dimensions[1],
implant_type,
well_type)
name = "{0}_{1}_{2}_{3}x{4}_{5}{6}_{7}".format(layer_stack[0],
layer_stack[1],
layer_stack[2],
dimensions[0],
dimensions[1],
implant_type,
well_type,
contact.unique_id)
else:
name = "{0}_{1}_{2}_{3}x{4}".format(layer_stack[0],
layer_stack[1],
layer_stack[2],
dimensions[0],
dimensions[1])
name = "{0}_{1}_{2}_{3}x{4}_{5}".format(layer_stack[0],
layer_stack[1],
layer_stack[2],
dimensions[0],
dimensions[1],
contact.unique_id)
contact.unique_id += 1
hierarchy_design.hierarchy_design.__init__(self, name)
debug.info(4, "create contact object {0}".format(name))

View File

@ -34,14 +34,14 @@ class geometry:
# coordinate += [(x, y)]
# return coordinate
def transform_coords(self, coords, offset, mirr, angle):
"""Calculate coordinates after flip, rotate, and shift"""
coordinate = []
for item in coords:
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]
coordinate += [[x, y]]
return coordinate
# def transform_coords(self, coords, offset, mirr, angle):
# """Calculate coordinates after flip, rotate, and shift"""
# coordinate = []
# for item in coords:
# 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]
# coordinate += [[x, y]]
# return coordinate
def normalize(self):
""" Re-find the LL and UR points after a transform """
@ -148,40 +148,40 @@ class instance(geometry):
debug.info(4, "creating instance: " + self.name)
def get_blockages(self, layer, top=False):
""" Retrieve rectangular blockages of all modules in this instance.
Apply the transform of the instance placement to give absolute blockages."""
angle = math.radians(float(self.rotate))
mirr = 1
if self.mirror=="R90":
angle += math.radians(90.0)
elif self.mirror=="R180":
angle += math.radians(180.0)
elif self.mirror=="R270":
angle += math.radians(270.0)
elif self.mirror=="MX":
mirr = -1
elif self.mirror=="MY":
mirr = -1
angle += math.radians(180.0)
elif self.mirror=="XY":
mirr = 1
angle += math.radians(180.0)
# def get_blockages(self, layer, top=False):
# """ Retrieve rectangular blockages of all modules in this instance.
# Apply the transform of the instance placement to give absolute blockages."""
# angle = math.radians(float(self.rotate))
# mirr = 1
# if self.mirror=="R90":
# angle += math.radians(90.0)
# elif self.mirror=="R180":
# angle += math.radians(180.0)
# elif self.mirror=="R270":
# angle += math.radians(270.0)
# elif self.mirror=="MX":
# mirr = -1
# elif self.mirror=="MY":
# mirr = -1
# angle += math.radians(180.0)
# elif self.mirror=="XY":
# mirr = 1
# angle += math.radians(180.0)
if self.mod.is_library_cell:
# For lib cells, block the whole thing except on metal3
# since they shouldn't use metal3
if layer==tech.layer["metal1"] or layer==tech.layer["metal2"]:
return [self.transform_coords(self.mod.get_boundary(), self.offset, mirr, angle)]
else:
return []
else:
# if self.mod.is_library_cell:
# # For lib cells, block the whole thing except on metal3
# # since they shouldn't use metal3
# if layer==tech.layer["metal1"] or layer==tech.layer["metal2"]:
# return [self.transform_coords(self.mod.get_boundary(), self.offset, mirr, angle)]
# else:
# return []
# else:
blockages = self.mod.get_blockages(layer)
new_blockages = []
for b in blockages:
new_blockages.append(self.transform_coords(b,self.offset, mirr, angle))
return new_blockages
# blockages = self.mod.get_blockages(layer)
# new_blockages = []
# for b in blockages:
# new_blockages.append(self.transform_coords(b,self.offset, mirr, angle))
# return new_blockages
def gds_write_file(self, new_layout):
"""Recursively writes all the sub-modules in this instance"""

View File

@ -379,12 +379,10 @@ class layout(lef.lef):
dimensions=size,
implant_type=implant_type,
well_type=well_type)
debug.check(mirror=="R0","Use rotate to rotate vias instead of mirror.")
height = via.height
width = via.width
debug.check(mirror=="R0","Use rotate to rotate vias instead of mirror.")
if rotate==0:
corrected_offset = offset + vector(-0.5*width,-0.5*height)
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
"""
debug.info(0,"Adding power pin {0} at {1} rotate={2}".format(name, loc, rotate))
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=loc,
rotate=rotate)

View File

@ -36,16 +36,14 @@ class pin_layout:
def __eq__(self, other):
""" Check if these are the same pins for duplicate checks """
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:
return False
def overlaps(self, other):
""" Check if a shape overlaps with a rectangle """
ll = self.rect[0]
ur = self.rect[1]
oll = other.rect[0]
our = other.rect[1]
(ll,ur) = self.rect
(oll,our) = other.rect
# Start assuming no overlaps
x_overlaps = False
y_overlaps = False

View File

@ -294,7 +294,7 @@ class Gds2reader:
mirrorFlag = bool(transFlags&0x8000) ##these flags are a bit sketchy
rotateFlag = bool(transFlags&0x0002)
magnifyFlag = bool(transFlags&0x0004)
thisSref.transFlags=[mirrorFlag,rotateFlag,magnifyFlag]
thisSref.transFlags=[mirrorFlag,magnifyFlag,rotateFlag]
if(self.debugToTerminal==1):
print("\t\t\tMirror X:"+str(mirrorFlag))
print( "\t\t\tRotate:"+str(rotateFlag))
@ -345,7 +345,7 @@ class Gds2reader:
mirrorFlag = bool(transFlags&0x8000) ##these flags are a bit sketchy
rotateFlag = bool(transFlags&0x0002)
magnifyFlag = bool(transFlags&0x0004)
thisAref.transFlags=[mirrorFlag,rotateFlag,magnifyFlag]
thisAref.transFlags=[mirrorFlag,magnifyFlag,rotateFlag]
if(self.debugToTerminal==1):
print("\t\t\tMirror X:"+str(mirrorFlag))
print("\t\t\tRotate:"+str(rotateFlag))
@ -408,7 +408,7 @@ class Gds2reader:
mirrorFlag = bool(transFlags&0x8000) ##these flags are a bit sketchy
rotateFlag = bool(transFlags&0x0002)
magnifyFlag = bool(transFlags&0x0004)
thisText.transFlags=[mirrorFlag,rotateFlag,magnifyFlag]
thisText.transFlags=[mirrorFlag,magnifyFlag,rotateFlag]
if(self.debugToTerminal==1):
print("\t\t\tMirror X:"+str(mirrorFlag))
print("\t\t\tRotate:"+str(rotateFlag))

View File

@ -280,15 +280,15 @@ class Gds2writer:
if(thisSref.transFlags!=""):
idBits=b'\x1A\x01'
mirrorFlag = int(thisSref.transFlags[0])<<15
rotateFlag = int(thisSref.transFlags[1])<<1
magnifyFlag = int(thisSref.transFlags[2])<<3
rotateFlag = int(thisSref.transFlags[2])<<1
magnifyFlag = int(thisSref.transFlags[1])<<3
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
self.writeRecord(idBits+transFlags)
if(thisSref.magFactor!=""):
if(thisSref.transFlags[1]):
idBits=b'\x1B\x05'
magFactor=self.ibmDataFromIeeeDouble(thisSref.magFactor)
self.writeRecord(idBits+magFactor)
if(thisSref.rotateAngle!=""):
if(thisSref.transFlags[2]):
idBits=b'\x1C\x05'
rotateAngle=self.ibmDataFromIeeeDouble(thisSref.rotateAngle)
self.writeRecord(idBits+rotateAngle)
@ -327,15 +327,15 @@ class Gds2writer:
if(thisAref.transFlags):
idBits=b'\x1A\x01'
mirrorFlag = int(thisAref.transFlags[0])<<15
rotateFlag = int(thisAref.transFlags[1])<<1
magnifyFlag = int(thisAref.transFlags[0])<<3
rotateFlag = int(thisAref.transFlags[2])<<1
magnifyFlag = int(thisAref.transFlags[1])<<3
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
self.writeRecord(idBits+transFlags)
if(thisAref.magFactor):
if(thisAref.transFlags[1]):
idBits=b'\x1B\x05'
magFactor=self.ibmDataFromIeeeDouble(thisAref.magFactor)
self.writeRecord(idBits+magFactor)
if(thisAref.rotateAngle):
if(thisAref.transFlags[2]):
idBits=b'\x1C\x05'
rotateAngle=self.ibmDataFromIeeeDouble(thisAref.rotateAngle)
self.writeRecord(idBits+rotateAngle)
@ -374,15 +374,15 @@ class Gds2writer:
if(thisText.transFlags != ""):
idBits=b'\x1A\x01'
mirrorFlag = int(thisText.transFlags[0])<<15
rotateFlag = int(thisText.transFlags[1])<<1
magnifyFlag = int(thisText.transFlags[0])<<3
rotateFlag = int(thisText.transFlags[2])<<1
magnifyFlag = int(thisText.transFlags[1])<<3
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
self.writeRecord(idBits+transFlags)
if(thisText.magFactor != ""):
if(thisText.transFlags[1]):
idBits=b'\x1B\x05'
magFactor=self.ibmDataFromIeeeDouble(thisText.magFactor)
self.writeRecord(idBits+magFactor)
if(thisText.rotateAngle != ""):
if(thisText.transFlags[2]):
idBits=b'\x1C\x05'
rotateAngle=self.ibmDataFromIeeeDouble(thisText.rotateAngle)
self.writeRecord(idBits+rotateAngle)

View File

@ -141,7 +141,7 @@ class GdsText:
self.plex=""
self.drawingLayer=""
self.purposeLayer = None
self.transFlags=[0,00]
self.transFlags=[0,0,0]
self.magFactor=""
self.rotateAngle=""
self.pathType=""

View File

@ -64,10 +64,11 @@ class VlsiLayout:
#helper method to rotate a list of coordinates
angle=math.radians(float(0))
if(rotateAngle):
angle = math.radians(float(repr(rotateAngle)))
angle = math.radians(float(rotateAngle))
coordinatesRotate = [] #this will hold the rotated values
for coordinate in coordinatesToRotate:
# This is the CCW rotation matrix
newX = coordinate[0]*math.cos(angle) - coordinate[1]*math.sin(angle)
newY = coordinate[0]*math.sin(angle) + coordinate[1]*math.cos(angle)
coordinatesRotate.extend((newX,newY))
@ -274,8 +275,9 @@ class VlsiLayout:
Method to insert one layout into another at a particular offset.
"""
offsetInLayoutUnits = (self.userUnits(offsetInMicrons[0]),self.userUnits(offsetInMicrons[1]))
if self.debug==1:
debug.info(0,"DEBUG: GdsMill vlsiLayout: addInstance: type %s, nameOfLayout "%type(layoutToAdd),nameOfLayout)
if self.debug:
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.
if layoutToAdd != self:
@ -316,9 +318,7 @@ class VlsiLayout:
if mirror or rotate:
layoutToAddSref.transFlags = [0,0,0]
# This is NOT the same as the order in the GDS spec!
# It gets written out in gds2writer in the right order though.
# transFlags = (mirror around x-axis, rotation, magnification)
# transFlags = (mirror around x-axis, magnification, rotation)
# If magnification or rotation is true, it is the flags are then
# followed by an amount in the record
if mirror=="R90":
@ -328,17 +328,16 @@ class VlsiLayout:
if mirror=="R270":
rotate = 270.0
if rotate:
#layoutToAddSref.transFlags = [0,1,0]
layoutToAddSref.transFlags[2] = 1
layoutToAddSref.rotateAngle = rotate
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
#layoutToAddSref.transFlags = [1,1,0]
layoutToAddSref.transFlags = [1,0,0]
layoutToAddSref.transFlags[0] = 1
layoutToAddSref.transFlags[2] = 1
layoutToAddSref.rotateAngle = 180.0
if mirror == "xy" or mirror == "XY": #NOTE: "XY" option will override specified rotate angle
#layoutToAddSref.transFlags = [0,1,0]
layoutToAddSref.transFlags = [0,0,0]
layoutToAddSref.transFlags[2] = 1
layoutToAddSref.rotateAngle = 180.0
#add the sref to the root structure
@ -405,10 +404,10 @@ class VlsiLayout:
if(len(text)%2 == 1):
text = text + '\x00'
textToAdd.textString = text
textToAdd.transFlags = [0,0,1]
textToAdd.transFlags[1] = 1
textToAdd.magFactor = magnification
if rotate:
textToAdd.transFlags = [0,1,1]
textToAdd.transFlags[2] = 1
textToAdd.rotateAngle = rotate
#add the sref to the root structure
self.structures[self.rootStructureName].texts.append(textToAdd)
@ -816,10 +815,10 @@ class VlsiLayout:
"""
(structureName,structureOrigin,structureuVector,structurevVector)=structure
#print(structureName,"u",structureuVector.transpose(),"v",structurevVector.transpose(),"o",structureOrigin.transpose())
boundaries = []
for boundary in self.structures[str(structureName)].boundaries:
# Pin enclosures only work on rectangular pins so ignore any non rectangle
# This may report not finding pins, but the user should fix this by adding a rectangle.
# FIXME: Right now, this only supports rectangular shapes!
if len(boundary.coordinates)!=5:
continue
if layer==boundary.drawingLayer:
@ -827,10 +826,11 @@ class VlsiLayout:
right_top=boundary.coordinates[2]
# Rectangle is [leftx, bottomy, rightx, topy].
boundaryRect=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
# perform the rotation
boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector)
# add the offset
boundaryRect=[boundaryRect[0]+structureOrigin[0].item(),boundaryRect[1]+structureOrigin[1].item(),
boundaryRect[2]+structureOrigin[0].item(),boundaryRect[3]+structureOrigin[1].item()]
boundaries.append(boundaryRect)
return boundaries
@ -858,8 +858,12 @@ class VlsiLayout:
"""
Rotate a coordinate in space.
"""
x=coordinate[0]*uVector[0].item()+coordinate[1]*uVector[1].item()
y=coordinate[1]*vVector[1].item()+coordinate[0]*vVector[0].item()
# MRG: 9/3/18 Incorrect matrixi multiplication!
# 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]
return transformCoordinate

View File

@ -115,11 +115,11 @@ class dff_inv_array(design.design):
def add_layout_pins(self):
for row in range(self.rows):
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")
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")
self.add_power_pin("gnd", gnd_pin.lc())

View File

@ -171,6 +171,8 @@ class pinv(pgate.pgate):
offset=vector(0.5*self.width,self.height),
width=self.width)
def create_ptx(self):
"""
Create the PMOS and NMOS netlist.

View File

@ -36,9 +36,6 @@ class grid:
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))
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 = []
for x in range(int(ll[0]),int(ur[0])+1):
for y in range(int(ll[1]),int(ur[1])+1):

View File

@ -49,6 +49,12 @@ class router:
""" If we want to route something besides the top-level cell."""
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):
"""Allows us to change the layers that we are routing on. First layer
is always horizontal, middle is via, and last is always
@ -203,15 +209,20 @@ class router:
def add_blockages(self):
""" 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:
# Skip pin shapes
all_pins = [x[0] for x in list(self.pins.values())]
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
else:
debug.info(2,"Adding blockage {}".format(str(blockage)))
[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)
@ -227,37 +238,6 @@ class router:
rect = [ll,ur]
new_pin = pin_layout("blockage{}".format(len(self.blockages)),rect,layer_num)
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):
@ -282,9 +262,11 @@ class router:
old_ur = ur
ll=ll.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()
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,"Converted [ {0} , {1} ]".format(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.
"""
(ll,ur) = pin.rect
#ll = snap_to_grid(ll)
#ur = snap_to_grid(ur)
#debug.info(1,"Converting [ {0} , {1} ]".format(ll,ur))
# scale the size bigger to include neaby tracks
@ -306,37 +285,40 @@ class router:
ur=ur.scale(self.track_factor).ceil()
# width depends on which layer it is
zindex = 0 if pin.layer_num==self.horiz_layer_number else 1
if zindex==0:
width = self.horiz_layer_width
else:
zindex=self.get_zindex(pin.layer_num)
if zindex:
width = self.vert_layer_width
else:
width = self.horiz_layer_width
track_list = []
block_list = []
# include +- 1 so when a shape is less than one grid
for x in range(ll[0]-1,ur[0]+1):
for y in range(ll[1]-1,ur[1]+1):
track_area = self.track_width*self.track_width
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))
# 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,
# 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_overlap=max(self.compute_overlap(pin.rect,full_rect))
full_rect = self.convert_track_to_shape(vector3d(x,y,zindex))
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))
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))
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))
else:
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.info(1,"Converted [ {0} , {1} ]".format(ll,ur))
return (track_list,block_list)
@ -381,7 +363,7 @@ class router:
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
track.
@ -447,9 +429,8 @@ class router:
grid_keys=self.rg.map.keys()
partial_track=vector(0,self.track_width/6.0)
for g in grid_keys:
continue # for now...
shape = self.convert_full_track_to_shape(g)
self.cell.add_rect(layer="boundary",
shape = self.convert_track_to_shape(g)
self.cell.add_rect(layer="text",
offset=shape[0],
width=shape[1].x-shape[0].x,
height=shape[1].y-shape[0].y)
@ -481,7 +462,7 @@ class router:
zoom=0.05)
for blockage in self.blockages:
self.cell.add_rect(layer="boundary",
self.cell.add_rect(layer="blockage",
offset=blockage.ll(),
width=blockage.width(),
height=blockage.height())

View File

@ -32,12 +32,14 @@ class no_blockages_test(openram_test):
globals.setup_paths()
from control_logic import control_logic
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")
#cell = gds_cell(name, gds_file)
self.add_inst(name=name,
mod=cell,
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)
layer_stack =("metal3","via2","metal2")

View File

@ -56,6 +56,7 @@ layer["via9"] = 28
layer["metal10"] = 29
layer["text"] = 239
layer["boundary"]= 239
layer["blockage"]= 239
###################################################
##END GDS Layer Map

View File

@ -41,6 +41,7 @@ layer["via2"] = 61
layer["metal3"] = 62
layer["text"] = 63
layer["boundary"] = 63
layer["blockage"] = 83
###################################################
##END GDS Layer Map