Starting single layer power router.

This commit is contained in:
mrg 2019-05-31 08:43:37 -07:00
parent bd4d965e37
commit 7b8c2cac30
8 changed files with 73 additions and 26 deletions

View File

@ -221,7 +221,7 @@ class pbitcell(design.design):
inverter_pmos_contact_extension = 0.5*(self.inverter_pmos.active_contact.height - self.inverter_pmos.active_height)
inverter_nmos_contact_extension = 0.5*(self.inverter_nmos.active_contact.height - self.inverter_nmos.active_height)
self.inverter_gap = max(self.poly_to_active, self.m1_space + inverter_nmos_contact_extension) \
+ self.poly_to_polycontact + 2*contact.poly.height \
+ self.poly_to_polycontact + 2*contact.poly.width \
+ self.m1_space + inverter_pmos_contact_extension
self.cross_couple_lower_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height \
+ max(self.poly_to_active, self.m1_space + inverter_nmos_contact_extension) \

View File

@ -50,7 +50,7 @@ class grid:
self.add_map(vector3d(x,y,1))
def set_blocked(self,n,value=True):
if isinstance(n, (list,tuple,set,frozenset)):
if not isinstance(n, vector3d):
for item in n:
self.set_blocked(item,value)
else:
@ -58,7 +58,7 @@ class grid:
self.map[n].blocked=value
def is_blocked(self,n):
if isinstance(n, (list,tuple,set,frozenset)):
if not isinstance(n, vector3d):
for item in n:
if self.is_blocked(item):
return True
@ -82,7 +82,7 @@ class grid:
self.map[k].blocked=False
def set_source(self,n,value=True):
if isinstance(n, (list,tuple,set,frozenset)):
if not isinstance(n, vector3d):
for item in n:
self.set_source(item,value)
else:
@ -91,7 +91,7 @@ class grid:
self.source.add(n)
def set_target(self,n,value=True):
if isinstance(n, (list,tuple,set,frozenset)):
if not isinstance(n, vector3d):
for item in n:
self.set_target(item,value)
else:
@ -125,7 +125,7 @@ class grid:
"""
Add a point to the map if it doesn't exist.
"""
if isinstance(n, (list,tuple,set,frozenset)):
if not isinstance(n, vector3d):
for item in n:
self.add_map(item)
else:

View File

@ -36,16 +36,21 @@ class grid_cell:
def get_type(self):
type_string = ""
if self.blocked:
return "X"
type_string += "X"
if self.source:
return "S"
type_string += "S"
if self.target:
return "T"
type_string += "T"
if self.path:
return "P"
type_string += "P"
if type_string != "":
return type_string
return None

View File

@ -668,7 +668,10 @@ class router(router_tech):
track.
"""
# to scale coordinates to tracks
x = track[0]*self.track_width - 0.5*self.track_width
try:
x = track[0]*self.track_width - 0.5*self.track_width
except TypeError:
print(track[0],type(track[0]),self.track_width,type(self.track_width))
y = track[1]*self.track_width - 0.5*self.track_width
# offset lowest corner object to to (-track halo,-track halo)
ll = snap_to_grid(vector(x,y))
@ -832,7 +835,7 @@ class router(router_tech):
This will mark only the pin tracks from the indexed pin component as a target.
It also unsets it as a blockage.
"""
debug.check(index<self.num_pin_grids(pin_name),"Pin component index too large.")
debug.check(index<self.num_pin_components(pin_name),"Pin component index too large.")
pin_in_tracks = self.pin_groups[pin_name][index].grids
debug.info(2,"Set target: " + str(pin_name) + " " + str(pin_in_tracks))
@ -894,9 +897,14 @@ class router(router_tech):
# This assumes 1-track wide again
abs_path = [self.convert_point_to_units(x[0]) for x in path]
# Otherwise, add the route which includes enclosures
self.cell.add_route(layers=self.layers,
coordinates=abs_path,
layer_widths=self.layer_widths)
if len(self.layers)>1:
self.cell.add_route(layers=self.layers,
coordinates=abs_path,
layer_widths=self.layer_widths)
else:
self.cell.add_path(layer=self.layers[0],
coordinates=abs_path,
width=self.layer_widths[0])
def add_single_enclosure(self, track):
"""
@ -965,12 +973,19 @@ class router(router_tech):
"""
This assumes the blockages, source, and target are all set up.
"""
# Double check source and taget are not same node, if so, we are done!
for k,v in self.rg.map.items():
if v.source and v.target:
debug.error("Grid cell is source and target! {}".format(k))
return False
# returns the path in tracks
(path,cost) = self.rg.route(detour_scale)
if path:
debug.info(2,"Found path: cost={0} ".format(cost))
debug.info(3,str(path))
debug.info(1,"Found path: cost={0} ".format(cost))
debug.info(1,str(path))
self.paths.append(path)
self.add_route(path)
@ -1011,6 +1026,7 @@ class router(router_tech):
Write out a GDS file with the routing grid and search information annotated on it.
"""
debug.info(0,"Writing annotated router gds file to {}".format(gds_name))
self.del_router_info()
self.add_router_info()
self.cell.gds_write(gds_name)
@ -1062,6 +1078,15 @@ class router(router_tech):
offset=shape[0],
zoom=0.05)
def del_router_info(self):
"""
Erase all of the comments on the current level.
"""
debug.info(0,"Erasing router info")
layer_num = techlayer["text"]
self.cell.objs = [x for x in self.cell.objs if x.layerNumber != layer_num]
def add_router_info(self):
"""
Write the routing grid and router cost, blockage, pins on

View File

@ -24,7 +24,7 @@ class router_tech:
"""
self.layers = layers
self.rail_track_width = rail_track_width
print(self.layers,len(self.layers))
if len(self.layers)==1:
self.horiz_layer_name = self.vert_layer_name = self.layers[0]
self.horiz_layer_number = self.vert_layer_number = layer[self.layers[0]]

View File

@ -74,13 +74,14 @@ class supply_tree_router(router):
# Block everything
self.prepare_blockages(self.gnd_name)
self.prepare_blockages(self.vdd_name)
# Route the supply pins to the supply rails
# Route vdd first since we want it to be shorter
start_time = datetime.now()
self.route_pins(vdd_name)
self.route_pins(gnd_name)
print_time("Maze routing supplies",datetime.now(), start_time, 3)
#self.write_debug_gds("final.gds",False)
# Did we route everything??
@ -147,7 +148,7 @@ class supply_tree_router(router):
if pg.is_routed():
continue
debug.info(3,"Routing component {0} {1}".format(pin_name, index))
debug.info(1,"Routing component {0} {1}".format(pin_name, index))
# Clear everything in the routing grid.
self.rg.reinit()
@ -159,13 +160,29 @@ class supply_tree_router(router):
# Add the single component of the pin as the source
# which unmarks it as a blockage too
self.add_pin_component_source(pin_name,index)
# Marks all pin components except index as target
self.add_pin_component_target_except(pin_name,index)
# Add the prevous paths as a target too
self.add_path_target(self.paths)
print("SOURCE: ")
for k,v in self.rg.map.items():
if v.source:
print(k)
print("TARGET: ")
for k,v in self.rg.map.items():
if v.target:
print(k)
import pdb; pdb.set_trace()
if index==1:
self.write_debug_gds("debug{}.gds".format(pin_name),False)
# Actually run the A* router
if not self.run_router(detour_scale=5):
self.write_debug_gds("debug_route.gds",False)
self.write_debug_gds("debug_route.gds",True)
#if index==3 and pin_name=="vdd":
# self.write_debug_gds("route.gds",False)

View File

@ -7,8 +7,6 @@
#
import debug
from globals import OPTS
from importlib import reload
class sram_factory:
"""
@ -54,7 +52,8 @@ class sram_factory:
try:
mod = self.modules[module_type]
except KeyError:
c = reload(__import__(module_name))
import importlib
c = importlib.reload(__import__(module_name))
mod = getattr(c, module_name)
self.modules[module_type] = mod
self.module_indices[module_type] = 0

View File

@ -281,6 +281,7 @@ class openram_test(unittest.TestCase):
debug.info(2,"MATCH {0} {1}".format(filename1,filename2))
return True
def header(filename, technology):
# Skip the header for gitlab regression
import getpass