From 5246d0a93ba845a4a7f3db5fe89de5d61eaf807d Mon Sep 17 00:00:00 2001 From: jcirimel Date: Mon, 5 Oct 2020 12:10:44 -0700 Subject: [PATCH] track s8 customs modules --- compiler/custom/s8_col_cap_array.py | 136 +++++++++++++++++++++++ compiler/custom/s8_dummy_bitcell.py | 52 +++++++++ compiler/custom/s8_row_cap_array.py | 166 ++++++++++++++++++++++++++++ compiler/custom/s8_row_end.py | 34 ++++++ 4 files changed, 388 insertions(+) create mode 100644 compiler/custom/s8_col_cap_array.py create mode 100644 compiler/custom/s8_dummy_bitcell.py create mode 100644 compiler/custom/s8_row_cap_array.py create mode 100644 compiler/custom/s8_row_end.py diff --git a/compiler/custom/s8_col_cap_array.py b/compiler/custom/s8_col_cap_array.py new file mode 100644 index 00000000..9b275fbd --- /dev/null +++ b/compiler/custom/s8_col_cap_array.py @@ -0,0 +1,136 @@ +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2019 Regents of the University of California +# All rights reserved. +# +import design +from sram_factory import factory +from globals import OPTS +from tech import cell_properties + + +class s8_col_cap_array(design.design): + """ + Generate a dummy row/column for the replica array. + """ + def __init__(self, rows, cols, location, column_offset=0, mirror=0, name=""): + super().__init__(name) + self.rows = rows + self.cols = cols + self.location = location + self.column_offset = column_offset + self.mirror = mirror + self.no_instances = True + self.create_netlist() + if not OPTS.netlist_only: + self.create_layout() + + def create_netlist(self): + """ Create and connect the netlist """ + self.add_modules() + self.add_pins() + self.create_instances() + + def create_layout(self): + + self.place_array("col_cap_r{0}_c{1}", self.mirror) + self.add_layout_pins() + self.add_boundary() + self.DRC_LVS() + + def add_modules(self): + """ Add the modules used in this design """ + if self.location == "top": + self.colend1 = factory.create(module_type="s8_col_end", version = "colend") + self.add_mod(self.colend1) + self.colend2 = factory.create(module_type="s8_col_end", version = "colend_p_cent") + self.add_mod(self.colend2) + elif self.location == "bottom": + self.colend1 = factory.create(module_type="s8_col_end", version = "colenda") + self.add_mod(self.colend1) + self.colend2 = factory.create(module_type="s8_col_end", version = "colenda_p_cent") + self.add_mod(self.colend2) + + self.cell = factory.create(module_type="s8_bitcell", version = "opt1") + + def create_instances(self): + """ Create the module instances used in this design """ + self.cell_inst = {} + self.array_layout = [] + alternate_bitcell = 0 + for col in range((self.cols * 2 )-1): + row_layout = [] + name="rca_{0}".format(col) + # Top/bottom cell are always dummy cells. + # Regular array cells are replica cells (>left_rbl and 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(self.get_bitcell_pins(row, 0)) + 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)) + 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)) + + 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.array_layout.append(row_layout) + + + 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 + """ + + pin_name = cell_properties.bitcell.cell_1rw1r.pin + bitcell_pins = ["{0}_{1}".format(pin_name.wl0, row), + "{0}_{1}".format(pin_name.wl1, row), + "gnd"] + + return bitcell_pins + + def place_array(self, name_template, row_offset=0): + self.width = 0 + self.height = 0 + + for inst in self.insts: + self.height += inst.height + if inst.width > self.width: + self.width = inst.width + yoffset = 0.0 + + for row in range(0, len(self.array_layout)): + 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]) + xoffset += inst.width + yoffset += inst.height + + + + def add_pins(self): + for row in range(self.rows-2): + for port in self.all_ports: + self.add_pin("wl_{}_{}".format(port, row), "INPUT") + for row in range(self.rows-2): + for port in self.all_ports: + self.add_pin("wl0_{}_{}".format(port, row), "OUTPUT") + self.add_pin("wl1_{}_{}".format(port, row), "OUTPUT") + self.add_pin("vpwr", "POWER") + self.add_pin("vgnd", "GROUND") + + def add_layout_pins(self): + """ Add the layout pins """ + return + 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()) + + # 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"]: + for pin in inst.get_pins(pin_name): + self.add_power_pin(name=pin.name, + loc=pin.center(), + start_layer=pin.layer) + diff --git a/compiler/custom/s8_row_end.py b/compiler/custom/s8_row_end.py new file mode 100644 index 00000000..e9902397 --- /dev/null +++ b/compiler/custom/s8_row_end.py @@ -0,0 +1,34 @@ +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2019 Regents of the University of California and The Board +# of Regents for the Oklahoma Agricultural and Mechanical College +# (acting for and on behalf of Oklahoma State University) +# All rights reserved. +# + +import debug +import design +import utils +from globals import OPTS +from tech import parameter, drc, layer, GDS + +class s8_row_end(design.design): + + + def __init__(self, version, name=""): + super().__init__(name) + pin_names = [] + type_list = [] + + if version == "rowend": + self.name = "s8sram16x16_rowend" + elif version == "rowenda": + self.name = "s8sram16x16_rowenda" + else: + debug.error("Invalid type for row_end", -1) + design.design.__init__(self, name=self.name) + (self.width, self.height) = utils.get_libcell_size(self.name, + GDS["unit"], + layer["mem"], + "s8sram16x16_rowend_ce\x00") + pin_map = utils.get_libcell_pins(pin_names, self.name, GDS["unit"])