diff --git a/compiler/custom/s8_row_cap_array.py b/compiler/custom/s8_row_cap_array.py index ab3dce1c..e19db1be 100644 --- a/compiler/custom/s8_row_cap_array.py +++ b/compiler/custom/s8_row_cap_array.py @@ -73,24 +73,24 @@ class s8_row_cap_array(design.design): if alternate_bitcell == 0: row_layout.append(self.rowend1) self.cell_inst[row]=self.add_inst(name=name, mod=self.rowend1) - #self.connect_inst(self.get_bitcell_pins(row, 0)) + self.connect_inst(["wl_0_{}".format(row-1), "vpwr"]) alternate_bitcell = 1 else: row_layout.append(self.rowend2) self.cell_inst[row]=self.add_inst(name=name,mod=self.rowend2) - #self.connect_inst(self.get_bitcell_pins(row, 0)) + self.connect_inst(["wl_0_{}".format(row-1), "vpwr"]) alternate_bitcell = 0 elif (row == 0): row_layout.append(self.bottom_corner) self.cell_inst[row]=self.add_inst(name=name, mod=self.bottom_corner) - #self.connect_inst(self.get_bitcell_pins_col_cap(row, 0)) + self.connect_inst([]) elif (row == self.rows - 1): row_layout.append(self.top_corner) self.cell_inst[row]=self.add_inst(name=name, mod=self.top_corner) - #self.connect_inst(self.get_bitcell_pins_col_cap(row, 0)) + self.connect_inst([]) self.array_layout.append(row_layout) @@ -118,9 +118,9 @@ class s8_row_cap_array(design.design): if inst.width > self.width: self.width = inst.width yoffset = 0.0 - for row in range(0, len(self.array_layout)): - xoffset = 0.0 + xoffset = 0.0 + for col in range(0, len(self.array_layout[row])): inst = self.insts[col + row*len(self.array_layout[row])] inst.place(offset=[xoffset, yoffset]) @@ -138,25 +138,25 @@ class s8_row_cap_array(design.design): def add_layout_pins(self): """ Add the layout pins """ - return - row_list = self.cell.get_all_wl_names() + if self.column_offset == 0: + row_list = self.cell.get_all_wl_names() - for row in range(1, self.row_size - 1): - for cell_row in row_list: - wl_pin = self.cell_inst[row, 0].get_pin(cell_row) - self.add_layout_pin(text=cell_row + "_{0}".format(row), - layer=wl_pin.layer, - offset=wl_pin.ll().scale(0, 1), - width=self.width, - height=wl_pin.height()) + for row in range(1, self.rows-1): + if row > 0 and row < self.rows: + for cell_row in row_list: + wl_pin = self.cell_inst[row].get_pin(cell_row) + self.add_layout_pin(text=cell_row + "_0_{0}".format(row), + layer=wl_pin.layer, + offset=wl_pin.ll().scale(0, 1), + width=self.width, + height=wl_pin.height()) - # Add vdd/gnd via stacks - for row in range(1, self.row_size - 1): - for col in range(self.column_size): - inst = self.cell_inst[row, col] - for pin_name in ["vdd", "gnd"]: + # Add vdd/gnd via stacks + for row in range(1, self.rows): + inst = self.cell_inst[row] + for pin_name in ["vpwr", "vgnd"]: for pin in inst.get_pins(pin_name): self.add_power_pin(name=pin.name, - loc=pin.center(), - start_layer=pin.layer) + loc=pin.center(), + start_layer=pin.layer) diff --git a/compiler/custom/s8_row_end.py b/compiler/custom/s8_row_end.py index e9902397..d02ca709 100644 --- a/compiler/custom/s8_row_end.py +++ b/compiler/custom/s8_row_end.py @@ -17,8 +17,8 @@ class s8_row_end(design.design): def __init__(self, version, name=""): super().__init__(name) - pin_names = [] - type_list = [] + pin_names = ["wl", "vpwr"] + type_list = ["OUTPUT", "POWER"] if version == "rowend": self.name = "s8sram16x16_rowend" @@ -31,4 +31,8 @@ class s8_row_end(design.design): GDS["unit"], layer["mem"], "s8sram16x16_rowend_ce\x00") - pin_map = utils.get_libcell_pins(pin_names, self.name, GDS["unit"]) + self.pin_map = utils.get_libcell_pins(pin_names, self.name, GDS["unit"]) + + + self.add_pin("wl", "OUTPUT") + self.add_pin("vpwr", "POWER") diff --git a/compiler/modules/bitcell_base_array.py b/compiler/modules/bitcell_base_array.py index ffc3bb0f..ff2ff5a0 100644 --- a/compiler/modules/bitcell_base_array.py +++ b/compiler/modules/bitcell_base_array.py @@ -64,7 +64,7 @@ class bitcell_base_array(design.design): else: self.wordline_names[port].append("wl0_{0}_{1}".format(port, row)) self.wordline_names[port].append("wl1_{0}_{1}".format(port, row)) - + self.all_wordline_names = [x for sl in zip(*self.wordline_names) for x in sl] def add_pins(self): @@ -147,32 +147,33 @@ class bitcell_base_array(design.design): def add_layout_pins(self): """ Add the layout pins """ - if not cell_properties.compare_ports(cell_properties.bitcell_array.use_custom_cell_arrangement): - bitline_names = self.cell.get_all_bitline_names() - for col in range(self.column_size): - for port in self.all_ports: - bl_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port]) - self.add_layout_pin(text="bl_{0}_{1}".format(port, col), - layer=bl_pin.layer, - offset=bl_pin.ll().scale(1, 0), - width=bl_pin.width(), - height=self.height) - br_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port + 1]) - self.add_layout_pin(text="br_{0}_{1}".format(port, col), - layer=br_pin.layer, - offset=br_pin.ll().scale(1, 0), - width=br_pin.width(), - height=self.height) + bitline_names = self.cell.get_all_bitline_names() + for col in range(self.column_size): + for port in self.all_ports: + bl_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port]) + self.add_layout_pin(text="bl_{0}_{1}".format(port, col), + layer=bl_pin.layer, + offset=bl_pin.ll().scale(1, 0), + width=bl_pin.width(), + height=self.height) + br_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port + 1]) + self.add_layout_pin(text="br_{0}_{1}".format(port, col), + layer=br_pin.layer, + offset=br_pin.ll().scale(1, 0), + width=br_pin.width(), + height=self.height) - wl_names = self.cell.get_all_wl_names() - for row in range(self.row_size): - for port in self.all_ports: - wl_pin = self.cell_inst[row, 0].get_pin(wl_names[port]) - self.add_layout_pin(text="wl_{0}_{1}".format(port, row), - layer=wl_pin.layer, - offset=wl_pin.ll().scale(0, 1), - width=self.width, - height=wl_pin.height()) + wl_names = self.cell.get_all_wl_names() + for row in range(self.row_size): + for port in self.all_ports: + wl_pin = self.cell_inst[row, 0].get_pin(wl_names[port]) + self.add_layout_pin(text="wl_{0}_{1}".format(port, row), + layer=wl_pin.layer, + offset=wl_pin.ll().scale(0, 1), + width=self.width, + height=wl_pin.height()) + + if not cell_properties.compare_ports(cell_properties.bitcell_array.use_custom_cell_arrangement): # Copy a vdd/gnd layout pin from every cell for row in range(self.row_size): @@ -181,37 +182,8 @@ class bitcell_base_array(design.design): for pin_name in ["vdd", "gnd"]: self.copy_layout_pin(inst, pin_name) else: - bitline_names = self.cell.get_all_bitline_names() - for col in range(self.column_size): - for port in self.all_ports: - bl_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port]) - self.add_layout_pin(text="bl0_{0}_{1}".format(port, col), - layer=bl_pin.layer, - offset=bl_pin.ll().scale(1, 0), - width=bl_pin.width(), - height=self.height) - br_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port + 1]) - self.add_layout_pin(text="bl1_{0}_{1}".format(port, col), - layer=br_pin.layer, - offset=br_pin.ll().scale(1, 0), - width=br_pin.width(), - height=self.height) - wl_names = self.cell.get_all_wl_names() - for row in range(self.row_size): - for port in self.all_ports: - wl0_pin = self.cell_inst[row, 0].get_pin(wl_names[port]) - self.add_layout_pin(text="wl0_{0}_{1}".format(port, row), - layer=wl0_pin.layer, - offset=wl0_pin.ll().scale(0, 1), - width=self.width, - height=wl0_pin.height()) - wl1_pin = self.cell_inst[row, 0].get_pin(wl_names[port]) - self.add_layout_pin(text="wl1_{0}_{1}".format(port, row), - layer=wl1_pin.layer, - offset=wl1_pin.ll().scale(0, 1), - width=self.width, - height=wl1_pin.height()) + # Copy a vdd/gnd layout pin from every cell for row in range(self.row_size): for col in range(self.column_size): diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 816a5391..dbd724c7 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -502,26 +502,18 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): def add_layout_pins(self): """ Add the layout pins """ - # All wordlines - # Main array wl and bl/br - for pin_name in self.all_wordline_names: - pin_list = self.bitcell_array_inst.get_pins(pin_name) - for pin in pin_list: - self.add_layout_pin(text=pin_name, - layer=pin.layer, - offset=pin.ll().scale(0, 1), - width=self.width, - height=pin.height()) - - for pin_name in self.all_bitline_names: - pin_list = self.bitcell_array_inst.get_pins(pin_name) - for pin in pin_list: - self.add_layout_pin(text=pin_name, - layer=pin.layer, - offset=pin.ll().scale(1, 0), - width=pin.width(), - height=self.height) + #All wordlines + #Main array wl and bl/br + if not cell_properties.compare_ports(cell_properties.bitcell_array.use_custom_cell_arrangement): + for pin_name in self.all_wordline_names: + pin_list = self.bitcell_array_inst.get_pins(pin_name) + for pin in pin_list: + self.add_layout_pin(text=pin_name, + layer=pin.layer, + offset=pin.ll().scale(0, 1), + width=self.width, + height=pin.height()) # Replica wordlines (go by the row instead of replica column because we may have to add a pin # even though the column is in another local bitcell array) for (names, inst) in zip(self.rbl_wordline_names, self.dummy_row_replica_insts): @@ -534,6 +526,36 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): offset=pin.ll().scale(0, 1), width=self.width, height=pin.height()) + else: + for pin_name in self.all_wordline_names: + pin_list = self.dummy_col_insts[0].get_pins(pin_name) + for pin in pin_list: + self.add_layout_pin(text=pin_name, + layer=pin.layer, + offset=pin.ll().scale(0, 1), + width=self.width, + height=pin.height()) + # Replica wordlines (go by the row instead of replica column because we may have to add a pin + # even though the column is in another local bitcell array) + for (names, inst) in zip(self.rbl_wordline_names, self.dummy_row_replica_insts): + for (wl_name, pin_name) in zip(names, self.dummy_row.get_wordline_names()): + if wl_name in self.gnd_wordline_names: + continue + pin = inst.get_pin(pin_name) + self.add_layout_pin(text=wl_name, + layer=pin.layer, + offset=pin.ll().scale(0, 1), + width=self.width, + height=pin.height()) + + for pin_name in self.all_bitline_names: + pin_list = self.bitcell_array_inst.get_pins(pin_name) + for pin in pin_list: + self.add_layout_pin(text=pin_name, + layer=pin.layer, + offset=pin.ll().scale(1, 0), + width=pin.width(), + height=self.height) # Replica bitlines if len(self.rbls) > 0: diff --git a/compiler/tests/missing_pin.gds b/compiler/tests/missing_pin.gds index 692677d9..69d112e4 100644 Binary files a/compiler/tests/missing_pin.gds and b/compiler/tests/missing_pin.gds differ diff --git a/compiler/tests/sram_1b_16_1rw_sky130.log b/compiler/tests/sram_1b_16_1rw_sky130.log index e92e1a3b..0fafc96e 100644 --- a/compiler/tests/sram_1b_16_1rw_sky130.log +++ b/compiler/tests/sram_1b_16_1rw_sky130.log @@ -1,4 +1,4 @@ -WARNING: file magic.py: line 210: DRC Errors replica_bitcell_array 985 +WARNING: file magic.py: line 210: DRC Errors replica_bitcell_array 1010 ERROR: file magic.py: line 285: replica_bitcell_array LVS mismatch (results in /home/jesse/output/replica_bitcell_array.lvs.report) diff --git a/missing_pin.gds b/missing_pin.gds index 692677d9..69d112e4 100644 Binary files a/missing_pin.gds and b/missing_pin.gds differ diff --git a/sram_1b_16_1rw_sky130.log b/sram_1b_16_1rw_sky130.log index f57734de..248d025f 100644 --- a/sram_1b_16_1rw_sky130.log +++ b/sram_1b_16_1rw_sky130.log @@ -17,3 +17,4 @@ [bitcell_base_array/__init__]: Creating bitcell_array 4 x 4 [bitcell_array/__init__]: Creating bitcell_array 4 x 4 [bitcell_base_array/__init__]: Creating replica_column 7 x 1 +[bitcell_base_array/__init__]: Creating dummy_array 1 x 4