Clean up GdsMill. Fix rotate bug I introduced in transFlags!

This commit is contained in:
Matt Guthaus 2018-08-29 15:32:45 -07:00
parent 0ce2dd2791
commit 73289a6090
9 changed files with 81 additions and 110 deletions

View File

@ -845,7 +845,7 @@ class layout(lef.lef):
def add_power_pin(self, name, loc, rotate=90): def add_power_pin(self, name, loc, rotate=90):
""" """
Add a single power pin from M3 own to M1 at the given center location Add a single power pin from M3 down to M1 at the given center location
""" """
self.add_via_center(layers=("metal1", "via1", "metal2"), self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=loc, offset=loc,

View File

@ -118,7 +118,7 @@ class GdsSref:
self.elementFlags="" self.elementFlags=""
self.plex="" self.plex=""
self.sName="" self.sName=""
self.transFlags=(False,False,False) self.transFlags=[0,0,0]
self.magFactor="" self.magFactor=""
self.rotateAngle="" self.rotateAngle=""
self.coordinates="" self.coordinates=""
@ -129,7 +129,7 @@ class GdsAref:
self.elementFlags="" self.elementFlags=""
self.plex="" self.plex=""
self.aName="" self.aName=""
self.transFlags=(False,False,False) self.transFlags=[0,0,0]
self.magFactor="" self.magFactor=""
self.rotateAngle="" self.rotateAngle=""
self.coordinates="" self.coordinates=""
@ -141,7 +141,7 @@ class GdsText:
self.plex="" self.plex=""
self.drawingLayer="" self.drawingLayer=""
self.purposeLayer = None self.purposeLayer = None
self.transFlags=(False,False,False) self.transFlags=[0,00]
self.magFactor="" self.magFactor=""
self.rotateAngle="" self.rotateAngle=""
self.pathType="" self.pathType=""
@ -167,4 +167,4 @@ class GdsBox:
self.drawingLayer="" self.drawingLayer=""
self.purposeLayer = None self.purposeLayer = None
self.boxValue="" self.boxValue=""
self.coordinates="" self.coordinates=""

View File

@ -70,7 +70,7 @@ class VlsiLayout:
for coordinate in coordinatesToRotate: for coordinate in coordinatesToRotate:
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 += [(newX,newY)] coordinatesRotate.extend((newX,newY))
return coordinatesRotate return coordinatesRotate
def rename(self,newName): def rename(self,newName):
@ -141,7 +141,7 @@ class VlsiLayout:
contained by any other structure. this is the root.""" contained by any other structure. this is the root."""
structureNames=[] structureNames=[]
for name in self.structures: for name in self.structures:
structureNames+=[name] structureNames.append(name)
for name in self.structures: for name in self.structures:
if(len(self.structures[name].srefs)>0): #does this structure reference any others? if(len(self.structures[name].srefs)>0): #does this structure reference any others?
@ -162,7 +162,8 @@ class VlsiLayout:
if(rotateAngle == None or rotateAngle == ""): if(rotateAngle == None or rotateAngle == ""):
angle = 0 angle = 0
else: else:
angle = math.radians(float(rotateAngle)) # MRG: Added negative to make CCW rotate 8/29/18
angle = math.radians(-1.0*float(rotateAngle))
mRotate = matrix([[math.cos(angle),-math.sin(angle),0.0], mRotate = matrix([[math.cos(angle),-math.sin(angle),0.0],
[math.sin(angle),math.cos(angle),0.0], [math.sin(angle),math.cos(angle),0.0],
[0.0,0.0,1.0]]) [0.0,0.0,1.0]])
@ -180,7 +181,7 @@ class VlsiLayout:
#we need to keep track of all transforms in the hierarchy #we need to keep track of all transforms in the hierarchy
#when we add an element to the xy tree, we apply all transforms from the bottom up #when we add an element to the xy tree, we apply all transforms from the bottom up
transformPath += [(mRotate,mScale,mTranslate)] transformPath.append((mRotate,mScale,mTranslate))
if delegateFunction != None: if delegateFunction != None:
delegateFunction(startingStructureName, transformPath) delegateFunction(startingStructureName, transformPath)
#starting with a particular structure, we will recursively traverse the tree #starting with a particular structure, we will recursively traverse the tree
@ -226,8 +227,10 @@ class VlsiLayout:
vVector = transform[1] * vVector #scale vVector = transform[1] * vVector #scale
origin = transform[2] * origin #translate origin = transform[2] * origin #translate
#we don't need to do a translation on the basis vectors #we don't need to do a translation on the basis vectors
self.xyTree+=[(startingStructureName,origin,uVector,vVector)] #populate the xyTree with each #uVector = transform[2] * uVector #translate
#structureName and coordinate space #vVector = transform[2] * vVector #translate
#populate the xyTree with each structureName and coordinate space
self.xyTree.append((startingStructureName,origin,uVector,vVector))
self.traverseTheHierarchy(delegateFunction = addToXyTree) self.traverseTheHierarchy(delegateFunction = addToXyTree)
def microns(self,userUnits): def microns(self,userUnits):
@ -303,7 +306,7 @@ class VlsiLayout:
#also combine the "layers in use" list #also combine the "layers in use" list
for layerNumber in layoutToAdd.layerNumbersInUse: for layerNumber in layoutToAdd.layerNumbersInUse:
if layerNumber not in self.layerNumbersInUse: if layerNumber not in self.layerNumbersInUse:
self.layerNumbersInUse += [layerNumber] self.layerNumbersInUse.append(layerNumber)
# if debug: print("DEBUG: vlsilayout: Using %d layers") # if debug: print("DEBUG: vlsilayout: Using %d layers")
@ -314,7 +317,9 @@ class VlsiLayout:
layoutToAddSref.coordinates = offsetInLayoutUnits layoutToAddSref.coordinates = offsetInLayoutUnits
if mirror or rotate: if mirror or rotate:
# transFlags = (mirror around x-axis, magnification, rotation) # 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)
# 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":
@ -326,19 +331,20 @@ class VlsiLayout:
layoutToAddSref.transFlags = [0,0,0] layoutToAddSref.transFlags = [0,0,0]
if rotate: if rotate:
layoutToAddSref.transFlags = [0,0,1] layoutToAddSref.transFlags = [0,1,0]
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 = [1,0,0]
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,0,1] layoutToAddSref.transFlags = [1,1,0]
#layoutToAddSref.transFlags = [1,0,0]
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,0,1] layoutToAddSref.transFlags = [0,1,0]
layoutToAddSref.rotateAngle = 180.0 layoutToAddSref.rotateAngle = 180.0
#add the sref to the root structure #add the sref to the root structure
self.structures[self.rootStructureName].srefs+=[layoutToAddSref] self.structures[self.rootStructureName].srefs.append(layoutToAddSref)
def addBox(self,layerNumber=0, purposeNumber=None, offsetInMicrons=(0,0), width=1.0, height=1.0,center=False): def addBox(self,layerNumber=0, purposeNumber=None, offsetInMicrons=(0,0), width=1.0, height=1.0,center=False):
""" """
@ -356,11 +362,7 @@ class VlsiLayout:
(offsetInLayoutUnits[0],offsetInLayoutUnits[1]+heightInLayoutUnits), (offsetInLayoutUnits[0],offsetInLayoutUnits[1]+heightInLayoutUnits),
offsetInLayoutUnits] offsetInLayoutUnits]
else: else:
startPoint = (offsetInLayoutUnits[0]-widthInLayoutUnits/2.0, offsetInLayoutUnits[1]-heightInLayoutUnits/2.0)
#is there where gdsmill is halving the coordinates???
#if you printGDS of temp.gds, the header says 1 user unit = .0005 database units. By default user units = .001.
#something to do with the ieeedouble in gdswriter.py????
startPoint = (offsetInLayoutUnits[0]-widthInLayoutUnits/2, offsetInLayoutUnits[1]-heightInLayoutUnits/2) #width/2 height/2
coordinates=[startPoint, coordinates=[startPoint,
(startPoint[0]+widthInLayoutUnits,startPoint[1]), (startPoint[0]+widthInLayoutUnits,startPoint[1]),
(startPoint[0]+widthInLayoutUnits,startPoint[1]+heightInLayoutUnits), (startPoint[0]+widthInLayoutUnits,startPoint[1]+heightInLayoutUnits),
@ -373,7 +375,7 @@ class VlsiLayout:
boundaryToAdd.coordinates = coordinates boundaryToAdd.coordinates = coordinates
boundaryToAdd.purposeLayer = purposeNumber boundaryToAdd.purposeLayer = purposeNumber
#add the sref to the root structure #add the sref to the root structure
self.structures[self.rootStructureName].boundaries+=[boundaryToAdd] self.structures[self.rootStructureName].boundaries.append(boundaryToAdd)
def addPath(self, layerNumber=0, purposeNumber = None, coordinates=[(0,0)], width=1.0): def addPath(self, layerNumber=0, purposeNumber = None, coordinates=[(0,0)], width=1.0):
""" """
@ -385,14 +387,14 @@ class VlsiLayout:
for coordinate in coordinates: for coordinate in coordinates:
cX = self.userUnits(coordinate[0]) cX = self.userUnits(coordinate[0])
cY = self.userUnits(coordinate[1]) cY = self.userUnits(coordinate[1])
layoutUnitCoordinates += [(cX,cY)] layoutUnitCoordinates.append((cX,cY))
pathToAdd = GdsPath() pathToAdd = GdsPath()
pathToAdd.drawingLayer=layerNumber pathToAdd.drawingLayer=layerNumber
pathToAdd.purposeLayer = purposeNumber pathToAdd.purposeLayer = purposeNumber
pathToAdd.pathWidth=widthInLayoutUnits pathToAdd.pathWidth=widthInLayoutUnits
pathToAdd.coordinates=layoutUnitCoordinates pathToAdd.coordinates=layoutUnitCoordinates
#add the sref to the root structure #add the sref to the root structure
self.structures[self.rootStructureName].paths+=[pathToAdd] self.structures[self.rootStructureName].paths.append(pathToAdd)
def addText(self, text, layerNumber=0, purposeNumber = None, offsetInMicrons=(0,0), magnification=0.1, rotate = None): def addText(self, text, layerNumber=0, purposeNumber = None, offsetInMicrons=(0,0), magnification=0.1, rotate = None):
offsetInLayoutUnits = (self.userUnits(offsetInMicrons[0]),self.userUnits(offsetInMicrons[1])) offsetInLayoutUnits = (self.userUnits(offsetInMicrons[0]),self.userUnits(offsetInMicrons[1]))
@ -411,7 +413,7 @@ class VlsiLayout:
textToAdd.transFlags[2] = 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+=[textToAdd] self.structures[self.rootStructureName].texts.append(textToAdd)
def isBounded(self,testPoint,startPoint,endPoint): def isBounded(self,testPoint,startPoint,endPoint):
#these arguments are touples of (x,y) coordinates #these arguments are touples of (x,y) coordinates
@ -523,7 +525,7 @@ class VlsiLayout:
#remap coordinates #remap coordinates
shiftedBoundaryCoordinates = [] shiftedBoundaryCoordinates = []
for shapeCoordinate in boundary.rotatedCoordinates(rotateAngle): for shapeCoordinate in boundary.rotatedCoordinates(rotateAngle):
shiftedBoundaryCoordinates+=[(shapeCoordinate[0]+coordinates[0],shapeCoordinate[1]+coordinates[1])] shiftedBoundaryCoordinates.append((shapeCoordinate[0]+coordinates[0],shapeCoordinate[1]+coordinates[1]))
joint = self.doShapesIntersect(self.tempCoordinates, shiftedBoundaryCoordinates) joint = self.doShapesIntersect(self.tempCoordinates, shiftedBoundaryCoordinates)
if joint: if joint:
self.tempPassFail = False self.tempPassFail = False
@ -536,7 +538,7 @@ class VlsiLayout:
#remap coordinates #remap coordinates
shiftedBoundaryCoordinates = [] shiftedBoundaryCoordinates = []
for shapeCoordinate in path.equivalentBoundaryCoordinates(rotateAngle): for shapeCoordinate in path.equivalentBoundaryCoordinates(rotateAngle):
shiftedBoundaryCoordinates+=[(shapeCoordinate[0]+coordinates[0],shapeCoordinate[1]+coordinates[1])] shiftedBoundaryCoordinates.append((shapeCoordinate[0]+coordinates[0],shapeCoordinate[1]+coordinates[1]))
joint = self.doShapesIntersect(self.tempCoordinates, shiftedBoundaryCoordinates) joint = self.doShapesIntersect(self.tempCoordinates, shiftedBoundaryCoordinates)
if joint: if joint:
self.tempPassFail = False self.tempPassFail = False
@ -559,7 +561,7 @@ class VlsiLayout:
self.traverseTheHierarchy(delegateFunction = isThisBlockOk) self.traverseTheHierarchy(delegateFunction = isThisBlockOk)
#if its bad, this global tempPassFail will be false #if its bad, this global tempPassFail will be false
#if true, we can add the block #if true, we can add the block
passFailRecord+=[self.tempPassFail] passFailRecord.append(self.tempPassFail)
print("Percent Complete:"+str(percentDone)) print("Percent Complete:"+str(percentDone))
@ -570,7 +572,7 @@ class VlsiLayout:
blockY = (yIndex*effectiveBlock)+offsetInMicrons[1] blockY = (yIndex*effectiveBlock)+offsetInMicrons[1]
if passFailRecord[passFailIndex]: if passFailRecord[passFailIndex]:
self.addBox(layerToFill, (blockX,blockY), width=blockSize, height=blockSize) self.addBox(layerToFill, (blockX,blockY), width=blockSize, height=blockSize)
passFailIndex+=1 passFailIndex += 1
print("Done\n\n") print("Done\n\n")
def getLayoutBorder(self,borderlayer): def getLayoutBorder(self,borderlayer):
@ -606,19 +608,15 @@ class VlsiLayout:
return [[self.units[0]*cellBoundary[0],self.units[0]*cellBoundary[1]], return [[self.units[0]*cellBoundary[0],self.units[0]*cellBoundary[1]],
[self.units[0]*cellBoundary[2],self.units[0]*cellBoundary[3]]] [self.units[0]*cellBoundary[2],self.units[0]*cellBoundary[3]]]
def measureSizeInStructure(self,Structure,cellBoundary): def measureSizeInStructure(self,structure,cellBoundary):
StructureName=Structure[0] (structureName,structureOrigin,structureuVector,structurevVector)=structure
StructureOrigin=[Structure[1][0],Structure[1][1]] for boundary in self.structures[str(structureName)].boundaries:
StructureuVector=[Structure[2][0],Structure[2][1],Structure[2][2]]
StructurevVector=[Structure[3][0],Structure[3][1],Structure[3][2]]
for boundary in self.structures[str(StructureName)].boundaries:
left_bottom=boundary.coordinates[0] left_bottom=boundary.coordinates[0]
right_top=boundary.coordinates[2] right_top=boundary.coordinates[2]
thisBoundary=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]] thisBoundary=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
thisBoundary=self.transformRectangle(thisBoundary,StructureuVector,StructurevVector) thisBoundary=self.transformRectangle(thisBoundary,structureuVector,structurevVector)
thisBoundary=[thisBoundary[0]+StructureOrigin[0],thisBoundary[1]+StructureOrigin[1], thisBoundary=[thisBoundary[0]+structureOrigin[0],thisBoundary[1]+structureOrigin[1],
thisBoundary[2]+StructureOrigin[0],thisBoundary[3]+StructureOrigin[1]] thisBoundary[2]+structureOrigin[0],thisBoundary[3]+structureOrigin[1]]
cellBoundary=self.updateBoundary(thisBoundary,cellBoundary) cellBoundary=self.updateBoundary(thisBoundary,cellBoundary)
return cellBoundary return cellBoundary
@ -755,9 +753,8 @@ class VlsiLayout:
Return all pin shapes. Return all pin shapes.
""" """
boundaries = [] boundaries = []
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
boundaries += self.getPinInStructure(coordinates,layer,TreeUnit) boundaries.extend(self.getPinInStructure(coordinates,layer,TreeUnit))
return boundaries return boundaries
@ -768,14 +765,8 @@ class VlsiLayout:
that the label coordinates are inside. that the label coordinates are inside.
""" """
# check if this is a rectangle (structureName,structureOrigin,structureuVector,structurevVector)=structure
structureName=structure[0]
structureOrigin=[structure[1][0],structure[1][1]]
structureuVector=[structure[2][0],structure[2][1],structure[2][2]]
structurevVector=[structure[3][0],structure[3][1],structure[3][2]]
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 # 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. # This may report not finding pins, but the user should fix this by adding a rectangle.
@ -789,7 +780,7 @@ class VlsiLayout:
boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector) boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector)
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()]
if self.labelInRectangle(coordinates,boundaryRect): if self.labelInRectangle(coordinates,boundaryRect):
boundaries.append(boundaryRect) boundaries.append(boundaryRect)
@ -803,7 +794,7 @@ class VlsiLayout:
boundaries = [] boundaries = []
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
#print(TreeUnit[0]) #print(TreeUnit[0])
boundaries += self.getShapesInStructure(layer,TreeUnit) boundaries.extend(self.getShapesInStructure(layer,TreeUnit))
# Remove duplicates without defining a hash # Remove duplicates without defining a hash
# (could be sped up by creating hash and using list(set()) # (could be sped up by creating hash and using list(set())
@ -826,14 +817,8 @@ class VlsiLayout:
Go through all the shapes in a structure and return the list of shapes. Go through all the shapes in a structure and return the list of shapes.
""" """
# check if this is a rectangle (structureName,structureOrigin,structureuVector,structurevVector)=structure
structureName=structure[0]
structureOrigin=[structure[1][0],structure[1][1]]
structureuVector=[structure[2][0],structure[2][1],structure[2][2]]
structurevVector=[structure[3][0],structure[3][1],structure[3][2]]
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 # 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. # This may report not finding pins, but the user should fix this by adding a rectangle.

View File

@ -15,12 +15,21 @@ class router:
It populates blockages on a grid class. It populates blockages on a grid class.
""" """
def __init__(self, gds_name): def __init__(self, gds_name=None, module=None):
"""Use the gds file for the blockages with the top module topName and """Use the gds file or the cell for the blockages with the top module topName and
layers for the layers to route on layers for the layers to route on
""" """
# Load the gds file and read in all the shapes
self.gds_name = gds_name self.gds_name = gds_name
self.module = module
debug.check(not (gds_name and module), "Specify only a GDS file or module")
# If we specified a module instead, write it out to read the gds
# This isn't efficient, but easy for now
if module:
gds_name = OPTS.openram_temp+"temp.gds"
module.gds_write(gds_name)
# Load the gds file and read in all the shapes
self.layout = gdsMill.VlsiLayout(units=tech.GDS["unit"]) self.layout = gdsMill.VlsiLayout(units=tech.GDS["unit"])
self.reader = gdsMill.Gds2reader(self.layout) self.reader = gdsMill.Gds2reader(self.layout)
self.reader.loadFromFile(gds_name) self.reader.loadFromFile(gds_name)
@ -212,12 +221,14 @@ class router:
""" """
shapes = self.layout.getAllShapesInStructureList(layer_num) shapes = self.layout.getAllShapesInStructureList(layer_num)
for boundary in shapes: for boundary in shapes:
rect = [vector(boundary[0],boundary[1]),vector(boundary[2],boundary[3])] ll = vector(boundary[0],boundary[1])
new_pin = pin_layout("blockage",rect,layer_num) ur = vector(boundary[2],boundary[3])
rect = [ll,ur]
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: # for boundary in self.layout.structures[sref].boundaries:
# coord_trans = self.translate_coordinates(boundary.coordinates, mirr, angle, xyShift) # coord_trans = self.translate_coordinates(boundary.coordinates, mirr, angle, xyShift)
@ -470,7 +481,6 @@ class router:
layer="text", layer="text",
offset=shape[0], offset=shape[0],
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="boundary",
offset=blockage.ll(), offset=blockage.ll(),

View File

@ -14,11 +14,11 @@ class signal_router(router):
route on a given layer. This is limited to two layer routes. route on a given layer. This is limited to two layer routes.
""" """
def __init__(self, gds_name): def __init__(self, gds_name=None, module=None):
"""Use the gds file for the blockages with the top module topName and """Use the gds file for the blockages with the top module topName and
layers for the layers to route on layers for the layers to route on
""" """
router.__init__(self, gds_name) router.__init__(self, gds_name, module)
# all the paths we've routed so far (to supplement the blockages) # all the paths we've routed so far (to supplement the blockages)
self.paths = [] self.paths = []
@ -43,6 +43,7 @@ class signal_router(router):
the simplified rectilinear path. Cost factor is how sub-optimal to explore for a feasible route. the simplified rectilinear path. Cost factor is how sub-optimal to explore for a feasible route.
This is used to speed up the routing when there is not much detouring needed. This is used to speed up the routing when there is not much detouring needed.
""" """
debug.info(1,"Running signal router from {0} to {1}...".format(src,dest))
self.cell = cell self.cell = cell
self.source_pin_name = src self.source_pin_name = src
self.target_pin_name = dest self.target_pin_name = dest

View File

@ -16,12 +16,11 @@ class supply_router(router):
routes a grid to connect the supply on the two layers. routes a grid to connect the supply on the two layers.
""" """
def __init__(self, gds_name): def __init__(self, gds_name=None, module=None):
"""Use the gds file for the blockages with the top module topName and """Use the gds file for the blockages with the top module topName and
layers for the layers to route on layers for the layers to route on
""" """
router.__init__(self, gds_name, module)
router.__init__(self, gds_name)
self.pins = {} self.pins = {}
@ -40,6 +39,7 @@ class supply_router(router):
Route a single source-destination net and return Route a single source-destination net and return
the simplified rectilinear path. the simplified rectilinear path.
""" """
debug.info(1,"Running supply router on {0} and {1}...".format(vdd_name, gnd_name))
self.cell = cell self.cell = cell
self.pins[vdd_name] = [] self.pins[vdd_name] = []
self.pins[gnd_name] = [] self.pins[gnd_name] = []

View File

@ -4,7 +4,6 @@
import unittest import unittest
from testutils import header,openram_test from testutils import header,openram_test
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
import debug import debug
@ -30,14 +29,17 @@ class no_blockages_test(openram_test):
design.__init__(self, "top") design.__init__(self, "top")
# Instantiate a GDS cell with the design # Instantiate a GDS cell with the design
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name) globals.setup_paths()
cell = gds_cell(name, gds_file) from control_logic import control_logic
cell = control_logic(16)
#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, self.add_inst(name=name,
mod=cell, mod=cell,
offset=[0,0]) offset=[0,0])
self.connect_inst([]) self.connect_inst(["csb","web","clk","s_en","w_en","clk_buf_bar","clk_buf","vdd","gnd"])
r=router(gds_file) r=router(module=cell)
layer_stack =("metal3","via2","metal2") layer_stack =("metal3","via2","metal2")
self.assertTrue(r.route(self,layer_stack)) self.assertTrue(r.route(self,layer_stack))

View File

@ -3,21 +3,8 @@ num_words = 16
num_banks = 1 num_banks = 1
tech_name = "freepdk45" tech_name = "freepdk45"
process_corners = ["TT"]
supply_voltages = [1.0]
temperatures = [25]
decoder = "hierarchical_decoder"
ms_flop = "ms_flop"
ms_flop_array = "ms_flop_array"
control_logic = "control_logic"
bitcell_array = "bitcell_array"
sense_amp = "sense_amp"
sense_amp_array = "sense_amp_array"
precharge_array = "precharge_array"
column_mux_array = "single_level_column_mux_array"
write_driver = "write_driver"
write_driver_array = "write_driver_array"
tri_gate = "tri_gate"
tri_gate_array = "tri_gate_array"
wordline_driver = "wordline_driver"
replica_bitcell = "replica_bitcell"
bitcell = "bitcell"
delay_chain = "logic_effort_dc"

View File

@ -3,21 +3,7 @@ num_words = 16
num_banks = 1 num_banks = 1
tech_name = "scn3me_subm" tech_name = "scn3me_subm"
process_corners = ["TT"]
supply_voltages = [5.0]
temperatures = [25]
decoder = "hierarchical_decoder"
ms_flop = "ms_flop"
ms_flop_array = "ms_flop_array"
control_logic = "control_logic"
bitcell_array = "bitcell_array"
sense_amp = "sense_amp"
sense_amp_array = "sense_amp_array"
precharge_array = "precharge_array"
column_mux_array = "single_level_column_mux_array"
write_driver = "write_driver"
write_driver_array = "write_driver_array"
tri_gate = "tri_gate"
tri_gate_array = "tri_gate_array"
wordline_driver = "wordline_driver"
replica_bitcell = "replica_bitcell"
bitcell = "bitcell"
delay_chain = "logic_effort_dc"