Horizontal and vertical grid wires done.

This commit is contained in:
Matt Guthaus 2018-09-06 14:30:59 -07:00
parent cd987479b8
commit c2c17a33d2
4 changed files with 196 additions and 60 deletions

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -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)