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
|
||||
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):
|
||||
if self.blocked:
|
||||
return "X"
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ class grid:
|
|||
|
||||
self.convert_pins_to_blockages()
|
||||
|
||||
self.reset_cells()
|
||||
|
||||
# clear source and target pins
|
||||
self.source=[]
|
||||
self.target=[]
|
||||
|
|
@ -163,6 +165,13 @@ class grid:
|
|||
self.map[n].blocked=False
|
||||
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):
|
||||
"""
|
||||
Convert all the pins to blockages and reset the pin sets.
|
||||
|
|
@ -189,16 +198,15 @@ class grid:
|
|||
for p in path:
|
||||
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.
|
||||
"""
|
||||
|
||||
# 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.
|
||||
if (cost_bound==0):
|
||||
cost_bound = self.cost_to_target(self.source[0])*self.NONPREFERRED_COST
|
||||
|
||||
cost_bound = factor*self.cost_to_target(self.source[0])*self.NONPREFERRED_COST
|
||||
|
||||
# Make sure the queue is empty if we run another route
|
||||
while not self.q.empty():
|
||||
self.q.get()
|
||||
|
|
@ -210,19 +218,18 @@ class grid:
|
|||
|
||||
# Keep expanding and adding to the priority queue until we are done
|
||||
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()
|
||||
debug.info(2,"Queue size: size=" + str(self.q.qsize()) + " " + str(cost))
|
||||
debug.info(3,"Expanding: cost=" + str(cost) + " " + str(path))
|
||||
|
||||
# expand the last element
|
||||
neighbors = self.expand_dirs(path)
|
||||
debug.info(4,"Neighbors: " + str(neighbors))
|
||||
debug.info(3,"Neighbors: " + str(neighbors))
|
||||
|
||||
for n in neighbors:
|
||||
# node is added to the map by the expand routine
|
||||
newpath = path + [n]
|
||||
if n not in self.map.keys():
|
||||
self.map[n]=cell()
|
||||
|
||||
# check if we hit the target and are done
|
||||
if self.is_target(n):
|
||||
return (newpath,self.cost(newpath))
|
||||
|
|
@ -242,6 +249,7 @@ class grid:
|
|||
self.q.put((predicted_cost,newpath))
|
||||
#self.view()
|
||||
|
||||
self.view()
|
||||
debug.error("Unable to route path. Expand area?",-1)
|
||||
|
||||
def is_target(self,point):
|
||||
|
|
|
|||
|
|
@ -30,9 +30,6 @@ class router:
|
|||
self.pin_shapes = {}
|
||||
# The corresponding layers of the above pin shapes
|
||||
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
|
||||
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])]
|
||||
# convert the pin coordinates to tracks and round the sizes down
|
||||
self.pin_shapes[str(pin)].append(shape)
|
||||
self.all_pin_shapes.append(shape)
|
||||
|
||||
return self.pin_shapes[str(pin)]
|
||||
|
||||
def find_blockages(self):
|
||||
"""
|
||||
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:
|
||||
self.write_obstacle(self.top_name)
|
||||
|
||||
|
|
@ -122,50 +118,46 @@ class router:
|
|||
def clear_pins(self):
|
||||
"""
|
||||
Reset the source and destination pins to start a new routing.
|
||||
Convert the source/dest to blockages.
|
||||
Keep the other blockages.
|
||||
Clear other pins from blockages?
|
||||
|
||||
Convert the source/dest pins to blockages.
|
||||
Convert the routed path to blockages.
|
||||
Keep the other blockages unchanged.
|
||||
"""
|
||||
|
||||
self.pin_names = []
|
||||
self.pin_shapes = {}
|
||||
self.pin_layers = {}
|
||||
self.all_pin_shapes = []
|
||||
|
||||
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
|
||||
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
|
||||
if (hasattr(self,'rg')):
|
||||
self.num=self.num+1
|
||||
self.clear_pins()
|
||||
else:
|
||||
self.num=0
|
||||
|
||||
# Set up layers and track sizes
|
||||
self.set_layers(layers)
|
||||
|
||||
# Creat a routing grid over the entire area
|
||||
# FIXME: This could be created only over the routing region,
|
||||
# but this is simplest for now.
|
||||
self.create_routing_grid()
|
||||
# Set up layers and track sizes
|
||||
self.set_layers(layers)
|
||||
# Creat a routing grid over the entire area
|
||||
# FIXME: This could be created only over the routing region,
|
||||
# but this is simplest for now.
|
||||
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_target(dest)
|
||||
|
||||
self.find_blockages()
|
||||
|
||||
self.rg.view()
|
||||
|
||||
# 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(2,str(self.path))
|
||||
self.set_path(self.path)
|
||||
|
|
@ -341,10 +333,8 @@ class router:
|
|||
# only consider the two layers that we are routing on
|
||||
if boundary.drawingLayer in [self.vert_layer_number,self.horiz_layer_number]:
|
||||
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)
|
||||
self.rg.add_blockage(ll,ur,zlayer)
|
||||
[ll,ur]=self.convert_shape_to_tracks(shape)
|
||||
self.rg.add_blockage(ll,ur,zlayer)
|
||||
|
||||
|
||||
# recurse given the mirror, angle, etc.
|
||||
|
|
|
|||
Loading…
Reference in New Issue