diff --git a/compiler/base/contact.py b/compiler/base/contact.py index 60d3c840..a02e6066 100644 --- a/compiler/base/contact.py +++ b/compiler/base/contact.py @@ -34,7 +34,7 @@ class contact(hierarchy_design.hierarchy_design): # This will ignore the name parameter since # we can guarantee a unique name here - super().__init__(name) + super().__init__(name, name) debug.info(4, "create contact object {0}".format(name)) self.add_comment("layers: {0}".format(layer_stack)) diff --git a/compiler/base/design.py b/compiler/base/design.py index 90364658..714eaf8b 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -20,8 +20,10 @@ class design(hierarchy_design): """ - def __init__(self, name): - super().__init__(name) + def __init__(self, name, cell_name=None): + if not cell_name: + cell_name = name + super().__init__(name, cell_name) self.setup_multiport_constants() diff --git a/compiler/base/geometry.py b/compiler/base/geometry.py index 0ba8e858..2cb6e897 100644 --- a/compiler/base/geometry.py +++ b/compiler/base/geometry.py @@ -227,7 +227,7 @@ class instance(geometry): self.mod.gds_write_file(self.gds) # now write an instance of my module/structure new_layout.addInstance(self.gds, - self.mod.name, + self.mod.cell_name, offsetInMicrons=self.offset, mirror=self.mirror, rotate=self.rotate) @@ -402,11 +402,11 @@ class instance(geometry): def __str__(self): """ override print function output """ - return "( inst: " + self.name + " @" + str(self.offset) + " mod=" + self.mod.name + " " + self.mirror + " R=" + str(self.rotate) + ")" + return "( inst: " + self.name + " @" + str(self.offset) + " mod=" + self.mod.cell_name + " " + self.mirror + " R=" + str(self.rotate) + ")" def __repr__(self): """ override print function output """ - return "( inst: " + self.name + " @" + str(self.offset) + " mod=" + self.mod.name + " " + self.mirror + " R=" + str(self.rotate) + ")" + return "( inst: " + self.name + " @" + str(self.offset) + " mod=" + self.mod.cell_name + " " + self.mirror + " R=" + str(self.rotate) + ")" class path(geometry): diff --git a/compiler/base/hierarchy_design.py b/compiler/base/hierarchy_design.py index b4b0ef72..d453297a 100644 --- a/compiler/base/hierarchy_design.py +++ b/compiler/base/hierarchy_design.py @@ -20,9 +20,9 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): """ name_map = [] - def __init__(self, name): - self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds" - self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp" + def __init__(self, name, cell_name): + self.gds_file = OPTS.openram_tech + "gds_lib/" + cell_name + ".gds" + self.sp_file = OPTS.openram_tech + "sp_lib/" + cell_name + ".sp" # If we have a separate lvs directory, then all the lvs files # should be in there (all or nothing!) @@ -41,8 +41,9 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): self.lvs_errors = "skipped" self.name = name - hierarchy_spice.spice.__init__(self, name) - hierarchy_layout.layout.__init__(self, name) + self.cell_name = cell_name + hierarchy_spice.spice.__init__(self, name, cell_name) + hierarchy_layout.layout.__init__(self, name, cell_name) self.init_graph_params() def get_layout_pins(self, inst): @@ -76,17 +77,17 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): self.lvs_write(tempspice) self.gds_write(tempgds) # Final verification option does not allow nets to be connected by label. - self.drc_errors = verify.run_drc(self.name, tempgds, extract=True, final_verification=final_verification) - self.lvs_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification) + self.drc_errors = verify.run_drc(self.cell_name, tempgds, extract=True, final_verification=final_verification) + self.lvs_errors = verify.run_lvs(self.cell_name, tempgds, tempspice, final_verification=final_verification) # force_check is used to determine decoder height and other things, so we shouldn't fail # if that flag is set if OPTS.inline_lvsdrc and not force_check: debug.check(self.drc_errors == 0, - "DRC failed for {0} with {1} error(s)".format(self.name, + "DRC failed for {0} with {1} error(s)".format(self.cell_name, self.drc_errors)) debug.check(self.lvs_errors == 0, - "LVS failed for {0} with {1} errors(s)".format(self.name, + "LVS failed for {0} with {1} errors(s)".format(self.cell_name, self.lvs_errors)) if OPTS.purge_temp: @@ -104,11 +105,11 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): if OPTS.netlist_only: return elif (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)): - tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name) + tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.cell_name) self.gds_write(tempgds) - num_errors = verify.run_drc(self.name, tempgds, final_verification=final_verification) + num_errors = verify.run_drc(self.cell_name, tempgds, final_verification=final_verification) debug.check(num_errors == 0, - "DRC failed for {0} with {1} error(s)".format(self.name, + "DRC failed for {0} with {1} error(s)".format(self.cell_name, num_errors)) if OPTS.purge_temp: @@ -125,13 +126,13 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): if OPTS.netlist_only: return elif (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)): - tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name) + tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.cell_name) tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name) self.lvs_write(tempspice) self.gds_write(tempgds) num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification) debug.check(num_errors == 0, - "LVS failed for {0} with {1} error(s)".format(self.name, + "LVS failed for {0} with {1} error(s)".format(self.cell_name, num_errors)) if OPTS.purge_temp: os.remove(tempspice) @@ -217,7 +218,7 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): pins = ",".join(self.pins) insts = [" {}".format(x) for x in self.insts] objs = [" {}".format(x) for x in self.objs] - s = "********** design {0} **********".format(self.name) + s = "********** design {0} **********".format(self.cell_name) s += "\n pins ({0})={1}\n".format(len(self.pins), pins) s += "\n objs ({0})=\n{1}\n".format(len(self.objs), "\n".join(objs)) s += "\n insts ({0})=\n{1}\n".format(len(self.insts), "\n".join(insts)) diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 7fe838cb..040af129 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -30,8 +30,9 @@ class layout(): layout/netlist and perform LVS/DRC. """ - def __init__(self, name): + def __init__(self, name, cell_name): self.name = name + self.cell_name = cell_name self.width = None self.height = None self.bounding_box = None @@ -214,7 +215,7 @@ class layout(): # Contacts are not really instances, so skip them if "contact" not in mod.name: # Check that the instance name is unique - debug.check(name not in self.inst_names, "Duplicate named instance in {0}: {1}".format(self.name, name)) + debug.check(name not in self.inst_names, "Duplicate named instance in {0}: {1}".format(self.cell_name, name)) self.inst_names.add(name) self.insts.append(geometry.instance(name, mod, offset, mirror, rotate)) @@ -315,7 +316,7 @@ class layout(): return any_pin except Exception: self.gds_write("missing_pin.gds") - debug.error("No pin found with name {0} on {1}. Saved as missing_pin.gds.".format(text, self.name), -1) + debug.error("No pin found with name {0} on {1}. Saved as missing_pin.gds.".format(text, self.cell_name), -1) def get_pins(self, text): """ diff --git a/compiler/base/hierarchy_spice.py b/compiler/base/hierarchy_spice.py index 08e2b474..c1271ee7 100644 --- a/compiler/base/hierarchy_spice.py +++ b/compiler/base/hierarchy_spice.py @@ -10,6 +10,7 @@ import re import os import math import tech +from pprint import pformat from delay_data import delay_data from wire_spice_model import wire_spice_model from power_data import power_data @@ -26,8 +27,9 @@ class spice(): Class consisting of a set of modules and instances of these modules """ - def __init__(self, name): + def __init__(self, name, cell_name): self.name = name + self.cell_name = cell_name self.valid_signal_types = ["INOUT", "INPUT", "OUTPUT", "POWER", "GROUND"] # Holds subckts/mods for this module @@ -164,7 +166,6 @@ class spice(): num_pins = len(self.insts[-1].mod.pins) num_args = len(args) if (check and num_pins != num_args): - from pprint import pformat if num_pins < num_args: mod_pins = self.insts[-1].mod.pins + [""] * (num_args - num_pins) arg_pins = args @@ -181,7 +182,6 @@ class spice(): self.conns.append(args) if check and (len(self.insts)!=len(self.conns)): - from pprint import pformat insts_string=pformat(self.insts) conns_string=pformat(self.conns) @@ -214,7 +214,7 @@ class spice(): f.close() # find the correct subckt line in the file - subckt = re.compile("^.subckt {}".format(self.name), re.IGNORECASE) + subckt = re.compile("^.subckt {}".format(self.cell_name), re.IGNORECASE) subckt_line = list(filter(subckt.search, self.spice))[0] # parses line into ports and remove subckt self.pins = subckt_line.split(" ")[2:] @@ -234,7 +234,7 @@ class spice(): # pins and subckt should be the same # find the correct subckt line in the file - subckt = re.compile("^.subckt {}".format(self.name), re.IGNORECASE) + subckt = re.compile("^.subckt {}".format(self.cell_name), re.IGNORECASE) subckt_line = list(filter(subckt.search, self.lvs))[0] # parses line into ports and remove subckt lvs_pins = subckt_line.split(" ")[2:] @@ -293,7 +293,7 @@ class spice(): return # write out the first spice line (the subcircuit) - sp.write("\n.SUBCKT {0} {1}\n".format(self.name, + sp.write("\n.SUBCKT {0} {1}\n".format(self.cell_name, " ".join(self.pins))) for pin in self.pins: @@ -304,7 +304,7 @@ class spice(): # every instance must have a set of connections, even if it is empty. if len(self.insts) != len(self.conns): - debug.error("{0} : Not all instance pins ({1}) are connected ({2}).".format(self.name, + debug.error("{0} : Not all instance pins ({1}) are connected ({2}).".format(self.cell_name, len(self.insts), len(self.conns))) debug.error("Instances: \n" + str(self.insts)) @@ -330,9 +330,9 @@ class spice(): else: sp.write("X{0} {1} {2}\n".format(self.insts[i].name, " ".join(self.conns[i]), - self.insts[i].mod.name)) + self.insts[i].mod.cell_name)) - sp.write(".ENDS {0}\n".format(self.name)) + sp.write(".ENDS {0}\n".format(self.cell_name)) else: # If spice is a hard module, output the spice file contents. @@ -390,7 +390,7 @@ class spice(): .format(self.__class__.__name__)) debug.warning("Class {0} name {1}" .format(self.__class__.__name__, - self.name)) + self.cell_name)) return None def get_cin(self): @@ -408,7 +408,7 @@ class spice(): .format(self.__class__.__name__)) debug.warning("Class {0} name {1}" .format(self.__class__.__name__, - self.name)) + self.cell_name)) return 0 def cal_delay_with_rc(self, corner, r, c, slew, swing=0.5): diff --git a/compiler/base/utils.py b/compiler/base/utils.py index 33b9b8c4..19ca98bd 100644 --- a/compiler/base/utils.py +++ b/compiler/base/utils.py @@ -95,6 +95,7 @@ def _get_gds_reader(units, gds_filename): _GDS_SIZE_CACHE = {} + def get_gds_size(name, gds_filename, units, lpp): """ Open a GDS file and return the size from either the @@ -129,6 +130,7 @@ def get_libcell_size(name, units, lpp): _GDS_PINS_CACHE = {} + def get_gds_pins(pin_names, name, gds_filename, units): """ Open a GDS file and find the pins in pin_names as text on a given layer. diff --git a/compiler/bitcells/bitcell.py b/compiler/bitcells/bitcell.py index 74d39550..66809c65 100644 --- a/compiler/bitcells/bitcell.py +++ b/compiler/bitcells/bitcell.py @@ -6,9 +6,8 @@ # All rights reserved. # import debug -import utils -from tech import GDS, layer from tech import cell_properties as props +from globals import OPTS import bitcell_base @@ -20,41 +19,20 @@ class bitcell(bitcell_base.bitcell_base): library. """ - name = "cell_6t" - 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, - ] - - - # If we have a split WL bitcell, if not be backwards - # compatible in the tech file + 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'] - cell_size_layer = "boundary" - - def __init__(self, name=""): - if not name: - name = self.name - - bitcell_base.bitcell_base.__init__(self, name) + def __init__(self, name, cell_name=None): + if not cell_name: + cell_name = OPTS.bitcell_name + bitcell_base.bitcell_base.__init__(self, name, cell_name) debug.info(2, "Create bitcell") - (width, height) = utils.get_libcell_size(name, - GDS["unit"], - layer[self.cell_size_layer]) - pin_map = utils.get_libcell_pins(self.pin_names, - name, - GDS["unit"]) - - self.width = width - self.height = height - self.pin_map = pin_map - self.add_pin_types(self.type_list) self.nets_match = self.do_nets_exist(self.storage_nets) def get_all_wl_names(self): diff --git a/compiler/bitcells/bitcell_1rw_1r.py b/compiler/bitcells/bitcell_1rw_1r.py index 820adcce..0b5c5bde 100644 --- a/compiler/bitcells/bitcell_1rw_1r.py +++ b/compiler/bitcells/bitcell_1rw_1r.py @@ -6,11 +6,9 @@ # All rights reserved. # import debug -import utils -from tech import GDS, layer, parameter, drc from tech import cell_properties as props -import logical_effort import bitcell_base +from globals import OPTS class bitcell_1rw_1r(bitcell_base.bitcell_base): @@ -29,27 +27,19 @@ class bitcell_1rw_1r(bitcell_base.bitcell_base): props.bitcell.cell_1rw1r.pin.wl1, props.bitcell.cell_1rw1r.pin.vdd, props.bitcell.cell_1rw1r.pin.gnd] - 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"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "cell_1rw_1r", GDS["unit"]) - - def __init__(self, name=""): - # Ignore the name argument - bitcell_base.bitcell_base.__init__(self, "cell_1rw_1r") + + def __init__(self, name, cell_name=None): + if not cell_name: + cell_name = OPTS.bitcell_name + bitcell_base.bitcell_base.__init__(self, name, cell_name) debug.info(2, "Create bitcell with 1RW and 1R Port") - self.width = bitcell_1rw_1r.width - self.height = bitcell_1rw_1r.height - self.pin_map = bitcell_1rw_1r.pin_map - self.add_pin_types(self.type_list) self.nets_match = self.do_nets_exist(self.storage_nets) - pin_names = bitcell_1rw_1r.pin_names + pin_names = self.pin_names self.bl_names = [pin_names[0], pin_names[2]] self.br_names = [pin_names[1], pin_names[3]] self.wl_names = [pin_names[4], pin_names[5]] diff --git a/compiler/bitcells/bitcell_1w_1r.py b/compiler/bitcells/bitcell_1w_1r.py index 56bd0b45..2f6bad5b 100644 --- a/compiler/bitcells/bitcell_1w_1r.py +++ b/compiler/bitcells/bitcell_1w_1r.py @@ -6,10 +6,9 @@ # All rights reserved. # import debug -import utils -from tech import GDS, layer from tech import cell_properties as props import bitcell_base +from globals import OPTS class bitcell_1w_1r(bitcell_base.bitcell_base): @@ -31,28 +30,20 @@ class bitcell_1w_1r(bitcell_base.bitcell_base): type_list = ["OUTPUT", "OUTPUT", "INPUT", "INPUT", "INPUT", "INPUT", "POWER", "GROUND"] storage_nets = ['Q', 'Q_bar'] - (width, height) = utils.get_libcell_size("cell_1w_1r", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "cell_1w_1r", GDS["unit"]) - - def __init__(self, name=""): - # Ignore the name argument - bitcell_base.bitcell_base.__init__(self, "cell_1w_1r") + + def __init__(self, name, cell_name): + if not cell_name: + cell_name = OPTS.bitcell_name + bitcell_base.bitcell_base.__init__(self, name, cell_name) debug.info(2, "Create bitcell with 1W and 1R Port") - self.width = bitcell_1w_1r.width - self.height = bitcell_1w_1r.height - self.pin_map = bitcell_1w_1r.pin_map - self.add_pin_types(self.type_list) self.nets_match = self.do_nets_exist(self.storage_nets) - pin_names = bitcell_1w_1r.pin_names + pin_names = self.pin_names self.bl_names = [pin_names[0], pin_names[2]] self.br_names = [pin_names[1], pin_names[3]] self.wl_names = [pin_names[4], pin_names[5]] - def get_bitcell_pins(self, col, row): """ Creates a list of connections in the bitcell, diff --git a/compiler/bitcells/bitcell_base.py b/compiler/bitcells/bitcell_base.py index 690e98fa..6d85fde0 100644 --- a/compiler/bitcells/bitcell_base.py +++ b/compiler/bitcells/bitcell_base.py @@ -8,18 +8,30 @@ import debug import design +import utils from globals import OPTS import logical_effort -from tech import parameter, drc, layer +from tech import GDS, parameter, drc, layer class bitcell_base(design.design): """ Base bitcell parameters to be over-riden. """ - def __init__(self, name): - design.design.__init__(self, name) + cell_size_layer = "boundary" + + def __init__(self, name, cell_name, hard_cell=True): + design.design.__init__(self, name, cell_name) + if hard_cell: + (self.width, self.height) = utils.get_libcell_size(cell_name, + GDS["unit"], + layer[self.cell_size_layer]) + self.pin_map = utils.get_libcell_pins(self.pin_names, + cell_name, + GDS["unit"]) + self.add_pin_types(self.type_list) + def get_stage_effort(self, load): parasitic_delay = 1 # This accounts for bitline being drained diff --git a/compiler/bitcells/col_cap_bitcell_1rw_1r.py b/compiler/bitcells/col_cap_bitcell_1rw_1r.py index 01818a12..a611965f 100644 --- a/compiler/bitcells/col_cap_bitcell_1rw_1r.py +++ b/compiler/bitcells/col_cap_bitcell_1rw_1r.py @@ -6,8 +6,6 @@ # All rights reserved. # import debug -import utils -from tech import GDS, layer from tech import cell_properties as props import bitcell_base @@ -21,24 +19,12 @@ class col_cap_bitcell_1rw_1r(bitcell_base.bitcell_base): props.bitcell.cell_1rw1r.pin.bl1, props.bitcell.cell_1rw1r.pin.br1, props.bitcell.cell_1rw1r.pin.vdd] - type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "POWER", "GROUND"] - - (width, height) = utils.get_libcell_size("col_cap_cell_1rw_1r", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, - "col_cap_cell_1rw_1r", - GDS["unit"]) - - def __init__(self, name=""): + + def __init__(self, name="col_cap_cell_1rw_1r"): # Ignore the name argument - bitcell_base.bitcell_base.__init__(self, "col_cap_cell_1rw_1r") + bitcell_base.bitcell_base.__init__(self, name) debug.info(2, "Create col_cap bitcell 1rw+1r object") - self.width = col_cap_bitcell_1rw_1r.width - self.height = col_cap_bitcell_1rw_1r.height - self.pin_map = col_cap_bitcell_1rw_1r.pin_map - self.add_pin_types(self.type_list) self.no_instances = True diff --git a/compiler/bitcells/dummy_bitcell.py b/compiler/bitcells/dummy_bitcell.py index 116ea3ed..7bf8a782 100644 --- a/compiler/bitcells/dummy_bitcell.py +++ b/compiler/bitcells/dummy_bitcell.py @@ -6,10 +6,9 @@ # All rights reserved. # import debug -import utils -from tech import GDS, layer from tech import cell_properties as props import bitcell_base +from globals import OPTS class dummy_bitcell(bitcell_base.bitcell_base): @@ -24,19 +23,12 @@ class dummy_bitcell(bitcell_base.bitcell_base): props.bitcell.cell_6t.pin.wl, props.bitcell.cell_6t.pin.vdd, props.bitcell.cell_6t.pin.gnd] - - (width, height) = utils.get_libcell_size("dummy_cell_6t", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "dummy_cell_6t", GDS["unit"]) - - def __init__(self, name=""): - # Ignore the name argument - bitcell_base.bitcell_base.__init__(self, "dummy_cell_6t") + type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] + + def __init__(self, name, cell_name=None): + if not cell_name: + cell_name = OPTS.dummy_bitcell_name + bitcell_base.bitcell_base.__init__(self, name, cell_name) debug.info(2, "Create dummy bitcell") - self.width = dummy_bitcell.width - self.height = dummy_bitcell.height - self.pin_map = dummy_bitcell.pin_map - diff --git a/compiler/bitcells/dummy_bitcell_1rw_1r.py b/compiler/bitcells/dummy_bitcell_1rw_1r.py index d29c804f..0a6203f7 100644 --- a/compiler/bitcells/dummy_bitcell_1rw_1r.py +++ b/compiler/bitcells/dummy_bitcell_1rw_1r.py @@ -6,10 +6,9 @@ # All rights reserved. # import debug -import utils -from tech import GDS, layer from tech import cell_properties as props import bitcell_base +from globals import OPTS class dummy_bitcell_1rw_1r(bitcell_base.bitcell_base): @@ -27,23 +26,13 @@ class dummy_bitcell_1rw_1r(bitcell_base.bitcell_base): props.bitcell.cell_1rw1r.pin.wl1, props.bitcell.cell_1rw1r.pin.vdd, props.bitcell.cell_1rw1r.pin.gnd] - type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"] - (width, height) = utils.get_libcell_size("dummy_cell_1rw_1r", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, - "dummy_cell_1rw_1r", - GDS["unit"]) - def __init__(self, name=""): - # Ignore the name argument - bitcell_base.bitcell_base.__init__(self, "dummy_cell_1rw_1r") + def __init__(self, name, cell_name=None): + if not cell_name: + cell_name = OPTS.dummy_bitcell_name + bitcell_base.bitcell_base.__init__(self, name, cell_name) debug.info(2, "Create dummy bitcell 1rw+1r object") - self.width = dummy_bitcell_1rw_1r.width - self.height = dummy_bitcell_1rw_1r.height - self.pin_map = dummy_bitcell_1rw_1r.pin_map - self.add_pin_types(self.type_list) diff --git a/compiler/bitcells/dummy_bitcell_1w_1r.py b/compiler/bitcells/dummy_bitcell_1w_1r.py index 758a5b16..a60f95ef 100644 --- a/compiler/bitcells/dummy_bitcell_1w_1r.py +++ b/compiler/bitcells/dummy_bitcell_1w_1r.py @@ -6,10 +6,9 @@ # All rights reserved. # import debug -import utils -from tech import GDS, layer from tech import cell_properties as props import bitcell_base +from globals import OPTS class dummy_bitcell_1w_1r(bitcell_base.bitcell_base): @@ -29,21 +28,13 @@ class dummy_bitcell_1w_1r(bitcell_base.bitcell_base): props.bitcell.cell_1w1r.pin.gnd] type_list = ["OUTPUT", "OUTPUT", "INPUT", "INPUT", "INPUT", "INPUT", "POWER", "GROUND"] - (width, height) = utils.get_libcell_size("dummy_cell_1w_1r", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, - "dummy_cell_1w_1r", - GDS["unit"]) - def __init__(self, name=""): - # Ignore the name argument - bitcell_base.bitcell_base.__init__(self, "dummy_cell_1w_1r") + def __init__(self, name, cell_name=None): + if not cell_name: + cell_name = OPTS.dummy_bitcell_name + bitcell_base.bitcell_base.__init__(self, name, cell_name) debug.info(2, "Create dummy bitcell 1w+1r object") - self.width = dummy_bitcell_1w_1r.width - self.height = dummy_bitcell_1w_1r.height - self.pin_map = dummy_bitcell_1w_1r.pin_map - self.add_pin_types(self.type_list) + diff --git a/compiler/bitcells/dummy_pbitcell.py b/compiler/bitcells/dummy_pbitcell.py index ead3d7f3..bdc98768 100644 --- a/compiler/bitcells/dummy_pbitcell.py +++ b/compiler/bitcells/dummy_pbitcell.py @@ -7,11 +7,11 @@ # import debug import design -from tech import drc, spice,parameter from vector import vector from globals import OPTS from sram_factory import factory + class dummy_pbitcell(design.design): """ Creates a replica bitcell using pbitcell @@ -23,7 +23,7 @@ class dummy_pbitcell(design.design): self.num_r_ports = OPTS.num_r_ports self.total_ports = self.num_rw_ports + self.num_w_ports + self.num_r_ports - design.design.__init__(self, name) + design.design.__init__(self, name, name) debug.info(1, "create a dummy bitcell using pbitcell with {0} rw ports, {1} w ports and {2} r ports".format(self.num_rw_ports, self.num_w_ports, self.num_r_ports)) @@ -54,7 +54,8 @@ class dummy_pbitcell(design.design): self.add_pin("gnd") def add_modules(self): - self.prbc = factory.create(module_type="pbitcell",dummy_bitcell=True) + self.prbc = factory.create(module_type="pbitcell", + dummy_bitcell=True) self.add_mod(self.prbc) self.height = self.prbc.height @@ -69,20 +70,20 @@ class dummy_pbitcell(design.design): temp.append("bl{}".format(port)) temp.append("br{}".format(port)) for port in range(self.total_ports): - temp.append("wl{}".format(port)) + temp.append("wl{}".format(port)) temp.append("vdd") temp.append("gnd") self.connect_inst(temp) def place_pbitcell(self): - self.prbc_inst.place(offset=vector(0,0)) + self.prbc_inst.place(offset=vector(0, 0)) - def route_rbc_connections(self): + def route_rbc_connections(self): for port in range(self.total_ports): self.copy_layout_pin(self.prbc_inst, "bl{}".format(port)) self.copy_layout_pin(self.prbc_inst, "br{}".format(port)) for port in range(self.total_ports): - self.copy_layout_pin(self.prbc_inst, "wl{}".format(port)) + self.copy_layout_pin(self.prbc_inst, "wl{}".format(port)) self.copy_layout_pin(self.prbc_inst, "vdd") self.copy_layout_pin(self.prbc_inst, "gnd") diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py index 25868df5..298be6d2 100644 --- a/compiler/bitcells/pbitcell.py +++ b/compiler/bitcells/pbitcell.py @@ -30,7 +30,7 @@ class pbitcell(bitcell_base.bitcell_base): self.replica_bitcell = replica_bitcell self.dummy_bitcell = dummy_bitcell - bitcell_base.bitcell_base.__init__(self, name) + bitcell_base.bitcell_base.__init__(self, name, name, hard_cell=False) fmt_str = "{0} rw ports, {1} w ports and {2} r ports" info_string = fmt_str.format(self.num_rw_ports, self.num_w_ports, diff --git a/compiler/bitcells/replica_bitcell.py b/compiler/bitcells/replica_bitcell.py index 597cf5b4..21b742b5 100644 --- a/compiler/bitcells/replica_bitcell.py +++ b/compiler/bitcells/replica_bitcell.py @@ -8,11 +8,11 @@ import design import debug import utils -from tech import GDS,layer,drc,parameter,cell_properties +from tech import GDS, layer from tech import cell_properties as props - from globals import OPTS + class replica_bitcell(design.design): """ A single bit cell (6T, 8T, etc.) @@ -26,24 +26,23 @@ class replica_bitcell(design.design): props.bitcell.cell_6t.pin.vdd, props.bitcell.cell_6t.pin.gnd] type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] + cell_size_layer = "boundary" - if not OPTS.netlist_only: - (width,height) = utils.get_libcell_size("replica_cell_6t", GDS["unit"], layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "replica_cell_6t", GDS["unit"]) - else: - (width,height) = (0,0) - pin_map = [] - - def __init__(self, name=""): + def __init__(self, name, cell_name=None): + if not cell_name: + cell_name = OPTS.replica_bitcell_name # Ignore the name argument - design.design.__init__(self, "replica_cell_6t") + design.design.__init__(self, name, cell_name) debug.info(2, "Create replica bitcell object") - - self.width = replica_bitcell.width - self.height = replica_bitcell.height - self.pin_map = replica_bitcell.pin_map - self.add_pin_types(self.type_list) + (self.width, self.height) = utils.get_libcell_size(cell_name, + GDS["unit"], + layer[self.cell_size_layer]) + self.pin_map = utils.get_libcell_pins(self.pin_names, + cell_name, + GDS["unit"]) + + def get_stage_effort(self, load): parasitic_delay = 1 size = 0.5 #This accounts for bitline being drained thought the access TX and internal node diff --git a/compiler/bitcells/replica_bitcell_1rw_1r.py b/compiler/bitcells/replica_bitcell_1rw_1r.py index 79f16a47..4386e5b0 100644 --- a/compiler/bitcells/replica_bitcell_1rw_1r.py +++ b/compiler/bitcells/replica_bitcell_1rw_1r.py @@ -7,9 +7,9 @@ # import design import debug -import utils -from tech import GDS,layer,drc,parameter from tech import cell_properties as props +from globals import OPTS + class replica_bitcell_1rw_1r(design.design): """ @@ -26,21 +26,14 @@ class replica_bitcell_1rw_1r(design.design): props.bitcell.cell_1rw1r.pin.wl1, 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"] - (width,height) = utils.get_libcell_size("replica_cell_1rw_1r", GDS["unit"], layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "replica_cell_1rw_1r", GDS["unit"]) - - def __init__(self, name=""): - # Ignore the name argument - design.design.__init__(self, "replica_cell_1rw_1r") + def __init__(self, name, cell_name=None): + if not cell_name: + cell_name = OPTS.replica_bitcell_name + design.design.__init__(self, name, cell_name) debug.info(2, "Create replica bitcell 1rw+1r object") - self.width = replica_bitcell_1rw_1r.width - self.height = replica_bitcell_1rw_1r.height - self.pin_map = replica_bitcell_1rw_1r.pin_map - self.add_pin_types(self.type_list) - def get_stage_effort(self, load): parasitic_delay = 1 size = 0.5 #This accounts for bitline being drained thought the access TX and internal node diff --git a/compiler/bitcells/replica_bitcell_1w_1r.py b/compiler/bitcells/replica_bitcell_1w_1r.py index 52bea519..919f4f3f 100644 --- a/compiler/bitcells/replica_bitcell_1w_1r.py +++ b/compiler/bitcells/replica_bitcell_1w_1r.py @@ -7,9 +7,9 @@ # import design import debug -import utils -from tech import GDS,layer,drc,parameter from tech import cell_properties as props +from globals import OPTS + class replica_bitcell_1w_1r(design.design): """ @@ -26,21 +26,14 @@ class replica_bitcell_1w_1r(design.design): props.bitcell.cell_1w1r.pin.wl1, props.bitcell.cell_1w1r.pin.vdd, props.bitcell.cell_1w1r.pin.gnd] + type_list = ["OUTPUT", "OUTPUT", "INPUT", "INPUT", "INPUT", "INPUT", "POWER", "GROUND"] - type_list = ["OUTPUT", "OUTPUT", "INPUT", "INPUT", "INPUT", "INPUT", "POWER", "GROUND"] - (width,height) = utils.get_libcell_size("replica_cell_1w_1r", GDS["unit"], layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "replica_cell_1w_1r", GDS["unit"]) - - def __init__(self, name=""): - # Ignore the name argument - design.design.__init__(self, "replica_cell_1w_1r") + def __init__(self, name, cell_name=None): + if not cell_name: + cell_name = OPTS.replica_bitcell_name + design.design.__init__(self, name, cell_name) debug.info(2, "Create replica bitcell 1w+1r object") - self.width = replica_bitcell_1w_1r.width - self.height = replica_bitcell_1w_1r.height - self.pin_map = replica_bitcell_1w_1r.pin_map - self.add_pin_types(self.type_list) - def get_stage_effort(self, load): parasitic_delay = 1 size = 0.5 #This accounts for bitline being drained thought the access TX and internal node diff --git a/compiler/bitcells/replica_pbitcell.py b/compiler/bitcells/replica_pbitcell.py index 5a588c1e..03abcb25 100644 --- a/compiler/bitcells/replica_pbitcell.py +++ b/compiler/bitcells/replica_pbitcell.py @@ -7,11 +7,11 @@ # import debug import design -from tech import drc, spice,parameter from vector import vector from globals import OPTS from sram_factory import factory + class replica_pbitcell(design.design): """ Creates a replica bitcell using pbitcell @@ -23,7 +23,7 @@ class replica_pbitcell(design.design): self.num_r_ports = OPTS.num_r_ports self.total_ports = self.num_rw_ports + self.num_w_ports + self.num_r_ports - design.design.__init__(self, name) + design.design.__init__(self, name, name) debug.info(1, "create a replica bitcell using pbitcell with {0} rw ports, {1} w ports and {2} r ports".format(self.num_rw_ports, self.num_w_ports, self.num_r_ports)) @@ -54,7 +54,8 @@ class replica_pbitcell(design.design): self.add_pin("gnd") def add_modules(self): - self.prbc = factory.create(module_type="pbitcell",replica_bitcell=True) + self.prbc = factory.create(module_type="pbitcell", + replica_bitcell=True) self.add_mod(self.prbc) self.height = self.prbc.height @@ -69,20 +70,20 @@ class replica_pbitcell(design.design): temp.append("bl{}".format(port)) temp.append("br{}".format(port)) for port in range(self.total_ports): - temp.append("wl{}".format(port)) + temp.append("wl{}".format(port)) temp.append("vdd") temp.append("gnd") self.connect_inst(temp) def place_pbitcell(self): - self.prbc_inst.place(offset=vector(0,0)) + self.prbc_inst.place(offset=vector(0, 0)) - def route_rbc_connections(self): + def route_rbc_connections(self): for port in range(self.total_ports): self.copy_layout_pin(self.prbc_inst, "bl{}".format(port)) self.copy_layout_pin(self.prbc_inst, "br{}".format(port)) for port in range(self.total_ports): - self.copy_layout_pin(self.prbc_inst, "wl{}".format(port)) + self.copy_layout_pin(self.prbc_inst, "wl{}".format(port)) self.copy_layout_pin(self.prbc_inst, "vdd") self.copy_layout_pin(self.prbc_inst, "gnd") diff --git a/compiler/bitcells/row_cap_bitcell_1rw_1r.py b/compiler/bitcells/row_cap_bitcell_1rw_1r.py index f7a3a687..fbe08a54 100644 --- a/compiler/bitcells/row_cap_bitcell_1rw_1r.py +++ b/compiler/bitcells/row_cap_bitcell_1rw_1r.py @@ -6,8 +6,6 @@ # All rights reserved. # import debug -import utils -from tech import GDS, layer from tech import cell_properties as props import bitcell_base @@ -22,23 +20,11 @@ class row_cap_bitcell_1rw_1r(bitcell_base.bitcell_base): pin_names = [props.bitcell.cell_1rw1r.pin.wl0, props.bitcell.cell_1rw1r.pin.wl1, props.bitcell.cell_1rw1r.pin.gnd] - type_list = ["INPUT", "INPUT", "GROUND"] - - (width, height) = utils.get_libcell_size("row_cap_cell_1rw_1r", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, - "row_cap_cell_1rw_1r", - GDS["unit"]) - def __init__(self, name=""): + def __init__(self, name="row_cap_cell_1rw_1r"): # Ignore the name argument - bitcell_base.bitcell_base.__init__(self, "row_cap_cell_1rw_1r") + bitcell_base.bitcell_base.__init__(self, name) debug.info(2, "Create row_cap bitcell 1rw+1r object") - self.width = row_cap_bitcell_1rw_1r.width - self.height = row_cap_bitcell_1rw_1r.height - self.pin_map = row_cap_bitcell_1rw_1r.pin_map - self.add_pin_types(self.type_list) self.no_instances = True diff --git a/compiler/custom/dff.py b/compiler/custom/dff.py index cb703707..07f7e990 100644 --- a/compiler/custom/dff.py +++ b/compiler/custom/dff.py @@ -23,18 +23,22 @@ class dff(design.design): pin_names = props.dff.custom_port_list type_list = props.dff.custom_type_list clk_pin = props.dff.clk_pin - - (width, height) = utils.get_libcell_size("dff", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "dff", GDS["unit"]) + cell_size_layer = "boundary" def __init__(self, name="dff"): design.design.__init__(self, name) - self.width = dff.width - self.height = dff.height - self.pin_map = dff.pin_map + (width, height) = utils.get_libcell_size(name, + GDS["unit"], + layer[self.cell_size_layer]) + + pin_map = utils.get_libcell_pins(self.pin_names, + name, + GDS["unit"]) + + self.width = width + self.height = height + self.pin_map = pin_map self.add_pin_types(self.type_list) def analytical_power(self, corner, load): diff --git a/compiler/custom/inv_dec.py b/compiler/custom/inv_dec.py index 80fdb74e..46138edd 100644 --- a/compiler/custom/inv_dec.py +++ b/compiler/custom/inv_dec.py @@ -19,18 +19,22 @@ class inv_dec(design.design): pin_names = ["A", "Z", "vdd", "gnd"] type_list = ["INPUT", "OUTPUT", "POWER", "GROUND"] + cell_size_layer = "boundary" - (width, height) = utils.get_libcell_size("inv_dec", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "inv_dec", GDS["unit"]) - def __init__(self, name="inv_dec", height=None): design.design.__init__(self, name) - self.width = inv_dec.width - self.height = inv_dec.height - self.pin_map = inv_dec.pin_map + (width, height) = utils.get_libcell_size(name, + GDS["unit"], + layer[self.cell_size_layer]) + + pin_map = utils.get_libcell_pins(self.pin_names, + name, + GDS["unit"]) + + self.width = width + self.height = height + self.pin_map = pin_map self.add_pin_types(self.type_list) def analytical_power(self, corner, load): diff --git a/compiler/custom/nand2_dec.py b/compiler/custom/nand2_dec.py index c806bf5a..a9a1a7c0 100644 --- a/compiler/custom/nand2_dec.py +++ b/compiler/custom/nand2_dec.py @@ -18,18 +18,22 @@ class nand2_dec(design.design): pin_names = ["A", "B", "Z", "vdd", "gnd"] type_list = ["INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"] + cell_size_layer = "boundary" - (width, height) = utils.get_libcell_size("nand2_dec", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "nand2_dec", GDS["unit"]) - def __init__(self, name="nand2_dec", height=None): design.design.__init__(self, name) - self.width = nand2_dec.width - self.height = nand2_dec.height - self.pin_map = nand2_dec.pin_map + (width, height) = utils.get_libcell_size(name, + GDS["unit"], + layer[self.cell_size_layer]) + + pin_map = utils.get_libcell_pins(self.pin_names, + name, + GDS["unit"]) + + self.width = width + self.height = height + self.pin_map = pin_map self.add_pin_types(self.type_list) # FIXME: For now... diff --git a/compiler/custom/nand3_dec.py b/compiler/custom/nand3_dec.py index 5eea68de..3b19b35f 100644 --- a/compiler/custom/nand3_dec.py +++ b/compiler/custom/nand3_dec.py @@ -18,18 +18,22 @@ class nand3_dec(design.design): pin_names = ["A", "B", "C", "Z", "vdd", "gnd"] type_list = ["INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"] + cell_size_layer = "boundary" - (width, height) = utils.get_libcell_size("nand3_dec", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "nand3_dec", GDS["unit"]) - def __init__(self, name="nand3_dec", height=None): design.design.__init__(self, name) - self.width = nand3_dec.width - self.height = nand3_dec.height - self.pin_map = nand3_dec.pin_map + (width, height) = utils.get_libcell_size(name, + GDS["unit"], + layer[self.cell_size_layer]) + + pin_map = utils.get_libcell_pins(self.pin_names, + name, + GDS["unit"]) + + self.width = width + self.height = height + self.pin_map = pin_map self.add_pin_types(self.type_list) # FIXME: For now... diff --git a/compiler/custom/nand4_dec.py b/compiler/custom/nand4_dec.py index df3eee14..da575fd5 100644 --- a/compiler/custom/nand4_dec.py +++ b/compiler/custom/nand4_dec.py @@ -18,18 +18,22 @@ class nand4_dec(design.design): pin_names = ["A", "B", "C", "D", "Z", "vdd", "gnd"] type_list = ["INPUT", "INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"] + cell_size_layer = "boundary" - (width, height) = utils.get_libcell_size("nand4_dec", - GDS["unit"], - layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "nand4_dec", GDS["unit"]) - def __init__(self, name="nand4_dec", height=None): design.design.__init__(self, name) - self.width = nand4_dec.width - self.height = nand4_dec.height - self.pin_map = nand4_dec.pin_map + (width, height) = utils.get_libcell_size(name, + GDS["unit"], + layer[self.cell_size_layer]) + + pin_map = utils.get_libcell_pins(self.pin_names, + name, + GDS["unit"]) + + self.width = width + self.height = height + self.pin_map = pin_map self.add_pin_types(self.type_list) # FIXME: For now... diff --git a/compiler/custom/tri_gate.py b/compiler/custom/tri_gate.py index 998562b1..bc59fa1c 100644 --- a/compiler/custom/tri_gate.py +++ b/compiler/custom/tri_gate.py @@ -8,7 +8,8 @@ import debug import design import utils -from tech import GDS,layer +from tech import GDS, layer + class tri_gate(design.design): """ @@ -19,8 +20,7 @@ class tri_gate(design.design): pin_names = ["in", "out", "en", "en_bar", "vdd", "gnd"] type_list = ["INPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"] - (width,height) = utils.get_libcell_size("tri_gate", GDS["unit"], layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "tri_gate", GDS["unit"]) + cell_size_layer = "boundary" unique_id = 1 @@ -31,9 +31,17 @@ class tri_gate(design.design): design.design.__init__(self, name) debug.info(2, "Create tri_gate") - self.width = tri_gate.width - self.height = tri_gate.height - self.pin_map = tri_gate.pin_map + (width, height) = utils.get_libcell_size(name, + GDS["unit"], + layer[self.cell_size_layer]) + + pin_map = utils.get_libcell_pins(self.pin_names, + name, + GDS["unit"]) + + self.width = width + self.height = height + self.pin_map = pin_map self.add_pin_types(self.type_list) def analytical_power(self, corner, load): @@ -47,4 +55,4 @@ class tri_gate(design.design): def build_graph(self, graph, inst_name, port_nets): """Adds edges based on inputs/outputs. Overrides base class function.""" - self.add_graph_edges(graph, port_nets) \ No newline at end of file + self.add_graph_edges(graph, port_nets) diff --git a/compiler/custom/write_driver.py b/compiler/custom/write_driver.py index 9afac81b..62b1387e 100644 --- a/compiler/custom/write_driver.py +++ b/compiler/custom/write_driver.py @@ -8,10 +8,10 @@ import debug import design import utils -from globals import OPTS -from tech import GDS,layer +from tech import GDS, layer from tech import cell_properties as props + class write_driver(design.design): """ Tristate write driver to be active during write operations only. @@ -28,20 +28,23 @@ class write_driver(design.design): props.write_driver.pin.gnd] type_list = ["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] - if not OPTS.netlist_only: - (width,height) = utils.get_libcell_size("write_driver", GDS["unit"], layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "write_driver", GDS["unit"]) - else: - (width,height) = (0,0) - pin_map = [] + cell_size_layer = "boundary" def __init__(self, name): design.design.__init__(self, name) debug.info(2, "Create write_driver") - self.width = write_driver.width - self.height = write_driver.height - self.pin_map = write_driver.pin_map + (width, height) = utils.get_libcell_size(name, + GDS["unit"], + layer[self.cell_size_layer]) + + pin_map = utils.get_libcell_pins(self.pin_names, + name, + GDS["unit"]) + + self.width = width + self.height = height + self.pin_map = pin_map self.add_pin_types(self.type_list) def get_bl_names(self): @@ -65,4 +68,4 @@ class write_driver(design.design): def build_graph(self, graph, inst_name, port_nets): """Adds edges based on inputs/outputs. Overrides base class function.""" - self.add_graph_edges(graph, port_nets) \ No newline at end of file + self.add_graph_edges(graph, port_nets) diff --git a/compiler/globals.py b/compiler/globals.py index 3ebb2c11..b46addd0 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -188,6 +188,9 @@ def init_openram(config_file, is_unit_test=True): if is_unit_test and CHECKPOINT_OPTS: OPTS.__dict__ = CHECKPOINT_OPTS.__dict__.copy() return + + # Setup the correct bitcell names + setup_bitcell() # Import these to find the executables for checkpointing import characterizer @@ -202,8 +205,6 @@ def setup_bitcell(): """ Determine the correct custom or parameterized bitcell for the design. """ - global OPTS - # If we have non-1rw ports, # and the user didn't over-ride the bitcell manually, # figure out the right bitcell to use @@ -211,8 +212,11 @@ def setup_bitcell(): if (OPTS.num_rw_ports == 1 and OPTS.num_w_ports == 0 and OPTS.num_r_ports == 0): OPTS.bitcell = "bitcell" + OPTS.bitcell_name = "cell_6t" OPTS.replica_bitcell = "replica_bitcell" + OPTS.replica_bitcell_name = "replica_cell_6t" OPTS.dummy_bitcell = "dummy_bitcell" + OPTS.dummy_bitcell_name = "dummy_cell_6t" else: ports = "" if OPTS.num_rw_ports > 0: @@ -225,6 +229,7 @@ def setup_bitcell(): if ports != "": OPTS.bitcell_suffix = "_" + ports OPTS.bitcell = "bitcell" + OPTS.bitcell_suffix + OPTS.bitcell_name = "cell" + OPTS.bitcell_suffix # See if bitcell exists try: diff --git a/compiler/modules/replica_column.py b/compiler/modules/replica_column.py index 0ce472c3..5a33a6d0 100644 --- a/compiler/modules/replica_column.py +++ b/compiler/modules/replica_column.py @@ -77,9 +77,9 @@ class replica_column(bitcell_base_array): self.add_pin("gnd", "GROUND") def add_modules(self): - self.replica_cell = factory.create(module_type="replica_{}".format(OPTS.bitcell)) + self.replica_cell = factory.create(module_type=OPTS.replica_bitcell) self.add_mod(self.replica_cell) - self.dummy_cell = factory.create(module_type="dummy_{}".format(OPTS.bitcell)) + self.dummy_cell = factory.create(module_type=OPTS.dummy_bitcell) self.add_mod(self.dummy_cell) try: edge_module_type = ("col_cap" if cell_properties.bitcell.end_caps else "dummy") diff --git a/compiler/modules/sense_amp.py b/compiler/modules/sense_amp.py index f1d5de92..21353f4c 100644 --- a/compiler/modules/sense_amp.py +++ b/compiler/modules/sense_amp.py @@ -10,7 +10,6 @@ import debug import utils from tech import GDS, layer, parameter, drc from tech import cell_properties as props -from globals import OPTS import logical_effort @@ -28,13 +27,25 @@ class sense_amp(design.design): props.sense_amp.pin.vdd, props.sense_amp.pin.gnd] type_list = ["INPUT", "INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] - if not OPTS.netlist_only: - (width, height) = utils.get_libcell_size("sense_amp", GDS["unit"], layer["boundary"]) - pin_map = utils.get_libcell_pins(pin_names, "sense_amp", GDS["unit"]) - else: - (width, height) = (0, 0) - pin_map = [] + cell_size_layer = "boundary" + def __init__(self, name="sense_amp"): + super().__init__(name) + debug.info(2, "Create sense_amp") + + (width, height) = utils.get_libcell_size(name, + GDS["unit"], + layer[self.cell_size_layer]) + + pin_map = utils.get_libcell_pins(self.pin_names, + name, + GDS["unit"]) + + self.width = width + self.height = height + self.pin_map = pin_map + self.add_pin_types(self.type_list) + def get_bl_names(self): return props.sense_amp.pin.bl @@ -49,15 +60,6 @@ class sense_amp(design.design): def en_name(self): return props.sense_amp.pin.en - def __init__(self, name): - super().__init__(name) - debug.info(2, "Create sense_amp") - - self.width = sense_amp.width - self.height = sense_amp.height - self.pin_map = sense_amp.pin_map - self.add_pin_types(self.type_list) - def get_cin(self): # FIXME: This input load will be applied to both the s_en timing and bitline timing. diff --git a/compiler/sram/sram_config.py b/compiler/sram/sram_config.py index 573e7514..7544e946 100644 --- a/compiler/sram/sram_config.py +++ b/compiler/sram/sram_config.py @@ -39,7 +39,7 @@ class sram_config: def compute_sizes(self): """ Computes the organization of the memory using bitcell size by trying to make it square.""" - bitcell = factory.create(module_type="bitcell") + bitcell = factory.create(module_type=OPTS.bitcell, cell_name=OPTS.bitcell_name) debug.check(self.num_banks in [1, 2, 4], "Valid number of banks are 1 , 2 and 4.") diff --git a/compiler/sram_factory.py b/compiler/sram_factory.py index 0e9721c7..4f8dcc5c 100644 --- a/compiler/sram_factory.py +++ b/compiler/sram_factory.py @@ -125,7 +125,7 @@ class sram_factory: module_name = real_module_type else: if self.is_duplicate_name(module_name): - raise ValueError("Modules with duplicate name are not allowed." \ + raise ValueError("Modules with duplicate name are not allowed." " '{}'".format(module_name)) # type_str = "type={}".format(real_module_type) diff --git a/compiler/tests/06_hierarchical_decoder_test.py b/compiler/tests/06_hierarchical_decoder_test.py index 42bc38cd..027daf98 100755 --- a/compiler/tests/06_hierarchical_decoder_test.py +++ b/compiler/tests/06_hierarchical_decoder_test.py @@ -22,12 +22,11 @@ class hierarchical_decoder_test(openram_test): config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) globals.init_openram(config_file) - # Use the 2 port cell since it is usually bigger/easier - OPTS.bitcell = "bitcell_1rw_1r" OPTS.num_rw_ports = 1 OPTS.num_r_ports = 1 OPTS.num_w_ports = 0 - + globals.setup_bitcell() + # Checks 2x4 and 2-input NAND decoder debug.info(1, "Testing 16 row sample for hierarchical_decoder") a = factory.create(module_type="hierarchical_decoder", num_outputs=16) diff --git a/compiler/tests/06_hierarchical_predecode4x16_test.py b/compiler/tests/06_hierarchical_predecode4x16_test.py index 7ded6144..3ea60c5d 100755 --- a/compiler/tests/06_hierarchical_predecode4x16_test.py +++ b/compiler/tests/06_hierarchical_predecode4x16_test.py @@ -24,10 +24,10 @@ class hierarchical_predecode4x16_test(openram_test): globals.init_openram(config_file) # Use the 2 port cell since it is usually bigger/easier - OPTS.bitcell = "bitcell_1rw_1r" OPTS.num_rw_ports = 1 OPTS.num_r_ports = 1 OPTS.num_w_ports = 0 + globals.setup_bitcell() debug.info(1, "Testing sample for hierarchy_predecode4x16") a = factory.create(module_type="hierarchical_predecode4x16") diff --git a/compiler/tests/18_port_data_wmask_1rw_1r_test.py b/compiler/tests/18_port_data_wmask_1rw_1r_test.py index 74aa7fc0..c4e422d2 100755 --- a/compiler/tests/18_port_data_wmask_1rw_1r_test.py +++ b/compiler/tests/18_port_data_wmask_1rw_1r_test.py @@ -62,11 +62,11 @@ class port_data_wmask_1rw_1r_test(openram_test): a = factory.create("port_data", sram_config=c, port=0) self.local_check(a) - OPTS.bitcell = "bitcell_1w_1r" OPTS.num_rw_ports = 0 OPTS.num_r_ports = 1 OPTS.num_w_ports = 1 - + globals.setup_bitcell() + c.num_words = 16 c.words_per_row = 1 factory.reset() diff --git a/compiler/tests/18_port_data_wmask_test.py b/compiler/tests/18_port_data_wmask_test.py index 1c650c74..b01460ed 100755 --- a/compiler/tests/18_port_data_wmask_test.py +++ b/compiler/tests/18_port_data_wmask_test.py @@ -57,11 +57,11 @@ class port_data_wmask_test(openram_test): a = factory.create("port_data", sram_config=c, port=0) self.local_check(a) - OPTS.bitcell = "bitcell_1w_1r" OPTS.num_rw_ports = 0 OPTS.num_r_ports = 1 OPTS.num_w_ports = 1 - + globals.setup_bitcell() + c.num_words = 16 c.words_per_row = 1 factory.reset()