Contract path to simplified route

This commit is contained in:
Matt Guthaus 2016-11-17 13:26:03 -08:00
parent aa950c3b21
commit 0a9b326f6a
9 changed files with 135 additions and 43 deletions

View File

@ -244,12 +244,9 @@ class layout:
self.gds = gdsMill.VlsiLayout(units=GDS["unit"])
reader = gdsMill.Gds2reader(self.gds)
reader.loadFromFile(self.gds_file)
# TODO: parse the width/height
# TODO: parse the pin locations
else:
debug.info(3, "creating structure %s" % self.name)
self.gds = gdsMill.VlsiLayout(
name=self.name, units=GDS["unit"])
self.gds = gdsMill.VlsiLayout(name=self.name, units=GDS["unit"])
def print_gds(self, gds_file=None):
"""Print the gds file (not the vlsi class) to the terminal """

View File

@ -24,7 +24,7 @@ class cell:
b+=b1
count+=1
if self.source or self.target:
if self.source or self.target:
[r1,g1,b1] = ImageColor.getrgb("Red")
r+=r1
g+=g1

View File

@ -154,11 +154,12 @@ class grid:
"""
# expand from the last point
point = path[-1]
neighbors = []
# check z layer for enforced direction routing
if point.z==0:
east = point + vector3d(1,0,0)
west= point + vector3d(-11,0,0)
west= point + vector3d(-1,0,0)
if east.x<self.width and not self.map[east].blocked and not self.map[east].visited:
neighbors.append(east)
if west.x>=0 and not self.map[west].blocked and not self.map[west].visited:

View File

@ -62,9 +62,6 @@ class router:
self.track_width = max(self.horiz_track_width,self.vert_track_width)
print "Track width:",self.track_width
# to scale coordinates to tracks
self.track_factor = [1/self.track_width] * 2
def create_routing_grid(self):
@ -117,15 +114,16 @@ class router:
self.set_source(src)
self.set_target(dest)
self.find_blockages()
# returns the path in tracks
path = self.rg.route()
debug.info(0,"Found path. ")
debug.info(2,str(path))
return path
self.set_path(path)
# convert the path back to absolute units from tracks
abs_path = self.convert_path_to_units(path)
debug.info(2,str(abs_path))
return abs_path
def add_route(self,start, end, layerstack):
""" Add a wire route from the start to the end point"""
pass
def create_steiner_routes(self,pins):
"""Find a set of steiner points and then return the list of
point-to-point routes."""
@ -163,6 +161,41 @@ class router:
coordinate += [vector(maxx, maxy)]
return coordinate
def get_inertia(self,p0,p1):
# direction (index) of movement
if p0.x==p1.x:
inertia = 1
elif p0.y==p1.y:
inertia = 0
else:
inertia = 2
return inertia
def contract_path(self,path):
"""
Remove intermediate points in a rectilinear path.
"""
debug.info(0,"Initial path:"+str(path))
newpath = [path[0]]
for i in range(len(path)-1):
if i==0:
continue
prev_inertia=self.get_inertia(path[i-1],path[i])
next_inertia=self.get_inertia(path[i],path[i+1])
if prev_inertia!=next_inertia:
newpath.append(path[i])
else:
continue
newpath.append(path[-1])
debug.info(0,"Final path:"+str(newpath))
return newpath
def set_path(self,path):
debug.info(2,"Set path: " + str(path))
self.rg.set_path(path)
def set_source(self,name):
shape = self.find_pin(name)
zindex = 0 if self.pin_layers[name]==self.horiz_layer_number else 1
@ -215,6 +248,24 @@ class router:
self.write_obstacle(cur_sref.sName, sMirr, sAngle, sxyShift)
def convert_path_to_units(self,path):
"""
Convert a path set of tracks to center line path.
"""
# First, simplify the path.
path = self.contract_path(path)
newpath = []
track_factor = [self.track_width] * 2
for p in path:
# we can ignore the layers here
# add_wire will filter out duplicates
pt = vector(p[0],p[1])
pt=pt.scale(track_factor)
pt=snap_to_grid(pt+self.offset)
newpath.append(pt)
return newpath
def convert_to_tracks(self,shape,round_bigger=True):
"""
Convert a rectangular shape into track units.
@ -225,14 +276,18 @@ class router:
ll = snap_to_grid(ll-self.offset)
ur = snap_to_grid(ur-self.offset)
# to scale coordinates to tracks
track_factor = [1/self.track_width] * 2
# Always round blockage shapes up.
if round_bigger:
ll = ll.scale(self.track_factor).floor()
ur = ur.scale(self.track_factor).ceil()
ll = ll.scale(track_factor).floor()
ur = ur.scale(track_factor).ceil()
# Always round pin shapes down
else:
ll = ll.scale(self.track_factor).round()
ur = ur.scale(self.track_factor).round()
ll = ll.scale(track_factor).round()
ur = ur.scale(track_factor).round()
return [ll,ur]

View File

@ -10,46 +10,73 @@ import globals
import debug
import calibre
class no_blockages_test(unittest.TestCase):
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
globals.init_openram("config_{0}".format(OPTS.tech_name))
import design
import router
import wire
import tech
#r=router.router("A_to_B_no_blockages.gds")
#r=router.router("A_to_B_m1m2_blockages.gds")
#r=router.router("A_to_B_m1m2_same_layer_pins.gds")
r=router.router("A_to_B_m1m2_diff_layer_pins.gds")
layer_stack =("metal1","via1","metal2")
path=r.route(layer_stack,src="A",dest="B")
# For debug, to view the result as an image
r.rg.set_path(path)
r.rg.view()
OPTS.check_lvsdrc = False
class gdscell(design.design):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name):
#design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
self.name = name
self.gds_file = name + ".gds"
self.sp_file = name + ".sp"
design.hierarchy_layout.layout.__init__(self, name)
design.hierarchy_spice.spice.__init__(self, name)
class routing(design.design):
"""
A generic GDS design that we can route on.
"""
def __init__(self, name, gdsname):
design.design.__init__(self, name)
debug.info(2, "Create {0} object".format(name))
#w = wire.wire(layer_stack, path)
OPTS.check_lvsdrc = True
#self.local_check(w)
cell = gdscell(gdsname)
self.add_inst(name=gdsname,
mod=cell,
offset=[0,0])
self.connect_inst([])
r=router.router(gdsname+".gds")
layer_stack =("metal1","via1","metal2")
path=r.route(layer_stack,src="A",dest="B")
r.rg.view()
self.add_wire(layer_stack,path)
#drc_errors = calibre.run_drc(name, gds_name)
drc_errors = 1
r = routing("test1", "A_to_B_no_blockages")
self.local_check(r)
r = routing("A_to_B_m1m2_blockages")
self.local_check(r)
r = routing("A_to_B_m1m2_same_layer_pins")
self.local_check(r)
r = routing("A_to_B_m1m2_diff_layer_pins")
self.local_check(r)
# fails if there are any DRC errors on any cells
self.assertEqual(drc_errors, 0)
globals.end_openram()
def local_check(self, w):
def local_check(self, r):
tempgds = OPTS.openram_temp + "temp.gds"
w.gds_write(tempgds)
self.assertFalse(calibre.run_drc(w.name, tempgds))
r.gds_write(tempgds)
self.assertFalse(calibre.run_drc(r.name, tempgds))
os.remove(tempgds)
assert(0)

View File

@ -0,0 +1,3 @@
.SUBCKT cell
.ENDS cell

View File

@ -0,0 +1,3 @@
.SUBCKT cell
.ENDS cell

View File

@ -0,0 +1,3 @@
.SUBCKT cell
.ENDS cell

View File

@ -0,0 +1,3 @@
.SUBCKT cell
.ENDS cell