mirror of https://github.com/VLSIDA/OpenRAM.git
Fix multiple net routing cost reset bug.
This commit is contained in:
parent
96f1eb413e
commit
388794b1e0
|
|
@ -14,6 +14,15 @@ class cell:
|
||||||
# -1 means it isn't visited yet
|
# -1 means it isn't visited yet
|
||||||
self.min_cost = -1
|
self.min_cost = -1
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
"""
|
||||||
|
Reset the dynamic info about routing. The pins/blockages are not reset so
|
||||||
|
that they can be reused.
|
||||||
|
"""
|
||||||
|
self.visited=False
|
||||||
|
self.min_cost=-1
|
||||||
|
self.min_path=None
|
||||||
|
|
||||||
def get_type(self):
|
def get_type(self):
|
||||||
if self.blocked:
|
if self.blocked:
|
||||||
return "X"
|
return "X"
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ class grid:
|
||||||
|
|
||||||
self.convert_pins_to_blockages()
|
self.convert_pins_to_blockages()
|
||||||
|
|
||||||
|
self.reset_cells()
|
||||||
|
|
||||||
# clear source and target pins
|
# clear source and target pins
|
||||||
self.source=[]
|
self.source=[]
|
||||||
self.target=[]
|
self.target=[]
|
||||||
|
|
@ -163,6 +165,13 @@ class grid:
|
||||||
self.map[n].blocked=False
|
self.map[n].blocked=False
|
||||||
self.target.append(n)
|
self.target.append(n)
|
||||||
|
|
||||||
|
def reset_cells(self):
|
||||||
|
"""
|
||||||
|
Reset the path and costs for all the grid cells.
|
||||||
|
"""
|
||||||
|
for p in self.map.values():
|
||||||
|
p.reset()
|
||||||
|
|
||||||
def convert_pins_to_blockages(self):
|
def convert_pins_to_blockages(self):
|
||||||
"""
|
"""
|
||||||
Convert all the pins to blockages and reset the pin sets.
|
Convert all the pins to blockages and reset the pin sets.
|
||||||
|
|
@ -189,15 +198,14 @@ class grid:
|
||||||
for p in path:
|
for p in path:
|
||||||
self.map[p].path=True
|
self.map[p].path=True
|
||||||
|
|
||||||
def route(self,cost_bound=0):
|
def route(self,factor):
|
||||||
"""
|
"""
|
||||||
This does the A* maze routing with preferred direction routing.
|
This does the A* maze routing with preferred direction routing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# We set a cost bound of 2.5 x the HPWL for run-time. This can be
|
# We set a cost bound of the HPWL for run-time. This can be
|
||||||
# over-ridden if the route fails due to pruning a feasible solution.
|
# over-ridden if the route fails due to pruning a feasible solution.
|
||||||
if (cost_bound==0):
|
cost_bound = factor*self.cost_to_target(self.source[0])*self.NONPREFERRED_COST
|
||||||
cost_bound = self.cost_to_target(self.source[0])*self.NONPREFERRED_COST
|
|
||||||
|
|
||||||
# Make sure the queue is empty if we run another route
|
# Make sure the queue is empty if we run another route
|
||||||
while not self.q.empty():
|
while not self.q.empty():
|
||||||
|
|
@ -210,19 +218,18 @@ class grid:
|
||||||
|
|
||||||
# Keep expanding and adding to the priority queue until we are done
|
# Keep expanding and adding to the priority queue until we are done
|
||||||
while not self.q.empty():
|
while not self.q.empty():
|
||||||
|
# should we keep the path in the queue as well or just the final node?
|
||||||
(cost,path) = self.q.get()
|
(cost,path) = self.q.get()
|
||||||
debug.info(2,"Queue size: size=" + str(self.q.qsize()) + " " + str(cost))
|
debug.info(2,"Queue size: size=" + str(self.q.qsize()) + " " + str(cost))
|
||||||
debug.info(3,"Expanding: cost=" + str(cost) + " " + str(path))
|
debug.info(3,"Expanding: cost=" + str(cost) + " " + str(path))
|
||||||
|
|
||||||
# expand the last element
|
# expand the last element
|
||||||
neighbors = self.expand_dirs(path)
|
neighbors = self.expand_dirs(path)
|
||||||
debug.info(4,"Neighbors: " + str(neighbors))
|
debug.info(3,"Neighbors: " + str(neighbors))
|
||||||
|
|
||||||
for n in neighbors:
|
for n in neighbors:
|
||||||
|
# node is added to the map by the expand routine
|
||||||
newpath = path + [n]
|
newpath = path + [n]
|
||||||
if n not in self.map.keys():
|
|
||||||
self.map[n]=cell()
|
|
||||||
|
|
||||||
# check if we hit the target and are done
|
# check if we hit the target and are done
|
||||||
if self.is_target(n):
|
if self.is_target(n):
|
||||||
return (newpath,self.cost(newpath))
|
return (newpath,self.cost(newpath))
|
||||||
|
|
@ -242,6 +249,7 @@ class grid:
|
||||||
self.q.put((predicted_cost,newpath))
|
self.q.put((predicted_cost,newpath))
|
||||||
#self.view()
|
#self.view()
|
||||||
|
|
||||||
|
self.view()
|
||||||
debug.error("Unable to route path. Expand area?",-1)
|
debug.error("Unable to route path. Expand area?",-1)
|
||||||
|
|
||||||
def is_target(self,point):
|
def is_target(self,point):
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,6 @@ class router:
|
||||||
self.pin_shapes = {}
|
self.pin_shapes = {}
|
||||||
# The corresponding layers of the above pin shapes
|
# The corresponding layers of the above pin shapes
|
||||||
self.pin_layers = {}
|
self.pin_layers = {}
|
||||||
# Used to track which shapes should not become blockages. This
|
|
||||||
# will contain all of both source and dest pin shapes in units not tracks.
|
|
||||||
self.all_pin_shapes = []
|
|
||||||
|
|
||||||
# The boundary will determine the limits to the size of the routing grid
|
# The boundary will determine the limits to the size of the routing grid
|
||||||
self.boundary = self.layout.measureBoundary(self.top_name)
|
self.boundary = self.layout.measureBoundary(self.top_name)
|
||||||
|
|
@ -105,16 +102,15 @@ class router:
|
||||||
shape=[vector(pin_shape[0],pin_shape[1]),vector(pin_shape[2],pin_shape[3])]
|
shape=[vector(pin_shape[0],pin_shape[1]),vector(pin_shape[2],pin_shape[3])]
|
||||||
# convert the pin coordinates to tracks and round the sizes down
|
# convert the pin coordinates to tracks and round the sizes down
|
||||||
self.pin_shapes[str(pin)].append(shape)
|
self.pin_shapes[str(pin)].append(shape)
|
||||||
self.all_pin_shapes.append(shape)
|
|
||||||
|
|
||||||
return self.pin_shapes[str(pin)]
|
return self.pin_shapes[str(pin)]
|
||||||
|
|
||||||
def find_blockages(self):
|
def find_blockages(self):
|
||||||
"""
|
"""
|
||||||
Iterate through all the layers and write the obstacles to the routing grid.
|
Iterate through all the layers and write the obstacles to the routing grid.
|
||||||
|
This doesn't consider whether the obstacles will be pins or not. They get reset later
|
||||||
|
if they are not actually a blockage.
|
||||||
"""
|
"""
|
||||||
if len(self.pin_names)!=2:
|
|
||||||
debug.error("Must set pins before creating blockages.",-1)
|
|
||||||
for layer in self.layers:
|
for layer in self.layers:
|
||||||
self.write_obstacle(self.top_name)
|
self.write_obstacle(self.top_name)
|
||||||
|
|
||||||
|
|
@ -122,50 +118,46 @@ class router:
|
||||||
def clear_pins(self):
|
def clear_pins(self):
|
||||||
"""
|
"""
|
||||||
Reset the source and destination pins to start a new routing.
|
Reset the source and destination pins to start a new routing.
|
||||||
Convert the source/dest to blockages.
|
Convert the source/dest pins to blockages.
|
||||||
Keep the other blockages.
|
Convert the routed path to blockages.
|
||||||
Clear other pins from blockages?
|
Keep the other blockages unchanged.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.pin_names = []
|
self.pin_names = []
|
||||||
self.pin_shapes = {}
|
self.pin_shapes = {}
|
||||||
self.pin_layers = {}
|
self.pin_layers = {}
|
||||||
self.all_pin_shapes = []
|
|
||||||
|
|
||||||
self.rg.reinit()
|
self.rg.reinit()
|
||||||
|
|
||||||
|
|
||||||
def route(self, layers, src, dest):
|
def route(self, layers, src, dest, cost_factor=1):
|
||||||
"""
|
"""
|
||||||
Route a single source-destination net and return
|
Route a single source-destination net and return
|
||||||
the simplified rectilinear path.
|
the simplified rectilinear path. Cost factor is how sub-optimal to explore for a feasible route.
|
||||||
|
This is used to speed up the routing when there is not much detouring needed.
|
||||||
"""
|
"""
|
||||||
# Clear the pins if we have previously routed
|
# Clear the pins if we have previously routed
|
||||||
if (hasattr(self,'rg')):
|
if (hasattr(self,'rg')):
|
||||||
self.num=self.num+1
|
|
||||||
self.clear_pins()
|
self.clear_pins()
|
||||||
else:
|
else:
|
||||||
self.num=0
|
|
||||||
|
|
||||||
# Set up layers and track sizes
|
# Set up layers and track sizes
|
||||||
self.set_layers(layers)
|
self.set_layers(layers)
|
||||||
|
|
||||||
# Creat a routing grid over the entire area
|
# Creat a routing grid over the entire area
|
||||||
# FIXME: This could be created only over the routing region,
|
# FIXME: This could be created only over the routing region,
|
||||||
# but this is simplest for now.
|
# but this is simplest for now.
|
||||||
self.create_routing_grid()
|
self.create_routing_grid()
|
||||||
|
# This will write all shapes as blockages, but setting pins will
|
||||||
|
# clear the blockage attribute
|
||||||
|
self.find_blockages()
|
||||||
|
|
||||||
self.set_source(src)
|
self.set_source(src)
|
||||||
|
|
||||||
self.set_target(dest)
|
self.set_target(dest)
|
||||||
|
|
||||||
self.find_blockages()
|
|
||||||
|
|
||||||
self.rg.view()
|
self.rg.view()
|
||||||
|
|
||||||
# returns the path in tracks
|
# returns the path in tracks
|
||||||
(self.path,cost) = self.rg.route()
|
(self.path,cost) = self.rg.route(cost_factor)
|
||||||
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.set_path(self.path)
|
self.set_path(self.path)
|
||||||
|
|
@ -341,8 +333,6 @@ class router:
|
||||||
# only consider the two layers that we are routing on
|
# only consider the two layers that we are routing on
|
||||||
if boundary.drawingLayer in [self.vert_layer_number,self.horiz_layer_number]:
|
if boundary.drawingLayer in [self.vert_layer_number,self.horiz_layer_number]:
|
||||||
zlayer = 0 if boundary.drawingLayer==self.horiz_layer_number else 1
|
zlayer = 0 if boundary.drawingLayer==self.horiz_layer_number else 1
|
||||||
# don't add a blockage if this shape was a pin shape
|
|
||||||
if shape not in self.all_pin_shapes:
|
|
||||||
[ll,ur]=self.convert_shape_to_tracks(shape)
|
[ll,ur]=self.convert_shape_to_tracks(shape)
|
||||||
self.rg.add_blockage(ll,ur,zlayer)
|
self.rg.add_blockage(ll,ur,zlayer)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue