From 8d9166a01b3cac8b2ed7abb2688ab9b040bb6c11 Mon Sep 17 00:00:00 2001 From: Jesse Cirimelli-Low Date: Wed, 29 Dec 2021 12:43:02 -0800 Subject: [PATCH] only rba lvs errors is colend body extraction --- .../sky130/modules/sky130_bitcell_array.py | 14 ++--- .../modules/sky130_bitcell_base_array.py | 4 ++ .../sky130/modules/sky130_col_cap_array.py | 34 +++++++++- .../sky130/modules/sky130_dummy_array.py | 63 ++++++++++++++----- .../modules/sky130_replica_bitcell_array.py | 10 ++- .../sky130/modules/sky130_replica_column.py | 3 + technology/sky130/tech/tech.py | 7 ++- 7 files changed, 100 insertions(+), 35 deletions(-) diff --git a/technology/sky130/modules/sky130_bitcell_array.py b/technology/sky130/modules/sky130_bitcell_array.py index cbc2b2f9..d0d69c74 100644 --- a/technology/sky130/modules/sky130_bitcell_array.py +++ b/technology/sky130/modules/sky130_bitcell_array.py @@ -68,25 +68,23 @@ class sky130_bitcell_array(bitcell_array, sky130_bitcell_base_array): if col != self.column_size - 1: if alternate_strap: if row % 2: + name="row_{}_col_{}_wlstrapa_p".format(row, col) row_layout.append(self.strap4) - self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), - mod=self.strap4) + self.add_inst(name=name, mod=self.strap4) else: + name="row_{}_col_{}_wlstrap_p".format(row, col) row_layout.append(self.strap2) - self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), - mod=self.strap2) + self.add_inst(name=name, mod=self.strap2) alternate_strap = 0 else: if row % 2: name="row_{}_col_{}_wlstrapa".format(row, col) row_layout.append(self.strap3) - self.add_inst(name=name.format(row, col), - mod=self.strap3) + self.add_inst(name=name.format(row, col), mod=self.strap3) else: name="row_{}_col_{}_wlstrap".format(row, col) row_layout.append(self.strap) - self.add_inst(name=name.format(row, col), - mod=self.strap) + self.add_inst(name=name.format(row, col), mod=self.strap) alternate_strap = 1 self.connect_inst(self.get_strap_pins(row, col, name)) if alternate_bitcell == 0: diff --git a/technology/sky130/modules/sky130_bitcell_base_array.py b/technology/sky130/modules/sky130_bitcell_base_array.py index b52d5eb9..d472b264 100644 --- a/technology/sky130/modules/sky130_bitcell_base_array.py +++ b/technology/sky130/modules/sky130_bitcell_base_array.py @@ -103,6 +103,10 @@ class sky130_bitcell_base_array(bitcell_base_array): strap_pins.extend(["vdd", "gnd"]) 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))]) + if row == 0: + strap_pins.extend(["gate_top"]) + else: + strap_pins.extend(["gate_bottom"]) return strap_pins def get_row_cap_pins(self, row, col): diff --git a/technology/sky130/modules/sky130_col_cap_array.py b/technology/sky130/modules/sky130_col_cap_array.py index 26d97ee2..a363dda2 100644 --- a/technology/sky130/modules/sky130_col_cap_array.py +++ b/technology/sky130/modules/sky130_col_cap_array.py @@ -8,7 +8,8 @@ from sram_factory import factory from sky130_bitcell_base_array import sky130_bitcell_base_array from globals import OPTS - +import geometry +from tech import layer 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.add_layout_pins() - + #self.add_supply_pins() self.add_boundary() self.DRC_LVS() @@ -77,6 +78,7 @@ class sky130_col_cap_array(sky130_bitcell_base_array): pins.append("vdd") pins.append("gnd") pins.append("fake_br_{}".format(bitline)) + pins.append("gate") bitline += 1 elif col % 4 == 1: row_layout.append(self.colend2) @@ -91,13 +93,14 @@ class sky130_col_cap_array(sky130_bitcell_base_array): pins.append("vdd") pins.append("gnd") pins.append("fake_br_{}".format(bitline)) + pins.append("gate") bitline += 1 elif col % 4 ==3: row_layout.append(self.colend2) self.cell_inst[col]=self.add_inst(name=name, mod=self.colend2) pins.append("gnd") pins.append("vdd") - pins.append("gnd") + pins.append("vnb") 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("vdd", "POWER") self.add_pin("gnd", "GROUND") + self.add_pin("gate", "BIAS") def add_layout_pins(self): """ Add the layout pins """ @@ -167,6 +171,30 @@ class sky130_col_cap_array(sky130_bitcell_base_array): width=pin.width(), height=pin.height()) 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): if row_size == None: diff --git a/technology/sky130/modules/sky130_dummy_array.py b/technology/sky130/modules/sky130_dummy_array.py index c53b0fc3..416e9f3d 100644 --- a/technology/sky130/modules/sky130_dummy_array.py +++ b/technology/sky130/modules/sky130_dummy_array.py @@ -8,7 +8,8 @@ from sky130_bitcell_base_array import sky130_bitcell_base_array from sram_factory import factory from globals import OPTS - +import geometry +from tech import layer 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.add_layout_pins() - + self.add_supply_pins() self.add_boundary() self.DRC_LVS() @@ -76,25 +77,29 @@ class sky130_dummy_array(sky130_bitcell_base_array): if col != self.column_size - 1: if alternate_strap: if col % 2: + name="row_{}_col_{}_wlstrap_p".format(row, col) row_layout.append(self.strap4) - self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), + self.add_inst(name=name, mod=self.strap4) else: - row_layout.append(self.strap4) - self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), - mod=self.strap4) + name="row_{}_col_{}_wlstrapa_p".format(row, col) + row_layout.append(self.strap2) + self.add_inst(name=name, + mod=self.strap2) alternate_strap = 0 else: if col % 2: - row_layout.append(self.strap) - self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), - mod=self.strap) + name="row_{}_col_{}_wlstrap".format(row, col) + row_layout.append(self.strap) + self.add_inst(name=name, + mod=self.strap) else: - row_layout.append(self.strap3) - self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), - mod=self.strap3) + name="row_{}_col_{}_wlstrapa".format(row, col) + row_layout.append(self.strap3) + self.add_inst(name=name, + mod=self.strap3) 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: alternate_bitcell = 1 else: @@ -106,10 +111,12 @@ class sky130_dummy_array(sky130_bitcell_base_array): for wl_name in self.get_wordline_names(): self.add_pin(wl_name, "INPUT") for bl in range(self.column_size): - self.add_pin("dummy_bl_{}".format(bl)) - self.add_pin("dummy_br_{}".format(bl)) + self.add_pin("bl_0_{}".format(bl)) + self.add_pin("br_0_{}".format(bl)) self.add_pin("vdd", "POWER") self.add_pin("gnd", "GROUND") + #self.add_pin("vpb", "BIAS") + #Sself.add_pin("vnb", "BIAS") def add_layout_pins(self): """ Add the layout pins """ @@ -154,6 +161,32 @@ class sky130_dummy_array(sky130_bitcell_base_array): for pin_name in ["vdd", "gnd"]: 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): # FIXME: This appears to be old code from previous characterization. Needs to be updated. wl_wire = self.gen_wl_wire() diff --git a/technology/sky130/modules/sky130_replica_bitcell_array.py b/technology/sky130/modules/sky130_replica_bitcell_array.py index 0e7469de..0bc402ed 100644 --- a/technology/sky130/modules/sky130_replica_bitcell_array.py +++ b/technology/sky130/modules/sky130_replica_bitcell_array.py @@ -99,8 +99,6 @@ class sky130_replica_bitcell_array(replica_bitcell_array, sky130_bitcell_base_ar def add_pins(self): super().add_pins() - self.add_pin("vpb", "BIAS") - self.add_pin("vnb", "BIAS") def add_replica_columns(self): """ 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) 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) 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')]) @@ -388,7 +386,7 @@ class sky130_replica_bitcell_array(replica_bitcell_array, sky130_bitcell_base_ar if port in self.rbls: self.replica_col_insts.append(self.add_inst(name="replica_col_{}".format(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: 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.append(self.add_inst(name="dummy_row_bot", 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", 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 self.dummy_col_insts = [] diff --git a/technology/sky130/modules/sky130_replica_column.py b/technology/sky130/modules/sky130_replica_column.py index 495f5a89..f3d1801b 100644 --- a/technology/sky130/modules/sky130_replica_column.py +++ b/technology/sky130/modules/sky130_replica_column.py @@ -90,6 +90,9 @@ class sky130_replica_column(sky130_bitcell_base_array): self.add_pin("vdd", "POWER") self.add_pin("gnd", "GROUND") + self.add_pin("gate_top", "BIAS") + self.add_pin("gate_bottom", "BIAS") + def add_modules(self): self.replica_cell = factory.create(module_type="replica_bitcell_1port", version="opt1") self.cell = self.replica_cell diff --git a/technology/sky130/tech/tech.py b/technology/sky130/tech/tech.py index e42c0d89..e81fe476 100644 --- a/technology/sky130/tech/tech.py +++ b/technology/sky130/tech/tech.py @@ -99,12 +99,13 @@ cell_properties.bitcell_2port.port_map = {'bl0': 'BL0', 'vdd': 'VDD', 'gnd': 'GND'} -cell_properties.col_cap_1port_bitcell = cell(['br', 'vdd', 'gnd', 'bl'], - ['INPUT', 'POWER', 'GROUND', 'INPUT'], +cell_properties.col_cap_1port_bitcell = cell(['br', 'vdd', 'gnd', 'bl', 'gate'], + ['INPUT', 'POWER', 'GROUND', 'INPUT', 'INPUT'], {'bl': 'BL0', 'br': 'BL1', 'vdd': 'VPWR', - 'gnd': 'VGND'}) + 'gnd': 'VGND', + 'gate': 'gate'}) cell_properties.col_cap_1port_bitcell.boundary_layer = "mem" cell_properties.col_cap_1port_strap_power = cell(['vdd', 'vpb', 'vnb'],