only rba lvs errors is colend body extraction

This commit is contained in:
Jesse Cirimelli-Low 2021-12-29 12:43:02 -08:00
parent 9e85d17fbe
commit 8d9166a01b
7 changed files with 100 additions and 35 deletions

View File

@ -68,25 +68,23 @@ class sky130_bitcell_array(bitcell_array, sky130_bitcell_base_array):
if col != self.column_size - 1: if col != self.column_size - 1:
if alternate_strap: if alternate_strap:
if row % 2: if row % 2:
name="row_{}_col_{}_wlstrapa_p".format(row, col)
row_layout.append(self.strap4) row_layout.append(self.strap4)
self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), self.add_inst(name=name, mod=self.strap4)
mod=self.strap4)
else: else:
name="row_{}_col_{}_wlstrap_p".format(row, col)
row_layout.append(self.strap2) row_layout.append(self.strap2)
self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), self.add_inst(name=name, mod=self.strap2)
mod=self.strap2)
alternate_strap = 0 alternate_strap = 0
else: else:
if row % 2: if row % 2:
name="row_{}_col_{}_wlstrapa".format(row, col) name="row_{}_col_{}_wlstrapa".format(row, col)
row_layout.append(self.strap3) row_layout.append(self.strap3)
self.add_inst(name=name.format(row, col), self.add_inst(name=name.format(row, col), mod=self.strap3)
mod=self.strap3)
else: else:
name="row_{}_col_{}_wlstrap".format(row, col) name="row_{}_col_{}_wlstrap".format(row, col)
row_layout.append(self.strap) row_layout.append(self.strap)
self.add_inst(name=name.format(row, col), self.add_inst(name=name.format(row, col), mod=self.strap)
mod=self.strap)
alternate_strap = 1 alternate_strap = 1
self.connect_inst(self.get_strap_pins(row, col, name)) self.connect_inst(self.get_strap_pins(row, col, name))
if alternate_bitcell == 0: if alternate_bitcell == 0:

View File

@ -103,6 +103,10 @@ class sky130_bitcell_base_array(bitcell_base_array):
strap_pins.extend(["vdd", "gnd"]) strap_pins.extend(["vdd", "gnd"])
for port in self.all_ports: for port in self.all_ports:
strap_pins.extend([x for x in self.get_bitline_names(port) if "br" in x and x.endswith("_{0}".format(col))]) strap_pins.extend([x for x in self.get_bitline_names(port) if "br" in x and x.endswith("_{0}".format(col))])
if row == 0:
strap_pins.extend(["gate_top"])
else:
strap_pins.extend(["gate_bottom"])
return strap_pins return strap_pins
def get_row_cap_pins(self, row, col): def get_row_cap_pins(self, row, col):

View File

@ -8,7 +8,8 @@
from sram_factory import factory from sram_factory import factory
from sky130_bitcell_base_array import sky130_bitcell_base_array from sky130_bitcell_base_array import sky130_bitcell_base_array
from globals import OPTS from globals import OPTS
import geometry
from tech import layer
class sky130_col_cap_array(sky130_bitcell_base_array): class sky130_col_cap_array(sky130_bitcell_base_array):
""" """
@ -41,7 +42,7 @@ class sky130_col_cap_array(sky130_bitcell_base_array):
self.place_array("dummy_r{0}_c{1}", self.mirror) self.place_array("dummy_r{0}_c{1}", self.mirror)
self.add_layout_pins() self.add_layout_pins()
#self.add_supply_pins()
self.add_boundary() self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
@ -77,6 +78,7 @@ class sky130_col_cap_array(sky130_bitcell_base_array):
pins.append("vdd") pins.append("vdd")
pins.append("gnd") pins.append("gnd")
pins.append("fake_br_{}".format(bitline)) pins.append("fake_br_{}".format(bitline))
pins.append("gate")
bitline += 1 bitline += 1
elif col % 4 == 1: elif col % 4 == 1:
row_layout.append(self.colend2) row_layout.append(self.colend2)
@ -91,13 +93,14 @@ class sky130_col_cap_array(sky130_bitcell_base_array):
pins.append("vdd") pins.append("vdd")
pins.append("gnd") pins.append("gnd")
pins.append("fake_br_{}".format(bitline)) pins.append("fake_br_{}".format(bitline))
pins.append("gate")
bitline += 1 bitline += 1
elif col % 4 ==3: elif col % 4 ==3:
row_layout.append(self.colend2) row_layout.append(self.colend2)
self.cell_inst[col]=self.add_inst(name=name, mod=self.colend2) self.cell_inst[col]=self.add_inst(name=name, mod=self.colend2)
pins.append("gnd") pins.append("gnd")
pins.append("vdd") pins.append("vdd")
pins.append("gnd") pins.append("vnb")
self.connect_inst(pins) self.connect_inst(pins)
@ -131,6 +134,7 @@ class sky130_col_cap_array(sky130_bitcell_base_array):
self.add_pin("fake_wl", "INPUT") self.add_pin("fake_wl", "INPUT")
self.add_pin("vdd", "POWER") self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND") self.add_pin("gnd", "GROUND")
self.add_pin("gate", "BIAS")
def add_layout_pins(self): def add_layout_pins(self):
""" Add the layout pins """ """ Add the layout pins """
@ -168,6 +172,30 @@ class sky130_col_cap_array(sky130_bitcell_base_array):
height=pin.height()) height=pin.height())
return return
def add_supply_pins(self):
for col in range(self.cols):
inst = self.cell_inst[col]
if 'VPB' in self.cell_inst[col].mod.pins:
pin = inst.get_pin("vpb")
self.objs.append(geometry.rectangle(layer["nwell"],
pin.ll(),
pin.width(),
pin.height()))
self.objs.append(geometry.label("vdd", layer["nwell"], pin.center()))
if 'VNB' in self.cell_inst[col].mod.pins:
try:
from tech import layer_override
if layer_override['VNB']:
pin = inst.get_pin("vnb")
self.objs.append(geometry.label("gnd", layer["pwellp"], pin.center()))
self.objs.append(geometry.rectangle(layer["pwellp"],
pin.ll(),
pin.width(),
pin.height()))
except:
pin = inst.get_pin("vnb")
def create_all_wordline_names(self, row_size=None): def create_all_wordline_names(self, row_size=None):
if row_size == None: if row_size == None:
row_size = self.row_size row_size = self.row_size

View File

@ -8,7 +8,8 @@
from sky130_bitcell_base_array import sky130_bitcell_base_array from sky130_bitcell_base_array import sky130_bitcell_base_array
from sram_factory import factory from sram_factory import factory
from globals import OPTS from globals import OPTS
import geometry
from tech import layer
class sky130_dummy_array(sky130_bitcell_base_array): class sky130_dummy_array(sky130_bitcell_base_array):
""" """
@ -37,7 +38,7 @@ class sky130_dummy_array(sky130_bitcell_base_array):
self.place_array("dummy_r{0}_c{1}", self.mirror) self.place_array("dummy_r{0}_c{1}", self.mirror)
self.add_layout_pins() self.add_layout_pins()
self.add_supply_pins()
self.add_boundary() self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
@ -76,25 +77,29 @@ class sky130_dummy_array(sky130_bitcell_base_array):
if col != self.column_size - 1: if col != self.column_size - 1:
if alternate_strap: if alternate_strap:
if col % 2: if col % 2:
name="row_{}_col_{}_wlstrap_p".format(row, col)
row_layout.append(self.strap4) row_layout.append(self.strap4)
self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), self.add_inst(name=name,
mod=self.strap4) mod=self.strap4)
else: else:
row_layout.append(self.strap4) name="row_{}_col_{}_wlstrapa_p".format(row, col)
self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), row_layout.append(self.strap2)
mod=self.strap4) self.add_inst(name=name,
mod=self.strap2)
alternate_strap = 0 alternate_strap = 0
else: else:
if col % 2: if col % 2:
row_layout.append(self.strap) name="row_{}_col_{}_wlstrap".format(row, col)
self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), row_layout.append(self.strap)
mod=self.strap) self.add_inst(name=name,
mod=self.strap)
else: else:
row_layout.append(self.strap3) name="row_{}_col_{}_wlstrapa".format(row, col)
self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), row_layout.append(self.strap3)
mod=self.strap3) self.add_inst(name=name,
mod=self.strap3)
alternate_strap = 1 alternate_strap = 1
self.connect_inst(self.get_strap_pins(row, col)) self.connect_inst(self.get_strap_pins(row, col, name))
if alternate_bitcell == 0: if alternate_bitcell == 0:
alternate_bitcell = 1 alternate_bitcell = 1
else: else:
@ -106,10 +111,12 @@ class sky130_dummy_array(sky130_bitcell_base_array):
for wl_name in self.get_wordline_names(): for wl_name in self.get_wordline_names():
self.add_pin(wl_name, "INPUT") self.add_pin(wl_name, "INPUT")
for bl in range(self.column_size): for bl in range(self.column_size):
self.add_pin("dummy_bl_{}".format(bl)) self.add_pin("bl_0_{}".format(bl))
self.add_pin("dummy_br_{}".format(bl)) self.add_pin("br_0_{}".format(bl))
self.add_pin("vdd", "POWER") self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND") self.add_pin("gnd", "GROUND")
#self.add_pin("vpb", "BIAS")
#Sself.add_pin("vnb", "BIAS")
def add_layout_pins(self): def add_layout_pins(self):
""" Add the layout pins """ """ Add the layout pins """
@ -154,6 +161,32 @@ class sky130_dummy_array(sky130_bitcell_base_array):
for pin_name in ["vdd", "gnd"]: for pin_name in ["vdd", "gnd"]:
self.copy_layout_pin(inst, pin_name) self.copy_layout_pin(inst, pin_name)
def add_supply_pins(self):
for row in range(self.row_size):
for col in range(self.column_size):
inst = self.cell_inst[row, col]
if 'VPB' in self.cell_inst[row, col].mod.pins:
pin = inst.get_pin("vpb")
self.objs.append(geometry.rectangle(layer["nwell"],
pin.ll(),
pin.width(),
pin.height()))
self.objs.append(geometry.label("vdd", layer["nwell"], pin.center()))
if 'VNB' in self.cell_inst[row, col].mod.pins:
try:
from tech import layer_override
if layer_override['VNB']:
pin = inst.get_pin("vnb")
self.objs.append(geometry.label("gnd", layer["pwellp"], pin.center()))
self.objs.append(geometry.rectangle(layer["pwellp"],
pin.ll(),
pin.width(),
pin.height()))
except:
pin = inst.get_pin("vnb")
self.add_label("vdd", pin.layer, pin.center())
def input_load(self): def input_load(self):
# FIXME: This appears to be old code from previous characterization. Needs to be updated. # FIXME: This appears to be old code from previous characterization. Needs to be updated.
wl_wire = self.gen_wl_wire() wl_wire = self.gen_wl_wire()

View File

@ -99,8 +99,6 @@ class sky130_replica_bitcell_array(replica_bitcell_array, sky130_bitcell_base_ar
def add_pins(self): def add_pins(self):
super().add_pins() super().add_pins()
self.add_pin("vpb", "BIAS")
self.add_pin("vnb", "BIAS")
def add_replica_columns(self): def add_replica_columns(self):
""" Add replica columns on left and right of array """ """ Add replica columns on left and right of array """
@ -284,7 +282,7 @@ class sky130_replica_bitcell_array(replica_bitcell_array, sky130_bitcell_base_ar
# start_layer=pin.layer) # start_layer=pin.layer)
min_area = drc["minarea_{}".format('m3')] min_area = drc["minarea_{}".format('m3')]
for track,supply, offset in zip(range(1,5),['vdd','vpb','vnb','gnd'],[min_area * 6,min_area * 6, 0, 0]): for track,supply, offset in zip(range(1,5),['vdd','vdd','gnd','gnd'],[min_area * 6,min_area * 6, 0, 0]):
y_offset = track * (pin_height + drc_width*2) y_offset = track * (pin_height + drc_width*2)
self.add_segment_center('m2', vector(0,-y_offset), vector(self.width, -y_offset), drc["minwidth_{}".format('m2')]) self.add_segment_center('m2', vector(0,-y_offset), vector(self.width, -y_offset), drc["minwidth_{}".format('m2')])
self.add_segment_center('m2', vector(0,self.height + y_offset), vector(self.width, self.height + y_offset), drc["minwidth_{}".format('m2')]) self.add_segment_center('m2', vector(0,self.height + y_offset), vector(self.width, self.height + y_offset), drc["minwidth_{}".format('m2')])
@ -388,7 +386,7 @@ class sky130_replica_bitcell_array(replica_bitcell_array, sky130_bitcell_base_ar
if port in self.rbls: if port in self.rbls:
self.replica_col_insts.append(self.add_inst(name="replica_col_{}".format(port), self.replica_col_insts.append(self.add_inst(name="replica_col_{}".format(port),
mod=self.replica_columns[port])) mod=self.replica_columns[port]))
self.connect_inst(self.rbl_bitline_names[port] + self.replica_array_wordline_names + self.supplies) self.connect_inst(self.rbl_bitline_names[port] + self.replica_array_wordline_names + self.supplies + ["gnd"] + ["gnd"])
else: else:
self.replica_col_insts.append(None) self.replica_col_insts.append(None)
@ -404,10 +402,10 @@ class sky130_replica_bitcell_array(replica_bitcell_array, sky130_bitcell_base_ar
self.dummy_row_insts = [] self.dummy_row_insts = []
self.dummy_row_insts.append(self.add_inst(name="dummy_row_bot", self.dummy_row_insts.append(self.add_inst(name="dummy_row_bot",
mod=self.col_cap_bottom)) mod=self.col_cap_bottom))
self.connect_inst(self.all_bitline_names + ["gnd"] * len(self.col_cap_bottom.get_wordline_names()) + self.supplies) self.connect_inst(self.all_bitline_names + ["gnd"] * len(self.col_cap_bottom.get_wordline_names()) + self.supplies + ["gnd"])
self.dummy_row_insts.append(self.add_inst(name="dummy_row_top", self.dummy_row_insts.append(self.add_inst(name="dummy_row_top",
mod=self.col_cap_top)) mod=self.col_cap_top))
self.connect_inst(self.all_bitline_names + ["gnd"] * len(self.col_cap_top.get_wordline_names()) + self.supplies) self.connect_inst(self.all_bitline_names + ["gnd"] * len(self.col_cap_top.get_wordline_names()) + self.supplies + ["gnd"])
# Left/right Dummy columns # Left/right Dummy columns
self.dummy_col_insts = [] self.dummy_col_insts = []

View File

@ -90,6 +90,9 @@ class sky130_replica_column(sky130_bitcell_base_array):
self.add_pin("vdd", "POWER") self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND") self.add_pin("gnd", "GROUND")
self.add_pin("gate_top", "BIAS")
self.add_pin("gate_bottom", "BIAS")
def add_modules(self): def add_modules(self):
self.replica_cell = factory.create(module_type="replica_bitcell_1port", version="opt1") self.replica_cell = factory.create(module_type="replica_bitcell_1port", version="opt1")
self.cell = self.replica_cell self.cell = self.replica_cell

View File

@ -99,12 +99,13 @@ cell_properties.bitcell_2port.port_map = {'bl0': 'BL0',
'vdd': 'VDD', 'vdd': 'VDD',
'gnd': 'GND'} 'gnd': 'GND'}
cell_properties.col_cap_1port_bitcell = cell(['br', 'vdd', 'gnd', 'bl'], cell_properties.col_cap_1port_bitcell = cell(['br', 'vdd', 'gnd', 'bl', 'gate'],
['INPUT', 'POWER', 'GROUND', 'INPUT'], ['INPUT', 'POWER', 'GROUND', 'INPUT', 'INPUT'],
{'bl': 'BL0', {'bl': 'BL0',
'br': 'BL1', 'br': 'BL1',
'vdd': 'VPWR', 'vdd': 'VPWR',
'gnd': 'VGND'}) 'gnd': 'VGND',
'gate': 'gate'})
cell_properties.col_cap_1port_bitcell.boundary_layer = "mem" cell_properties.col_cap_1port_bitcell.boundary_layer = "mem"
cell_properties.col_cap_1port_strap_power = cell(['vdd', 'vpb', 'vnb'], cell_properties.col_cap_1port_strap_power = cell(['vdd', 'vpb', 'vnb'],