mirror of https://github.com/VLSIDA/OpenRAM.git
Horizontal and vertical grid wires done.
This commit is contained in:
parent
cd987479b8
commit
c2c17a33d2
|
|
@ -54,11 +54,24 @@ class pin_layout:
|
|||
newur = ur + spacing
|
||||
|
||||
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):
|
||||
""" Check if a shape overlaps with a rectangle """
|
||||
(ll,ur) = self.rect
|
||||
(oll,our) = other.rect
|
||||
|
||||
# Start assuming no overlaps
|
||||
x_overlaps = False
|
||||
y_overlaps = False
|
||||
|
|
@ -77,6 +90,7 @@ class pin_layout:
|
|||
y_overlaps = True
|
||||
|
||||
return x_overlaps and y_overlaps
|
||||
|
||||
def height(self):
|
||||
""" Return height. Abs is for pre-normalized value."""
|
||||
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)
|
||||
self.paths = []
|
||||
self.wave_paths = []
|
||||
|
||||
# The boundary will determine the limits to the size of the routing grid
|
||||
self.boundary = self.layout.measureBoundary(self.top_name)
|
||||
|
|
@ -562,15 +561,15 @@ class router:
|
|||
|
||||
# convert the path back to absolute units from tracks
|
||||
abs_path = [self.convert_wave_to_units(i) for i in path]
|
||||
debug.info(1,str(abs_path))
|
||||
if self.is_wave(path):
|
||||
ur = abs_path[-1][-1]
|
||||
ll = abs_path[0][0]
|
||||
self.cell.add_layout_pin(name,
|
||||
layer=self.get_layer(ll.z),
|
||||
offset=vector(ll.x,ll.y),
|
||||
width=ur.x-ll.x,
|
||||
height=ur.y-ll.y)
|
||||
#debug.info(1,str(abs_path))
|
||||
ur = abs_path[-1][-1]
|
||||
ll = abs_path[0][0]
|
||||
pin = self.cell.add_layout_pin(name,
|
||||
layer=self.get_layer(ll.z),
|
||||
offset=vector(ll.x,ll.y),
|
||||
width=ur.x-ll.x,
|
||||
height=ur.y-ll.y)
|
||||
return pin
|
||||
|
||||
|
||||
def get_inertia(self,p0,p1):
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ class supply_grid(grid.grid):
|
|||
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.
|
||||
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)]
|
||||
self.width = width
|
||||
|
|
@ -37,13 +37,37 @@ class supply_grid(grid.grid):
|
|||
return None
|
||||
|
||||
# Increment while the wave is blocked
|
||||
while self.is_wave_blocked(wave):
|
||||
# Or until we cannot increment further
|
||||
if not self.increment_wave(wave):
|
||||
return None
|
||||
|
||||
if self.is_wave_blocked(wave):
|
||||
while wave:
|
||||
wave=self.increment_east_wave(wave)
|
||||
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
|
||||
|
||||
|
||||
def is_wave_blocked(self, 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
|
||||
new wave if successful.
|
||||
|
|
@ -68,11 +92,22 @@ class supply_grid(grid.grid):
|
|||
if new_wave[0].x>self.ur.x:
|
||||
return None
|
||||
|
||||
if not self.is_wave_blocked(new_wave):
|
||||
return new_wave
|
||||
return None
|
||||
return new_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
|
||||
|
||||
def probe_wave(self, wave):
|
||||
return new_wave
|
||||
|
||||
def probe_east_wave(self, wave):
|
||||
"""
|
||||
Expand the wave until there is a blockage and return
|
||||
the wave path.
|
||||
|
|
@ -80,7 +115,19 @@ class supply_grid(grid.grid):
|
|||
wave_path = []
|
||||
while wave and not self.is_wave_blocked(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
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class supply_router(router):
|
|||
layers for the layers to route on
|
||||
"""
|
||||
router.__init__(self, gds_name, module)
|
||||
|
||||
|
||||
def create_routing_grid(self):
|
||||
"""
|
||||
|
|
@ -89,25 +90,100 @@ class supply_router(router):
|
|||
Add supply rails for vdd and gnd alternating in both layers.
|
||||
Connect cross-over points with vias.
|
||||
"""
|
||||
# vdd will be the odd grids
|
||||
vdd_rails = self.route_supply_rail(name="vdd",offset=0,width=2)
|
||||
|
||||
# gnd will be the even grids (0 + width)
|
||||
gnd_rails = self.route_supply_rail(name="gnd",offset=0,width=2)
|
||||
# width in grid units
|
||||
width = 2
|
||||
|
||||
# List of all the rails
|
||||
self.rails = []
|
||||
self.wave_paths = []
|
||||
|
||||
# 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)
|
||||
|
||||
# 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)
|
||||
|
||||
|
||||
pass
|
||||
|
||||
def route_supply_rail(self, name, offset=0, width=1):
|
||||
def route_horizontal_supply_rail(self, name, loc, width):
|
||||
"""
|
||||
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)
|
||||
wave_path = self.rg.probe_wave(wave)
|
||||
self.add_wave(name, wave_path)
|
||||
|
||||
|
||||
|
||||
|
||||
# Sweep to find an initial wave
|
||||
start_wave = self.rg.find_horizontal_start_wave(loc, width)
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def route_supply_pins(self, pin):
|
||||
"""
|
||||
|
|
@ -129,31 +205,31 @@ class supply_router(router):
|
|||
pass
|
||||
|
||||
|
||||
def add_route(self,path):
|
||||
"""
|
||||
Add the current wire route to the given design instance.
|
||||
"""
|
||||
debug.info(3,"Set path: " + str(path))
|
||||
# def add_route(self,path):
|
||||
# """
|
||||
# Add the current wire route to the given design instance.
|
||||
# """
|
||||
# debug.info(3,"Set path: " + str(path))
|
||||
|
||||
# Keep track of path for future blockages
|
||||
self.paths.append(path)
|
||||
# # Keep track of path for future blockages
|
||||
# self.paths.append(path)
|
||||
|
||||
# This is marked for debug
|
||||
self.rg.add_path(path)
|
||||
# # This is marked for debug
|
||||
# self.rg.add_path(path)
|
||||
|
||||
# For debugging... if the path failed to route.
|
||||
if False or path==None:
|
||||
self.write_debug_gds()
|
||||
# # For debugging... if the path failed to route.
|
||||
# if False or path==None:
|
||||
# self.write_debug_gds()
|
||||
|
||||
# First, simplify the path for
|
||||
#debug.info(1,str(self.path))
|
||||
contracted_path = self.contract_path(path)
|
||||
debug.info(1,str(contracted_path))
|
||||
# # First, simplify the path for
|
||||
# #debug.info(1,str(self.path))
|
||||
# contracted_path = self.contract_path(path)
|
||||
# debug.info(1,str(contracted_path))
|
||||
|
||||
# convert the path back to absolute units from tracks
|
||||
abs_path = map(self.convert_point_to_units,contracted_path)
|
||||
debug.info(1,str(abs_path))
|
||||
self.cell.add_route(self.layers,abs_path)
|
||||
# # convert the path back to absolute units from tracks
|
||||
# abs_path = map(self.convert_point_to_units,contracted_path)
|
||||
# debug.info(1,str(abs_path))
|
||||
# self.cell.add_route(self.layers,abs_path)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue