mirror of https://github.com/VLSIDA/OpenRAM.git
Add test to reroute after route fails. Disable GDS route debug info unless verbosity is more than 0.
This commit is contained in:
parent
5960324ca6
commit
93389ac723
|
|
@ -26,6 +26,7 @@ class grid:
|
|||
# rather than 2 vias + preferred direction (cost 5)
|
||||
self.VIA_COST = 2
|
||||
self.NONPREFERRED_COST = 4
|
||||
self.PREFERRED_COST = 1
|
||||
|
||||
# list of the source/target grid coordinates
|
||||
self.source = []
|
||||
|
|
@ -109,14 +110,14 @@ class grid:
|
|||
for p in path:
|
||||
self.map[p].path=True
|
||||
|
||||
def route(self,cost_bound_factor):
|
||||
def route(self,detour_scale):
|
||||
"""
|
||||
This does the A* maze routing with preferred direction routing.
|
||||
"""
|
||||
|
||||
# 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.
|
||||
cost_bound = cost_bound_factor*self.cost_to_target(self.source[0])*self.NONPREFERRED_COST
|
||||
cost_bound = detour_scale*self.cost_to_target(self.source[0])*self.PREFERRED_COST
|
||||
|
||||
# Make sure the queue is empty if we run another route
|
||||
while not self.q.empty():
|
||||
|
|
@ -159,7 +160,7 @@ class grid:
|
|||
# add the cost to get to this point if we haven't reached it yet
|
||||
self.q.put((predicted_cost,newpath))
|
||||
|
||||
debug.warning("Unable to route path. Expand area?")
|
||||
debug.warning("Unable to route path. Expand the detour_scale to allow detours.")
|
||||
return (None,None)
|
||||
|
||||
def is_target(self,point):
|
||||
|
|
@ -276,9 +277,9 @@ class grid:
|
|||
if p0.z != p1.z: # via
|
||||
cost += self.VIA_COST
|
||||
elif p0.x != p1.x: # horizontal
|
||||
cost += self.NONPREFERRED_COST if (p0.z == 1) else 1
|
||||
cost += self.NONPREFERRED_COST if (p0.z == 1) else self.PREFERRED_COST
|
||||
elif p0.y != p1.y: # vertical
|
||||
cost += self.NONPREFERRED_COST if (p0.z == 0) else 1
|
||||
cost += self.NONPREFERRED_COST if (p0.z == 0) else self.PREFERRED_COST
|
||||
else:
|
||||
debug.error("Non-changing direction!")
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import debug
|
|||
import grid
|
||||
from vector import vector
|
||||
from vector3d import vector3d
|
||||
|
||||
from globals import OPTS
|
||||
|
||||
class router:
|
||||
"""A router class to read an obstruction map from a gds and plan a
|
||||
|
|
@ -136,7 +136,7 @@ class router:
|
|||
self.rg.reinit()
|
||||
|
||||
|
||||
def route(self, cell, layers, src, dest, cost_bound_scale=1):
|
||||
def route(self, cell, layers, src, dest, detour_scale=2):
|
||||
"""
|
||||
Route a single source-destination net and return
|
||||
the simplified rectilinear path. Cost factor is how sub-optimal to explore for a feasible route.
|
||||
|
|
@ -172,7 +172,7 @@ class router:
|
|||
|
||||
|
||||
# returns the path in tracks
|
||||
(path,cost) = self.rg.route(cost_bound_scale)
|
||||
(path,cost) = self.rg.route(detour_scale)
|
||||
if path:
|
||||
debug.info(1,"Found path: cost={0} ".format(cost))
|
||||
debug.info(2,str(path))
|
||||
|
|
@ -180,6 +180,9 @@ class router:
|
|||
return True
|
||||
else:
|
||||
self.write_debug_gds()
|
||||
# clean up so we can try a reroute
|
||||
self.clear_pins()
|
||||
|
||||
|
||||
return False
|
||||
|
||||
|
|
@ -187,6 +190,10 @@ class router:
|
|||
"""
|
||||
Write out a GDS file with the routing grid and search information annotated on it.
|
||||
"""
|
||||
# Only add the debug info to the gds file if we have any debugging on.
|
||||
# This is because we may reroute a wire with detours and don't want the debug information.
|
||||
if OPTS.debug_level==0: return
|
||||
|
||||
self.add_router_info()
|
||||
debug.error("Writing debug_route.gds from {0} to {1}".format(self.source_pin,self.target_pin))
|
||||
self.cell.gds_write("debug_route.gds")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python2.7
|
||||
"Run a regresion test the library cells for DRC"
|
||||
|
||||
import unittest
|
||||
from testutils import header
|
||||
import sys,os
|
||||
sys.path.append(os.path.join(sys.path[0],"../.."))
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
import debug
|
||||
import calibre
|
||||
|
||||
OPTS = globals.OPTS
|
||||
|
||||
class expand_region_test(unittest.TestCase):
|
||||
"""
|
||||
Test an infeasible route followed by a feasible route with an expanded region.
|
||||
"""
|
||||
|
||||
def runTest(self):
|
||||
globals.init_openram("config_{0}".format(OPTS.tech_name))
|
||||
|
||||
import design
|
||||
import router
|
||||
|
||||
class gdscell(design.design):
|
||||
"""
|
||||
A generic GDS design that we can route on.
|
||||
"""
|
||||
def __init__(self, name):
|
||||
#design.design.__init__(self, name)
|
||||
debug.info(2, "Create {0} object".format(name))
|
||||
self.name = name
|
||||
self.gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
|
||||
self.sp_file = "{0}/{1}.sp".format(os.path.dirname(os.path.realpath(__file__)),name)
|
||||
design.hierarchy_layout.layout.__init__(self, name)
|
||||
design.hierarchy_spice.spice.__init__(self, name)
|
||||
|
||||
class routing(design.design,unittest.TestCase):
|
||||
"""
|
||||
A generic GDS design that we can route on.
|
||||
"""
|
||||
def __init__(self, name):
|
||||
design.design.__init__(self, name)
|
||||
debug.info(2, "Create {0} object".format(name))
|
||||
|
||||
cell = gdscell(name)
|
||||
self.add_inst(name=name,
|
||||
mod=cell,
|
||||
offset=[0,0])
|
||||
self.connect_inst([])
|
||||
|
||||
self.gdsname = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
|
||||
r=router.router(self.gdsname)
|
||||
layer_stack =("metal1","via1","metal2")
|
||||
# This should be infeasible because it is blocked without a detour.
|
||||
self.assertFalse(r.route(self,layer_stack,src="A",dest="B",detour_scale=1))
|
||||
# This should be feasible because we allow it to detour
|
||||
self.assertTrue(r.route(self,layer_stack,src="A",dest="B",detour_scale=3))
|
||||
|
||||
r = routing("08_expand_region_test_{0}".format(OPTS.tech_name))
|
||||
self.local_check(r)
|
||||
|
||||
# fails if there are any DRC errors on any cells
|
||||
globals.end_openram()
|
||||
|
||||
|
||||
def local_check(self, r):
|
||||
tempgds = OPTS.openram_temp + "temp.gds"
|
||||
r.gds_write(tempgds)
|
||||
self.assertFalse(calibre.run_drc(r.name, tempgds))
|
||||
os.remove(tempgds)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# instantiate a copy of the class to actually run the test
|
||||
if __name__ == "__main__":
|
||||
(OPTS, args) = globals.parse_args()
|
||||
del sys.argv[1:]
|
||||
header(__file__, OPTS.tech_name)
|
||||
unittest.main()
|
||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue