power ring working

This commit is contained in:
Jesse Cirimelli-Low 2023-08-28 22:15:05 -07:00
parent 8794070ebc
commit 8f2e4c6914
2 changed files with 128 additions and 96 deletions

View File

@ -2157,6 +2157,13 @@ class layout():
# Add the gnd ring
self.add_ring([ll, ur])
def reset_coordinates(self):
ll=vector(min([x.lx() for x in self.insts]),min([y.by() for y in self.insts]))
self.translate_all(ll)
self.width = max([x.rx() for x in self.insts]) - min([x.lx() for x in self.insts])
self.height = max([x.uy() for x in self.insts]) - min([y.by() for y in self.insts])
def add_ring(self, bbox=None, width_mult=8, offset=0):
"""
Add a ring around the bbox
@ -2209,7 +2216,7 @@ class layout():
size=(supply_vias,
supply_vias))
def add_power_ring(self):
def add_power_ring(self, h_layer="m2", v_layer="m1"):
"""
Create vdd and gnd power rings around an area of the bounding box
argument. Must have a supply_rail_width and supply_rail_pitch
@ -2217,42 +2224,42 @@ class layout():
left/right/top/bottom vdd/gnd center offsets for use in other
modules..
"""
[ll, ur] = self.bbox
supply_rail_spacing = self.supply_rail_pitch - self.supply_rail_width
supply_rail_spacing = self.supply_rail_pitch
height = (ur.y - ll.y) + 3 * self.supply_rail_pitch - supply_rail_spacing
width = (ur.x - ll.x) + 3 * self.supply_rail_pitch - supply_rail_spacing
# LEFT vertical rails
offset = ll + vector(-2 * self.supply_rail_pitch,
-2 * self.supply_rail_pitch)
left_gnd_pin = self.add_layout_pin(text="gnd",
layer="m2",
offset = ll + vector(-2*self.supply_rail_pitch,
-2*self.supply_rail_pitch)
self.left_gnd_pin = self.add_layout_pin(text="gnd",
layer=v_layer,
offset=offset,
width=self.supply_rail_width,
height=height)
height=height + 2 * supply_rail_spacing)
offset = ll + vector(-1 * self.supply_rail_pitch,
-1 * self.supply_rail_pitch)
left_vdd_pin = self.add_layout_pin(text="vdd",
layer="m2",
self.left_vdd_pin = self.add_layout_pin(text="vdd",
layer=v_layer,
offset=offset,
width=self.supply_rail_width,
height=height)
# RIGHT vertical rails
offset = vector(ur.x, ll.y) + vector(0, -2 * self.supply_rail_pitch)
right_gnd_pin = self.add_layout_pin(text="gnd",
layer="m2",
# RIGHT vertical railsteac a 460
offset = vector(ur.x, ll.y) + vector(2 * self.supply_rail_pitch - self.supply_rail_width,
-2 * self.supply_rail_pitch)
self.right_gnd_pin = self.add_layout_pin(text="gnd",
layer=v_layer,
offset=offset,
width=self.supply_rail_width,
height=height)
height=height + 2* supply_rail_spacing)
offset = vector(ur.x, ll.y) + vector(self.supply_rail_pitch,
offset = vector(ur.x, ll.y) + vector(1 * self.supply_rail_pitch - self.supply_rail_width,
-1 * self.supply_rail_pitch)
right_vdd_pin = self.add_layout_pin(text="vdd",
layer="m2",
self.right_vdd_pin = self.add_layout_pin(text="vdd",
layer=v_layer,
offset=offset,
width=self.supply_rail_width,
height=height)
@ -2260,47 +2267,47 @@ class layout():
# BOTTOM horizontal rails
offset = ll + vector(-2 * self.supply_rail_pitch,
-2 * self.supply_rail_pitch)
bottom_gnd_pin = self.add_layout_pin(text="gnd",
layer="m1",
self.bottom_gnd_pin = self.add_layout_pin(text="gnd",
layer=h_layer,
offset=offset,
width=width,
width=width + 2 * supply_rail_spacing,
height=self.supply_rail_width)
offset = ll + vector(-1 * self.supply_rail_pitch,
-1 * self.supply_rail_pitch)
bottom_vdd_pin = self.add_layout_pin(text="vdd",
layer="m1",
self.bottom_vdd_pin = self.add_layout_pin(text="vdd",
layer=h_layer,
offset=offset,
width=width,
height=self.supply_rail_width)
# TOP horizontal rails
offset = vector(ll.x, ur.y) + vector(-2 * self.supply_rail_pitch,
0)
top_gnd_pin = self.add_layout_pin(text="gnd",
layer="m1",
2 * self.supply_rail_pitch - self.supply_rail_width)
self.top_gnd_pin = self.add_layout_pin(text="gnd",
layer=h_layer,
offset=offset,
width=width,
width=width + 2 * supply_rail_spacing,
height=self.supply_rail_width)
offset = vector(ll.x, ur.y) + vector(-1 * self.supply_rail_pitch,
self.supply_rail_pitch)
top_vdd_pin = self.add_layout_pin(text="vdd",
layer="m1",
offset = vector(ll.x, ur.y) + vector(-1 * self.supply_rail_pitch,
1 * self.supply_rail_pitch - self.supply_rail_width)
self.top_vdd_pin = self.add_layout_pin(text="vdd",
layer=h_layer,
offset=offset,
width=width,
height=self.supply_rail_width)
# Remember these for connecting things in the design
self.left_gnd_x_center = left_gnd_pin.cx()
self.left_vdd_x_center = left_vdd_pin.cx()
self.right_gnd_x_center = right_gnd_pin.cx()
self.right_vdd_x_center = right_vdd_pin.cx()
self.left_gnd_x_center = self.left_gnd_pin.cx()
self.left_vdd_x_center = self.left_vdd_pin.cx()
self.right_gnd_x_center = self.right_gnd_pin.cx()
self.right_vdd_x_center = self.right_vdd_pin.cx()
self.bottom_gnd_y_center = bottom_gnd_pin.cy()
self.bottom_vdd_y_center = bottom_vdd_pin.cy()
self.top_gnd_y_center = top_gnd_pin.cy()
self.top_vdd_y_center = top_vdd_pin.cy()
self.bottom_gnd_y_center = self.bottom_gnd_pin.cy()
self.bottom_vdd_y_center = self.bottom_vdd_pin.cy()
self.top_gnd_y_center = self.top_gnd_pin.cy()
self.top_vdd_y_center = self.top_vdd_pin.cy()
# Find the number of vias for this pitch
self.supply_vias = 1

View File

@ -203,28 +203,29 @@ class capped_replica_bitcell_array(bitcell_base_array):
self.replica_bitcell_array_inst.place(offset=0)
self.add_end_caps()
ll=vector(min([x.lx() for x in self.insts]),min([y.by() for y in self.insts]))
ll = vector(-1 * self.dummy_col_insts[0].width, -1 * self.dummy_row_insts[0].height)
self.translate_all(ll)
self.width = max([x.rx() for x in self.insts]) - min([x.lx() for x in self.insts])
self.height = max([x.uy() for x in self.insts]) - min([y.by() for y in self.insts])
self.capped_rba_width = self.dummy_col_insts[0].width + self.dummy_row_insts[0].width + self.dummy_col_insts[1].width
self.capped_rba_height = self.dummy_col_insts[0].height
self.route_power_ring(self.supply_stack[2], self.supply_stack[0])
self.route_supplies()
self.route_unused_wordlines()
self.width = max([x.rx() for x in self.insts]) - min([x.lx() for x in self.insts])
self.height = max([x.uy() for x in self.insts]) - min([y.by() for y in self.insts])
ll=vector(min([x.lx() for x in self.insts]),min([y.by() for y in self.insts]))
self.translate_all(ll)
self.reset_coordinates()
self.add_layout_pins()
self.add_boundary()
self.DRC_LVS()
def route_power_ring(self, v_layer, h_layer):
self.bbox = (vector(0,0), vector(self.capped_rba_width, self.capped_rba_height))
self.supply_rail_width = drc["minwidth_m1"]
self.supply_rail_pitch = 3 * self.supply_rail_width
self.add_power_ring(v_layer, h_layer)
def get_main_array_top(self):
return self.replica_bitcell_array_inst.by() + self.replica_bitcell_array.get_main_array_top()
@ -288,13 +289,13 @@ class capped_replica_bitcell_array(bitcell_base_array):
if "wl" in pin_name:
# wordlines
pin_offset = pin.ll().scale(0, 1)
pin_width = self.width
pin_width = self.capped_rba_width
pin_height = pin.height()
else:
# bitlines
pin_offset = pin.ll().scale(1, 0)
pin_width = pin.width()
pin_height = self.height
pin_height = self.capped_rba_height
self.add_layout_pin(text=pin_name,
layer=pin.layer,
@ -309,55 +310,79 @@ class capped_replica_bitcell_array(bitcell_base_array):
else:
bitcell = getattr(props, "bitcell_{}port".format(OPTS.num_ports))
vdd_dir = bitcell.vdd_dir
gnd_dir = bitcell.gnd_dir
#vdd_dir = bitcell.vdd_dir
#gnd_dir = bitcell.gnd_dir
# vdd/gnd are only connected in the perimeter cells
supply_insts = self.dummy_col_insts + self.dummy_row_insts
#supply_insts = self.dummy_col_insts + self.dummy_row_insts
inst = self.dummy_row_insts[1]
if "vdd" in inst.mod.pins:
array_pins = inst.get_pins("vdd")
for array_pin in array_pins:
supply_pin = self.top_vdd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(array_pin.center()[0], supply_pin.center()[1])])
self.add_via_stack_center(from_layer = array_pin.layer,
to_layer = supply_pin.layer,
offset = vector(array_pin.center()[0], supply_pin.center()[1]))
# For the wordlines
top_bot_mult = 1
left_right_mult = 1
array_pins = inst.get_pins("gnd")
for array_pin in array_pins:
supply_pin = self.top_gnd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(array_pin.center()[0], supply_pin.center()[1])])
self.add_via_stack_center(from_layer = array_pin.layer,
to_layer = supply_pin.layer,
offset = vector(array_pin.center()[0], supply_pin.center()[1]))
inst = self.dummy_row_insts[0]
if "vdd" in inst.mod.pins:
array_pins = inst.get_pins("vdd")
for array_pin in array_pins:
supply_pin = self.bottom_vdd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(array_pin.center()[0], supply_pin.center()[1])])
self.add_via_stack_center(from_layer = array_pin.layer,
to_layer = supply_pin.layer,
offset = vector(array_pin.center()[0], supply_pin.center()[1]))
# There are always vertical pins for the WLs on the left/right if we have unused wordlines
self.left_gnd_locs = self.route_side_pin("gnd", "left", left_right_mult)
self.right_gnd_locs = self.route_side_pin("gnd", "right", left_right_mult)
# This needs to be big enough so that they aren't in the same supply routing grid
left_right_mult = 4
array_pins = inst.get_pins("gnd")
for array_pin in array_pins:
supply_pin = self.bottom_gnd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(array_pin.center()[0], supply_pin.center()[1])])
self.add_via_stack_center(from_layer = array_pin.layer,
to_layer = supply_pin.layer,
offset = vector(array_pin.center()[0], supply_pin.center()[1]))
inst = self.dummy_col_insts[0]
if "vdd" in inst.mod.pins:
array_pins = inst.get_pins("vdd")
for array_pin in array_pins:
supply_pin = self.left_vdd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(supply_pin.center()[0], array_pin.center()[1])])
self.add_via_stack_center(from_layer = array_pin.layer,
to_layer = supply_pin.layer,
offset = vector(supply_pin.center()[0], array_pin.center()[1]))
if gnd_dir == "V":
self.top_gnd_locs = self.route_side_pin("gnd", "top", top_bot_mult)
self.bot_gnd_locs = self.route_side_pin("gnd", "bot", top_bot_mult)
# This needs to be big enough so that they aren't in the same supply routing grid
top_bot_mult = 4
if vdd_dir == "V":
self.top_vdd_locs = self.route_side_pin("vdd", "top", top_bot_mult)
self.bot_vdd_locs = self.route_side_pin("vdd", "bot", top_bot_mult)
elif vdd_dir == "H":
self.left_vdd_locs = self.route_side_pin("vdd", "left", left_right_mult)
self.right_vdd_locs = self.route_side_pin("vdd", "right", left_right_mult)
else:
debug.error("Invalid vdd direction {}".format(vdd_dir), -1)
for inst in supply_insts:
for pin in inst.get_pins("vdd"):
if vdd_dir == "V":
self.connect_side_pin(pin, "top", self.top_vdd_locs[0].y)
self.connect_side_pin(pin, "bot", self.bot_vdd_locs[0].y)
elif vdd_dir == "H":
self.connect_side_pin(pin, "left", self.left_vdd_locs[0].x)
self.connect_side_pin(pin, "right", self.right_vdd_locs[0].x)
for inst in supply_insts:
for pin in inst.get_pins("gnd"):
if gnd_dir == "V":
self.connect_side_pin(pin, "top", self.top_gnd_locs[0].y)
self.connect_side_pin(pin, "bot", self.bot_gnd_locs[0].y)
elif gnd_dir == "H":
self.connect_side_pin(pin, "left", self.left_gnd_locs[0].x)
self.connect_side_pin(pin, "right", self.right_gnd_locs[0].x)
array_pins = inst.get_pins("gnd")
for array_pin in array_pins:
supply_pin = self.left_gnd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(supply_pin.center()[0], array_pin.center()[1])])
self.add_via_stack_center(from_layer = array_pin.layer,
to_layer = supply_pin.layer,
offset = vector(supply_pin.center()[0], array_pin.center()[1]))
inst = self.dummy_col_insts[1]
if "vdd" in inst.mod.pins:
array_pins = inst.get_pins("vdd")
for array_pin in array_pins:
supply_pin = self.right_vdd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(supply_pin.center()[0], array_pin.center()[1])])
self.add_via_stack_center(from_layer = array_pin.layer,
to_layer = supply_pin.layer,
offset = vector(supply_pin.center()[0], array_pin.center()[1]))
array_pins = inst.get_pins("gnd")
for array_pin in array_pins:
supply_pin = self.right_gnd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(supply_pin.center()[0], array_pin.center()[1])])
self.add_via_stack_center(from_layer = array_pin.layer,
to_layer = supply_pin.layer,
offset = vector(supply_pin.center()[0], array_pin.center()[1]))
def route_unused_wordlines(self):
"""
Connect the unused RBL and dummy wordlines to gnd