Improved router debugging and return error if unable to route.

This commit is contained in:
Matt Guthaus 2017-05-31 13:59:49 -07:00
parent 8cc63560f8
commit d31b1862a3
11 changed files with 66 additions and 122 deletions

View File

@ -40,4 +40,4 @@ class cell:
if self.min_cost > 0:
return self.min_cost
return "."
return None

View File

@ -54,84 +54,6 @@ class grid:
# clear the queue
while (not self.q.empty()):
self.q.get(False)
def view(self):
"""
View the data as text array.
"""
#os.system('clear')
xmin=-10
xmax=10
ymin=-10
ymax=10
for v in self.map.keys():
xmin = min(xmin,v.x)
xmax = max(xmax,v.x)
ymin = min(ymin,v.y)
ymax = max(ymax,v.y)
xoffset=0
if xmin < 0:
xoffset=xmin
yoffset=0
if ymin < 0:
yoffset=ymin
v_map = {}
h_map = {}
fieldwidth = 3
for h in self.map.keys():
fieldwidth = max(fieldwidth,len(self.map[h].get_type()))
for v in self.map.keys():
fieldwidth = max(fieldwidth,len(self.map[v].get_type()))
# for x in range(width):
# for y in range(height):
# v_map[x,y]="."
# h_map[x,y]="."
# h = vector3d(x+xoffset,y+yoffset,0)
# v = vector3d(x+xoffset,y+yoffset,1)
# if (h in self.map.keys()):
# h_map[x,y] = self.map[h].get_type()
# fieldwidth = max(fieldwidth,len(h_map[x,y]))
# if (v in self.map.keys()):
# v_map[x,y] = self.map[v].get_type()
# fieldwidth = max(fieldwidth,len(v_map[x,y]))
# display lower layer
print '='*80
print '='*80
self.print_grid(0,xmin,xmax,ymin,ymax,fieldwidth)
print '='*80
self.print_grid(1,xmin,xmax,ymin,ymax,fieldwidth)
print '='*80
print '='*80
raw_input("Press Enter to continue...")
def print_grid(self,layer,xmin,xmax,ymin,ymax,fieldwidth):
"""
Display a text representation of a layer of the routing grid.
"""
print "".center(fieldwidth),
for x in range(xmin,xmax+1):
print str(x).center(fieldwidth),
print ""
for y in reversed(range(ymin,ymax+1)):
print str(y).center(fieldwidth),
for x in range(xmin,xmax+1):
n = vector3d(x,y,layer)
if n in self.map.keys():
print str(self.map[n].get_type()).center(fieldwidth),
else:
print ".".center(fieldwidth),
print ""
def add_blockage(self,ll,ur,z):
@ -142,7 +64,6 @@ class grid:
self.add_map(n)
self.map[n].blocked=True
def add_source(self,track_list):
debug.info(3,"Adding source list={0}".format(str(track_list)))
for n in track_list:
@ -175,6 +96,8 @@ class grid:
for p in self.map.values():
if (p.source or p.target):
p.blocked=True
p.source=False
p.target=False
def convert_path_to_blockages(self):
"""
@ -243,11 +166,9 @@ class grid:
debug.info(3,"Enqueuing: cost=" + str(current_cost) + "+" + str(target_cost) + " " + str(newpath))
# add the cost to get to this point if we haven't reached it yet
self.q.put((predicted_cost,newpath))
#self.view()
# View the unable to route result.
self.view()
debug.error("Unable to route path. Expand area?",-1)
debug.warning("Unable to route path. Expand area?")
return (None,None)
def is_target(self,point):
"""

View File

@ -154,24 +154,24 @@ class router:
self.add_target(dest)
# View the initial route pins and blockages for debugging
#self.rg.view()
# returns the path in tracks
(self.path,cost) = self.rg.route(cost_bound_scale)
debug.info(1,"Found path: cost={0} ".format(cost))
debug.info(2,str(self.path))
self.add_path(self.path)
# View the final route for debugging
#self.rg.view()
return
if self.path!=None:
debug.info(1,"Found path: cost={0} ".format(cost))
debug.info(2,str(self.path))
self.add_path(self.path)
return True
def add_grid_map(self,cell):
return False
def add_router_info(self,cell):
"""
Write the routing grid as the boundary layer for debugging purposes.
Write the routing grid and router cost, blockage, pins on
the boundary layer for debugging purposes. This can only be
called once or the labels will overlap.
"""
grid_keys=self.rg.map.keys()
partial_track=vector(0,self.track_width/6.0)
for g in grid_keys:
shape = self.convert_full_track_to_shape(g)
cell.add_rect(layer="boundary",
@ -180,11 +180,20 @@ class router:
height=shape[1].y-shape[0].y)
t=self.rg.map[g].get_type()
if (type(t)==str):
cell.add_label(text=t,
layer="text",
offset=vector((shape[1].x+shape[0].x)/2,
(shape[1].y+shape[0].y)/2))
if t == None: continue
# midpoint offset
off=vector((shape[1].x+shape[0].x)/2,
(shape[1].y+shape[0].y)/2)
if g[2]==1:
# Upper layer is upper right label
off+=partial_track
else:
# Lower layer is lower left label
off-=partial_track
cell.add_label(text=str(t),
layer="text",
offset=off)
def add_route(self,cell):
@ -193,7 +202,7 @@ class router:
"""
# For debugging...
self.add_grid_map(cell)
#self.add_router_info(cell)
# First, simplify the path for
#debug.info(1,str(self.path))
@ -330,7 +339,7 @@ class router:
if (len(pin_in_tracks)>0): found_pin=True
debug.info(1,"Set source: " + str(pin) + " " + str(pin_in_tracks) + " z=" + str(zindex))
self.rg.add_source(pin_in_tracks)
debug.check(found_pin,"Unable to find source pin on grid.")
def add_target(self,pin):
@ -349,8 +358,10 @@ class router:
if (len(pin_in_tracks)>0): found_pin=True
debug.info(1,"Set target: " + str(pin) + " " + str(pin_in_tracks) + " z=" + str(zindex))
self.rg.add_target(pin_in_tracks)
debug.check(found_pin,"Unable to find source pin on grid.")
def write_obstacle(self, sref, mirr = 1, angle = math.radians(float(0)), xyShift = (0, 0)):
"""

View File

@ -53,8 +53,10 @@ class no_blockages_test(unittest.TestCase):
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
r.route(layer_stack,src="A",dest="B")
r.add_route(self)
if r.route(layer_stack,src="A",dest="B"):
r.add_route(self)
else:
self.assertTrue(False)
r = routing("test1", "01_no_blockages_test_{0}".format(OPTS.tech_name))
self.local_check(r)

View File

@ -53,9 +53,11 @@ class blockages_test(unittest.TestCase):
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
r.route(layer_stack,src="A",dest="B")
r.add_route(self)
if r.route(layer_stack,src="A",dest="B"):
r.add_route(self)
else:
self.assertTrue(False)
r = routing("test1", "02_blockages_test_{0}".format(OPTS.tech_name))
self.local_check(r)

View File

@ -52,9 +52,11 @@ class same_layer_pins_test(unittest.TestCase):
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
r.route(layer_stack,src="A",dest="B")
r.add_route(self)
if r.route(layer_stack,src="A",dest="B"):
r.add_route(self)
else:
self.assertTrue(False)
r = routing("test1", "03_same_layer_pins_test_{0}".format(OPTS.tech_name))
self.local_check(r)

View File

@ -54,8 +54,10 @@ class diff_layer_pins_test(unittest.TestCase):
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
r.route(layer_stack,src="A",dest="B")
r.add_route(self)
if r.route(layer_stack,src="A",dest="B"):
r.add_route(self)
else:
self.assertTrue(False)
r = routing("test1", "04_diff_layer_pins_test_{0}".format(OPTS.tech_name))
self.local_check(r)

View File

@ -54,14 +54,16 @@ class two_nets_test(unittest.TestCase):
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
r=router.router(self.gdsname)
layer_stack =("metal1","via1","metal2")
r.route(layer_stack,src="A",dest="B")
r.add_route(self)
if r.route(layer_stack,src="A",dest="B"):
r.add_route(self)
else:
self.assertTrue(False)
r.route(layer_stack,src="C",dest="D")
r.add_route(self)
if r.route(layer_stack,src="C",dest="D"):
r.add_route(self)
else:
debug.error("Unable to route")
r = routing("test1", "05_two_nets_test_{0}".format(OPTS.tech_name))
self.local_check(r)

View File

@ -56,9 +56,11 @@ class pin_location_test(unittest.TestCase):
# these are user coordinates and layers
src_pin = [[0.52, 4.099],11]
tgt_pin = [[3.533, 1.087],11]
r.route(layer_stack,src=src_pin,dest=tgt_pin)
#r.route(layer_stack,src="A",dest="B")
r.add_route(self)
if r.route(layer_stack,src=src_pin,dest=tgt_pin):
r.add_route(self)
else:
debug.error("Unable to route")
# This only works for freepdk45 since the coordinates are hard coded
if OPTS.tech_name == "freepdk45":