From 68d74737f7dff953675abf83e65f7c8635d44177 Mon Sep 17 00:00:00 2001 From: mrg Date: Tue, 13 Oct 2020 07:41:21 -0700 Subject: [PATCH 1/2] Different bitcell and array supply pins --- compiler/modules/bitcell_base_array.py | 33 +++++++++++--------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/compiler/modules/bitcell_base_array.py b/compiler/modules/bitcell_base_array.py index 90eb7910..06fcafb5 100644 --- a/compiler/modules/bitcell_base_array.py +++ b/compiler/modules/bitcell_base_array.py @@ -9,7 +9,6 @@ import debug import design from tech import cell_properties from sram_factory import factory -from globals import OPTS class bitcell_base_array(design.design): @@ -27,7 +26,6 @@ class bitcell_base_array(design.design): # Bitcell for port names only self.cell = factory.create(module_type="bitcell") - self.wordline_names = [[] for port in self.all_ports] self.all_wordline_names = [] self.bitline_names = [[] for port in self.all_ports] @@ -37,9 +35,11 @@ class bitcell_base_array(design.design): self.rbl_wordline_names = [[] for port in self.all_ports] self.all_rbl_wordline_names = [] - def get_all_bitline_names(self, prefix=""): - return [prefix + x for x in self.all_bitline_names] - + # The supply pin namesn + self.bitcell_supplies = ["vdd", "gnd"] + # If the technology needs renaming of the supplies + self.supplies = self.bitcell_supplies + def create_all_bitline_names(self): for col in range(self.column_size): for port in self.all_ports: @@ -54,11 +54,7 @@ class bitcell_base_array(design.design): def create_all_wordline_names(self, remove_num_wordlines=0): for row in range(self.row_size - remove_num_wordlines): for port in self.all_ports: - if not cell_properties.compare_ports(cell_properties.bitcell.split_wl): - self.wordline_names[port].append("wl_{0}_{1}".format(port, row)) - else: - self.wordline_names[port].append("wl0_{0}_{1}".format(port, row)) - self.wordline_names[port].append("wl1_{0}_{1}".format(port, row)) + self.wordline_names[port].append("wl_{0}_{1}".format(port, row)) self.all_wordline_names = [x for sl in zip(*self.wordline_names) for x in sl] @@ -67,10 +63,9 @@ class bitcell_base_array(design.design): self.add_pin(bl_name, "INOUT") for wl_name in self.get_wordline_names(): self.add_pin(wl_name, "INPUT") - self.add_pin("vdd", "POWER") - self.add_pin("gnd", "GROUND") + self.add_pin(self.supplies[0], "POWER") + self.add_pin(self.supplies[1], "GROUND") - def get_bitcell_pins(self, row, col): """ Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """ @@ -78,8 +73,8 @@ class bitcell_base_array(design.design): for port in self.all_ports: bitcell_pins.extend([x for x in self.get_bitline_names(port) if x.endswith("_{0}".format(col))]) bitcell_pins.extend([x for x in self.all_wordline_names if x.endswith("_{0}".format(row))]) - bitcell_pins.append("vdd") - bitcell_pins.append("gnd") + bitcell_pins.append(self.bitcell_supplies[0]) + bitcell_pins.append(self.bitcell_supplies[1]) return bitcell_pins @@ -169,8 +164,8 @@ class bitcell_base_array(design.design): for row in range(self.row_size): for col in range(self.column_size): inst = self.cell_inst[row, col] - for pin_name in ["vdd", "gnd"]: - self.copy_layout_pin(inst, pin_name) + for (pin_name, new_name) in zip(self.bitcell_supplies, self.supplies): + self.copy_layout_pin(inst, pin_name, new_name) def _adjust_x_offset(self, xoffset, col, col_offset): tempx = xoffset @@ -191,7 +186,7 @@ class bitcell_base_array(design.design): return (tempy, dir_x) def place_array(self, name_template, row_offset=0): - # We increase it by a well enclosure so the precharges don't overlap our wells + # We increase it by a well enclosure so the precharges don't overlap our wells self.height = self.row_size * self.cell.height self.width = self.column_size * self.cell.width @@ -213,7 +208,7 @@ class bitcell_base_array(design.design): dir_key = "" self.cell_inst[row, col].place(offset=[tempx, tempy], - mirror=dir_key) + mirror=dir_key) yoffset += self.cell.height xoffset += self.cell.width From 6a1f12b62db320a65bd0ed9bc1030f1d0463aac4 Mon Sep 17 00:00:00 2001 From: mrg Date: Tue, 13 Oct 2020 11:07:31 -0700 Subject: [PATCH 2/2] Refactored to utilize OOP --- compiler/modules/bitcell_array.py | 1 - compiler/modules/bitcell_base_array.py | 9 +++-- compiler/modules/col_cap_array.py | 25 +++++++++---- compiler/modules/dummy_array.py | 13 ++++--- compiler/modules/replica_bitcell_array.py | 44 ++++++++++++++--------- compiler/modules/row_cap_array.py | 4 +++ 6 files changed, 59 insertions(+), 37 deletions(-) diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index 6bd290a2..65470726 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -8,7 +8,6 @@ import debug from bitcell_base_array import bitcell_base_array from tech import drc, spice -from tech import cell_properties as props from globals import OPTS from sram_factory import factory diff --git a/compiler/modules/bitcell_base_array.py b/compiler/modules/bitcell_base_array.py index 06fcafb5..477100fe 100644 --- a/compiler/modules/bitcell_base_array.py +++ b/compiler/modules/bitcell_base_array.py @@ -48,9 +48,6 @@ 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 get_all_wordline_names(self, prefix=""): - # return [prefix + x for x in self.all_wordline_names] - def create_all_wordline_names(self, remove_num_wordlines=0): for row in range(self.row_size - remove_num_wordlines): for port in self.all_ports: @@ -67,8 +64,10 @@ class bitcell_base_array(design.design): self.add_pin(self.supplies[1], "GROUND") def get_bitcell_pins(self, row, col): - """ Creates a list of connections in the bitcell, - indexed by column and row, for instance use in bitcell_array """ + """ + Creates a list of connections in the bitcell, + indexed by column and row, for instance use in bitcell_array + """ bitcell_pins = [] for port in self.all_ports: bitcell_pins.extend([x for x in self.get_bitline_names(port) if x.endswith("_{0}".format(col))]) diff --git a/compiler/modules/col_cap_array.py b/compiler/modules/col_cap_array.py index a2bf8379..392f573c 100644 --- a/compiler/modules/col_cap_array.py +++ b/compiler/modules/col_cap_array.py @@ -13,9 +13,10 @@ class col_cap_array(bitcell_base_array): """ Generate a dummy row/column for the replica array. """ - def __init__(self, rows, cols, column_offset=0, mirror=0, name=""): + def __init__(self, rows, cols, column_offset=0, mirror=0, location="", name=""): super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name) self.mirror = mirror + self.location = location self.no_instances = True self.create_netlist() @@ -24,6 +25,10 @@ class col_cap_array(bitcell_base_array): def create_netlist(self): """ Create and connect the netlist """ + # This will create a default set of bitline/wordline names + self.create_all_wordline_names() + self.create_all_bitline_names() + self.add_modules() self.add_pins() self.create_instances() @@ -58,12 +63,18 @@ class col_cap_array(bitcell_base_array): indexed by column and row, for instance use in bitcell_array """ - pin_name = cell_properties.bitcell.cell_1rw1r.pin - bitcell_pins = ["{0}_{1}".format(pin_name.bl0, col), - "{0}_{1}".format(pin_name.br0, col), - "{0}_{1}".format(pin_name.bl1, col), - "{0}_{1}".format(pin_name.br1, col), - "vdd"] + if len(self.ports) == 1: + pin_name = cell_properties.bitcell.cell_6t.pin + bitcell_pins = ["{0}_{1}".format(pin_name.bl0, col), + "{0}_{1}".format(pin_name.br0, col), + "vdd"] + else: + pin_name = cell_properties.bitcell.cell_1rw1r.pin + bitcell_pins = ["{0}_{1}".format(pin_name.bl0, col), + "{0}_{1}".format(pin_name.br0, col), + "{0}_{1}".format(pin_name.bl1, col), + "{0}_{1}".format(pin_name.br1, col), + "vdd"] return bitcell_pins diff --git a/compiler/modules/dummy_array.py b/compiler/modules/dummy_array.py index 399073d0..7024a6fc 100644 --- a/compiler/modules/dummy_array.py +++ b/compiler/modules/dummy_array.py @@ -5,7 +5,6 @@ # from bitcell_base_array import bitcell_base_array from sram_factory import factory -from tech import GDS,layer,drc,parameter,cell_properties from tech import cell_properties as props from globals import OPTS @@ -14,20 +13,20 @@ class dummy_array(bitcell_base_array): """ Generate a dummy row/column for the replica array. """ - def __init__(self, rows, cols, column_offset=0, mirror=0, name=""): + def __init__(self, rows, cols, column_offset=0, mirror=0, location="", name=""): super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name) self.mirror = mirror - # This will create a default set of bitline/wordline names - self.create_all_bitline_names() - self.create_all_wordline_names() - self.create_netlist() if not OPTS.netlist_only: self.create_layout() def create_netlist(self): """ Create and connect the netlist """ + # This will create a default set of bitline/wordline names + self.create_all_bitline_names() + self.create_all_wordline_names() + self.add_modules() self.add_pins() self.create_instances() @@ -56,7 +55,7 @@ class dummy_array(bitcell_base_array): for row in range(self.row_size): name = "bit_r{0}_c{1}".format(row, col) self.cell_inst[row, col]=self.add_inst(name=name, - mod=self.dummy_cell) + mod=self.dummy_cell) self.connect_inst(self.get_bitcell_pins(row, col)) def add_pins(self): diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index e468788b..0814728f 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -5,14 +5,14 @@ # import debug -import bitcell_base_array +from bitcell_base_array import bitcell_base_array from tech import drc, spice, cell_properties from vector import vector from globals import OPTS from sram_factory import factory -class replica_bitcell_array(bitcell_base_array.bitcell_base_array): +class replica_bitcell_array(bitcell_base_array): """ Creates a bitcell arrow of cols x rows and then adds the replica and dummy columns and rows. Replica columns are on the left and @@ -150,13 +150,23 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): # Dummy Row or Col Cap, depending on bitcell array properties col_cap_module_type = ("col_cap_array" if end_caps_enabled else "dummy_array") - self.col_cap = factory.create(module_type=col_cap_module_type, - cols=self.column_size, - rows=1, - # dummy column + left replica column - column_offset=1 + len(self.left_rbl), - mirror=0) - self.add_mod(self.col_cap) + self.col_cap_top = factory.create(module_type=col_cap_module_type, + cols=self.column_size, + rows=1, + # dummy column + left replica column(s) + column_offset=1 + len(self.left_rbl), + mirror=0, + location="top") + self.add_mod(self.col_cap_top) + + self.col_cap_bottom = factory.create(module_type=col_cap_module_type, + cols=self.column_size, + rows=1, + # dummy column + left replica column(s) + column_offset=1 + len(self.left_rbl), + mirror=0, + location="bottom") + self.add_mod(self.col_cap_bottom) # Dummy Col or Row Cap, depending on bitcell array properties row_cap_module_type = ("row_cap_array" if end_caps_enabled else "dummy_array") @@ -238,13 +248,13 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): # All wordlines including dummy and RBL self.replica_array_wordline_names = [] - self.replica_array_wordline_names.extend(["gnd"] * len(self.col_cap.get_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.get_wordline_names())) + 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") @@ -285,11 +295,11 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): # 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)) - self.connect_inst(["gnd"] * len(self.col_cap.get_wordline_names()) + self.supplies) + mod=self.col_cap_bottom)) + self.connect_inst(["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)) - self.connect_inst(["gnd"] * len(self.col_cap.get_wordline_names()) + self.supplies) + mod=self.col_cap_top)) + self.connect_inst(["gnd"] * len(self.col_cap_top.get_wordline_names()) + self.supplies) # Left/right Dummy columns self.dummy_col_insts = [] @@ -491,7 +501,7 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): # replica column should only have a vdd/gnd in the dummy cell on top/bottom supply_insts = self.dummy_col_insts + self.dummy_row_insts - for pin_name in self.supplies: + for pin_name in self.supplies: for inst in supply_insts: pin_list = inst.get_pins(pin_name) for pin in pin_list: @@ -524,7 +534,7 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): """ Connect the unused RBL and dummy wordlines to gnd """ # This grounds all the dummy row word lines for inst in self.dummy_row_insts: - for wl_name in self.col_cap.get_wordline_names(): + for wl_name in self.col_cap_top.get_wordline_names(): self.ground_pin(inst, wl_name) # Ground the unused replica wordlines diff --git a/compiler/modules/row_cap_array.py b/compiler/modules/row_cap_array.py index 58b33c89..f327aecf 100644 --- a/compiler/modules/row_cap_array.py +++ b/compiler/modules/row_cap_array.py @@ -23,6 +23,10 @@ class row_cap_array(bitcell_base_array): def create_netlist(self): """ Create and connect the netlist """ + # This will create a default set of bitline/wordline names + self.create_all_wordline_names() + self.create_all_bitline_names() + self.add_modules() self.add_pins() self.create_instances()