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

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

View File

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

View File

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

View File

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