From ba51149dcef483aff06b5d014a9bb3c286a1929e Mon Sep 17 00:00:00 2001 From: Jesse Cirimelli-Low Date: Sat, 26 Aug 2023 18:54:07 -0700 Subject: [PATCH] placement working for sp capped rba, need fix rowcap patterns --- Makefile | 2 +- .../modules/capped_replica_bitcell_array.py | 76 +++----- compiler/modules/replica_bitcell_array.py | 20 +- compiler/modules/row_cap_array.py | 30 +-- .../sky130_capped_replica_bitcell_array.py | 2 +- .../sky130/custom/sky130_col_cap_array.py | 55 +++++- technology/sky130/custom/sky130_corner.py | 18 +- .../sky130/custom/sky130_row_cap_array.py | 182 +++++++----------- technology/sky130/tech/tech.py | 5 +- 9 files changed, 177 insertions(+), 213 deletions(-) diff --git a/Makefile b/Makefile index 18768dd4..dc07a5b1 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ SRAM_LIB_GIT_REPO ?= https://github.com/vlsida/sky130_fd_bd_sram.git # Use this for development #SRAM_LIB_GIT_REPO ?= git@github.com:VLSIDA/sky130_fd_bd_sram.git #SRAM_LIB_GIT_REPO ?= https://github.com/google/skywater-pdk-libs-sky130_fd_bd_sram.git -SRAM_LIB_GIT_COMMIT ?= 060f3638be6269dd9aa82cfbbdfd9525943c1582 +SRAM_LIB_GIT_COMMIT ?= 9fcf3a78398037583b6d6c1ebac71957343c4bd8 # Open PDKs OPEN_PDKS_DIR ?= $(PDK_ROOT)/open_pdks diff --git a/compiler/modules/capped_replica_bitcell_array.py b/compiler/modules/capped_replica_bitcell_array.py index 8e1395d1..a2976235 100644 --- a/compiler/modules/capped_replica_bitcell_array.py +++ b/compiler/modules/capped_replica_bitcell_array.py @@ -51,10 +51,7 @@ class capped_replica_bitcell_array(bitcell_base_array): self.rbls = self.left_rbl + self.right_rbl # Two dummy rows plus replica even if we don't add the column - self.extra_rows = sum(self.rbl) - # If we aren't using row/col caps, then we need to use the bitcell - if not self.cell.end_caps: - self.extra_rows += 2 + self.extra_rows = sum(self.rbl) + 2 self.create_netlist() if not OPTS.netlist_only: @@ -85,7 +82,7 @@ class capped_replica_bitcell_array(bitcell_base_array): cols=self.column_size + len(self.rbls), rows=1, # dummy column + left replica column(s) - column_offset=1, + column_offset=0, mirror=0, location="top") @@ -93,7 +90,7 @@ class capped_replica_bitcell_array(bitcell_base_array): cols=self.column_size + len(self.rbls), rows=1, # dummy column + left replica column(s) - column_offset=1, + column_offset=0, mirror=0, location="bottom") @@ -104,7 +101,7 @@ class capped_replica_bitcell_array(bitcell_base_array): cols=1, column_offset=0, rows=self.row_size + self.extra_rows, - mirror=(self.rbl[0] + 1) % 2) + location="left") self.row_cap_right = factory.create(module_type=row_cap_module_type, cols=1, @@ -112,9 +109,9 @@ class capped_replica_bitcell_array(bitcell_base_array): # + left replica column(s) # + bitcell columns # + right replica column(s) - column_offset=1 + len(self.left_rbl) + self.column_size + self.rbl[0], + column_offset=len(self.left_rbl) + self.column_size + self.rbl[0], rows=self.row_size + self.extra_rows, - mirror=(self.rbl[0] + 1) % 2) + location="right") def add_pins(self): @@ -201,36 +198,26 @@ class capped_replica_bitcell_array(bitcell_base_array): # row-based or column based power and ground lines. self.vertical_pitch = 1.1 * getattr(self, "{}_pitch".format(self.supply_stack[0])) self.horizontal_pitch = 1.1 * getattr(self, "{}_pitch".format(self.supply_stack[2])) - # FIXME: custom sky130 replica module has a better version of this offset - self.unused_offset = vector(0.25, 0.25) - - # This is a bitcell x bitcell offset to scale - self.bitcell_offset = vector(self.cell.width, self.cell.height) - self.col_end_offset = vector(self.cell.width, self.cell.height) - self.row_end_offset = vector(self.cell.width, self.cell.height) # Everything is computed with the replica array - self.replica_bitcell_array_inst.place(offset=self.unused_offset) + self.replica_bitcell_array_inst.place(offset=0) self.add_end_caps() - - # shift everything up and right to account for cap cells - self.translate_all(self.bitcell_offset.scale(-1, -1)) - - self.width = self.dummy_col_insts[1].rx() + self.unused_offset.x - self.height = self.dummy_row_insts[1].uy() - + + self.width = max([x.rx() for x in self.insts]) - min([x.lx() for x in self.insts]) + self.height = max([x.uy() for x in self.insts]) - min([y.by() for y in self.insts]) + self.add_layout_pins() self.route_supplies() self.route_unused_wordlines() - lower_left = self.find_lowest_coords() - upper_right = self.find_highest_coords() - self.width = upper_right.x - lower_left.x - self.height = upper_right.y - lower_left.y - self.translate_all(lower_left) + self.width = max([x.rx() for x in self.insts]) - min([x.lx() for x in self.insts]) + self.height = max([x.uy() for x in self.insts]) - min([y.by() for y in self.insts]) + ll=vector(min([x.lx() for x in self.insts]),min([y.by() for y in self.insts])) + + self.translate_all(ll) self.add_boundary() @@ -248,7 +235,7 @@ class capped_replica_bitcell_array(bitcell_base_array): def get_main_array_right(self): return self.replica_bitcell_array_inst.lx() + self.replica_bitcell_array.get_main_array_right() - # FIXME: these names need to be changed to reflect what they're actually returning + #FIXME: these names need to be changed to reflect what they're actually returning def get_replica_top(self): return self.dummy_row_insts[1].by() @@ -273,26 +260,23 @@ class capped_replica_bitcell_array(bitcell_base_array): def add_end_caps(self): """ Add dummy cells or end caps around the array """ - # Far top dummy row (first row above array is NOT flipped if even number of rows) - flip_dummy = (self.row_size + self.rbl[1]) % 2 - dummy_row_offset = self.bitcell_offset.scale(0, flip_dummy) + self.replica_bitcell_array_inst.ul() - self.dummy_row_insts[1].place(offset=dummy_row_offset, - mirror="MX" if flip_dummy else "R0") + # Far top dummy row + offset = self.replica_bitcell_array_inst.ul() + self.dummy_row_insts[1].place(offset=offset) - # Far bottom dummy row (first row below array IS flipped) - flip_dummy = (self.rbl[0] + 1) % 2 - dummy_row_offset = self.bitcell_offset.scale(0, flip_dummy - 1) + self.unused_offset - self.dummy_row_insts[0].place(offset=dummy_row_offset, - mirror="MX" if flip_dummy else "R0") + # Far bottom dummy row + dummy_row_height = vector(0, self.dummy_row_insts[0].height) + offset = self.replica_bitcell_array_inst.ll() - dummy_row_height + self.dummy_row_insts[0].place(offset=offset) + # Far left dummy col - # Shifted down by the number of left RBLs even if we aren't adding replica column to this bitcell array - dummy_col_offset = self.bitcell_offset.scale(-1, -1) + self.unused_offset - self.dummy_col_insts[0].place(offset=dummy_col_offset) + dummy_col_width = vector(self.dummy_col_insts[0].width, 0) + offset = self.dummy_row_insts[0].ll() - dummy_col_width + self.dummy_col_insts[0].place(offset=offset) # Far right dummy col - # Shifted down by the number of left RBLs even if we aren't adding replica column to this bitcell array - dummy_col_offset = self.bitcell_offset.scale(0, -1) + self.replica_bitcell_array_inst.lr() - self.dummy_col_insts[1].place(offset=dummy_col_offset) + offset = self.dummy_row_insts[0].lr() + self.dummy_col_insts[1].place(offset=offset) def add_layout_pins(self): for pin_name in self.used_wordline_names + self.bitline_pin_list: diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 805b39f0..cbfdfbb1 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -232,32 +232,30 @@ class replica_bitcell_array(bitcell_base_array): self.vertical_pitch = 1.1 * getattr(self, "{}_pitch".format(self.supply_stack[0])) self.horizontal_pitch = 1.1 * getattr(self, "{}_pitch".format(self.supply_stack[2])) - # This is a bitcell x bitcell offset to scale - self.bitcell_offset = vector(self.cell.width, self.cell.height) - self.col_end_offset = vector(self.cell.width, self.cell.height) - self.row_end_offset = vector(self.cell.width, self.cell.height) - # Everything is computed with the main array - self.bitcell_array_inst.place(offset=0) + self.bitcell_array_inst.place(offset=(0,0)) self.add_replica_columns() # Array was at (0, 0) but move everything so it is at the lower left # We move DOWN the number of left RBL even if we didn't add the column to this bitcell array # Note that this doesn't include the row/col cap - array_offset = self.bitcell_offset.scale(-len(self.left_rbl), -self.rbl[0]) - self.translate_all(array_offset) + + #rbc_width = (self.replica_col_insts[0].width, 0) + #dummy_height = max(x for x in map(lambda x: x if x != None else 0, self.)) + #array_offset = self.bitcell_offset.scale(-len(self.left_rbl), -self.rbl[0]) + ll=vector(min([x.lx() for x in self.insts]),min([y.by() for y in self.insts])) + + self.translate_all(ll) self.add_layout_pins() self.route_supplies() - ll=vector(min([x.lx() for x in self.insts]),min([y.by() for y in self.insts])) - self.width = max([x.rx() for x in self.insts]) - min([x.lx() for x in self.insts]) self.height = max([x.uy() for x in self.insts]) - min([y.by() for y in self.insts]) - self.add_boundary(ll) + self.add_boundary() self.DRC_LVS() diff --git a/compiler/modules/row_cap_array.py b/compiler/modules/row_cap_array.py index 34760177..3c91932b 100644 --- a/compiler/modules/row_cap_array.py +++ b/compiler/modules/row_cap_array.py @@ -12,9 +12,10 @@ class row_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() if not OPTS.netlist_only: @@ -69,35 +70,12 @@ class row_cap_array(bitcell_base_array): return bitcell_pins - def place_array(self, name_template, row_offset=0): - xoffset = 0.0 - for col in range(self.column_size): - yoffset = self.cell.height - tempx, dir_y = self._adjust_x_offset(xoffset, col, self.column_offset) - - for row in range(self.row_size): - tempy, dir_x = self._adjust_y_offset(yoffset, row + 1, row_offset) - - if dir_x and dir_y: - dir_key = "XY" - elif dir_x: - dir_key = "MX" - elif dir_y: - dir_key = "MY" - else: - dir_key = "" - - self.cell_inst[row, col].place(offset=[tempx, tempy], - mirror=dir_key) - yoffset += self.cell.height - xoffset += self.cell.width - def add_layout_pins(self): """ Add the layout pins """ row_list = self.cell.get_all_wl_names() - for row in range(1, self.row_size - 1): + for row in range(0, self.row_size - 2): 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), @@ -106,7 +84,7 @@ class row_cap_array(bitcell_base_array): width=self.width, height=wl_pin.height()) - for row in range(1, self.row_size - 1): + for row in range(0, self.row_size - 2): for col in range(self.column_size): inst = self.cell_inst[row, col] for pin_name in ["vdd", "gnd"]: diff --git a/technology/sky130/custom/sky130_capped_replica_bitcell_array.py b/technology/sky130/custom/sky130_capped_replica_bitcell_array.py index ca3a9648..49868bbe 100644 --- a/technology/sky130/custom/sky130_capped_replica_bitcell_array.py +++ b/technology/sky130/custom/sky130_capped_replica_bitcell_array.py @@ -22,4 +22,4 @@ class sky130_capped_replica_bitcell_array(capped_replica_bitcell_array, sky130_b """ def __init__(self, rows, cols, rbl=None, left_rbl=None, right_rbl=None, name=""): super().__init__(rows, cols, rbl, left_rbl, right_rbl, name) - + diff --git a/technology/sky130/custom/sky130_col_cap_array.py b/technology/sky130/custom/sky130_col_cap_array.py index 03ea574c..eb44bc81 100644 --- a/technology/sky130/custom/sky130_col_cap_array.py +++ b/technology/sky130/custom/sky130_col_cap_array.py @@ -11,13 +11,15 @@ from openram.tech import layer from openram import OPTS from openram.modules.col_cap_array import col_cap_array from .sky130_bitcell_base_array import sky130_bitcell_base_array +from openram.modules import pattern +from math import ceil class sky130_col_cap_array(col_cap_array, sky130_bitcell_base_array): """ Generate a dummy row/column for the replica array. """ def __init__(self, rows, cols, column_offset=0, mirror=0, location="", name=""): - super().__init__(rows, cols, column_offset=0, mirror=0, location="", name="") + super().__init__(rows, cols, column_offset=column_offset, mirror=mirror, location=location, name=name) def add_modules(self): """ Add the modules used in this design """ @@ -33,4 +35,53 @@ class sky130_col_cap_array(col_cap_array, sky130_bitcell_base_array): self.cell = factory.create(module_type=OPTS.bitcell, version="opt1") def create_instances(self): - \ No newline at end of file + self.all_inst={} + self.cell_inst={} + + bit_row = [geometry.instance("00_colend", mod=self.colend1, is_bitcell=True)] \ + + [geometry.instance("01_strap_p_cent", mod=self.colend2, is_bitcell=False)]\ + + [geometry.instance("02_colend", mod=self.colend1, is_bitcell=True, mirror="MY")] \ + + [geometry.instance("03_strap_p", mod=self.colend3, is_bitcell=False)] + + bit_row = pattern.rotate_list(bit_row, self.column_offset * 2) + bit_block = [] + pattern.append_row_to_block(bit_block, bit_row) + self.pattern = pattern(self, "col_cap_array_" + self.location , bit_block, num_rows=self.row_size, num_cols=self.column_size, num_cores_x=ceil(self.column_size/2), num_cores_y=ceil(self.row_size/2), name_template="col_cap_array" + self.location + "_r{0}_c{1}") + self.pattern.connect_array() + + + 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 + """ + 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))]) + bitcell_pins.append("vdd") # vdd + bitcell_pins.append("gnd") # gnd + bitcell_pins.append("vdd") # vpb + bitcell_pins.append("gnd") # vnb + #bitcell_pins.extend([x for x in self.all_wordline_names if x.endswith("_{0}".format(row))]) + + return bitcell_pins + + def get_strap_pins(self, row, col): + + strap_pins = [] + if col % 2 == 0 and col % 4 != 0: + strap_pins.append("vdd") # vdd + else: + strap_pins.append("gnd") # gnd + strap_pins.append("vdd") # vpb + strap_pins.append("gnd") # vnb + + return strap_pins + + def create_layout(self): + + self.place_array() + self.add_layout_pins() + + self.add_boundary() + self.DRC_LVS() \ No newline at end of file diff --git a/technology/sky130/custom/sky130_corner.py b/technology/sky130/custom/sky130_corner.py index 164e07a0..1abf832a 100644 --- a/technology/sky130/custom/sky130_corner.py +++ b/technology/sky130/custom/sky130_corner.py @@ -7,27 +7,21 @@ from openram import debug from openram.base import design -from openram.base import get_libcell_size -from openram.tech import layer, GDS +from openram.tech import cell_properties as props class sky130_corner(design): def __init__(self, location, name=""): - super().__init__(name) if location == "ul": - self.name = "sky130_fd_bd_sram__sram_sp_corner" + cell_name = "sky130_fd_bd_sram__sram_sp_corner" elif location == "ur": - self.name = "sky130_fd_bd_sram__sram_sp_cornerb" + cell_name = "sky130_fd_bd_sram__sram_sp_cornerb" elif location == "ll": - self.name = "sky130_fd_bd_sram__sram_sp_cornera" + cell_name = "sky130_fd_bd_sram__sram_sp_cornera" elif location == "lr": - self.name = "sky130_fd_bd_sram__sram_sp_cornera" + cell_name = "sky130_fd_bd_sram__sram_sp_cornera" else: debug.error("Invalid sky130_corner location", -1) - design.__init__(self, name=self.name) - (self.width, self.height) = get_libcell_size(self.name, - GDS["unit"], - layer["mem"]) - # pin_map = get_libcell_pins(pin_names, self.name, GDS["unit"]) + super().__init__(name=name, cell_name=cell_name, prop=props.col_cap_1port_strap_power) diff --git a/technology/sky130/custom/sky130_row_cap_array.py b/technology/sky130/custom/sky130_row_cap_array.py index f8d9d91c..b0754896 100644 --- a/technology/sky130/custom/sky130_row_cap_array.py +++ b/technology/sky130/custom/sky130_row_cap_array.py @@ -5,140 +5,100 @@ # All rights reserved. # +from openram.base import geometry from openram.sram_factory import factory from openram import OPTS from .sky130_bitcell_base_array import sky130_bitcell_base_array +from openram.modules.row_cap_array import row_cap_array +from openram.modules.pattern import pattern +from math import ceil - -class sky130_row_cap_array(sky130_bitcell_base_array): +class sky130_row_cap_array(row_cap_array, sky130_bitcell_base_array): """ Generate a dummy row/column for the replica array. """ - def __init__(self, rows, cols, column_offset=0, mirror=0, name=""): - # Don't call the regular col-cap_array constructor since we don't want its constructor, just - # some of it's useful member functions - sky130_bitcell_base_array.__init__(self, rows=rows, cols=cols, column_offset=column_offset, name=name) - self.rows = rows - self.cols = cols - self.column_offset = column_offset + def __init__(self, rows, cols, column_offset=0, mirror=0, location="", name=""): + super().__init__(rows, cols, column_offset=column_offset, location=location, name=name) self.mirror = mirror - self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() - - def create_netlist(self): - """ Create and connect the netlist """ - self.create_all_wordline_names() - # This module has no bitlines - # self.create_all_bitline_names() - - self.add_modules() - self.add_pins() - self.create_instances() - - def create_layout(self): - - self.place_array("dummy_r{0}_c{1}", self.mirror) - self.add_layout_pins() - - self.width = max([x.rx() for x in self.insts]) - self.height = max([x.uy() for x in self.insts]) - - self.add_boundary() - self.DRC_LVS() - + self.location = location def add_modules(self): """ Add the modules used in this design """ if self.column_offset == 0: self.top_corner = factory.create(module_type="corner", location="ul") self.bottom_corner =factory.create(module_type="corner", location="ll") - self.rowend1 = factory.create(module_type="row_cap", version="rowend_replica") - self.rowend2 = factory.create(module_type="row_cap", version="rowenda_replica") + #self.rowend1 = factory.create(module_type="row_cap", version="rowend_replica") + #self.rowend2 = factory.create(module_type="row_cap", version="rowenda_replica") else: self.top_corner = factory.create(module_type="corner", location="ur") self.bottom_corner = factory.create(module_type="corner", location="lr") - self.rowend1 = factory.create(module_type="row_cap", version="rowend") - self.rowend2 = factory.create(module_type="row_cap", version="rowenda") - + #self.rowend1 = factory.create(module_type="row_cap", version="rowend") + #self.rowend2 = factory.create(module_type="row_cap", version="rowenda") + self.rowend = factory.create(module_type="row_cap", version="rowend") + self.rowenda = factory.create(module_type="row_cap", version="rowenda") self.cell = factory.create(module_type=OPTS.bitcell, version="opt1") def create_instances(self): - """ Create the module instances used in this design """ - self.cell_inst = {} - self.array_layout = [] - alternate_bitcell = (self.rows + 1) % 2 - for row in range(self.rows + 2): - row_layout = [] - name="rca_{0}".format(row) - # Top/bottom cell are always dummy cells. - # Regular array cells are replica cells (>left_rbl and 0): - - if alternate_bitcell == 0: - row_layout.append(self.rowend1) - self.cell_inst[row]=self.add_inst(name=name, mod=self.rowend1) - self.connect_inst(["wl_0_{}".format(row - 1), "vdd"]) - alternate_bitcell = 1 - - else: - row_layout.append(self.rowend2) - self.cell_inst[row] = self.add_inst(name=name, mod=self.rowend2) - self.connect_inst(["wl_0_{}".format(row - 1), "vdd"]) - 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_corner_pins()) - - 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_corner_pins()) - - self.array_layout.append(row_layout) - - def place_array(self, name_template, row_offset=0): - xoffset = 0.0 - yoffset = 0.0 - for row in range(len(self.insts)): - inst = self.insts[row] - if row == 0: - inst.place(offset=[xoffset, yoffset + inst.height], mirror="MX") - elif row == len(self.insts)-1: - inst.place(offset=[xoffset, yoffset]) + self.all_inst={} + self.cell_inst={} + + bit_block = [] + top_corner = geometry.instance("row_cap_top_corner", mod=self.top_corner, is_bitcell=False, mirror="XY") + bottom_corner = geometry.instance("row_cap_bottom_corner", mod=self.bottom_corner, is_bitcell=False) + rowend = geometry.instance("row_cap_rowend", mod=self.rowend, is_bitcell=True) + rowenda = geometry.instance("row_cap_rowenda", mod=self.rowenda, is_bitcell=True, mirror="XY") + + pattern.append_row_to_block(bit_block, [top_corner]) + for row in range(1,self.row_size-1): + if row % 2 == 0: + pattern.append_row_to_block(bit_block, [rowend]) else: - if row % 2 ==0: - inst.place(offset=[xoffset, yoffset + inst.height], mirror="MX") - else: - inst.place(offset=[xoffset, yoffset]) - yoffset += inst.height + pattern.append_row_to_block(bit_block, [rowenda]) + pattern.append_row_to_block(bit_block, [bottom_corner]) + self.pattern = pattern(self, "row_cap_array_" + self.location, bit_block, num_rows=self.row_size, num_cols=self.column_size, num_cores_x=ceil(self.column_size/2), num_cores_y=ceil(self.row_size/2), name_template="row_cap_array" + self.location + "_r{0}_c{1}") + self.pattern.connect_array_raw() + + + 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 + """ - def add_pins(self): - for row in range(self.rows + 2): + bitcell_pins = [] + bitcell_pins.append("vdd") # vdd + bitcell_pins.extend([x for x in self.all_wordline_names if x.endswith("_{0}".format(row))]) + + #bitcell_pins.extend([x for x in self.all_wordline_names if x.endswith("_{0}".format(row))]) + + return bitcell_pins + + def get_strap_pins(self, row, col): + + strap_pins = [] + + strap_pins.append("vdd") # vdd + strap_pins.append("vdd") # vpb + strap_pins.append("gnd") # vnb + + return strap_pins + + def create_all_wordline_names(self, row_size=None, start_row=0): + if row_size == None: + row_size = self.row_size + row_size = row_size - 2 + for row in range(start_row, row_size): for port in self.all_ports: - self.add_pin("wl_{}_{}".format(port, row), "OUTPUT") - self.add_pin("vdd", "POWER") - self.add_pin("gnd", "GROUND") + self.wordline_names[port].append("wl_{0}_{1}".format(port, row)) - def add_layout_pins(self): - """ Add the layout pins """ - for row in range(0, self.rows + 1): - if row > 0 and row < self.rows + 1: - wl_pin = self.cell_inst[row].get_pin("wl") - self.add_layout_pin(text="wl_0_{0}".format(row -1), - layer=wl_pin.layer, - offset=wl_pin.ll().scale(0, 1), - width=self.width, - height=wl_pin.height()) + self.all_wordline_names = [x for sl in zip(*self.wordline_names) for x in sl] + + def create_layout(self): - # Add vdd/gnd via stacks - for row in range(1, self.rows): - inst = self.cell_inst[row] - for pin_name in ["vdd", "gnd"]: - for pin in inst.get_pins(pin_name): - self.copy_layout_pin(inst, pin_name) + self.place_array() + self.add_layout_pins() + + self.add_boundary() + self.DRC_LVS() + diff --git a/technology/sky130/tech/tech.py b/technology/sky130/tech/tech.py index 9c491013..51a4b8d7 100755 --- a/technology/sky130/tech/tech.py +++ b/technology/sky130/tech/tech.py @@ -114,13 +114,12 @@ cell_properties.bitcell_2port.vdd_dir = "H" cell_properties.bitcell_2port.gnd_layer = "m2" cell_properties.bitcell_2port.gnd_dir = "H" -cell_properties.col_cap_1port_bitcell = d.cell(['bl', 'vdd', 'gnd', 'br', 'gate', 'vpb', 'vnb'], - ['INPUT', 'POWER', 'GROUND', 'INPUT', 'INPUT', 'BIAS', 'BIAS'], +cell_properties.col_cap_1port_bitcell = d.cell(['bl', 'br', 'vdd', 'gnd', 'vpb', 'vnb'], + ['INPUT', 'INPUT','POWER', 'GROUND', 'BIAS', 'BIAS'], {'bl': 'bl', 'br': 'br', 'vdd': 'vdd', 'gnd': 'gnd', - 'gate': 'gate', 'vnb': 'vnb', 'vpb': 'vpb'}) cell_properties.col_cap_1port_bitcell.boundary_layer = "mem"