mirror of https://github.com/VLSIDA/OpenRAM.git
Starting single layer power router.
This commit is contained in:
parent
bd4d965e37
commit
7b8c2cac30
|
|
@ -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_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)
|
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.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.m1_space + inverter_pmos_contact_extension
|
||||||
self.cross_couple_lower_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height \
|
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) \
|
+ max(self.poly_to_active, self.m1_space + inverter_nmos_contact_extension) \
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class grid:
|
||||||
self.add_map(vector3d(x,y,1))
|
self.add_map(vector3d(x,y,1))
|
||||||
|
|
||||||
def set_blocked(self,n,value=True):
|
def set_blocked(self,n,value=True):
|
||||||
if isinstance(n, (list,tuple,set,frozenset)):
|
if not isinstance(n, vector3d):
|
||||||
for item in n:
|
for item in n:
|
||||||
self.set_blocked(item,value)
|
self.set_blocked(item,value)
|
||||||
else:
|
else:
|
||||||
|
|
@ -58,7 +58,7 @@ class grid:
|
||||||
self.map[n].blocked=value
|
self.map[n].blocked=value
|
||||||
|
|
||||||
def is_blocked(self,n):
|
def is_blocked(self,n):
|
||||||
if isinstance(n, (list,tuple,set,frozenset)):
|
if not isinstance(n, vector3d):
|
||||||
for item in n:
|
for item in n:
|
||||||
if self.is_blocked(item):
|
if self.is_blocked(item):
|
||||||
return True
|
return True
|
||||||
|
|
@ -82,7 +82,7 @@ class grid:
|
||||||
self.map[k].blocked=False
|
self.map[k].blocked=False
|
||||||
|
|
||||||
def set_source(self,n,value=True):
|
def set_source(self,n,value=True):
|
||||||
if isinstance(n, (list,tuple,set,frozenset)):
|
if not isinstance(n, vector3d):
|
||||||
for item in n:
|
for item in n:
|
||||||
self.set_source(item,value)
|
self.set_source(item,value)
|
||||||
else:
|
else:
|
||||||
|
|
@ -91,7 +91,7 @@ class grid:
|
||||||
self.source.add(n)
|
self.source.add(n)
|
||||||
|
|
||||||
def set_target(self,n,value=True):
|
def set_target(self,n,value=True):
|
||||||
if isinstance(n, (list,tuple,set,frozenset)):
|
if not isinstance(n, vector3d):
|
||||||
for item in n:
|
for item in n:
|
||||||
self.set_target(item,value)
|
self.set_target(item,value)
|
||||||
else:
|
else:
|
||||||
|
|
@ -125,7 +125,7 @@ class grid:
|
||||||
"""
|
"""
|
||||||
Add a point to the map if it doesn't exist.
|
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:
|
for item in n:
|
||||||
self.add_map(item)
|
self.add_map(item)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -36,16 +36,21 @@ class grid_cell:
|
||||||
|
|
||||||
|
|
||||||
def get_type(self):
|
def get_type(self):
|
||||||
|
type_string = ""
|
||||||
|
|
||||||
if self.blocked:
|
if self.blocked:
|
||||||
return "X"
|
type_string += "X"
|
||||||
|
|
||||||
if self.source:
|
if self.source:
|
||||||
return "S"
|
type_string += "S"
|
||||||
|
|
||||||
if self.target:
|
if self.target:
|
||||||
return "T"
|
type_string += "T"
|
||||||
|
|
||||||
if self.path:
|
if self.path:
|
||||||
return "P"
|
type_string += "P"
|
||||||
|
|
||||||
|
if type_string != "":
|
||||||
|
return type_string
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -668,7 +668,10 @@ class router(router_tech):
|
||||||
track.
|
track.
|
||||||
"""
|
"""
|
||||||
# to scale coordinates to tracks
|
# 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
|
y = track[1]*self.track_width - 0.5*self.track_width
|
||||||
# offset lowest corner object to to (-track halo,-track halo)
|
# offset lowest corner object to to (-track halo,-track halo)
|
||||||
ll = snap_to_grid(vector(x,y))
|
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.
|
This will mark only the pin tracks from the indexed pin component as a target.
|
||||||
It also unsets it as a blockage.
|
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
|
pin_in_tracks = self.pin_groups[pin_name][index].grids
|
||||||
debug.info(2,"Set target: " + str(pin_name) + " " + str(pin_in_tracks))
|
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
|
# This assumes 1-track wide again
|
||||||
abs_path = [self.convert_point_to_units(x[0]) for x in path]
|
abs_path = [self.convert_point_to_units(x[0]) for x in path]
|
||||||
# Otherwise, add the route which includes enclosures
|
# Otherwise, add the route which includes enclosures
|
||||||
self.cell.add_route(layers=self.layers,
|
if len(self.layers)>1:
|
||||||
coordinates=abs_path,
|
self.cell.add_route(layers=self.layers,
|
||||||
layer_widths=self.layer_widths)
|
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):
|
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.
|
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
|
# returns the path in tracks
|
||||||
(path,cost) = self.rg.route(detour_scale)
|
(path,cost) = self.rg.route(detour_scale)
|
||||||
if path:
|
if path:
|
||||||
debug.info(2,"Found path: cost={0} ".format(cost))
|
debug.info(1,"Found path: cost={0} ".format(cost))
|
||||||
debug.info(3,str(path))
|
debug.info(1,str(path))
|
||||||
|
|
||||||
self.paths.append(path)
|
self.paths.append(path)
|
||||||
self.add_route(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.
|
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))
|
debug.info(0,"Writing annotated router gds file to {}".format(gds_name))
|
||||||
|
self.del_router_info()
|
||||||
self.add_router_info()
|
self.add_router_info()
|
||||||
self.cell.gds_write(gds_name)
|
self.cell.gds_write(gds_name)
|
||||||
|
|
||||||
|
|
@ -1062,6 +1078,15 @@ class router(router_tech):
|
||||||
offset=shape[0],
|
offset=shape[0],
|
||||||
zoom=0.05)
|
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):
|
def add_router_info(self):
|
||||||
"""
|
"""
|
||||||
Write the routing grid and router cost, blockage, pins on
|
Write the routing grid and router cost, blockage, pins on
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class router_tech:
|
||||||
"""
|
"""
|
||||||
self.layers = layers
|
self.layers = layers
|
||||||
self.rail_track_width = rail_track_width
|
self.rail_track_width = rail_track_width
|
||||||
print(self.layers,len(self.layers))
|
|
||||||
if len(self.layers)==1:
|
if len(self.layers)==1:
|
||||||
self.horiz_layer_name = self.vert_layer_name = self.layers[0]
|
self.horiz_layer_name = self.vert_layer_name = self.layers[0]
|
||||||
self.horiz_layer_number = self.vert_layer_number = layer[self.layers[0]]
|
self.horiz_layer_number = self.vert_layer_number = layer[self.layers[0]]
|
||||||
|
|
|
||||||
|
|
@ -74,13 +74,14 @@ class supply_tree_router(router):
|
||||||
# Block everything
|
# Block everything
|
||||||
self.prepare_blockages(self.gnd_name)
|
self.prepare_blockages(self.gnd_name)
|
||||||
self.prepare_blockages(self.vdd_name)
|
self.prepare_blockages(self.vdd_name)
|
||||||
|
|
||||||
# Route the supply pins to the supply rails
|
# Route the supply pins to the supply rails
|
||||||
# Route vdd first since we want it to be shorter
|
# Route vdd first since we want it to be shorter
|
||||||
start_time = datetime.now()
|
start_time = datetime.now()
|
||||||
self.route_pins(vdd_name)
|
self.route_pins(vdd_name)
|
||||||
self.route_pins(gnd_name)
|
self.route_pins(gnd_name)
|
||||||
print_time("Maze routing supplies",datetime.now(), start_time, 3)
|
print_time("Maze routing supplies",datetime.now(), start_time, 3)
|
||||||
|
|
||||||
#self.write_debug_gds("final.gds",False)
|
#self.write_debug_gds("final.gds",False)
|
||||||
|
|
||||||
# Did we route everything??
|
# Did we route everything??
|
||||||
|
|
@ -147,7 +148,7 @@ class supply_tree_router(router):
|
||||||
if pg.is_routed():
|
if pg.is_routed():
|
||||||
continue
|
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.
|
# Clear everything in the routing grid.
|
||||||
self.rg.reinit()
|
self.rg.reinit()
|
||||||
|
|
@ -159,13 +160,29 @@ class supply_tree_router(router):
|
||||||
# Add the single component of the pin as the source
|
# Add the single component of the pin as the source
|
||||||
# which unmarks it as a blockage too
|
# which unmarks it as a blockage too
|
||||||
self.add_pin_component_source(pin_name,index)
|
self.add_pin_component_source(pin_name,index)
|
||||||
|
|
||||||
# Marks all pin components except index as target
|
# Marks all pin components except index as target
|
||||||
self.add_pin_component_target_except(pin_name,index)
|
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
|
# Actually run the A* router
|
||||||
if not self.run_router(detour_scale=5):
|
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":
|
#if index==3 and pin_name=="vdd":
|
||||||
# self.write_debug_gds("route.gds",False)
|
# self.write_debug_gds("route.gds",False)
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@
|
||||||
#
|
#
|
||||||
import debug
|
import debug
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
from importlib import reload
|
|
||||||
|
|
||||||
|
|
||||||
class sram_factory:
|
class sram_factory:
|
||||||
"""
|
"""
|
||||||
|
|
@ -54,7 +52,8 @@ class sram_factory:
|
||||||
try:
|
try:
|
||||||
mod = self.modules[module_type]
|
mod = self.modules[module_type]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
c = reload(__import__(module_name))
|
import importlib
|
||||||
|
c = importlib.reload(__import__(module_name))
|
||||||
mod = getattr(c, module_name)
|
mod = getattr(c, module_name)
|
||||||
self.modules[module_type] = mod
|
self.modules[module_type] = mod
|
||||||
self.module_indices[module_type] = 0
|
self.module_indices[module_type] = 0
|
||||||
|
|
|
||||||
|
|
@ -281,6 +281,7 @@ class openram_test(unittest.TestCase):
|
||||||
debug.info(2,"MATCH {0} {1}".format(filename1,filename2))
|
debug.info(2,"MATCH {0} {1}".format(filename1,filename2))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def header(filename, technology):
|
def header(filename, technology):
|
||||||
# Skip the header for gitlab regression
|
# Skip the header for gitlab regression
|
||||||
import getpass
|
import getpass
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue