mirror of https://github.com/VLSIDA/OpenRAM.git
Add supply router to top-level SRAM. Change get_pins to elegantly fail.
This commit is contained in:
parent
83fd2c0512
commit
8499983cc2
|
|
@ -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=""):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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 """
|
||||
|
|
|
|||
|
|
@ -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 """
|
||||
|
|
|
|||
Loading…
Reference in New Issue