mirror of https://github.com/VLSIDA/OpenRAM.git
Improved router debugging and return error if unable to route.
This commit is contained in:
parent
8cc63560f8
commit
d31b1862a3
|
|
@ -40,4 +40,4 @@ class cell:
|
||||||
if self.min_cost > 0:
|
if self.min_cost > 0:
|
||||||
return self.min_cost
|
return self.min_cost
|
||||||
|
|
||||||
return "."
|
return None
|
||||||
|
|
|
||||||
|
|
@ -55,84 +55,6 @@ class grid:
|
||||||
while (not self.q.empty()):
|
while (not self.q.empty()):
|
||||||
self.q.get(False)
|
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):
|
def add_blockage(self,ll,ur,z):
|
||||||
debug.info(3,"Adding blockage ll={0} ur={1} z={2}".format(str(ll),str(ur),z))
|
debug.info(3,"Adding blockage ll={0} ur={1} z={2}".format(str(ll),str(ur),z))
|
||||||
|
|
@ -142,7 +64,6 @@ class grid:
|
||||||
self.add_map(n)
|
self.add_map(n)
|
||||||
self.map[n].blocked=True
|
self.map[n].blocked=True
|
||||||
|
|
||||||
|
|
||||||
def add_source(self,track_list):
|
def add_source(self,track_list):
|
||||||
debug.info(3,"Adding source list={0}".format(str(track_list)))
|
debug.info(3,"Adding source list={0}".format(str(track_list)))
|
||||||
for n in track_list:
|
for n in track_list:
|
||||||
|
|
@ -175,6 +96,8 @@ class grid:
|
||||||
for p in self.map.values():
|
for p in self.map.values():
|
||||||
if (p.source or p.target):
|
if (p.source or p.target):
|
||||||
p.blocked=True
|
p.blocked=True
|
||||||
|
p.source=False
|
||||||
|
p.target=False
|
||||||
|
|
||||||
def convert_path_to_blockages(self):
|
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))
|
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
|
# add the cost to get to this point if we haven't reached it yet
|
||||||
self.q.put((predicted_cost,newpath))
|
self.q.put((predicted_cost,newpath))
|
||||||
#self.view()
|
|
||||||
|
|
||||||
# View the unable to route result.
|
debug.warning("Unable to route path. Expand area?")
|
||||||
self.view()
|
return (None,None)
|
||||||
debug.error("Unable to route path. Expand area?",-1)
|
|
||||||
|
|
||||||
def is_target(self,point):
|
def is_target(self,point):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -154,24 +154,24 @@ class router:
|
||||||
|
|
||||||
self.add_target(dest)
|
self.add_target(dest)
|
||||||
|
|
||||||
# View the initial route pins and blockages for debugging
|
|
||||||
#self.rg.view()
|
|
||||||
|
|
||||||
# returns the path in tracks
|
# returns the path in tracks
|
||||||
(self.path,cost) = self.rg.route(cost_bound_scale)
|
(self.path,cost) = self.rg.route(cost_bound_scale)
|
||||||
|
if self.path!=None:
|
||||||
debug.info(1,"Found path: cost={0} ".format(cost))
|
debug.info(1,"Found path: cost={0} ".format(cost))
|
||||||
debug.info(2,str(self.path))
|
debug.info(2,str(self.path))
|
||||||
self.add_path(self.path)
|
self.add_path(self.path)
|
||||||
# View the final route for debugging
|
return True
|
||||||
#self.rg.view()
|
|
||||||
|
|
||||||
return
|
return False
|
||||||
|
|
||||||
def add_grid_map(self,cell):
|
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()
|
grid_keys=self.rg.map.keys()
|
||||||
|
partial_track=vector(0,self.track_width/6.0)
|
||||||
for g in grid_keys:
|
for g in grid_keys:
|
||||||
shape = self.convert_full_track_to_shape(g)
|
shape = self.convert_full_track_to_shape(g)
|
||||||
cell.add_rect(layer="boundary",
|
cell.add_rect(layer="boundary",
|
||||||
|
|
@ -180,11 +180,20 @@ class router:
|
||||||
height=shape[1].y-shape[0].y)
|
height=shape[1].y-shape[0].y)
|
||||||
|
|
||||||
t=self.rg.map[g].get_type()
|
t=self.rg.map[g].get_type()
|
||||||
if (type(t)==str):
|
if t == None: continue
|
||||||
cell.add_label(text=t,
|
|
||||||
|
# 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",
|
layer="text",
|
||||||
offset=vector((shape[1].x+shape[0].x)/2,
|
offset=off)
|
||||||
(shape[1].y+shape[0].y)/2))
|
|
||||||
|
|
||||||
|
|
||||||
def add_route(self,cell):
|
def add_route(self,cell):
|
||||||
|
|
@ -193,7 +202,7 @@ class router:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# For debugging...
|
# For debugging...
|
||||||
self.add_grid_map(cell)
|
#self.add_router_info(cell)
|
||||||
|
|
||||||
# First, simplify the path for
|
# First, simplify the path for
|
||||||
#debug.info(1,str(self.path))
|
#debug.info(1,str(self.path))
|
||||||
|
|
@ -352,6 +361,8 @@ class router:
|
||||||
|
|
||||||
debug.check(found_pin,"Unable to find source pin on grid.")
|
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)):
|
def write_obstacle(self, sref, mirr = 1, angle = math.radians(float(0)), xyShift = (0, 0)):
|
||||||
"""
|
"""
|
||||||
Recursive write boundaries as blockages to the routing grid.
|
Recursive write boundaries as blockages to the routing grid.
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,10 @@ class no_blockages_test(unittest.TestCase):
|
||||||
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
|
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
|
||||||
r=router.router(self.gdsname)
|
r=router.router(self.gdsname)
|
||||||
layer_stack =("metal1","via1","metal2")
|
layer_stack =("metal1","via1","metal2")
|
||||||
r.route(layer_stack,src="A",dest="B")
|
if r.route(layer_stack,src="A",dest="B"):
|
||||||
r.add_route(self)
|
r.add_route(self)
|
||||||
|
else:
|
||||||
|
self.assertTrue(False)
|
||||||
|
|
||||||
r = routing("test1", "01_no_blockages_test_{0}".format(OPTS.tech_name))
|
r = routing("test1", "01_no_blockages_test_{0}".format(OPTS.tech_name))
|
||||||
self.local_check(r)
|
self.local_check(r)
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,10 @@ class blockages_test(unittest.TestCase):
|
||||||
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
|
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
|
||||||
r=router.router(self.gdsname)
|
r=router.router(self.gdsname)
|
||||||
layer_stack =("metal1","via1","metal2")
|
layer_stack =("metal1","via1","metal2")
|
||||||
r.route(layer_stack,src="A",dest="B")
|
if r.route(layer_stack,src="A",dest="B"):
|
||||||
r.add_route(self)
|
r.add_route(self)
|
||||||
|
else:
|
||||||
|
self.assertTrue(False)
|
||||||
|
|
||||||
r = routing("test1", "02_blockages_test_{0}".format(OPTS.tech_name))
|
r = routing("test1", "02_blockages_test_{0}".format(OPTS.tech_name))
|
||||||
self.local_check(r)
|
self.local_check(r)
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,10 @@ class same_layer_pins_test(unittest.TestCase):
|
||||||
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
|
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
|
||||||
r=router.router(self.gdsname)
|
r=router.router(self.gdsname)
|
||||||
layer_stack =("metal1","via1","metal2")
|
layer_stack =("metal1","via1","metal2")
|
||||||
r.route(layer_stack,src="A",dest="B")
|
if r.route(layer_stack,src="A",dest="B"):
|
||||||
r.add_route(self)
|
r.add_route(self)
|
||||||
|
else:
|
||||||
|
self.assertTrue(False)
|
||||||
|
|
||||||
r = routing("test1", "03_same_layer_pins_test_{0}".format(OPTS.tech_name))
|
r = routing("test1", "03_same_layer_pins_test_{0}".format(OPTS.tech_name))
|
||||||
self.local_check(r)
|
self.local_check(r)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
|
||||||
r=router.router(self.gdsname)
|
r=router.router(self.gdsname)
|
||||||
layer_stack =("metal1","via1","metal2")
|
layer_stack =("metal1","via1","metal2")
|
||||||
r.route(layer_stack,src="A",dest="B")
|
if r.route(layer_stack,src="A",dest="B"):
|
||||||
r.add_route(self)
|
r.add_route(self)
|
||||||
|
else:
|
||||||
|
self.assertTrue(False)
|
||||||
|
|
||||||
r = routing("test1", "04_diff_layer_pins_test_{0}".format(OPTS.tech_name))
|
r = routing("test1", "04_diff_layer_pins_test_{0}".format(OPTS.tech_name))
|
||||||
self.local_check(r)
|
self.local_check(r)
|
||||||
|
|
|
||||||
|
|
@ -54,13 +54,15 @@ class two_nets_test(unittest.TestCase):
|
||||||
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
|
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),gdsname)
|
||||||
r=router.router(self.gdsname)
|
r=router.router(self.gdsname)
|
||||||
layer_stack =("metal1","via1","metal2")
|
layer_stack =("metal1","via1","metal2")
|
||||||
r.route(layer_stack,src="A",dest="B")
|
if r.route(layer_stack,src="A",dest="B"):
|
||||||
r.add_route(self)
|
r.add_route(self)
|
||||||
|
else:
|
||||||
|
self.assertTrue(False)
|
||||||
|
|
||||||
r.route(layer_stack,src="C",dest="D")
|
if r.route(layer_stack,src="C",dest="D"):
|
||||||
r.add_route(self)
|
r.add_route(self)
|
||||||
|
else:
|
||||||
|
debug.error("Unable to route")
|
||||||
|
|
||||||
r = routing("test1", "05_two_nets_test_{0}".format(OPTS.tech_name))
|
r = routing("test1", "05_two_nets_test_{0}".format(OPTS.tech_name))
|
||||||
self.local_check(r)
|
self.local_check(r)
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -56,9 +56,11 @@ class pin_location_test(unittest.TestCase):
|
||||||
# these are user coordinates and layers
|
# these are user coordinates and layers
|
||||||
src_pin = [[0.52, 4.099],11]
|
src_pin = [[0.52, 4.099],11]
|
||||||
tgt_pin = [[3.533, 1.087],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.route(layer_stack,src="A",dest="B")
|
||||||
|
if r.route(layer_stack,src=src_pin,dest=tgt_pin):
|
||||||
r.add_route(self)
|
r.add_route(self)
|
||||||
|
else:
|
||||||
|
debug.error("Unable to route")
|
||||||
|
|
||||||
# This only works for freepdk45 since the coordinates are hard coded
|
# This only works for freepdk45 since the coordinates are hard coded
|
||||||
if OPTS.tech_name == "freepdk45":
|
if OPTS.tech_name == "freepdk45":
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue