diff --git a/compiler/modules/bitcell_base_array.py b/compiler/modules/bitcell_base_array.py index f9eeaeb7..5bff2448 100644 --- a/compiler/modules/bitcell_base_array.py +++ b/compiler/modules/bitcell_base_array.py @@ -43,11 +43,11 @@ class bitcell_base_array(design.design): # Make a flat list too self.all_bitline_names = [x for sl in zip(*self.bitline_names) for x in sl] - def create_all_wordline_names(self, row_size=None): + def create_all_wordline_names(self, row_size=None, start_row=0): if row_size == None: row_size = self.row_size - for row in range(row_size): + for row in range(start_row, row_size): for port in self.all_ports: self.wordline_names[port].append("wl_{0}_{1}".format(port, row)) diff --git a/technology/sky130/modules/sky130_bitcell_array.py b/technology/sky130/modules/sky130_bitcell_array.py index 5d250f15..bd3a9457 100644 --- a/technology/sky130/modules/sky130_bitcell_array.py +++ b/technology/sky130/modules/sky130_bitcell_array.py @@ -71,21 +71,24 @@ class sky130_bitcell_array(bitcell_array, sky130_bitcell_base_array): self.connect_inst(self.get_bitcell_pins(row, col)) if col != self.column_size - 1: if alternate_strap: + name="row_{}_col_{}_wlstrap_p".format(row, col) row_layout.append(self.strap2) - self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), + self.add_inst(name=name.format(row, col), 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="row_{}_col_{}_wlstrap".format(row, col), + 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="row_{}_col_{}_wlstrap".format(row, col), + self.add_inst(name=name.format(row, col), mod=self.strap) 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: diff --git a/technology/sky130/modules/sky130_bitcell_base_array.py b/technology/sky130/modules/sky130_bitcell_base_array.py index 5b0e39d4..b52d5eb9 100644 --- a/technology/sky130/modules/sky130_bitcell_base_array.py +++ b/technology/sky130/modules/sky130_bitcell_base_array.py @@ -77,21 +77,24 @@ class sky130_bitcell_base_array(bitcell_base_array): return bitcell_pins - def get_strap_pins(self, row, col): + def get_strap_pins(self, row, col, name=""): """ Creates a list of connections in the strap cell, indexed by column and row, for instance use in bitcell_array """ - strap_pins = ["vdd"] - return strap_pins - - def get_col_cap_pins(self, row, col): - """ - """ - strap_pins = ["gnd", "gnd", "vdd"] + if name and "_p" in name: + strap_pins = ["gnd"] + else: + strap_pins = ["vdd"] return strap_pins def get_col_cap_p_pins(self, row, col): + """ + """ + strap_pins = ["gnd", "vdd", "gnd"] + return strap_pins + + def get_col_cap_pins(self, row, col): """ """ strap_pins = [] diff --git a/technology/sky130/modules/sky130_dummy_array.py b/technology/sky130/modules/sky130_dummy_array.py index 9f854dd8..56f53d8b 100644 --- a/technology/sky130/modules/sky130_dummy_array.py +++ b/technology/sky130/modules/sky130_dummy_array.py @@ -77,17 +77,18 @@ class sky130_dummy_array(sky130_bitcell_base_array): self.connect_inst(self.get_bitcell_pins(row, col)) if col != self.column_size - 1: if alternate_strap: + name = "row_{}_col_{}_wlstrap_p".format(row, col) row_layout.append(self.strap2) - self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), + self.add_inst(name=name, mod=self.strap2) alternate_strap = 0 else: - + name="row_{}_col_{}_wlstrap".format(row, col) row_layout.append(self.strap) - self.add_inst(name="row_{}_col_{}_wlstrap".format(row, col), + self.add_inst(name=name, mod=self.strap) 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: @@ -96,11 +97,11 @@ class sky130_dummy_array(sky130_bitcell_base_array): def add_pins(self): # bitline pins are not added because they are floating + for bl_name in self.get_bitline_names(): + self.add_pin(bl_name, "INOUT") 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("vdd", "POWER") self.add_pin("gnd", "GROUND") diff --git a/technology/sky130/modules/sky130_replica_bitcell_array.py b/technology/sky130/modules/sky130_replica_bitcell_array.py index bc5d2036..28312c6c 100644 --- a/technology/sky130/modules/sky130_replica_bitcell_array.py +++ b/technology/sky130/modules/sky130_replica_bitcell_array.py @@ -338,3 +338,83 @@ class sky130_replica_bitcell_array(replica_bitcell_array, sky130_bitcell_base_ar width=pin.width(), height=self.height - 2 *(pin_height + drc_width*2)) return + + def add_wordline_pins(self): + + # Wordlines to ground + self.gnd_wordline_names = [] + + for port in self.all_ports: + for bit in self.all_ports: + self.rbl_wordline_names[port].append("rbl_wl_{0}_{1}".format(port, bit)) + if bit != port: + self.gnd_wordline_names.append("rbl_wl_{0}_{1}".format(port, bit)) + + self.all_rbl_wordline_names = [x for sl in self.rbl_wordline_names for x in sl] + + self.wordline_names = self.bitcell_array.wordline_names + self.all_wordline_names = self.bitcell_array.all_wordline_names + + # All wordlines including dummy and RBL + self.replica_array_wordline_names = [] + #self.replica_array_wordline_names.extend(["gnd"] * len(self.col_cap_top.get_wordline_names())) + for bit in range(self.rbl[0]): + self.replica_array_wordline_names.extend([x if x not in self.gnd_wordline_names else "gnd" for x in self.rbl_wordline_names[bit]]) + self.replica_array_wordline_names.extend(self.all_wordline_names) + for bit in range(self.rbl[1]): + self.replica_array_wordline_names.extend([x if x not in self.gnd_wordline_names else "gnd" for x in self.rbl_wordline_names[self.rbl[0] + bit]]) + #self.replica_array_wordline_names.extend(["gnd"] * len(self.col_cap_top.get_wordline_names())) + + for port in range(self.rbl[0]): + self.add_pin(self.rbl_wordline_names[port][port], "INPUT") + self.add_pin_list(self.all_wordline_names, "INPUT") + for port in range(self.rbl[0], self.rbl[0] + self.rbl[1]): + self.add_pin(self.rbl_wordline_names[port][port], "INPUT") + + def create_instances(self): + """ Create the module instances used in this design """ + self.supplies = ["vdd", "gnd"] + + # Used for names/dimensions only + # self.cell = factory.create(module_type=OPTS.bitcell) + + # Main array + self.bitcell_array_inst=self.add_inst(name="bitcell_array", + mod=self.bitcell_array) + self.connect_inst(self.all_bitline_names + self.all_wordline_names + self.supplies) + print("running\n\n\n") + # Replica columns + self.replica_col_insts = [] + for port in self.all_ports: + 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) + else: + self.replica_col_insts.append(None) + + # Dummy rows under the bitcell array (connected with with the replica cell wl) + self.dummy_row_replica_insts = [] + # Note, this is the number of left and right even if we aren't adding the columns to this bitcell array! + for port in self.all_ports: + self.dummy_row_replica_insts.append(self.add_inst(name="dummy_row_{}".format(port), + mod=self.dummy_row)) + self.connect_inst(self.all_bitline_names + [x if x not in self.gnd_wordline_names else "gnd" for x in self.rbl_wordline_names[port]] + self.supplies) + + # Top/bottom dummy rows or col caps + 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.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) + + # Left/right Dummy columns + self.dummy_col_insts = [] + self.dummy_col_insts.append(self.add_inst(name="dummy_col_left", + mod=self.row_cap_left)) + self.connect_inst(["dummy_left_" + bl for bl in self.row_cap_left.all_bitline_names] + self.replica_array_wordline_names + self.supplies) + self.dummy_col_insts.append(self.add_inst(name="dummy_col_right", + mod=self.row_cap_right)) + self.connect_inst(["dummy_right_" + bl for bl in self.row_cap_right.all_bitline_names] + self.replica_array_wordline_names + self.supplies) diff --git a/technology/sky130/modules/sky130_replica_column.py b/technology/sky130/modules/sky130_replica_column.py index a900b0fe..db37d26f 100644 --- a/technology/sky130/modules/sky130_replica_column.py +++ b/technology/sky130/modules/sky130_replica_column.py @@ -81,9 +81,9 @@ class sky130_replica_column(sky130_bitcell_base_array): def add_pins(self): self.create_all_bitline_names() - self.create_all_wordline_names(self.row_size+2) + #self.create_all_wordline_names(self.row_size+2) # +2 to add fake wl pins for colends - + self.create_all_wordline_names(self.row_size+1, 1) self.add_pin_list(self.all_bitline_names, "OUTPUT") self.add_pin_list(self.all_wordline_names, "INPUT") @@ -132,8 +132,8 @@ class sky130_replica_column(sky130_bitcell_base_array): self.cell_inst[row]=self.add_inst(name=name, mod=self.replica_cell) self.connect_inst(self.get_bitcell_pins(row, 0)) row_layout.append(self.strap2) - self.add_inst(name=name + "_strap", mod=self.strap2) - self.connect_inst(self.get_strap_pins(row, 0)) + self.add_inst(name=name + "_strap_p", mod=self.strap2) + self.connect_inst(self.get_strap_pins(row, 0, name + "_strap_p")) alternate_bitcell = 1 else: @@ -141,24 +141,24 @@ class sky130_replica_column(sky130_bitcell_base_array): self.cell_inst[row]=self.add_inst(name=name, mod=self.replica_cell2) self.connect_inst(self.get_bitcell_pins(row, 0)) row_layout.append(self.strap2) - self.add_inst(name=name + "_strap", mod=self.strap2) - self.connect_inst(self.get_strap_pins(row, 0)) + self.add_inst(name=name + "_strap_p", mod=self.strap2) + self.connect_inst(self.get_strap_pins(row, 0, name + "_strap_p")) alternate_bitcell = 0 elif (row == 0): row_layout.append(self.colend) self.cell_inst[row]=self.add_inst(name=name, mod=self.colend) - self.connect_inst(self.get_col_cap_p_pins(row, 0)) + self.connect_inst(self.get_col_cap_pins(row, 0)) row_layout.append(self.colend_p_cent) self.add_inst(name=name + "_cap", mod=self.colend_p_cent) - self.connect_inst(self.get_col_cap_pins(row, 0)) + self.connect_inst(self.get_col_cap_p_pins(row, 0)) elif (row == self.total_size - 1): row_layout.append(self.colenda) self.cell_inst[row]=self.add_inst(name=name, mod=self.colenda) - self.connect_inst(self.get_col_cap_p_pins(row, 0)) + self.connect_inst(self.get_col_cap_pins(row, 0)) row_layout.append(self.colenda_p_cent) self.add_inst(name=name + "_cap", mod=self.colenda_p_cent) - self.connect_inst(self.get_col_cap_pins(row, 0)) + self.connect_inst(self.get_col_cap_p_pins(row, 0)) self.array_layout.append(row_layout) diff --git a/technology/sky130/tech/tech.py b/technology/sky130/tech/tech.py index a2c4d185..f82855c6 100644 --- a/technology/sky130/tech/tech.py +++ b/technology/sky130/tech/tech.py @@ -100,7 +100,7 @@ cell_properties.bitcell_2port.port_map = {'bl0': 'BL0', 'gnd': 'GND'} cell_properties.col_cap_1port_bitcell = cell(['br', 'vdd', 'gnd', 'bl'], - ['INPUT', 'INPUT', 'GROUND', 'POWER'], + ['INPUT', 'POWER', 'GROUND', 'INPUT'], {'bl': 'BL0', 'br': 'BL1', 'vdd': 'VPWR',