Add supply router to top-level SRAM. Change get_pins to elegantly fail.

This commit is contained in:
Matt Guthaus 2018-10-06 08:30:38 -07:00
parent 83fd2c0512
commit 8499983cc2
4 changed files with 37 additions and 98 deletions

View File

@ -192,7 +192,10 @@ class layout(lef.lef):
def get_pins(self, text):
""" Return a pin list (instead of a single pin) """
return self.pin_map[text]
if text in self.pin_map.keys():
return self.pin_map[text]
else:
return []
def copy_layout_pin(self, instance, pin_name, new_name=""):
"""

View File

@ -281,7 +281,7 @@ def setup_paths():
# Add all of the subdirs to the python path
# These subdirs are modules and don't need to be added: characterizer, verify
for subdir in ["gdsMill", "tests", "modules", "base", "pgates", "bitcells"]:
for subdir in ["gdsMill", "tests", "modules", "base", "pgates", "bitcells", "router"]:
full_path = "{0}/{1}".format(OPENRAM_HOME,subdir)
debug.check(os.path.isdir(full_path),
"$OPENRAM_HOME/{0} does not exist: {1}".format(subdir,full_path))

View File

@ -119,8 +119,6 @@ class sram_1bank(sram_base):
self.add_layout_pins()
self.route_vdd_gnd()
self.route_clk()
self.route_control_logic()
@ -172,99 +170,6 @@ class sram_1bank(sram_base):
# the control logic to the bank
self.add_wire(("metal3","via2","metal2"),[row_addr_clk_pos, mid1_pos, mid2_pos, control_clk_buf_pos])
def route_vdd_gnd(self):
""" Propagate all vdd/gnd pins up to this level for all modules """
# These are the instances that every bank has
top_instances = [self.bank_inst,
self.row_addr_dff_inst,
self.data_dff_inst,
self.control_logic_inst[0]]
if self.col_addr_dff:
top_instances.append(self.col_addr_dff_inst)
for inst in top_instances:
self.copy_layout_pin(inst, "vdd")
self.copy_layout_pin(inst, "gnd")
def new_route_vdd_gnd(self):
""" Propagate all vdd/gnd pins up to this level for all modules """
# These are the instances that every bank has
top_instances = [self.bank_inst,
self.row_addr_dff_inst,
self.data_dff_inst,
self.control_logic_inst[0]]
if self.col_addr_dff:
top_instances.append(self.col_addr_dff_inst)
# for inst in top_instances:
# self.copy_layout_pin(inst, "vdd")
# self.copy_layout_pin(inst, "gnd")
blockages=self.get_blockages("metal3", top_level=True)
# Gather all of the vdd/gnd pins
vdd_pins=[]
gnd_pins=[]
for inst in top_instances:
vdd_pins.extend([x for x in inst.get_pins("vdd") if x.layer == "metal3"])
gnd_pins.extend([x for x in inst.get_pins("gnd") if x.layer == "metal3"])
# Create candidate stripes on M3/M4
lowest=self.find_lowest_coords()
highest=self.find_highest_coords()
m3_y_coords = np.arange(lowest[1],highest[1],self.m2_pitch)
# These are the rails that will be available for vdd/gnd
m3_rects = []
# These are the "inflated" shapes for DRC checks
m3_drc_rects = []
for y in m3_y_coords:
# This is just what metal will be drawn
ll = vector(lowest[0], y - 0.5*self.m3_width)
ur = vector(highest[0], y + 0.5*self.m3_width)
m3_rects.append([ll, ur])
# This is a full m3 pitch for DRC conflict checking
ll = vector(lowest[0], y - 0.5*self.m3_pitch )
ur = vector(highest[0], y + 0.5*self.m3_pitch)
m3_drc_rects.append([ll, ur])
vdd_rects = []
gnd_rects = []
# Now, figure how if the rails intersect a blockage, vdd, or gnd pin
# Divide the rails up alternately
# This should be done in less than n^2 using a kd-tree or something
# for drc_rect,rect in zip(m3_drc_rects,m3_rects):
# for b in blockages:
# if rect_overlaps(b,drc_rect):
# break
# else:
# gnd_rects.append(rect)
# Create the vdd and gnd rails
for rect in m3_rects:
(ll,ur) = rect
for rect in gnd_rects:
(ll,ur) = rect
self.add_layout_pin(text="gnd",
layer="metal3",
offset=ll,
width=ur.x-ll.x,
height=ur.y-ll.y)
for rect in vdd_rects:
(ll,ur) = rect
self.add_layout_pin(text="vdd",
layer="metal3",
offset=ll,
width=ur.x-ll.x,
height=ur.y-ll.y)
def route_control_logic(self):
""" Route the outputs from the control logic module """

View File

@ -7,7 +7,7 @@ from vector import vector
from globals import OPTS, print_time
from design import design
class sram_base(design):
"""
Dynamically generated SRAM by connecting banks to control logic. The
@ -80,6 +80,7 @@ class sram_base(design):
""" Layout creation """
self.place_modules()
self.route()
self.supply_route()
self.add_lvs_correspondence_points()
self.offset_all_coordinates()
@ -90,6 +91,36 @@ class sram_base(design):
self.DRC_LVS(final_verification=True)
def route_vdd_gnd_pins(self):
""" Propagate all vdd/gnd pins up to this level for all modules """
#These are the instances that every bank has
top_instances = [self.bank_inst,
self.row_addr_dff_inst,
self.data_dff_inst,
self.control_logic_inst[0]]
if self.col_addr_dff:
top_instances.append(self.col_addr_dff_inst)
for inst in top_instances:
self.copy_layout_pin(inst, "vdd")
self.copy_layout_pin(inst, "gnd")
def supply_route(self):
""" Route the supply grid and connect the pins to them. """
for inst in self.insts:
self.copy_layout_pin(inst, "vdd")
self.copy_layout_pin(inst, "gnd")
from supply_router import supply_router as router
layer_stack =("metal3","via3","metal4")
rtr=router(layer_stack, self)
rtr.route()
def compute_bus_sizes(self):
""" Compute the independent bus widths shared between two and four bank SRAMs """