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:
|
||||
return self.min_cost
|
||||
|
||||
return "."
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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)):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -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":
|
||||
|
|
|
|||
Loading…
Reference in New Issue