Merge branch 'dev' of https://github.com/VLSIDA/PrivateRAM into multiport

This commit is contained in:
Michael Timothy Grimes 2018-09-08 18:56:58 -07:00
commit c91735b23b
16 changed files with 166 additions and 150 deletions

View File

@ -15,6 +15,7 @@ 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.
"""
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],
@ -24,13 +25,14 @@ class contact(hierarchy_design.hierarchy_design):
dimensions[1],
implant_type,
well_type)
else:
name = "{0}_{1}_{2}_{3}x{4}".format(layer_stack[0],
layer_stack[1],
layer_stack[2],
dimensions[0],
dimensions[1])
layer_stack[1],
layer_stack[2],
dimensions[0],
dimensions[1])
hierarchy_design.hierarchy_design.__init__(self, name)
debug.info(4, "create contact object {0}".format(name))

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:
@ -849,10 +847,10 @@ class layout(lef.lef):
"""
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=loc,
rotate=rotate)
rotate=float(rotate))
via=self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=loc,
rotate=rotate)
rotate=float(rotate))
self.add_layout_pin_rect_center(text=name,
layer="metal3",
offset=loc,

View File

@ -1,5 +1,5 @@
import debug
from tech import GDS
from tech import GDS, drc
from vector import vector
from tech import layer
@ -36,16 +36,29 @@ 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 inflate(self, spacing=None):
"""
Inflate the rectangle by the spacing (or other rule)
and return the new rectangle.
"""
if not spacing:
spacing = drc["{0}_to_{0}".format(self.layer)]
(ll,ur) = self.rect
spacing = vector(spacing, spacing)
newll = ll - spacing
newur = ur + spacing
return (newll, newur)
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,8 +280,13 @@ 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
# The rotate and magnify flags specify "absolute" rotate and magnify.
# It is unclear what that is (ignore all further rotates/mags in the
# hierarchy? But anyway, calibre doesn't support it.
rotateFlag=0
magnifyFlag = 0
#rotateFlag = int(thisSref.transFlags[2])<<1
#magnifyFlag = int(thisSref.transFlags[1])<<2
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
self.writeRecord(idBits+transFlags)
if(thisSref.magFactor!=""):
@ -327,15 +332,20 @@ 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
# The rotate and magnify flags specify "absolute" rotate and magnify.
# It is unclear what that is (ignore all further rotates/mags in the
# hierarchy? But anyway, calibre doesn't support it.
rotateFlag=0
magnifyFlag = 0
#rotateFlag = int(thisAref.transFlags[2])<<1
#magnifyFlag = int(thisAref.transFlags[1])<<2
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
self.writeRecord(idBits+transFlags)
if(thisAref.magFactor):
if(thisAref.magFactor!=""):
idBits=b'\x1B\x05'
magFactor=self.ibmDataFromIeeeDouble(thisAref.magFactor)
self.writeRecord(idBits+magFactor)
if(thisAref.rotateAngle):
if(thisAref.rotateAngle!=""):
idBits=b'\x1C\x05'
rotateAngle=self.ibmDataFromIeeeDouble(thisAref.rotateAngle)
self.writeRecord(idBits+rotateAngle)
@ -374,15 +384,20 @@ 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
# The rotate and magnify flags specify "absolute" rotate and magnify.
# It is unclear what that is (ignore all further rotates/mags in the
# hierarchy? But anyway, calibre doesn't support it.
rotateFlag=0
magnifyFlag = 0
#rotateFlag = int(thisText.transFlags[2])<<1
#magnifyFlag = int(thisText.transFlags[1])<<2
transFlags = struct.pack(">H",mirrorFlag|rotateFlag|magnifyFlag)
self.writeRecord(idBits+transFlags)
if(thisText.magFactor != ""):
if(thisText.magFactor!=""):
idBits=b'\x1B\x05'
magFactor=self.ibmDataFromIeeeDouble(thisText.magFactor)
self.writeRecord(idBits+magFactor)
if(thisText.rotateAngle != ""):
if(thisText.rotateAngle!=""):
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

@ -118,9 +118,6 @@ def init_openram(config_file, is_unit_test=True):
init_paths()
# This depends on the tech, so do it after tech is loaded
init_config()
# Reset the static duplicate name checker for unit tests.
import hierarchy_design
hierarchy_design.hierarchy_design.name_map=[]
@ -257,7 +254,8 @@ def cleanup_paths():
if not OPTS.purge_temp:
debug.info(0,"Preserving temp directory: {}".format(OPTS.openram_temp))
return
if os.path.exists(OPTS.openram_temp):
elif os.path.exists(OPTS.openram_temp):
debug.info(1,"Purging temp directory: {}".format(OPTS.openram_temp))
# This annoyingly means you have to re-cd into the directory each debug iteration
#shutil.rmtree(OPTS.openram_temp, ignore_errors=True)
contents = [os.path.join(OPTS.openram_temp, i) for i in os.listdir(OPTS.openram_temp)]
@ -293,8 +291,6 @@ def setup_paths():
OPTS.openram_temp += "/"
debug.info(1, "Temporary files saved in " + OPTS.openram_temp)
cleanup_paths()
def is_exe(fpath):
@ -316,6 +312,7 @@ def init_paths():
# make the directory if it doesn't exist
try:
debug.info(1,"Creating temp directory: {}".format(OPTS.openram_temp))
os.makedirs(OPTS.openram_temp, 0o750)
except OSError as e:
if e.errno == 17: # errno.EEXIST
@ -330,16 +327,7 @@ def init_paths():
os.chmod(OPTS.output_path, 0o750)
except:
debug.error("Unable to make output directory.",-1)
def init_config():
""" Initialize the SRAM configurations. """
# Create the SRAM configuration
from sram_config import sram_config
OPTS.sram_config = sram_config(OPTS.word_size,
OPTS.num_words,
OPTS.num_banks)
# imports correct technology directories for testing
def import_tech():

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
@ -84,19 +90,19 @@ class router:
def find_pin(self,pin):
def find_pin(self,pin_name):
"""
Finds the pin shapes and converts to tracks.
Pin can either be a label or a location,layer pair: [[x,y],layer].
"""
label_list=self.layout.getPinShapeByLabel(str(pin))
shape_list=self.layout.getPinShapeByLabel(str(pin_name))
pin_list = []
for label in label_list:
(name,layer,boundary)=label
for shape in shape_list:
(name,layer,boundary)=shape
rect = [vector(boundary[0],boundary[1]),vector(boundary[2],boundary[3])]
# this is a list because other cells/designs may have must-connect pins
pin_list.append(pin_layout(pin, rect, layer))
pin = pin_layout(pin_name, rect, layer)
pin_list.append(pin)
debug.check(len(pin_list)>0,"Did not find any pin shapes for {0}.".format(str(pin)))
@ -202,17 +208,30 @@ class router:
def add_blockages(self):
""" Add the blockages except the pin shapes """
""" Add the blockages except the pin shapes. Also remove the pin shapes from the blockages list. """
# Join all the pin shapes into one big list
all_pins = [item for sublist in list(self.pins.values()) for item in sublist]
# Do an n^2 check to see if any shapes are the same, otherwise add them
# FIXME: Make faster, but number of pins won't be *that* large
real_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:
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,"Removing blockage for pin {}".format(str(pin)))
break
else:
[ll,ur]=self.convert_blockage_to_tracks(blockage.rect)
zlayer = 0 if blockage.layer_num==self.horiz_layer_number else 1
debug.info(2,"Adding blockage {}".format(str(blockage)))
# Inflate the blockage by spacing rule
[ll,ur]=self.convert_blockage_to_tracks(blockage.inflate())
zlayer = self.get_zindex(blockage.layer_num)
self.rg.add_blockage_shape(ll,ur,zlayer)
real_blockages.append(blockage)
# Remember the filtered blockages
self.blockages = real_blockages
def get_blockages(self, layer_num):
@ -227,37 +246,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,11 +270,15 @@ class router:
old_ur = ur
ll=ll.scale(self.track_factor)
ur=ur.scale(self.track_factor)
ll = ll.floor()
ur = ur.ceil()
if ll[0]<45 and ll[0]>35 and ll[1]<10 and ll[1]>0:
debug.info(0,"Converting [ {0} , {1} ]".format(old_ll,old_ur))
debug.info(0,"Converted [ {0} , {1} ]".format(ll,ur))
# We can round since we are using inflated shapes
# and the track points are at the center
ll = ll.round()
ur = ur.round()
# if ll[0]<45 and ll[0]>35 and ll[1]<5 and ll[1]>-5:
# debug.info(0,"Converting [ {0} , {1} ]".format(old_ll,old_ur))
# debug.info(0,"Converted [ {0} , {1} ]".format(ll,ur))
# pin=self.convert_track_to_shape(ll)
# debug.info(0,"Pin {}".format(pin))
return [ll,ur]
def convert_pin_to_tracks(self, pin):
@ -296,9 +288,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 +295,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 +373,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 +439,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,10 +472,12 @@ class router:
zoom=0.05)
for blockage in self.blockages:
self.cell.add_rect(layer="boundary",
offset=blockage.ll(),
width=blockage.width(),
height=blockage.height())
# Display the inflated blockage
(ll,ur) = blockage.inflate()
self.cell.add_rect(layer="blockage",
offset=ll,
width=ur.x-ll.x,
height=ur.y-ll.y)
# FIXME: This should be replaced with vector.snap_to_grid at some point

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

View File

@ -625,7 +625,7 @@ drDefinePacket(
( display deviceAnt stipple0 solid yellow yellow solid )
( display winBottomShadow solid solid winColor1 winColor1 solid )
( display PselectNet dots4 solid brown brown outlineStipple)
( display comment stipple0 lineStyle0 winBack winBack solid )
( display comment stipple0 lineStyle0 winBack winBack outline )
( display Poly1 dots lineStyle0 red red outlineStipple)
( display Unrouted stipple0 lineStyle1 winColor5 winColor5 solid )
( display stretch stipple0 solid yellow yellow solid )