mirror of https://github.com/VLSIDA/OpenRAM.git
Horizontal and vertical grid wires done.
This commit is contained in:
parent
cd987479b8
commit
c2c17a33d2
|
|
@ -55,10 +55,23 @@ class pin_layout:
|
||||||
|
|
||||||
return (newll, newur)
|
return (newll, newur)
|
||||||
|
|
||||||
|
def intersection(self, other):
|
||||||
|
""" Check if a shape overlaps with a rectangle """
|
||||||
|
(ll,ur) = self.rect
|
||||||
|
(oll,our) = other.rect
|
||||||
|
|
||||||
|
min_x = max(ll.x, oll.x)
|
||||||
|
max_x = min(ll.x, oll.x)
|
||||||
|
min_y = max(ll.y, oll.y)
|
||||||
|
max_y = min(ll.y, oll.y)
|
||||||
|
|
||||||
|
return [vector(min_x,min_y),vector(max_x,max_y)]
|
||||||
|
|
||||||
def overlaps(self, other):
|
def overlaps(self, other):
|
||||||
""" Check if a shape overlaps with a rectangle """
|
""" Check if a shape overlaps with a rectangle """
|
||||||
(ll,ur) = self.rect
|
(ll,ur) = self.rect
|
||||||
(oll,our) = other.rect
|
(oll,our) = other.rect
|
||||||
|
|
||||||
# Start assuming no overlaps
|
# Start assuming no overlaps
|
||||||
x_overlaps = False
|
x_overlaps = False
|
||||||
y_overlaps = False
|
y_overlaps = False
|
||||||
|
|
@ -77,6 +90,7 @@ class pin_layout:
|
||||||
y_overlaps = True
|
y_overlaps = True
|
||||||
|
|
||||||
return x_overlaps and y_overlaps
|
return x_overlaps and y_overlaps
|
||||||
|
|
||||||
def height(self):
|
def height(self):
|
||||||
""" Return height. Abs is for pre-normalized value."""
|
""" Return height. Abs is for pre-normalized value."""
|
||||||
return abs(self.rect[1].y-self.rect[0].y)
|
return abs(self.rect[1].y-self.rect[0].y)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ class router:
|
||||||
|
|
||||||
# all the paths we've routed so far (to supplement the blockages)
|
# all the paths we've routed so far (to supplement the blockages)
|
||||||
self.paths = []
|
self.paths = []
|
||||||
self.wave_paths = []
|
|
||||||
|
|
||||||
# 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)
|
||||||
|
|
@ -562,15 +561,15 @@ class router:
|
||||||
|
|
||||||
# convert the path back to absolute units from tracks
|
# convert the path back to absolute units from tracks
|
||||||
abs_path = [self.convert_wave_to_units(i) for i in path]
|
abs_path = [self.convert_wave_to_units(i) for i in path]
|
||||||
debug.info(1,str(abs_path))
|
#debug.info(1,str(abs_path))
|
||||||
if self.is_wave(path):
|
ur = abs_path[-1][-1]
|
||||||
ur = abs_path[-1][-1]
|
ll = abs_path[0][0]
|
||||||
ll = abs_path[0][0]
|
pin = self.cell.add_layout_pin(name,
|
||||||
self.cell.add_layout_pin(name,
|
layer=self.get_layer(ll.z),
|
||||||
layer=self.get_layer(ll.z),
|
offset=vector(ll.x,ll.y),
|
||||||
offset=vector(ll.x,ll.y),
|
width=ur.x-ll.x,
|
||||||
width=ur.x-ll.x,
|
height=ur.y-ll.y)
|
||||||
height=ur.y-ll.y)
|
return pin
|
||||||
|
|
||||||
|
|
||||||
def get_inertia(self,p0,p1):
|
def get_inertia(self,p0,p1):
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ class supply_grid(grid.grid):
|
||||||
p.reset()
|
p.reset()
|
||||||
|
|
||||||
|
|
||||||
def start_wave(self, loc, width):
|
def find_horizontal_start_wave(self, loc, width):
|
||||||
"""
|
"""
|
||||||
Finds the first loc starting at loc and to the right that is open.
|
Finds the first loc starting at loc and to the right that is open.
|
||||||
Returns false if it reaches max size first.
|
Returns None if it reaches max size first.
|
||||||
"""
|
"""
|
||||||
wave = [loc+vector3d(0,i,0) for i in range(width)]
|
wave = [loc+vector3d(0,i,0) for i in range(width)]
|
||||||
self.width = width
|
self.width = width
|
||||||
|
|
@ -37,11 +37,35 @@ class supply_grid(grid.grid):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Increment while the wave is blocked
|
# Increment while the wave is blocked
|
||||||
while self.is_wave_blocked(wave):
|
if self.is_wave_blocked(wave):
|
||||||
# Or until we cannot increment further
|
while wave:
|
||||||
if not self.increment_wave(wave):
|
wave=self.increment_east_wave(wave)
|
||||||
return None
|
if not self.is_wave_blocked(wave):
|
||||||
|
return wave
|
||||||
|
|
||||||
|
# This may return None
|
||||||
|
return wave
|
||||||
|
|
||||||
|
def find_vertical_start_wave(self, loc, width):
|
||||||
|
"""
|
||||||
|
Finds the first loc starting at loc and up that is open.
|
||||||
|
Returns None if it reaches max size first.
|
||||||
|
"""
|
||||||
|
wave = [loc+vector3d(i,0,1) for i in range(width)]
|
||||||
|
self.width = width
|
||||||
|
|
||||||
|
# Don't expand outside the bounding box
|
||||||
|
if wave[0].x > self.ur.x:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Increment while the wave is blocked
|
||||||
|
if self.is_wave_blocked(wave):
|
||||||
|
while wave:
|
||||||
|
wave=self.increment_up_wave(wave)
|
||||||
|
if not self.is_wave_blocked(wave):
|
||||||
|
return wave
|
||||||
|
|
||||||
|
# This may return None
|
||||||
return wave
|
return wave
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -57,7 +81,7 @@ class supply_grid(grid.grid):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def increment_wave(self, wave):
|
def increment_east_wave(self, wave):
|
||||||
"""
|
"""
|
||||||
Increment the head by moving one step right. Return
|
Increment the head by moving one step right. Return
|
||||||
new wave if successful.
|
new wave if successful.
|
||||||
|
|
@ -68,11 +92,22 @@ class supply_grid(grid.grid):
|
||||||
if new_wave[0].x>self.ur.x:
|
if new_wave[0].x>self.ur.x:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not self.is_wave_blocked(new_wave):
|
return new_wave
|
||||||
return new_wave
|
|
||||||
return None
|
|
||||||
|
|
||||||
def probe_wave(self, wave):
|
def increment_up_wave(self, wave):
|
||||||
|
"""
|
||||||
|
Increment the head by moving one step up. Return
|
||||||
|
new wave if successful.
|
||||||
|
"""
|
||||||
|
new_wave = [v+vector3d(0,1,0) for v in wave]
|
||||||
|
|
||||||
|
# Don't expand outside the bounding box
|
||||||
|
if new_wave[0].y>self.ur.y:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return new_wave
|
||||||
|
|
||||||
|
def probe_east_wave(self, wave):
|
||||||
"""
|
"""
|
||||||
Expand the wave until there is a blockage and return
|
Expand the wave until there is a blockage and return
|
||||||
the wave path.
|
the wave path.
|
||||||
|
|
@ -80,7 +115,19 @@ class supply_grid(grid.grid):
|
||||||
wave_path = []
|
wave_path = []
|
||||||
while wave and not self.is_wave_blocked(wave):
|
while wave and not self.is_wave_blocked(wave):
|
||||||
wave_path.append(wave)
|
wave_path.append(wave)
|
||||||
wave = self.increment_wave(wave)
|
wave = self.increment_east_wave(wave)
|
||||||
|
|
||||||
|
return wave_path
|
||||||
|
|
||||||
|
def probe_up_wave(self, wave):
|
||||||
|
"""
|
||||||
|
Expand the wave until there is a blockage and return
|
||||||
|
the wave path.
|
||||||
|
"""
|
||||||
|
wave_path = []
|
||||||
|
while wave and not self.is_wave_blocked(wave):
|
||||||
|
wave_path.append(wave)
|
||||||
|
wave = self.increment_up_wave(wave)
|
||||||
|
|
||||||
return wave_path
|
return wave_path
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ class supply_router(router):
|
||||||
"""
|
"""
|
||||||
router.__init__(self, gds_name, module)
|
router.__init__(self, gds_name, module)
|
||||||
|
|
||||||
|
|
||||||
def create_routing_grid(self):
|
def create_routing_grid(self):
|
||||||
"""
|
"""
|
||||||
Create a sprase routing grid with A* expansion functions.
|
Create a sprase routing grid with A* expansion functions.
|
||||||
|
|
@ -89,21 +90,96 @@ class supply_router(router):
|
||||||
Add supply rails for vdd and gnd alternating in both layers.
|
Add supply rails for vdd and gnd alternating in both layers.
|
||||||
Connect cross-over points with vias.
|
Connect cross-over points with vias.
|
||||||
"""
|
"""
|
||||||
# vdd will be the odd grids
|
# width in grid units
|
||||||
vdd_rails = self.route_supply_rail(name="vdd",offset=0,width=2)
|
width = 2
|
||||||
|
|
||||||
# gnd will be the even grids (0 + width)
|
# List of all the rails
|
||||||
gnd_rails = self.route_supply_rail(name="gnd",offset=0,width=2)
|
self.rails = []
|
||||||
|
self.wave_paths = []
|
||||||
|
|
||||||
pass
|
# vdd will be the even grids every 2 widths
|
||||||
|
for offset in range(0, self.rg.ur.y, 2*width):
|
||||||
|
loc = vector3d(0,offset,0)
|
||||||
|
# While we can keep expanding east
|
||||||
|
while loc and loc.x < self.rg.ur.x:
|
||||||
|
loc = self.route_horizontal_supply_rail("vdd",loc,width)
|
||||||
|
|
||||||
def route_supply_rail(self, name, offset=0, width=1):
|
# gnd will be the odd grids every 2 widths
|
||||||
|
for offset in range(width, self.rg.ur.y, 2*width):
|
||||||
|
loc = vector3d(0,offset,0)
|
||||||
|
# While we can keep expanding east
|
||||||
|
while loc and loc.x < self.rg.ur.x:
|
||||||
|
loc = self.route_horizontal_supply_rail("gnd",loc,width)
|
||||||
|
|
||||||
|
# vdd will be the even grids every 2 widths
|
||||||
|
for offset in range(0, self.rg.ur.x, 2*width):
|
||||||
|
loc = vector3d(offset,0,0)
|
||||||
|
# While we can keep expanding up
|
||||||
|
while loc and loc.y < self.rg.ur.y:
|
||||||
|
loc = self.route_vertical_supply_rail("vdd",loc,width)
|
||||||
|
|
||||||
|
# gnd will be the odd grids every 2 widths
|
||||||
|
for offset in range(width, self.rg.ur.x, 2*width):
|
||||||
|
loc = vector3d(offset,0,0)
|
||||||
|
# While we can keep expanding up
|
||||||
|
while loc and loc.y < self.rg.ur.y:
|
||||||
|
loc = self.route_vertical_supply_rail("gnd",loc,width)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def route_horizontal_supply_rail(self, name, loc, width):
|
||||||
"""
|
"""
|
||||||
Add supply rails alternating layers.
|
Add supply rails alternating layers.
|
||||||
|
Return the final wavefront for seeding the next wave.
|
||||||
"""
|
"""
|
||||||
wave = self.rg.start_wave(loc=vector3d(0,offset,0), width=width)
|
# Sweep to find an initial wave
|
||||||
wave_path = self.rg.probe_wave(wave)
|
start_wave = self.rg.find_horizontal_start_wave(loc, width)
|
||||||
self.add_wave(name, wave_path)
|
if not start_wave:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Expand the wave to the right
|
||||||
|
wave_path = self.rg.probe_east_wave(start_wave)
|
||||||
|
if not wave_path:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Filter single unit paths
|
||||||
|
# FIXME: Should we filter bigger sizes?
|
||||||
|
if len(wave_path)>1:
|
||||||
|
new_pin = self.add_wave(name, wave_path)
|
||||||
|
self.rails.append(new_pin)
|
||||||
|
self.wave_paths.append(wave_path)
|
||||||
|
|
||||||
|
# seed the next start wave location
|
||||||
|
wave_end = wave_path[-1]
|
||||||
|
next_seed = wave_end[0]+vector3d(1,0,0)
|
||||||
|
return next_seed
|
||||||
|
|
||||||
|
def route_vertical_supply_rail(self, name, loc, width):
|
||||||
|
"""
|
||||||
|
Add supply rails alternating layers.
|
||||||
|
Return the final wavefront for seeding the next wave.
|
||||||
|
"""
|
||||||
|
# Sweep to find an initial wave
|
||||||
|
start_wave = self.rg.find_vertical_start_wave(loc, width)
|
||||||
|
if not start_wave:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Expand the wave to the right
|
||||||
|
wave_path = self.rg.probe_up_wave(start_wave)
|
||||||
|
if not wave_path:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Filter single unit paths
|
||||||
|
# FIXME: Should we filter bigger sizes?
|
||||||
|
if len(wave_path)>1:
|
||||||
|
new_pin = self.add_wave(name, wave_path)
|
||||||
|
self.rails.append(new_pin)
|
||||||
|
self.wave_paths.append(wave_path)
|
||||||
|
|
||||||
|
# seed the next start wave location
|
||||||
|
wave_end = wave_path[-1]
|
||||||
|
next_seed = wave_end[0]+vector3d(0,1,0)
|
||||||
|
return next_seed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -129,31 +205,31 @@ class supply_router(router):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def add_route(self,path):
|
# def add_route(self,path):
|
||||||
"""
|
# """
|
||||||
Add the current wire route to the given design instance.
|
# Add the current wire route to the given design instance.
|
||||||
"""
|
# """
|
||||||
debug.info(3,"Set path: " + str(path))
|
# debug.info(3,"Set path: " + str(path))
|
||||||
|
|
||||||
# Keep track of path for future blockages
|
# # Keep track of path for future blockages
|
||||||
self.paths.append(path)
|
# self.paths.append(path)
|
||||||
|
|
||||||
# This is marked for debug
|
# # This is marked for debug
|
||||||
self.rg.add_path(path)
|
# self.rg.add_path(path)
|
||||||
|
|
||||||
# For debugging... if the path failed to route.
|
# # For debugging... if the path failed to route.
|
||||||
if False or path==None:
|
# if False or path==None:
|
||||||
self.write_debug_gds()
|
# self.write_debug_gds()
|
||||||
|
|
||||||
# First, simplify the path for
|
# # First, simplify the path for
|
||||||
#debug.info(1,str(self.path))
|
# #debug.info(1,str(self.path))
|
||||||
contracted_path = self.contract_path(path)
|
# contracted_path = self.contract_path(path)
|
||||||
debug.info(1,str(contracted_path))
|
# debug.info(1,str(contracted_path))
|
||||||
|
|
||||||
# convert the path back to absolute units from tracks
|
# # convert the path back to absolute units from tracks
|
||||||
abs_path = map(self.convert_point_to_units,contracted_path)
|
# abs_path = map(self.convert_point_to_units,contracted_path)
|
||||||
debug.info(1,str(abs_path))
|
# debug.info(1,str(abs_path))
|
||||||
self.cell.add_route(self.layers,abs_path)
|
# self.cell.add_route(self.layers,abs_path)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue