mirror of https://github.com/VLSIDA/OpenRAM.git
Contract path to simplified route
This commit is contained in:
parent
aa950c3b21
commit
0a9b326f6a
|
|
@ -244,12 +244,9 @@ class layout:
|
|||
self.gds = gdsMill.VlsiLayout(units=GDS["unit"])
|
||||
reader = gdsMill.Gds2reader(self.gds)
|
||||
reader.loadFromFile(self.gds_file)
|
||||
# TODO: parse the width/height
|
||||
# TODO: parse the pin locations
|
||||
else:
|
||||
debug.info(3, "creating structure %s" % self.name)
|
||||
self.gds = gdsMill.VlsiLayout(
|
||||
name=self.name, units=GDS["unit"])
|
||||
self.gds = gdsMill.VlsiLayout(name=self.name, units=GDS["unit"])
|
||||
|
||||
def print_gds(self, gds_file=None):
|
||||
"""Print the gds file (not the vlsi class) to the terminal """
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class cell:
|
|||
b+=b1
|
||||
count+=1
|
||||
|
||||
if self.source or self.target:
|
||||
if self.source or self.target:
|
||||
[r1,g1,b1] = ImageColor.getrgb("Red")
|
||||
r+=r1
|
||||
g+=g1
|
||||
|
|
|
|||
|
|
@ -154,11 +154,12 @@ class grid:
|
|||
"""
|
||||
# expand from the last point
|
||||
point = path[-1]
|
||||
|
||||
neighbors = []
|
||||
# check z layer for enforced direction routing
|
||||
if point.z==0:
|
||||
east = point + vector3d(1,0,0)
|
||||
west= point + vector3d(-11,0,0)
|
||||
west= point + vector3d(-1,0,0)
|
||||
if east.x<self.width and not self.map[east].blocked and not self.map[east].visited:
|
||||
neighbors.append(east)
|
||||
if west.x>=0 and not self.map[west].blocked and not self.map[west].visited:
|
||||
|
|
|
|||
|
|
@ -62,9 +62,6 @@ class router:
|
|||
self.track_width = max(self.horiz_track_width,self.vert_track_width)
|
||||
print "Track width:",self.track_width
|
||||
|
||||
# to scale coordinates to tracks
|
||||
self.track_factor = [1/self.track_width] * 2
|
||||
|
||||
|
||||
|
||||
def create_routing_grid(self):
|
||||
|
|
@ -117,15 +114,16 @@ class router:
|
|||
self.set_source(src)
|
||||
self.set_target(dest)
|
||||
self.find_blockages()
|
||||
# returns the path in tracks
|
||||
path = self.rg.route()
|
||||
debug.info(0,"Found path. ")
|
||||
debug.info(2,str(path))
|
||||
return path
|
||||
self.set_path(path)
|
||||
# convert the path back to absolute units from tracks
|
||||
abs_path = self.convert_path_to_units(path)
|
||||
debug.info(2,str(abs_path))
|
||||
return abs_path
|
||||
|
||||
def add_route(self,start, end, layerstack):
|
||||
""" Add a wire route from the start to the end point"""
|
||||
pass
|
||||
|
||||
def create_steiner_routes(self,pins):
|
||||
"""Find a set of steiner points and then return the list of
|
||||
point-to-point routes."""
|
||||
|
|
@ -163,6 +161,41 @@ class router:
|
|||
coordinate += [vector(maxx, maxy)]
|
||||
return coordinate
|
||||
|
||||
def get_inertia(self,p0,p1):
|
||||
# direction (index) of movement
|
||||
if p0.x==p1.x:
|
||||
inertia = 1
|
||||
elif p0.y==p1.y:
|
||||
inertia = 0
|
||||
else:
|
||||
inertia = 2
|
||||
return inertia
|
||||
|
||||
def contract_path(self,path):
|
||||
"""
|
||||
Remove intermediate points in a rectilinear path.
|
||||
"""
|
||||
debug.info(0,"Initial path:"+str(path))
|
||||
newpath = [path[0]]
|
||||
for i in range(len(path)-1):
|
||||
if i==0:
|
||||
continue
|
||||
prev_inertia=self.get_inertia(path[i-1],path[i])
|
||||
next_inertia=self.get_inertia(path[i],path[i+1])
|
||||
|
||||
if prev_inertia!=next_inertia:
|
||||
newpath.append(path[i])
|
||||
else:
|
||||
continue
|
||||
|
||||
newpath.append(path[-1])
|
||||
debug.info(0,"Final path:"+str(newpath))
|
||||
return newpath
|
||||
|
||||
def set_path(self,path):
|
||||
debug.info(2,"Set path: " + str(path))
|
||||
self.rg.set_path(path)
|
||||
|
||||
def set_source(self,name):
|
||||
shape = self.find_pin(name)
|
||||
zindex = 0 if self.pin_layers[name]==self.horiz_layer_number else 1
|
||||
|
|
@ -215,6 +248,24 @@ class router:
|
|||
|
||||
self.write_obstacle(cur_sref.sName, sMirr, sAngle, sxyShift)
|
||||
|
||||
def convert_path_to_units(self,path):
|
||||
"""
|
||||
Convert a path set of tracks to center line path.
|
||||
"""
|
||||
# First, simplify the path.
|
||||
path = self.contract_path(path)
|
||||
|
||||
newpath = []
|
||||
track_factor = [self.track_width] * 2
|
||||
for p in path:
|
||||
# we can ignore the layers here
|
||||
# add_wire will filter out duplicates
|
||||
pt = vector(p[0],p[1])
|
||||
pt=pt.scale(track_factor)
|
||||
pt=snap_to_grid(pt+self.offset)
|
||||
newpath.append(pt)
|
||||
return newpath
|
||||
|
||||
def convert_to_tracks(self,shape,round_bigger=True):
|
||||
"""
|
||||
Convert a rectangular shape into track units.
|
||||
|
|
@ -225,14 +276,18 @@ class router:
|
|||
ll = snap_to_grid(ll-self.offset)
|
||||
ur = snap_to_grid(ur-self.offset)
|
||||
|
||||
# to scale coordinates to tracks
|
||||
track_factor = [1/self.track_width] * 2
|
||||
|
||||
|
||||
# Always round blockage shapes up.
|
||||
if round_bigger:
|
||||
ll = ll.scale(self.track_factor).floor()
|
||||
ur = ur.scale(self.track_factor).ceil()
|
||||
ll = ll.scale(track_factor).floor()
|
||||
ur = ur.scale(track_factor).ceil()
|
||||
# Always round pin shapes down
|
||||
else:
|
||||
ll = ll.scale(self.track_factor).round()
|
||||
ur = ur.scale(self.track_factor).round()
|
||||
ll = ll.scale(track_factor).round()
|
||||
ur = ur.scale(track_factor).round()
|
||||
|
||||
|
||||
return [ll,ur]
|
||||
|
|
|
|||
|
|
@ -10,46 +10,73 @@ import globals
|
|||
import debug
|
||||
import calibre
|
||||
|
||||
|
||||
class no_blockages_test(unittest.TestCase):
|
||||
|
||||
def runTest(self):
|
||||
globals.init_openram("config_{0}".format(OPTS.tech_name))
|
||||
|
||||
globals.init_openram("config_{0}".format(OPTS.tech_name))
|
||||
|
||||
import design
|
||||
import router
|
||||
import wire
|
||||
import tech
|
||||
#r=router.router("A_to_B_no_blockages.gds")
|
||||
#r=router.router("A_to_B_m1m2_blockages.gds")
|
||||
#r=router.router("A_to_B_m1m2_same_layer_pins.gds")
|
||||
r=router.router("A_to_B_m1m2_diff_layer_pins.gds")
|
||||
layer_stack =("metal1","via1","metal2")
|
||||
path=r.route(layer_stack,src="A",dest="B")
|
||||
|
||||
# For debug, to view the result as an image
|
||||
r.rg.set_path(path)
|
||||
r.rg.view()
|
||||
OPTS.check_lvsdrc = False
|
||||
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 = name + ".gds"
|
||||
self.sp_file = name + ".sp"
|
||||
design.hierarchy_layout.layout.__init__(self, name)
|
||||
design.hierarchy_spice.spice.__init__(self, name)
|
||||
|
||||
class routing(design.design):
|
||||
"""
|
||||
A generic GDS design that we can route on.
|
||||
"""
|
||||
def __init__(self, name, gdsname):
|
||||
design.design.__init__(self, name)
|
||||
debug.info(2, "Create {0} object".format(name))
|
||||
|
||||
#w = wire.wire(layer_stack, path)
|
||||
OPTS.check_lvsdrc = True
|
||||
#self.local_check(w)
|
||||
cell = gdscell(gdsname)
|
||||
self.add_inst(name=gdsname,
|
||||
mod=cell,
|
||||
offset=[0,0])
|
||||
self.connect_inst([])
|
||||
|
||||
r=router.router(gdsname+".gds")
|
||||
layer_stack =("metal1","via1","metal2")
|
||||
path=r.route(layer_stack,src="A",dest="B")
|
||||
r.rg.view()
|
||||
|
||||
self.add_wire(layer_stack,path)
|
||||
|
||||
#drc_errors = calibre.run_drc(name, gds_name)
|
||||
drc_errors = 1
|
||||
|
||||
r = routing("test1", "A_to_B_no_blockages")
|
||||
self.local_check(r)
|
||||
|
||||
r = routing("A_to_B_m1m2_blockages")
|
||||
self.local_check(r)
|
||||
|
||||
r = routing("A_to_B_m1m2_same_layer_pins")
|
||||
self.local_check(r)
|
||||
|
||||
r = routing("A_to_B_m1m2_diff_layer_pins")
|
||||
self.local_check(r)
|
||||
|
||||
# fails if there are any DRC errors on any cells
|
||||
self.assertEqual(drc_errors, 0)
|
||||
globals.end_openram()
|
||||
|
||||
|
||||
|
||||
|
||||
def local_check(self, w):
|
||||
def local_check(self, r):
|
||||
tempgds = OPTS.openram_temp + "temp.gds"
|
||||
w.gds_write(tempgds)
|
||||
self.assertFalse(calibre.run_drc(w.name, tempgds))
|
||||
r.gds_write(tempgds)
|
||||
self.assertFalse(calibre.run_drc(r.name, tempgds))
|
||||
os.remove(tempgds)
|
||||
|
||||
assert(0)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
.SUBCKT cell
|
||||
.ENDS cell
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
.SUBCKT cell
|
||||
.ENDS cell
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
.SUBCKT cell
|
||||
.ENDS cell
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
.SUBCKT cell
|
||||
.ENDS cell
|
||||
Loading…
Reference in New Issue