single port sky130 crba passing lvs

This commit is contained in:
Jesse Cirimelli-Low 2023-08-30 20:59:02 -07:00
parent 8f2e4c6914
commit 0cba6a6050
6 changed files with 180 additions and 173 deletions

View File

@ -2216,7 +2216,7 @@ class layout():
size=(supply_vias,
supply_vias))
def add_power_ring(self, h_layer="m2", v_layer="m1"):
def add_power_ring(self, h_layer="m2", v_layer="m1", top=True, bottom=True, left=True, right=True):
"""
Create vdd and gnd power rings around an area of the bounding box
argument. Must have a supply_rail_width and supply_rail_pitch
@ -2231,111 +2231,113 @@ class layout():
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)
self.left_gnd_pin = self.add_layout_pin(text="gnd",
layer=v_layer,
offset=offset,
width=self.supply_rail_width,
height=height + 2 * supply_rail_spacing)
if left:
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 + 2 * supply_rail_spacing)
offset = ll + vector(-1 * self.supply_rail_pitch,
-1 * self.supply_rail_pitch)
self.left_vdd_pin = self.add_layout_pin(text="vdd",
layer=v_layer,
offset=offset,
width=self.supply_rail_width,
height=height)
offset = ll + vector(-1 * self.supply_rail_pitch,
-1 * self.supply_rail_pitch)
self.left_vdd_pin = self.add_layout_pin(text="vdd",
layer=v_layer,
offset=offset,
width=self.supply_rail_width,
height=height)
# 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 + 2* supply_rail_spacing)
if right:
# 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 + 2* supply_rail_spacing)
offset = vector(ur.x, ll.y) + vector(1 * self.supply_rail_pitch - self.supply_rail_width,
-1 * self.supply_rail_pitch)
self.right_vdd_pin = self.add_layout_pin(text="vdd",
layer=v_layer,
offset=offset,
width=self.supply_rail_width,
height=height)
offset = vector(ur.x, ll.y) + vector(1 * self.supply_rail_pitch - self.supply_rail_width,
-1 * self.supply_rail_pitch)
self.right_vdd_pin = self.add_layout_pin(text="vdd",
layer=v_layer,
offset=offset,
width=self.supply_rail_width,
height=height)
# BOTTOM horizontal rails
offset = ll + vector(-2 * self.supply_rail_pitch,
-2 * self.supply_rail_pitch)
self.bottom_gnd_pin = self.add_layout_pin(text="gnd",
layer=h_layer,
offset=offset,
width=width + 2 * supply_rail_spacing,
height=self.supply_rail_width)
if bottom:
# BOTTOM horizontal rails
offset = ll + vector(-2 * self.supply_rail_pitch,
-2 * self.supply_rail_pitch)
self.bottom_gnd_pin = self.add_layout_pin(text="gnd",
layer=h_layer,
offset=offset,
width=width + 2 * supply_rail_spacing,
height=self.supply_rail_width)
offset = ll + vector(-1 * self.supply_rail_pitch,
-1 * self.supply_rail_pitch)
self.bottom_vdd_pin = self.add_layout_pin(text="vdd",
layer=h_layer,
offset=offset,
width=width,
height=self.supply_rail_width)
offset = ll + vector(-1 * self.supply_rail_pitch,
-1 * self.supply_rail_pitch)
self.bottom_vdd_pin = self.add_layout_pin(text="vdd",
layer=h_layer,
offset=offset,
width=width,
height=self.supply_rail_width)
if top:
# TOP horizontal rails
offset = vector(ll.x, ur.y) + vector(-2 * self.supply_rail_pitch,
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 + 2 * supply_rail_spacing,
height=self.supply_rail_width)
# TOP horizontal rails
offset = vector(ll.x, ur.y) + vector(-2 * self.supply_rail_pitch,
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 + 2 * supply_rail_spacing,
height=self.supply_rail_width)
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)
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 = 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 = 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
while True:
c = factory.create(module_type="contact",
layer_stack=self.m1_stack,
dimensions=(self.supply_vias, self.supply_vias))
if c.second_layer_width < self.supply_rail_width and c.second_layer_height < self.supply_rail_width:
self.supply_vias += 1
else:
self.supply_vias -= 1
break
via_points = [vector(self.left_gnd_x_center, self.bottom_gnd_y_center),
vector(self.left_gnd_x_center, self.top_gnd_y_center),
vector(self.right_gnd_x_center, self.bottom_gnd_y_center),
vector(self.right_gnd_x_center, self.top_gnd_y_center),
vector(self.left_vdd_x_center, self.bottom_vdd_y_center),
vector(self.left_vdd_x_center, self.top_vdd_y_center),
vector(self.right_vdd_x_center, self.bottom_vdd_y_center),
vector(self.right_vdd_x_center, self.top_vdd_y_center)]
if left:
self.left_gnd_x_center = self.left_gnd_pin.cx()
self.left_vdd_x_center = self.left_vdd_pin.cx()
if right:
self.right_gnd_x_center = self.right_gnd_pin.cx()
self.right_vdd_x_center = self.right_vdd_pin.cx()
if bottom:
self.bottom_gnd_y_center = self.bottom_gnd_pin.cy()
self.bottom_vdd_y_center = self.bottom_vdd_pin.cy()
if top:
self.top_gnd_y_center = self.top_gnd_pin.cy()
self.top_vdd_y_center = self.top_vdd_pin.cy()
via_points = []
if left and bottom:
via_points.append((self.left_gnd_x_center, self.bottom_gnd_y_center))
if left and top:
via_points.append(vector(self.left_gnd_x_center, self.top_gnd_y_center))
if right and bottom:
via_points.append(vector(self.right_gnd_x_center, self.bottom_gnd_y_center))
if right and top:
via_points.append(vector(self.right_gnd_x_center, self.top_gnd_y_center))
if left and bottom:
via_points.append(vector(self.left_vdd_x_center, self.bottom_vdd_y_center))
if left and top:
via_points.append(vector(self.left_vdd_x_center, self.top_vdd_y_center))
if right and bottom:
via_points.append(vector(self.right_vdd_x_center, self.bottom_vdd_y_center))
if right and top:
via_points.append((self.right_vdd_x_center, self.top_vdd_y_center))
for pt in via_points:
self.add_via_center(layers=self.m1_stack,
offset=pt,
size=(self.supply_vias,
self.supply_vias))
self.add_via_stack_center(offset=pt,
from_layer=h_layer,
to_layer=v_layer,
min_area=True)
def pdf_write(self, pdf_name):
"""
Display the layout to a PDF file.

View File

@ -224,8 +224,8 @@ class capped_replica_bitcell_array(bitcell_base_array):
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)
self.supply_rail_pitch = 6 * self.supply_rail_width
self.add_power_ring(v_layer=v_layer, h_layer=h_layer)
def get_main_array_top(self):
return self.replica_bitcell_array_inst.by() + self.replica_bitcell_array.get_main_array_top()
@ -309,80 +309,83 @@ class capped_replica_bitcell_array(bitcell_base_array):
bitcell = factory.create(module_type="pbitcell")
else:
bitcell = getattr(props, "bitcell_{}port".format(OPTS.num_ports))
top = True
bottom = True
left = False
right = False
if top:
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]))
#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
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]))
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]))
if bottom:
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]))
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]))
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]))
if left:
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]))
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]))
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]))
if right:
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.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]))
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

View File

@ -17,7 +17,7 @@ class col_cap_array(bitcell_base_array):
self.mirror = mirror
self.location = location
self.no_instances = True
#self.no_instances = True
self.create_netlist()
if not OPTS.netlist_only:
self.create_layout()

View File

@ -16,7 +16,7 @@ class row_cap_array(bitcell_base_array):
super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name)
self.mirror = mirror
self.location = location
self.no_instances = True
#self.no_instances = True
self.create_netlist()
if not OPTS.netlist_only:
self.create_layout()

View File

@ -68,6 +68,7 @@ class sky130_col_cap_array(col_cap_array, sky130_bitcell_base_array):
bitcell_pins.append("gnd") # gnd
bitcell_pins.append("vdd") # vpb
bitcell_pins.append("gnd") # vnb
bitcell_pins.append("gnd")# poly gate for parasitic tx
#bitcell_pins.extend([x for x in self.all_wordline_names if x.endswith("_{0}".format(row))])
return bitcell_pins

View File

@ -114,14 +114,15 @@ cell_properties.bitcell_2port.vdd_dir = "H"
cell_properties.bitcell_2port.gnd_layer = "m2"
cell_properties.bitcell_2port.gnd_dir = "H"
cell_properties.col_cap_1port_bitcell = d.cell(['bl', 'br', 'vdd', 'gnd', 'vpb', 'vnb'],
['INPUT', 'INPUT','POWER', 'GROUND', 'BIAS', 'BIAS'],
cell_properties.col_cap_1port_bitcell = d.cell(['bl', 'br', 'vdd', 'gnd', 'vpb', 'vnb', 'gate'],
['INPUT', 'INPUT','POWER', 'GROUND', 'BIAS', 'BIAS', 'INPUT'],
{'bl': 'bl',
'br': 'br',
'vdd': 'vdd',
'gnd': 'gnd',
'vnb': 'vnb',
'vpb': 'vpb'})
'vpb': 'vpb',
'gate': 'gate'})
cell_properties.col_cap_1port_bitcell.boundary_layer = "mem"
cell_properties.col_cap_1port_strap_power = d.cell(['vdd', 'vpb', 'vnb'],