Add layer width options to route object

Modify router to use track-width routes.
This commit is contained in:
Matt Guthaus 2018-09-18 14:55:36 -07:00
parent 8d2804b9cb
commit fd9ffe30d6
3 changed files with 62 additions and 34 deletions

View File

@ -312,7 +312,7 @@ class layout(lef.lef):
position_list=coordinates,
width=width)
def add_route(self, layers, coordinates):
def add_route(self, layers, coordinates, layer_widths):
"""Connects a routing path on given layer,coordinates,width. The
layers are the (horizontal, via, vertical). add_wire assumes
preferred direction routing whereas this includes layers in
@ -323,7 +323,8 @@ class layout(lef.lef):
# add an instance of our path that breaks down into rectangles and contacts
route.route(obj=self,
layer_stack=layers,
path=coordinates)
path=coordinates,
layer_widths=layer_widths)
def add_wire(self, layers, coordinates):

View File

@ -10,15 +10,17 @@ class route(design):
"""
Object route (used by the router module)
Add a route of minimium metal width between a set of points.
The widths are the layer widths of the layer stack.
(Vias are in numer of vias.)
The wire must be completely rectilinear and the
z-dimension of the points refers to the layers (plus via)
z-dimension of the points refers to the layers.
The points are the center of the wire.
This can have non-preferred direction routing.
"""
unique_route_id = 0
def __init__(self, obj, layer_stack, path):
def __init__(self, obj, layer_stack, path, layer_widths=[None,1,None]):
name = "route_{0}".format(route.unique_route_id)
route.unique_route_id += 1
design.__init__(self, name)
@ -26,6 +28,7 @@ class route(design):
self.obj = obj
self.layer_stack = layer_stack
self.layer_widths = layer_widths
self.path = path
self.setup_layers()
@ -33,16 +36,16 @@ class route(design):
def setup_layers(self):
(horiz_layer, via_layer, vert_layer) = self.layer_stack
self.via_layer_name = via_layer
self.vert_layer_name = vert_layer
self.vert_layer_width = drc["minwidth_{0}".format(vert_layer)]
self.horiz_layer_name = horiz_layer
self.horiz_layer_width = drc["minwidth_{0}".format(horiz_layer)]
(self.horiz_layer_name, self.via_layer, self.vert_layer_name) = self.layer_stack
(self.horiz_layer_width, self.num_vias, self.vert_layer_width) = self.layer_widths
if not self.vert_layer_width:
self.vert_layer_width = drc["minwidth_{0}".format(self.vert_layer_name)]
if not self.horiz_layer_width:
self.horiz_layer_width = drc["minwidth_{0}".format(self.horiz_layer_name)]
# offset this by 1/2 the via size
self.c=contact(self.layer_stack, (1, 1))
self.c=contact(self.layer_stack, (self.num_vias, self.num_vias))
def create_wires(self):
@ -63,7 +66,8 @@ class route(design):
#via_offset = vector(p0.x+0.5*self.c.width,p0.y+0.5*self.c.height)
# offset if rotated
via_offset = vector(p0.x+0.5*self.c.height,p0.y-0.5*self.c.width)
self.obj.add_via(self.layer_stack,via_offset,rotate=90)
via_size = [self.num_vias]*2
self.obj.add_via(self.layer_stack,via_offset,size=via_size,rotate=90)
elif p0.x != p1.x and p0.y != p1.y: # diagonal!
debug.error("Non-changing direction!")
else:
@ -79,14 +83,36 @@ class route(design):
self.draw_corner_wire(plist[-1][1])
def get_layer_width(self, layer_zindex):
"""
Return the layer width
"""
if layer_zindex==0:
return self.horiz_layer_width
elif layer_zindex==1:
return self.vert_layer_width
else:
debug.error("Incorrect layer zindex.",-1)
def get_layer_name(self, layer_zindex):
"""
Return the layer name
"""
if layer_zindex==0:
return self.horiz_layer_name
elif layer_zindex==1:
return self.vert_layer_name
else:
debug.error("Incorrect layer zindex.",-1)
def draw_wire(self, p0, p1):
"""
This draws a straight wire with layer_minwidth
"""
layer_name = self.layer_stack[2*p0.z]
layer_width = drc["minwidth_{0}".format(layer_name)]
layer_width = self.get_layer_width(p0.z)
layer_name = self.get_layer_name(p0.z)
# always route left to right or bottom to top
if p0.z != p1.z:
@ -120,8 +146,8 @@ class route(design):
""" This function adds the corner squares since the center
line convention only draws to the center of the corner."""
layer_name = self.layer_stack[2*p0.z]
layer_width = drc["minwidth_{0}".format(layer_name)]
layer_width = self.get_layer_width(p0.z)
layer_name = self.get_layer_name(p0.z)
offset = vector(p0.x-0.5*layer_width,p0.y-0.5*layer_width)
self.obj.add_rect(layer=layer_name,
offset=offset,

View File

@ -101,17 +101,15 @@ class router:
vertical.
"""
self.layers = layers
(horiz_layer, via_layer, vert_layer) = self.layers
(self.horiz_layer_name, self.via_layer_name, self.vert_layer_name) = self.layers
self.vert_layer_name = vert_layer
self.vert_layer_width = tech.drc["minwidth_{0}".format(vert_layer)]
self.vert_layer_width = tech.drc["minwidth_{0}".format(self.vert_layer_name)]
self.vert_layer_spacing = tech.drc[str(self.vert_layer_name)+"_to_"+str(self.vert_layer_name)]
self.vert_layer_number = tech.layer[vert_layer]
self.vert_layer_number = tech.layer[self.vert_layer_name]
self.horiz_layer_name = horiz_layer
self.horiz_layer_width = tech.drc["minwidth_{0}".format(horiz_layer)]
self.horiz_layer_width = tech.drc["minwidth_{0}".format(self.horiz_layer_name)]
self.horiz_layer_spacing = tech.drc[str(self.horiz_layer_name)+"_to_"+str(self.horiz_layer_name)]
self.horiz_layer_number = tech.layer[horiz_layer]
self.horiz_layer_number = tech.layer[self.horiz_layer_name]
# Contacted track spacing.
via_connect = contact(self.layers, (1, 1))
@ -127,7 +125,8 @@ class router:
self.track_factor = [1/self.track_width] * 2
debug.info(1,"Track factor: {0}".format(self.track_factor))
# When we actually create the routes, make them the width of the track (minus 1/2 spacing on each side)
self.layer_widths = [self.track_width - self.horiz_layer_spacing, 1, self.track_width - self.vert_layer_spacing]
def retrieve_pins(self,pin_name):
"""
@ -721,13 +720,15 @@ class router:
abs_path = [self.convert_point_to_units(x[0]) for x in path]
debug.info(1,str(abs_path))
# If we had a single grid route (source was equal to target)
self.add_enclosure(abs_path[0])
# Otherwise, add teh route and final enclosure
if len(abs_path)>1:
self.cell.add_route(self.layers,abs_path)
self.add_enclosure(abs_path[-1])
# If it is only a square, add an enclosure to the track
if len(path)==1:
self.add_enclosure(abs_path[0])
else:
# Otherwise, add the route which includes enclosures
self.cell.add_route(layers=self.layers,
coordinates=abs_path,
layer_widths=self.layer_widths)
def add_enclosure(self, loc):
"""
Add a metal enclosure that is the size of the routing grid minus a spacing on each side.