diff --git a/compiler/base/custom_cell_properties.py b/compiler/base/custom_cell_properties.py index 2e21c1ec..25c720ef 100644 --- a/compiler/base/custom_cell_properties.py +++ b/compiler/base/custom_cell_properties.py @@ -32,9 +32,8 @@ class _mirror_axis: self.y = y class _bitcell: - def __init__(self, mirror, split_wl, cell_s8_6t, cell_6t, cell_1rw1r, cell_1w1r): + def __init__(self, mirror, cell_s8_6t, cell_6t, cell_1rw1r, cell_1w1r): self.mirror = mirror - self.split_wl = split_wl self._s8_6t = cell_s8_6t self._6t = cell_6t self._1rw1r = cell_1rw1r @@ -43,8 +42,8 @@ class _bitcell: def _default(): axis = _mirror_axis(True, False) - cell_s8_6t = _cell({'bl' : 'bl0', - 'br' : 'bl1', + cell_s8_6t = _cell({'bl' : 'bl', + 'br' : 'br', 'wl': 'wl'}) cell_6t = _cell({'bl' : 'bl', @@ -69,7 +68,6 @@ class _bitcell: cell_6t=cell_6t, cell_1rw1r=cell_1rw1r, cell_1w1r=cell_1w1r, - split_wl = [], mirror=axis) @property diff --git a/compiler/bitcells/bitcell.py b/compiler/bitcells/bitcell.py index 48467121..5694a64d 100644 --- a/compiler/bitcells/bitcell.py +++ b/compiler/bitcells/bitcell.py @@ -22,17 +22,12 @@ class bitcell(bitcell_base.bitcell_base): # If we have a split WL bitcell, if not be backwards # compatible in the tech file - - if props.compare_ports(props.bitcell.split_wl): - pin_names = ["bl", "br", "wl0", "wl1", "vdd", "gnd"] - type_list = ["OUTPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"] - else: - pin_names = [props.bitcell.cell_6t.pin.bl, - props.bitcell.cell_6t.pin.br, - props.bitcell.cell_6t.pin.wl, - props.bitcell.cell_6t.pin.vdd, - props.bitcell.cell_6t.pin.gnd] - type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] + pin_names = [props.bitcell.cell_6t.pin.bl, + props.bitcell.cell_6t.pin.br, + props.bitcell.cell_6t.pin.wl, + props.bitcell.cell_6t.pin.vdd, + props.bitcell.cell_6t.pin.gnd] + type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] storage_nets = ['Q', 'Q_bar'] (width, height) = utils.get_libcell_size("cell_6t", @@ -55,10 +50,7 @@ class bitcell(bitcell_base.bitcell_base): def get_all_wl_names(self): """ Creates a list of all wordline pin names """ - if props.compare_ports(props.bitcell.split_wl): - row_pins = ["wl0", "wl1"] - else: - row_pins = [props.bitcell.cell_6t.pin.wl] + row_pins = [props.bitcell.cell_6t.pin.wl] return row_pins def get_all_bitline_names(self): @@ -87,11 +79,8 @@ class bitcell(bitcell_base.bitcell_base): def get_wl_name(self, port=0): """Get wl name""" - if props.compare_ports(props.bitcell.split_wl): - return "wl{}".format(port) - else: - debug.check(port == 0, "One port for bitcell only.") - return props.bitcell.cell_6t.pin.wl + debug.check(port == 0, "One port for bitcell only.") + return props.bitcell.cell_6t.pin.wl def build_graph(self, graph, inst_name, port_nets): """ diff --git a/compiler/bitcells/bitcell_1rw_1r.py b/compiler/bitcells/bitcell_1rw_1r.py index e5eb3043..820adcce 100644 --- a/compiler/bitcells/bitcell_1rw_1r.py +++ b/compiler/bitcells/bitcell_1rw_1r.py @@ -30,8 +30,8 @@ class bitcell_1rw_1r(bitcell_base.bitcell_base): props.bitcell.cell_1rw1r.pin.vdd, props.bitcell.cell_1rw1r.pin.gnd] - type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", - "INPUT", "INPUT", "POWER", "GROUND"] + type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", + "INPUT", "INPUT", "POWER", "GROUND"] storage_nets = ['Q', 'Q_bar'] (width, height) = utils.get_libcell_size("cell_1rw_1r", GDS["unit"], diff --git a/compiler/bitcells/replica_bitcell.py b/compiler/bitcells/replica_bitcell.py index e7aacd84..597cf5b4 100644 --- a/compiler/bitcells/replica_bitcell.py +++ b/compiler/bitcells/replica_bitcell.py @@ -20,17 +20,12 @@ class replica_bitcell(design.design): is a hand-made cell, so the layout and netlist should be available in the technology library. """ - if cell_properties.compare_ports(cell_properties.bitcell.split_wl): - pin_names = ["bl", "br", "wl0", "wl1", "vdd", "gnd"] - type_list = ["OUTPUT", "OUTPUT", "INPUT", "INPUT" , "POWER", "GROUND"] - else: - pin_names = [props.bitcell.cell_6t.pin.bl, - props.bitcell.cell_6t.pin.br, - props.bitcell.cell_6t.pin.wl, - props.bitcell.cell_6t.pin.vdd, - props.bitcell.cell_6t.pin.gnd] - - type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] + pin_names = [props.bitcell.cell_6t.pin.bl, + props.bitcell.cell_6t.pin.br, + props.bitcell.cell_6t.pin.wl, + props.bitcell.cell_6t.pin.vdd, + props.bitcell.cell_6t.pin.gnd] + type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] if not OPTS.netlist_only: (width,height) = utils.get_libcell_size("replica_cell_6t", GDS["unit"], layer["boundary"]) diff --git a/compiler/characterizer/simulation.py b/compiler/characterizer/simulation.py index ecb9adb8..2edb42bf 100644 --- a/compiler/characterizer/simulation.py +++ b/compiler/characterizer/simulation.py @@ -527,12 +527,10 @@ class simulation(): """ Gets the signal name associated with the bitlines in the bank. """ - cell_mod = factory.create(module_type=OPTS.bitcell) cell_bl = cell_mod.get_bl_name(port) cell_br = cell_mod.get_br_name(port) - - # Only a single path should contain a single s_en name. Anything else is an error. + bl_names = [] exclude_set = self.get_bl_name_search_exclusions() for int_net in [cell_bl, cell_br]: diff --git a/compiler/characterizer/stimuli.py b/compiler/characterizer/stimuli.py index 785b2b3b..0c528365 100644 --- a/compiler/characterizer/stimuli.py +++ b/compiler/characterizer/stimuli.py @@ -33,12 +33,22 @@ class stimuli(): self.sf = stim_file (self.process, self.voltage, self.temperature) = corner + found = False + self.device_libraries = [] + self.device_models = [] try: - self.device_libraries = tech.spice["fet_libraries"][self.process] - except: - debug.info(2, "Not using spice library") - self.device_models = tech.spice["fet_models"][self.process] - + self.device_libraries += tech.spice["fet_libraries"][self.process] + found = True + except KeyError: + pass + try: + self.device_models += tech.spice["fet_models"][self.process] + found = True + except KeyError: + pass + if not found: + debug.error("Must define either fet_libraries or fet_models.", -1) + def inst_model(self, pins, model_name): """ Function to instantiate a generic model with a set of pins """ @@ -265,16 +275,15 @@ class stimuli(): def write_include(self, circuit): """Writes include statements, inputs are lists of model files""" - includes = self.device_models + [circuit] self.sf.write("* {} process corner\n".format(self.process)) - if OPTS.tech_name == "sky130": - libraries = self.device_libraries - for item in list(libraries): - if os.path.isfile(item[0]): - self.sf.write(".lib \"{0}\" {1}\n".format(item[0], item[1])) - else: - debug.error("Could not find spice library: {0}\nSet SPICE_MODEL_DIR to over-ride path.\n".format(item[0])) - + for item in self.device_libraries: + if os.path.isfile(item[0]): + self.sf.write(".lib \"{0}\" {1}\n".format(item[0], item[1])) + else: + debug.error("Could not find spice library: {0}\nSet SPICE_MODEL_DIR to over-ride path.\n".format(item[0])) + + includes = self.device_models + [circuit] + for item in list(includes): if os.path.isfile(item): self.sf.write(".include \"{0}\"\n".format(item)) diff --git a/compiler/example_configs/run1.py b/compiler/example_configs/run1.py deleted file mode 100644 index f0b2d753..00000000 --- a/compiler/example_configs/run1.py +++ /dev/null @@ -1,19 +0,0 @@ -word_size = 2 -num_words = 16 - -tech_name = "scn4m_subm" -process_corners = ["TT"] -supply_voltages = [5.0] -temperatures = [25] - -#netlist_only = True -route_supplies = True -check_lvsdrc = True - -output_name = "sram_{0}_{1}_{2}".format(word_size, - num_words, - tech_name) - -drc_name = "magic" -lvs_name = "netgen" -pex_name = "magic" diff --git a/compiler/example_configs/run2.py b/compiler/example_configs/run2.py deleted file mode 100644 index c70009ed..00000000 --- a/compiler/example_configs/run2.py +++ /dev/null @@ -1,19 +0,0 @@ -word_size = 8 -num_words = 128 - -tech_name = "scn4m_subm" -process_corners = ["TT"] -supply_voltages = [5.0] -temperatures = [25] - -route_supplies = True -check_lvsdrc = True - -netlist_only = True -output_name = "sram_{0}_{1}_{2}".format(word_size, - num_words, - tech_name) - -drc_name = "magic" -lvs_name = "netgen" -pex_name = "magic" diff --git a/compiler/example_configs/run3.py b/compiler/example_configs/run3.py deleted file mode 100644 index 9c18c76e..00000000 --- a/compiler/example_configs/run3.py +++ /dev/null @@ -1,18 +0,0 @@ -word_size = 16 -num_words = 256 - -tech_name = "scn4m_subm" -process_corners = ["TT"] -supply_voltages = [5.0] -temperatures = [25] - -route_supplies = True -check_lvsdrc = True -netlist_only = True -output_name = "sram_{0}_{1}_{2}".format(word_size, - num_words, - tech_name) - -drc_name = "magic" -lvs_name = "netgen" -pex_name = "magic" diff --git a/compiler/example_configs/run4.py b/compiler/example_configs/run4.py deleted file mode 100644 index 5b2ba5b4..00000000 --- a/compiler/example_configs/run4.py +++ /dev/null @@ -1,18 +0,0 @@ -word_size = 32 -num_words = 128 - -tech_name = "scn4m_subm" -process_corners = ["TT"] -supply_voltages = [5.0] -temperatures = [25] - -route_supplies = True -check_lvsdrc = True -netlist_only = True -output_name = "sram_{0}_{1}_{2}".format(word_size, - num_words, - tech_name) - -drc_name = "magic" -lvs_name = "netgen" -pex_name = "magic" diff --git a/compiler/example_configs/run5.py b/compiler/example_configs/run5.py deleted file mode 100644 index 49416807..00000000 --- a/compiler/example_configs/run5.py +++ /dev/null @@ -1,19 +0,0 @@ -word_size = 64 -num_words = 128 - -tech_name = "scn4m_subm" -process_corners = ["TT"] -supply_voltages = [5.0] -temperatures = [25] - -route_supplies = True -check_lvsdrc = True - -output_path = "/home/jesse/thesis/outputs/run5" -output_name = "sram_{0}_{1}_{2}".format(word_size, - num_words, - tech_name) - -drc_name = "magic" -lvs_name = "netgen" -pex_name = "magic" diff --git a/compiler/example_configs/s8config.py b/compiler/example_configs/s8config.py deleted file mode 100644 index 7c0de527..00000000 --- a/compiler/example_configs/s8config.py +++ /dev/null @@ -1,31 +0,0 @@ -word_size = 16 -num_words = 16 - -num_rw_ports = 1 -num_r_ports = 1 -num_w_ports = 0 - -tech_name = "sky130" - - - -accuracy_requirement = 0.05 -magic_exe = ("magic", "magic") -nominal_corners_only = False -process_corners = ["TT"] -supply_voltages = [5.0] -temperatures = [25] - -netlist_only = False -route_supplies = "grid" -check_lvsdrc = False - -#replica_bitcell_array = "/home/jesse/openram/technology/sky130/modules/replica_bitcell_array.py" - -output_path = "sram_" + str(accuracy_requirement) -output_name = "sram_{0}_{1}_{2}_{3}".format(word_size, - num_words, - tech_name, - accuracy_requirement - ) -write_size=8 diff --git a/compiler/modules/bitcell_base_array.py b/compiler/modules/bitcell_base_array.py index 477100fe..6ceff7ca 100644 --- a/compiler/modules/bitcell_base_array.py +++ b/compiler/modules/bitcell_base_array.py @@ -48,8 +48,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, remove_num_wordlines=0): - for row in range(self.row_size - remove_num_wordlines): + def create_all_wordline_names(self, row_size=None): + if row_size == None: + row_size = self.row_size + + for row in range(row_size): for port in self.all_ports: self.wordline_names[port].append("wl_{0}_{1}".format(port, row)) diff --git a/compiler/modules/col_cap_array.py b/compiler/modules/col_cap_array.py index 392f573c..24ecc640 100644 --- a/compiler/modules/col_cap_array.py +++ b/compiler/modules/col_cap_array.py @@ -26,7 +26,13 @@ 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() + try: + end_caps_enabled = cell_properties.bitcell.end_caps + except AttributeError: + end_caps_enabled = False + + if not end_caps_enabled: + self.create_all_wordline_names() self.create_all_bitline_names() self.add_modules() @@ -63,7 +69,7 @@ class col_cap_array(bitcell_base_array): indexed by column and row, for instance use in bitcell_array """ - if len(self.ports) == 1: + if len(self.all_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), diff --git a/compiler/modules/dummy_array.py b/compiler/modules/dummy_array.py index 7024a6fc..465fb9d8 100644 --- a/compiler/modules/dummy_array.py +++ b/compiler/modules/dummy_array.py @@ -60,6 +60,9 @@ class dummy_array(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") + # bitline pins are not added because they are floating for wl_name in self.get_wordline_names(): self.add_pin(wl_name, "INPUT") self.add_pin("vdd", "POWER") @@ -85,25 +88,15 @@ class dummy_array(bitcell_base_array): height=self.height) wl_names = self.cell.get_all_wl_names() - if not props.compare_ports(props.bitcell.split_wl): - 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]) + for row in range(self.row_size): + for port in self.all_ports: + wl_pins = self.cell_inst[row, 0].get_pins(wl_names[port]) + for wl_pin in wl_pins: 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()) - else: - for row in range(self.row_size): - for port in self.all_ports: - for wl in range(len(wl_names)): - wl_pin = self.cell_inst[row, 0].get_pin("wl{}".format(wl)) - self.add_layout_pin(text="wl{0}_{1}_{2}".format(wl, port, row), - layer=wl_pin.layer, - offset=wl_pin.ll().scale(0, 1), - width=self.width, - height=wl_pin.height()) # Copy a vdd/gnd layout pin from every cell for row in range(self.row_size): @@ -112,7 +105,6 @@ class dummy_array(bitcell_base_array): for pin_name in ["vdd", "gnd"]: self.copy_layout_pin(inst, pin_name) - def input_load(self): # FIXME: This appears to be old code from previous characterization. Needs to be updated. wl_wire = self.gen_wl_wire() diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 0814728f..12c1706e 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -59,9 +59,19 @@ class replica_bitcell_array(bitcell_base_array): "Invalid number of RBLs for port configuration.") # Two dummy rows plus replica even if we don't add the column - self.extra_rows = 2 + sum(self.rbl) + self.extra_rows = sum(self.rbl) # Two dummy cols plus replica if we add the column - self.extra_cols = 2 + len(self.left_rbl) + len(self.right_rbl) + self.extra_cols = len(self.left_rbl) + len(self.right_rbl) + + + try: + end_caps_enabled = cell_properties.bitcell.end_caps + except AttributeError: + end_caps_enabled = False + # If we aren't using row/col caps, then we need to use the bitcell + if not end_caps_enabled: + self.extra_rows += 2 + self.extra_cols += 2 self.create_netlist() if not OPTS.netlist_only: @@ -184,7 +194,7 @@ class 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=1 + len(self.left_rbl) + self.column_size + self.rbl[0], rows=self.row_size + self.extra_rows, mirror=(self.rbl[0] + 1) %2) self.add_mod(self.row_cap_right) @@ -230,6 +240,11 @@ class replica_bitcell_array(bitcell_base_array): self.add_pin_list(self.rbl_bitline_names[port], "INOUT") def add_wordline_pins(self): + try: + end_caps_enabled = cell_properties.bitcell.end_caps + except AttributeError: + end_caps_enabled = False + # Wordlines to ground self.gnd_wordline_names = [] @@ -245,7 +260,6 @@ class replica_bitcell_array(bitcell_base_array): 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())) @@ -290,25 +304,25 @@ class replica_bitcell_array(bitcell_base_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([x if x not in self.gnd_wordline_names else "gnd" for x in self.rbl_wordline_names[port]] + self.supplies) + 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(["gnd"] * len(self.col_cap_bottom.get_wordline_names()) + self.supplies) + 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(["gnd"] * len(self.col_cap_top.get_wordline_names()) + self.supplies) + 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(self.replica_array_wordline_names + self.supplies) + 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(self.replica_array_wordline_names + self.supplies) + self.connect_inst(["dummy_right_" + bl for bl in self.row_cap_right.all_bitline_names] + self.replica_array_wordline_names + self.supplies) def create_layout(self): diff --git a/compiler/modules/replica_column.py b/compiler/modules/replica_column.py index 3d6b524b..d7e36fce 100644 --- a/compiler/modules/replica_column.py +++ b/compiler/modules/replica_column.py @@ -28,8 +28,13 @@ class replica_column(bitcell_base_array): self.right_rbl = rbl[1] self.replica_bit = replica_bit # left, right, regular rows plus top/bottom dummy cells - self.total_size = self.left_rbl + rows + self.right_rbl + 2 - + self.total_size = self.left_rbl + rows + self.right_rbl + try: + if not cell_properties.bitcell.end_caps: + self.total_size += 2 + except AttributeError: + self.total_size += 2 + self.column_offset = column_offset debug.check(replica_bit != 0 and replica_bit != rows, @@ -62,14 +67,7 @@ class replica_column(bitcell_base_array): def add_pins(self): self.create_all_bitline_names() - try: - if cell_properties.bitcell.end_caps: - # remove 2 wordlines to account for top/bot - self.create_all_wordline_names(remove_num_wordlines=2) - else: - self.create_all_wordline_names() - except AttributeError: - self.create_all_wordline_names() + self.create_all_wordline_names(self.total_size) self.add_pin_list(self.all_bitline_names, "OUTPUT") self.add_pin_list(self.all_wordline_names, "INPUT") @@ -91,7 +89,6 @@ class replica_column(bitcell_base_array): # Used for pin names only self.cell = factory.create(module_type="bitcell") - def create_instances(self): self.cell_inst = {} try: @@ -106,22 +103,22 @@ class replica_column(bitcell_base_array): # Replic bit specifies which other bit (in the full range (0,rows) to make a replica cell. if (row > self.left_rbl and row < self.total_size - self.right_rbl - 1): self.cell_inst[row]=self.add_inst(name=name, - mod=self.replica_cell) + mod=self.replica_cell) self.connect_inst(self.get_bitcell_pins(row, 0)) elif row==self.replica_bit: self.cell_inst[row]=self.add_inst(name=name, - mod=self.replica_cell) + mod=self.replica_cell) self.connect_inst(self.get_bitcell_pins(row, 0)) elif (row == 0 or row == self.total_size - 1): self.cell_inst[row]=self.add_inst(name=name, - mod=self.edge_cell) + mod=self.edge_cell) if end_caps_enabled: self.connect_inst(self.get_bitcell_pins_col_cap(row, 0)) else: self.connect_inst(self.get_bitcell_pins(row, 0)) else: self.cell_inst[row]=self.add_inst(name=name, - mod=self.dummy_cell) + mod=self.dummy_cell) self.connect_inst(self.get_bitcell_pins(row, 0)) def place_instances(self): @@ -153,8 +150,7 @@ class replica_column(bitcell_base_array): dir_key = "" self.cell_inst[row].place(offset=offset, - mirror=dir_key) - + mirror=dir_key) def add_layout_pins(self): """ Add the layout pins """ diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index db46b6b1..eca2d22c 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -88,8 +88,8 @@ class pinv(pgate.pgate): self.nmos_width = self.nmos_size * drc("minwidth_tx") self.pmos_width = self.pmos_size * drc("minwidth_tx") if OPTS.tech_name == "sky130": - (self.nmos_width, self.tx_mults) = self.bin_width("nmos", self.nmos_width) - (self.pmos_width, self.tx_mults) = self.bin_width("pmos", self.pmos_width) + (self.nmos_width, self.tx_mults) = pgate.pgate.best_bin("nmos", self.nmos_width) + (self.pmos_width, self.tx_mults) = pgate.pgate.best_bin("pmos", self.pmos_width) return # Do a quick sanity check and bail if unlikely feasible height diff --git a/compiler/pgates/ptx.py b/compiler/pgates/ptx.py index c7f69422..67368ce9 100644 --- a/compiler/pgates/ptx.py +++ b/compiler/pgates/ptx.py @@ -132,7 +132,7 @@ class ptx(design.design): if OPTS.tech_name == "sky130": # sky130 simulation cannot use the mult parameter in simulation (self.tx_width, self.mults) = pgate.best_bin(self.tx_type, self.tx_width) - main_str = "M{{0}} {{1}} {0} m={1} w={2} l={3} ".format(spice[self.tx_type], + main_str = "X{{0}} {{1}} {0} m={1} w={2} l={3} ".format(spice[self.tx_type], self.mults, self.tx_width, drc("minwidth_poly")) @@ -152,15 +152,20 @@ class ptx(design.design): if OPTS.tech_name == "sky130" and OPTS.lvs_exe and OPTS.lvs_exe[0] == "calibre": # sky130 requires mult parameter too - self.lvs_device = "M{{0}} {{1}} {0} m={1} w={2} l={3} mult={1}".format(spice[self.tx_type], - self.mults, - self.tx_width, - drc("minwidth_poly")) + # self.lvs_device = "X{{0}} {{1}} {0} m={1} w={2} l={3} mult={1}".format(spice[self.tx_type], + # self.mults, + # self.tx_width, + # drc("minwidth_poly")) + self.lvs_device = "M{{0}} {{1}} {0} m={1} w={2} l={3} mult={1}".format("nshort" if self.tx_type == "nmos" else "pshort", + self.mults, + self.tx_width, + drc("minwidth_poly")) else: self.lvs_device = "M{{0}} {{1}} {0} m={1} w={2}u l={3}u ".format(spice[self.tx_type], - self.mults, - self.tx_width, - drc("minwidth_poly")) + self.mults, + self.tx_width, + drc("minwidth_poly")) + def setup_layout_constants(self): """ Pre-compute some handy layout parameters. diff --git a/compiler/router/pin_group.py b/compiler/router/pin_group.py index 8a1362c2..7f30226a 100644 --- a/compiler/router/pin_group.py +++ b/compiler/router/pin_group.py @@ -552,7 +552,7 @@ class pin_group: Add the enclosure shape to the given cell. """ for enclosure in self.enclosures: - debug.info(2, "Adding enclosure {0} {1}".format(self.name, + debug.info(4, "Adding enclosure {0} {1}".format(self.name, enclosure)) cell.add_rect(layer=enclosure.layer, offset=enclosure.ll(), @@ -612,7 +612,7 @@ class pin_group: blockage_set = set() for pin in self.pins: - debug.info(2, " Converting {0}".format(pin)) + debug.info(4, " Converting {0}".format(pin)) # Determine which tracks the pin overlaps (sufficient, insufficient) = self.router.convert_pin_to_tracks(self.name, pin) @@ -628,15 +628,15 @@ class pin_group: # Remember, this excludes the pin blockages already shared_set = pin_set & self.router.blocked_grids if len(shared_set) > 0: - debug.info(2, "Removing pins {}".format(shared_set)) + debug.info(4, "Removing pins {}".format(shared_set)) pin_set.difference_update(shared_set) shared_set = partial_set & self.router.blocked_grids if len(shared_set) > 0: - debug.info(2, "Removing pins {}".format(shared_set)) + debug.info(4, "Removing pins {}".format(shared_set)) partial_set.difference_update(shared_set) shared_set = blockage_set & self.router.blocked_grids if len(shared_set) > 0: - debug.info(2, "Removing blocks {}".format(shared_set)) + debug.info(4, "Removing blocks {}".format(shared_set)) blockage_set.difference_update(shared_set) # At least one of the groups must have some valid tracks @@ -666,5 +666,5 @@ class pin_group: # Remember the secondary grids for removing adjacent pins self.secondary_grids = partial_set - debug.info(2, " pins {}".format(self.grids)) - debug.info(2, " secondary {}".format(self.secondary_grids)) + debug.info(4, " pins {}".format(self.grids)) + debug.info(4, " secondary {}".format(self.secondary_grids)) diff --git a/compiler/router/router.py b/compiler/router/router.py index cacd5117..ba678215 100644 --- a/compiler/router/router.py +++ b/compiler/router/router.py @@ -301,7 +301,6 @@ class router(router_tech): adj_grids)) self.remove_adjacent_grid(pg1, pg2, adj_grids) - debug.info(1, "Removed {} adjacent grids.".format(removed_grids)) def remove_adjacent_grid(self, pg1, pg2, adj_grids): @@ -539,7 +538,7 @@ class router(router_tech): sufficient_list.update([full_overlap]) if partial_overlap: insufficient_list.update([partial_overlap]) - debug.info(2, + debug.info(3, "Converting [ {0} , {1} ] full={2}".format(x, y, full_overlap)) @@ -632,26 +631,26 @@ class router(router_tech): pin.layer) overlap_length = pin.overlap_length(track_pin) - debug.info(2,"Check overlap: {0} {1} . {2} = {3}".format(coord, + debug.info(4,"Check overlap: {0} {1} . {2} = {3}".format(coord, pin.rect, track_pin, overlap_length)) inflated_overlap_length = inflated_pin.overlap_length(track_pin) - debug.info(2,"Check overlap: {0} {1} . {2} = {3}".format(coord, + debug.info(4,"Check overlap: {0} {1} . {2} = {3}".format(coord, inflated_pin.rect, track_pin, inflated_overlap_length)) # If it overlaps with the pin, it is sufficient if overlap_length == math.inf or overlap_length > 0: - debug.info(2," Overlap: {0} >? {1}".format(overlap_length, 0)) + debug.info(4," Overlap: {0} >? {1}".format(overlap_length, 0)) return (coord, None) # If it overlaps with the inflated pin, it is partial elif inflated_overlap_length == math.inf or inflated_overlap_length > 0: - debug.info(2," Partial overlap: {0} >? {1}".format(inflated_overlap_length, 0)) + debug.info(4," Partial overlap: {0} >? {1}".format(inflated_overlap_length, 0)) return (None, coord) else: - debug.info(2, " No overlap: {0} {1}".format(overlap_length, 0)) + debug.info(4, " No overlap: {0} {1}".format(overlap_length, 0)) return (None, None) def convert_track_to_pin(self, track): @@ -846,7 +845,7 @@ class router(router_tech): "Pin component index too large.") pin_in_tracks = self.pin_groups[pin_name][index].grids - debug.info(2,"Set source: " + str(pin_name) + " " + str(pin_in_tracks)) + debug.info(3,"Set source: " + str(pin_name) + " " + str(pin_in_tracks)) self.rg.add_source(pin_in_tracks) def add_path_target(self, paths): @@ -914,7 +913,7 @@ class router(router_tech): """ path = self.prepare_path(path) - debug.info(2, "Adding route: {}".format(str(path))) + debug.info(4, "Adding route: {}".format(str(path))) # If it is only a square, add an enclosure to the track if len(path) == 1: self.add_single_enclosure(path[0][0]) @@ -1007,8 +1006,7 @@ class router(router_tech): # returns the path in tracks (path, cost) = self.rg.route(detour_scale) if path: - debug.info(1, "Found path: cost={0} ".format(cost)) - debug.info(1, str(path)) + debug.info(2, "Found path: cost={0} {1}".format(cost, str(path))) self.paths.append(path) self.add_route(path) diff --git a/compiler/tests/skip_tests_sky130.txt b/compiler/tests/skip_tests_sky130.txt index 68a6549b..827c2cc7 100644 --- a/compiler/tests/skip_tests_sky130.txt +++ b/compiler/tests/skip_tests_sky130.txt @@ -2,7 +2,7 @@ 04_pbitcell_test.py 04_precharge_pbitcell_test.py 04_replica_pbitcell_test.py -04_single_level_column_mux_pbitcell_test.py +04_column_mux_pbitcell_test.py 05_bitcell_1rw_1r_array_test.py 05_bitcell_array_test.py 05_dummy_array_test.py @@ -14,7 +14,7 @@ 06_hierarchical_predecode3x8_pbitcell_test.py 06_hierarchical_predecode3x8_test.py 06_hierarchical_predecode4x16_test.py -07_single_level_column_mux_array_pbitcell_test.py +07_column_mux_array_pbitcell_test.py 08_wordline_driver_array_pbitcell_test.py 08_wordline_driver_array_test.py 09_sense_amp_array_test_pbitcell.py diff --git a/technology/freepdk45/tech/tech.py b/technology/freepdk45/tech/tech.py index 6de01254..abe09e34 100644 --- a/technology/freepdk45/tech/tech.py +++ b/technology/freepdk45/tech/tech.py @@ -363,16 +363,16 @@ spice["nmos"] = "nmos_vtg" spice["pmos"] = "pmos_vtg" # This is a map of corners to model files SPICE_MODEL_DIR=os.environ.get("SPICE_MODEL_DIR") -spice["fet_models"] = { "TT" : [SPICE_MODEL_DIR+"/models_nom/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_nom/NMOS_VTG.inc"], - "FF" : [SPICE_MODEL_DIR+"/models_ff/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ff/NMOS_VTG.inc"], - "SF" : [SPICE_MODEL_DIR+"/models_ss/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ff/NMOS_VTG.inc"], - "FS" : [SPICE_MODEL_DIR+"/models_ff/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ss/NMOS_VTG.inc"], - "SS" : [SPICE_MODEL_DIR+"/models_ss/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ss/NMOS_VTG.inc"], - "ST" : [SPICE_MODEL_DIR+"/models_ss/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_nom/NMOS_VTG.inc"], - "TS" : [SPICE_MODEL_DIR+"/models_nom/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ss/NMOS_VTG.inc"], - "FT" : [SPICE_MODEL_DIR+"/models_ff/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_nom/NMOS_VTG.inc"], - "TF" : [SPICE_MODEL_DIR+"/models_nom/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ff/NMOS_VTG.inc"], - } +spice["fet_models"] = {"TT": [SPICE_MODEL_DIR + "/models_nom/PMOS_VTG.inc", SPICE_MODEL_DIR + "/models_nom/NMOS_VTG.inc"], + "FF": [SPICE_MODEL_DIR + "/models_ff/PMOS_VTG.inc", SPICE_MODEL_DIR + "/models_ff/NMOS_VTG.inc"], + "SF": [SPICE_MODEL_DIR + "/models_ss/PMOS_VTG.inc", SPICE_MODEL_DIR + "/models_ff/NMOS_VTG.inc"], + "FS": [SPICE_MODEL_DIR + "/models_ff/PMOS_VTG.inc", SPICE_MODEL_DIR + "/models_ss/NMOS_VTG.inc"], + "SS": [SPICE_MODEL_DIR + "/models_ss/PMOS_VTG.inc", SPICE_MODEL_DIR + "/models_ss/NMOS_VTG.inc"], + "ST": [SPICE_MODEL_DIR + "/models_ss/PMOS_VTG.inc", SPICE_MODEL_DIR + "/models_nom/NMOS_VTG.inc"], + "TS": [SPICE_MODEL_DIR + "/models_nom/PMOS_VTG.inc", SPICE_MODEL_DIR + "/models_ss/NMOS_VTG.inc"], + "FT": [SPICE_MODEL_DIR + "/models_ff/PMOS_VTG.inc", SPICE_MODEL_DIR + "/models_nom/NMOS_VTG.inc"], + "TF": [SPICE_MODEL_DIR + "/models_nom/PMOS_VTG.inc", SPICE_MODEL_DIR + "/models_ff/NMOS_VTG.inc"], + } #spice stimulus related variables spice["feasible_period"] = 5 # estimated feasible period in ns diff --git a/technology/scn4m_subm/tech/tech.py b/technology/scn4m_subm/tech/tech.py index 55826ec5..41801566 100644 --- a/technology/scn4m_subm/tech/tech.py +++ b/technology/scn4m_subm/tech/tech.py @@ -321,16 +321,16 @@ spice["nmos"]="n" spice["pmos"]="p" # This is a map of corners to model files SPICE_MODEL_DIR=os.environ.get("SPICE_MODEL_DIR") -spice["fet_models"] = { "TT" : [SPICE_MODEL_DIR+"/nom/pmos.sp",SPICE_MODEL_DIR+"/nom/nmos.sp"], - "FF" : [SPICE_MODEL_DIR+"/ff/pmos.sp",SPICE_MODEL_DIR+"/ff/nmos.sp"], - "FS" : [SPICE_MODEL_DIR+"/ff/pmos.sp",SPICE_MODEL_DIR+"/ss/nmos.sp"], - "SF" : [SPICE_MODEL_DIR+"/ss/pmos.sp",SPICE_MODEL_DIR+"/ff/nmos.sp"], - "SS" : [SPICE_MODEL_DIR+"/ss/pmos.sp",SPICE_MODEL_DIR+"/ss/nmos.sp"], - "ST" : [SPICE_MODEL_DIR+"/ss/pmos.sp",SPICE_MODEL_DIR+"/nom/nmos.sp"], - "TS" : [SPICE_MODEL_DIR+"/nom/pmos.sp",SPICE_MODEL_DIR+"/ss/nmos.sp"], - "FT" : [SPICE_MODEL_DIR+"/ff/pmos.sp",SPICE_MODEL_DIR+"/nom/nmos.sp"], - "TF" : [SPICE_MODEL_DIR+"/nom/pmos.sp",SPICE_MODEL_DIR+"/ff/nmos.sp"], - } +spice["fet_models"] = {"TT": [SPICE_MODEL_DIR + "/nom/pmos.sp", SPICE_MODEL_DIR + "/nom/nmos.sp"], + "FF": [SPICE_MODEL_DIR + "/ff/pmos.sp", SPICE_MODEL_DIR + "/ff/nmos.sp"], + "FS": [SPICE_MODEL_DIR + "/ff/pmos.sp", SPICE_MODEL_DIR + "/ss/nmos.sp"], + "SF": [SPICE_MODEL_DIR + "/ss/pmos.sp", SPICE_MODEL_DIR + "/ff/nmos.sp"], + "SS": [SPICE_MODEL_DIR + "/ss/pmos.sp", SPICE_MODEL_DIR + "/ss/nmos.sp"], + "ST": [SPICE_MODEL_DIR + "/ss/pmos.sp", SPICE_MODEL_DIR + "/nom/nmos.sp"], + "TS": [SPICE_MODEL_DIR + "/nom/pmos.sp", SPICE_MODEL_DIR + "/ss/nmos.sp"], + "FT": [SPICE_MODEL_DIR + "/ff/pmos.sp", SPICE_MODEL_DIR + "/nom/nmos.sp"], + "TF": [SPICE_MODEL_DIR + "/nom/pmos.sp", SPICE_MODEL_DIR + "/ff/nmos.sp"], + } #spice stimulus related variables