diff --git a/compiler/base/custom_cell_properties.py b/compiler/base/custom_cell_properties.py index c592665a..2407f9c2 100644 --- a/compiler/base/custom_cell_properties.py +++ b/compiler/base/custom_cell_properties.py @@ -5,31 +5,92 @@ # (acting for and on behalf of Oklahoma State University) # All rights reserved. # -from globals import OPTS +class _cell: + def __init__(self, port_order, port_types, port_map=None, hard_cell=True, boundary_layer="boundary"): + + # Specifies if this is a hard (i.e. GDS) cell + self._hard_cell = hard_cell + self._boundary_layer = boundary_layer + + # Specifies the port directions + self._port_types_map = {x: y for (x, y) in zip(port_order, port_types)} + + # Specifies a map from OpenRAM names to cell names + # by default it is 1:1 + if not port_map: + self._port_map = {x: x for x in port_order} + # Update mapping of names + self._original_port_order = port_order + self._port_order = port_order + + # Create an index array + self._port_indices = [self._port_order.index(x) for x in self._original_port_order] + + # Update ordered name list + self._port_names = [self._port_map[x] for x in self._port_order] + + # Update ordered type list + self._port_types = [self._port_types_map[x] for x in self._port_order] + + @property + def hard_cell(self): + return self._hard_cell + + @property + def port_names(self): + return self._port_names + + @property + def port_order(self): + return self._port_order + + @port_order.setter + def port_order(self, x): + self._port_order = x + # Update ordered name list in the new order + self._port_names = [self._port_map[x] for x in self._port_order] + # Update ordered type list in the new order + self._port_types = [self._port_types_map[x] for x in self._port_order] + # Update the index array + self._port_indices = [self._port_order.index(x) for x in self._original_port_order] + + @property + def port_indices(self): + return self._port_indices + + @property + def port_map(self): + return self._port_map + + @port_map.setter + def port_map(self, x): + self._port_map = x + # Update ordered name list to use the new names + self._port_names = [self.port_map[x] for x in self._port_order] + + @property + def port_types(self): + return self._port_types + + @property + def boundary_layer(self): + return self._boundary_layer + + @boundary_layer.setter + def boundary_layer(self, x): + self._boundary_layer = x + + class _pins: def __init__(self, pin_dict): # make the pins elements of the class to allow "." access. - # For example: props.bitcell.cell_6t.pin.bl = "foobar" + # For example: props.bitcell.cell_1port.pin.bl = "foobar" for k, v in pin_dict.items(): self.__dict__[k] = v -class _cell: - def __init__(self, pin_dict): - pin_dict.update(self._default_power_pins()) - self._pins = _pins(pin_dict) - - @property - def pin(self): - return self._pins - - def _default_power_pins(self): - return {'vdd': 'vdd', - 'gnd': 'gnd'} - - class _mirror_axis: def __init__(self, x, y): self.x = x @@ -47,88 +108,20 @@ class _pgate: self.add_implants = add_implants -class _bitcell: - def __init__(self, mirror, cell_s8_6t, cell_6t, cell_1rw1r, cell_1w1r): - self.mirror = mirror - self._s8_6t = cell_s8_6t - self._6t = cell_6t - self._1rw1r = cell_1rw1r - self._1w1r = cell_1w1r +class _bitcell(_cell): + def __init__(self, port_order, port_types, port_map=None, storage_nets=["Q", "Q_bar"], mirror=None, end_caps=False): + super().__init__(port_order, port_types, port_map) - def _default(): - axis = _mirror_axis(True, False) - - cell_s8_6t = _cell({'bl': 'bl', - 'br': 'br', - 'wl': 'wl'}) - - cell_6t = _cell({'bl': 'bl', - 'br': 'br', - 'wl': 'wl'}) - - cell_1rw1r = _cell({'bl0': 'bl0', - 'br0': 'br0', - 'bl1': 'bl1', - 'br1': 'br1', - 'wl0': 'wl0', - 'wl1': 'wl1'}) - - cell_1w1r = _cell({'bl0': 'bl0', - 'br0': 'br0', - 'bl1': 'bl1', - 'br1': 'br1', - 'wl0': 'wl0', - 'wl1': 'wl1'}) - - return _bitcell(cell_s8_6t=cell_s8_6t, - cell_6t=cell_6t, - cell_1rw1r=cell_1rw1r, - cell_1w1r=cell_1w1r, - mirror=axis) - - @property - def cell_s8_6t(self): - return self._s8_6t - - @property - def cell_6t(self): - return self._6t - - @property - def cell_1rw1r(self): - return self._1rw1r - - @property - def cell_1w1r(self): - return self._1w1r - - -class _dff: - def __init__(self, use_custom_ports, custom_port_list, custom_type_list, clk_pin): - self.use_custom_ports = use_custom_ports - self.custom_port_list = custom_port_list - self.custom_type_list = custom_type_list - self.clk_pin = clk_pin - - -class _dff_buff: - def __init__(self, use_custom_ports, custom_buff_ports, add_body_contacts): - self.use_custom_ports = use_custom_ports - self.buf_ports = custom_buff_ports - self.add_body_contacts = add_body_contacts - - -class _dff_buff_array: - def __init__(self, use_custom_ports, add_body_contacts): - self.use_custom_ports = use_custom_ports - self.add_body_contacts = add_body_contacts - - -class _bitcell_array: - def __init__(self, use_custom_cell_arrangement): - self.use_custom_cell_arrangement = use_custom_cell_arrangement + self.end_caps = end_caps + + if not mirror: + self.mirror = _mirror_axis(True, False) + else: + self.mirror = mirror + self.storage_nets = storage_nets + class cell_properties(): """ This contains meta information about the custom designed cells. For @@ -137,56 +130,55 @@ class cell_properties(): """ def __init__(self): self.names = {} - self.names["bitcell"] = "cell_6t" - self.names["bitcell_1rw_1r"] = "cell_1rw_1r" - self.names["bitcell_1w_1r"] = "cell_1w_1r" - self.names["dummy_bitcell"] = "dummy_cell_6t" - self.names["dummy_bitcell_1rw_1r"] = "dummy_cell_1rw_1r" - self.names["dummy_bitcell_1w_1r"] = "dummy_cell_1w_1r" - self.names["replica_bitcell"] = "replica_cell_6t" - self.names["replica_bitcell_1rw_1r"] = "replica_cell_1rw_1r" - self.names["replica_bitcell_1w_1r"] = "replica_cell_1w_1r" - self.names["col_cap_bitcell_6t"] = "col_cap_cell_6t" - self.names["col_cap_bitcell_1rw_1r"] = "col_cap_cell_1rw_1r" - self.names["col_cap_bitcell_1w_1r"] = "col_cap_cell_1w_1r" - self.names["row_cap_bitcell_6t"] = "row_cap_cell_6t" - self.names["row_cap_bitcell_1rw_1r"] = "row_cap_cell_1rw_1r" - self.names["row_cap_bitcell_1w_1r"] = "row_cap_cell_1w_1r" - self._bitcell = _bitcell._default() + self.names["bitcell_1port"] = "cell_1rw" + self.names["bitcell_2port"] = "cell_2rw" + self.names["dummy_bitcell_1port"] = "dummy_cell_1rw" + self.names["dummy_bitcell_2port"] = "dummy_cell_2rw" + self.names["replica_bitcell_1port"] = "replica_cell_1rw" + self.names["replica_bitcell_2port"] = "replica_cell_2rw" + self.names["col_cap_bitcell_1port"] = "col_cap_cell_1rw" + self.names["col_cap_bitcell_2port"] = "col_cap_cell_2rw" + self.names["row_cap_bitcell_1port"] = "row_cap_cell_1rw" + self.names["row_cap_bitcell_2port"] = "row_cap_cell_2rw" self._ptx = _ptx(model_is_subckt=False, bin_spice_models=False) self._pgate = _pgate(add_implants=False) - self._dff = _dff(use_custom_ports=False, - custom_port_list=["D", "Q", "clk", "vdd", "gnd"], - custom_type_list=["INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"], - clk_pin="clk") + self._inv_dec = _cell(["A", "Z", "vdd", "gnd"], + ["INPUT", "OUTPUT", "POWER", "GROUND"]) + + self._nand2_dec = _cell(["A", "B", "Z", "vdd", "gnd"], + ["INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]) + + self._nand3_dec = _cell(["A", "B", "C", "Z", "vdd", "gnd"], + ["INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]) + + self._nand4_dec = _cell(["A", "B", "C", "D", "Z", "vdd", "gnd"], + ["INPUT", "INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]) + + self._dff = _cell(["D", "Q", "clk", "vdd", "gnd"], + ["INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]) - self._dff_buff = _dff_buff(use_custom_ports=False, - custom_buff_ports=["D", "qint", "clk", "vdd", "gnd"], - add_body_contacts=False) + self._write_driver = _cell(['din', 'bl', 'br', 'en', 'vdd', 'gnd'], + ["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]) - self._dff_buff_array = _dff_buff_array(use_custom_ports=False, - add_body_contacts=False) + self._sense_amp = _cell(['bl', 'br', 'dout', 'en', 'vdd', 'gnd'], + ["INPUT", "INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]) - self._write_driver = _cell({'din': 'din', - 'bl': 'bl', - 'br': 'br', - 'en': 'en'}) + self._bitcell_1port = _bitcell(["bl", "br", "wl", "vdd", "gnd"], + ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]) - self._sense_amp = _cell({'bl': 'bl', - 'br': 'br', - 'dout': 'dout', - 'en': 'en'}) + self._bitcell_2port = _bitcell(["bl0", "br0", "bl1", "br1", "wl0", "wl1", "vdd", "gnd"], + ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"]) - self._bitcell_array = _bitcell_array(use_custom_cell_arrangement=[]) + self._col_cap_2port = _bitcell(["bl0", "br0", "bl1", "br1", "vdd"], + ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "POWER"]) - @property - def bitcell(self): - return self._bitcell + self._row_cap_2port = _bitcell(["wl0", "wl1", "gnd"], + ["INPUT", "INPUT", "POWER", "GROUND"]) @property def ptx(self): @@ -196,18 +188,26 @@ class cell_properties(): def pgate(self): return self._pgate + @property + def inv_dec(self): + return self._inv_dec + + @property + def nand2_dec(self): + return self._nand2_dec + + @property + def nand3_dec(self): + return self._nand3_dec + + @property + def nand4_dec(self): + return self._nand4_dec + @property def dff(self): return self._dff - @property - def dff_buff(self): - return self._dff_buff - - @property - def dff_buff_array(self): - return self._dff_buff_array - @property def write_driver(self): return self._write_driver @@ -217,13 +217,18 @@ class cell_properties(): return self._sense_amp @property - def bitcell_array(self): - return self._bitcell_array + def bitcell_1port(self): + return self._bitcell_1port + + @property + def bitcell_2port(self): + return self._bitcell_2port - def compare_ports(self, port_list): - use_custom_arrangement = False - for ports in port_list: - if ports == "{}R_{}W_{}RW".format(OPTS.num_r_ports, OPTS.num_w_ports, OPTS.num_rw_ports): - use_custom_arrangement = True - break - return use_custom_arrangement + @property + def col_cap_2port(self): + return self._col_cap_2port + + @property + def row_cap_2port(self): + return self._row_cap_2port + diff --git a/compiler/base/design.py b/compiler/base/design.py index 93169f6a..2c3ba2ea 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -6,8 +6,9 @@ # All rights reserved. # from hierarchy_design import hierarchy_design -from utils import round_to_grid +import utils import contact +from tech import GDS, layer from tech import preferred_directions from tech import cell_properties as props from globals import OPTS @@ -21,7 +22,7 @@ class design(hierarchy_design): some DRC/layer constants and analytical models for other modules to reuse. """ - def __init__(self, name, cell_name=None): + def __init__(self, name, cell_name=None, prop=None): # This allows us to use different GDS/spice circuits for hard cells instead of the default ones # Except bitcell names are generated automatically by the globals.py setup_bitcells routines # depending on the number of ports. @@ -31,6 +32,28 @@ class design(hierarchy_design): cell_name = name super().__init__(name, cell_name) + # This means it is a custom cell. + # It could have properties and not be a hard cell too (e.g. dff_buf) + if prop and prop.hard_cell: + # The pins get added from the spice file, so just check + # that they matched here + debug.check(prop.port_names == self.pins, + "Custom cell pin names do not match spice file:\n{0} vs {1}".format(prop.port_names, self.pins)) + self.add_pin_indices(prop.port_indices) + self.add_pin_names(prop.port_map) + self.add_pin_types(prop.port_types) + + (width, height) = utils.get_libcell_size(self.cell_name, + GDS["unit"], + layer[prop.boundary_layer]) + + self.pin_map = utils.get_libcell_pins(self.pins, + self.cell_name, + GDS["unit"]) + + self.width = width + self.height = height + self.setup_multiport_constants() def check_pins(self): @@ -232,8 +255,7 @@ class design(hierarchy_design): #print(contact1) pitch = contact_width + layer_space - return round_to_grid(pitch) - + return utils.round_to_grid(pitch) def setup_multiport_constants(self): """ diff --git a/compiler/base/geometry.py b/compiler/base/geometry.py index c8f6036f..6d39a7dd 100644 --- a/compiler/base/geometry.py +++ b/compiler/base/geometry.py @@ -275,16 +275,16 @@ class instance(geometry): def calculate_transform(self, node): #set up the rotation matrix angle = math.radians(float(node.rotate)) - mRotate = np.array([[math.cos(angle),-math.sin(angle),0.0], - [math.sin(angle),math.cos(angle),0.0], - [0.0,0.0,1.0]]) + mRotate = np.array([[math.cos(angle), -math.sin(angle), 0.0], + [math.sin(angle), math.cos(angle), 0.0], + [0.0, 0.0, 1.0]]) #set up translation matrix translateX = float(node.offset[0]) translateY = float(node.offset[1]) - mTranslate = np.array([[1.0,0.0,translateX], - [0.0,1.0,translateY], - [0.0,0.0,1.0]]) + mTranslate = np.array([[1.0, 0.0, translateX], + [0.0, 1.0, translateY], + [0.0, 0.0, 1.0]]) #set up the scale matrix (handles mirror X) scaleX = 1.0 @@ -292,27 +292,27 @@ class instance(geometry): scaleY = -1.0 else: scaleY = 1.0 - mScale = np.array([[scaleX,0.0,0.0], - [0.0,scaleY,0.0], - [0.0,0.0,1.0]]) + mScale = np.array([[scaleX, 0.0, 0.0], + [0.0, scaleY, 0.0], + [0.0, 0.0, 1.0]]) return (mRotate, mScale, mTranslate) def apply_transform(self, mtransforms, uVector, vVector, origin): - origin = np.dot(mtransforms[0], origin) #rotate - uVector = np.dot(mtransforms[0], uVector) #rotate - vVector = np.dot(mtransforms[0], vVector) #rotate - origin = np.dot(mtransforms[1], origin) #scale - uVector = np.dot(mtransforms[1], uVector) #scale - vVector = np.dot(mtransforms[1], vVector) #scale + origin = np.dot(mtransforms[0], origin) # rotate + uVector = np.dot(mtransforms[0], uVector) # rotate + vVector = np.dot(mtransforms[0], vVector) # rotate + origin = np.dot(mtransforms[1], origin) # scale + uVector = np.dot(mtransforms[1], uVector) # scale + vVector = np.dot(mtransforms[1], vVector) # scale origin = np.dot(mtransforms[2], origin) return(uVector, vVector, origin) def apply_path_transform(self, path): - uVector = np.array([[1.0],[0.0],[0.0]]) - vVector = np.array([[0.0],[1.0],[0.0]]) - origin = np.array([[0.0],[0.0],[1.0]]) + uVector = np.array([[1.0], [0.0], [0.0]]) + vVector = np.array([[0.0], [1.0], [0.0]]) + origin = np.array([[0.0], [0.0], [1.0]]) while(path): instance = path.pop(-1) @@ -330,7 +330,7 @@ class instance(geometry): bl_offsets = [] # bl to cell offset br_offsets = [] # br to cell offset bl_meta = [] # bl offset metadata (row,col,name) - br_meta = [] #br offset metadata (row,col,name) + br_meta = [] # br offset metadata (row,col,name) def walk_subtree(node): path.append(node) @@ -338,8 +338,6 @@ class instance(geometry): if node.mod.name == cell_name: cell_paths.append(copy.copy(path)) - inst_name = path[-1].name - # get the row and col names from the path row = int(path[-1].name.split('_')[-2][1:]) col = int(path[-1].name.split('_')[-1][1:]) @@ -370,17 +368,15 @@ class instance(geometry): for pair in range(len(normalized_bl_offsets)): normalized_bl_offsets[pair] = (normalized_bl_offsets[pair][0], - -1 * normalized_bl_offsets[pair][1]) + -1 * normalized_bl_offsets[pair][1]) for pair in range(len(normalized_br_offsets)): normalized_br_offsets[pair] = (normalized_br_offsets[pair][0], - -1 * normalized_br_offsets[pair][1]) - + -1 * normalized_br_offsets[pair][1]) Q_offsets.append([Q_x, Q_y]) Q_bar_offsets.append([Q_bar_x, Q_bar_y]) - bl_offsets.append(normalized_bl_offsets) br_offsets.append(normalized_br_offsets) @@ -428,7 +424,7 @@ class path(geometry): def gds_write_file(self, new_layout): """Writes the path to GDS""" - debug.info(4, "writing path (" + str(self.layerNumber) + "): " + self.coordinates) + debug.info(4, "writing path (" + str(self.layerNumber) + "): " + self.coordinates) new_layout.addPath(layerNumber=self.layerNumber, purposeNumber=self.layerPurpose, coordinates=self.coordinates, diff --git a/compiler/base/hierarchy_design.py b/compiler/base/hierarchy_design.py index 5404838a..0a08c995 100644 --- a/compiler/base/hierarchy_design.py +++ b/compiler/base/hierarchy_design.py @@ -40,8 +40,6 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): self.drc_errors = "skipped" self.lvs_errors = "skipped" - self.name = 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() @@ -73,11 +71,11 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): elif (OPTS.inline_lvsdrc or force_check or final_verification): tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name) - tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name) self.lvs_write(tempspice) + tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name) self.gds_write(tempgds) # Final verification option does not allow nets to be connected by label. - self.drc_errors = verify.run_drc(self.cell_name, tempgds, extract=True, final_verification=final_verification) + self.drc_errors = verify.run_drc(self.cell_name, tempgds, tempspice, 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 @@ -105,9 +103,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.cell_name) + tempspice = "{0}{1}.sp".format(OPTS.openram_temp, self.name) + self.lvs_write(tempspice) + tempgds = "{0}{1}.gds".format(OPTS.openram_temp, self.cell_name) self.gds_write(tempgds) - num_errors = verify.run_drc(self.cell_name, tempgds, final_verification=final_verification) + num_errors = verify.run_drc(self.cell_name, tempgds, tempspice, final_verification=final_verification) debug.check(num_errors == 0, "DRC failed for {0} with {1} error(s)".format(self.cell_name, num_errors)) @@ -126,9 +126,9 @@ 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.cell_name) - tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name) + tempspice = "{0}{1}.sp".format(OPTS.openram_temp, self.cell_name) self.lvs_write(tempspice) + tempgds = "{0}{1}.gds".format(OPTS.openram_temp, self.name) self.gds_write(tempgds) num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification) debug.check(num_errors == 0, diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 67482f61..4e473397 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -32,17 +32,29 @@ class layout(): """ def __init__(self, name, cell_name): + # This gets set in both spice and layout so either can be called first. self.name = name self.cell_name = cell_name + self.width = None self.height = None self.bounding_box = None - self.insts = [] # Holds module/cell layout instances - self.inst_names = set() # Set of names to check for duplicates - self.objs = [] # Holds all other objects (labels, geometries, etc) - self.pin_map = {} # Holds name->pin_layout map for all pins - self.visited = [] # List of modules we have already visited - self.is_library_cell = False # Flag for library cells + # Holds module/cell layout instances + self.insts = [] + # Set of names to check for duplicates + self.inst_names = set() + # Holds all other objects (labels, geometries, etc) + self.objs = [] + # This is a mapping of internal pin names to cell pin names + # If the key is not found, the internal pin names is assumed + self.pin_names = {} + # Holds name->pin_layout map for all pins + self.pin_map = {} + # List of modules we have already visited + self.visited = [] + # Flag for library cells + self.is_library_cell = False + self.gds_read() try: @@ -50,9 +62,7 @@ class layout(): self.pwr_grid_layer = power_grid[0] except ImportError: self.pwr_grid_layer = "m3" - - - + ############################################################ # GDS layout ############################################################ @@ -308,26 +318,59 @@ class layout(): """ Return the pin or list of pins """ + name = self.get_pin_name(text) + try: - if len(self.pin_map[text]) > 1: + if len(self.pin_map[name]) > 1: debug.error("Should use a pin iterator since more than one pin {}".format(text), -1) # If we have one pin, return it and not the list. # Otherwise, should use get_pins() - any_pin = next(iter(self.pin_map[text])) + any_pin = next(iter(self.pin_map[name])) 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.cell_name), -1) + debug.error("No pin found with name {0} on {1}. Saved as missing_pin.gds.".format(name, self.cell_name), -1) def get_pins(self, text): """ Return a pin list (instead of a single pin) """ - if text in self.pin_map.keys(): - return self.pin_map[text] + name = self.get_pin_name(text) + + if name in self.pin_map.keys(): + return self.pin_map[name] else: return set() + def add_pin_names(self, pin_dict): + """ + Create a mapping from internal pin names to external pin names. + """ + self.pin_names = pin_dict + + self.original_pin_names = {y: x for (x, y) in self.pin_names.items()} + + def get_pin_name(self, text): + """ Return the custom cell pin name """ + + if text in self.pin_names: + return self.pin_names[text] + else: + return text + + def get_original_pin_names(self): + """ Return the internal cell pin name """ + + # This uses the hierarchy_spice pins (in order) + return [self.get_original_pin_name(x) for x in self.pins] + + def get_original_pin_name(self, text): + """ Return the internal cell pin names in custom port order """ + if text in self.original_pin_names: + return self.original_pin_names[text] + else: + return text + def get_pin_names(self): """ Return a pin list of all pins @@ -346,7 +389,7 @@ class layout(): for pin in pins: if new_name == "": - new_name = pin.name + new_name = pin_name self.add_layout_pin(new_name, pin.layer, pin.ll(), diff --git a/compiler/base/hierarchy_spice.py b/compiler/base/hierarchy_spice.py index d971492e..a51b9575 100644 --- a/compiler/base/hierarchy_spice.py +++ b/compiler/base/hierarchy_spice.py @@ -28,17 +28,20 @@ class spice(): """ def __init__(self, name, cell_name): + # This gets set in both spice and layout so either can be called first. self.name = name self.cell_name = cell_name self.valid_signal_types = ["INOUT", "INPUT", "OUTPUT", "POWER", "GROUND"] # Holds subckts/mods for this module self.mods = [] - # Holds the pins for this module + # Holds the pins for this module (in order) self.pins = [] # The type map of each pin: INPUT, OUTPUT, INOUT, POWER, GROUND # for each instance, this is the set of nets/nodes that map to the pins for this instance self.pin_type = {} + # An (optional) list of indices to reorder the pins to match the spice. + self.pin_indices = [] # THE CONNECTIONS MUST MATCH THE ORDER OF THE PINS (restriction imposed by the # Spice format) self.conns = [] @@ -94,19 +97,34 @@ class spice(): else: debug.error("Mismatch in type and pin list lengths.", -1) + def add_pin_indices(self, index_list): + """ + Add pin indices for all the cell's pins. + """ + self.pin_indices = index_list + + def get_ordered_inputs(self, input_list): + """ + Return the inputs reordered to match the pins. + """ + if not self.pin_indices: + return input_list + + new_list = [input_list[x] for x in self.pin_indices] + return new_list + def add_pin_types(self, type_list): """ Add pin types for all the cell's pins. - Typically, should only be used for handmade cells. """ # This only works if self.pins == bitcell.pin_names - if self.pin_names != self.pins: - debug.error("{} spice subcircuit port names do not match pin_names\ + if len(type_list) != len(self.pins): + debug.error("{} spice subcircuit number of port types does not match number of pins\ \n SPICE names={}\ \n Module names={}\ - ".format(self.name, self.pin_names, self.pins), 1) - self.pin_type = {pin: type for pin, type in zip(self.pin_names, type_list)} - + ".format(self.name, self.pins, type_list), 1) + self.pin_type = {pin: type for pin, type in zip(self.pins, type_list)} + def get_pin_type(self, name): """ Returns the type of the signal pin. """ pin_type = self.pin_type[name] @@ -158,19 +176,26 @@ class spice(): self.mods.append(mod) def connect_inst(self, args, check=True): - """Connects the pins of the last instance added + """ + Connects the pins of the last instance added It is preferred to use the function with the check to find if there is a problem. The check option can be set to false where we dynamically generate groups of connections after a - group of modules are generated.""" + group of modules are generated. + """ + num_pins = len(self.insts[-1].mod.pins) num_args = len(args) + + # Order the arguments if the hard cell has a custom port order + ordered_args = self.get_ordered_inputs(args) + if (check and num_pins != num_args): if num_pins < num_args: mod_pins = self.insts[-1].mod.pins + [""] * (num_args - num_pins) - arg_pins = args + arg_pins = ordered_args else: - arg_pins = args + [""] * (num_pins - num_args) + arg_pins = ordered_args + [""] * (num_pins - num_args) mod_pins = self.insts[-1].mod.pins modpins_string = "\n".join(["{0} -> {1}".format(arg, mod) for (arg, mod) in zip(arg_pins, mod_pins)]) @@ -179,8 +204,9 @@ class spice(): modpins_string), 1) - self.conns.append(args) + self.conns.append(ordered_args) + # This checks if we don't have enough instance port connections for the number of insts if check and (len(self.insts)!=len(self.conns)): insts_string=pformat(self.insts) conns_string=pformat(self.conns) @@ -238,7 +264,8 @@ class spice(): subckt_line = list(filter(subckt.search, self.lvs))[0] # parses line into ports and remove subckt lvs_pins = subckt_line.split(" ")[2:] - debug.check(lvs_pins == self.pins, "LVS and spice file pin mismatch.") + debug.check(lvs_pins == self.pins, + "Spice netlists for LVS and simulation have port mismatches: {0} (LVS) vs {1} (sim)".format(lvs_pins, self.pins)) def check_net_in_spice(self, net_name): """Checks if a net name exists in the current. Intended to be check nets in hand-made cells.""" @@ -296,6 +323,18 @@ class spice(): sp.write("\n.SUBCKT {0} {1}\n".format(self.cell_name, " ".join(self.pins))) + # write a PININFO line + pin_info = "*.PININFO" + for pin in self.pins: + if self.pin_type[pin] == "INPUT": + pin_info += " {0}:I".format(pin) + elif self.pin_type[pin] == "OUTPUT": + pin_info += " {0}:O".format(pin) + else: + pin_info += " {0}:B".format(pin) + sp.write(pin_info + "\n") + + # Also write pins as comments for pin in self.pins: sp.write("* {1:6}: {0} \n".format(pin, self.pin_type[pin])) diff --git a/compiler/base/pin_layout.py b/compiler/base/pin_layout.py index 31a47671..40e3c2f5 100644 --- a/compiler/base/pin_layout.py +++ b/compiler/base/pin_layout.py @@ -32,7 +32,7 @@ class pin_layout: debug.check(self.height() > 0, "Zero height pin.") # These are the valid pin layers - valid_layers = { x: layer[x] for x in layer_indices.keys()} + valid_layers = {x: layer[x] for x in layer_indices.keys()} # if it's a string, use the name if type(layer_name_pp) == str: @@ -46,7 +46,7 @@ class pin_layout: self._layer = layer_name break else: - debug.error("Couldn't find layer {}".format(layer_name_pp), -1) + debug.error("Layer {} is not a valid routing layer in the tech file.".format(layer_name_pp), -1) self.lpp = layer[self.layer] self._recompute_hash() diff --git a/compiler/base/verilog.py b/compiler/base/verilog.py index 636e3bd6..f5ef9107 100644 --- a/compiler/base/verilog.py +++ b/compiler/base/verilog.py @@ -5,9 +5,9 @@ # (acting for and on behalf of Oklahoma State University) # All rights reserved. # -import debug import math + class verilog: """ Create a behavioral Verilog file for simulation. @@ -16,7 +16,7 @@ class verilog: def __init__(self): pass - def verilog_write(self,verilog_name): + def verilog_write(self, verilog_name): """ Write a behavioral Verilog model. """ self.vf = open(verilog_name, "w") @@ -220,6 +220,9 @@ class verilog: self.vf.write(" dout{0} <= #(DELAY) mem[addr{0}_reg];\n".format(port)) self.vf.write(" end\n") + self.vf.write(" always @(csb{0})\n".format(port)) + self.vf.write(" dout{0} = 0)\n".format(port)) + def add_address_check(self, wport, rport): """ Output a warning if the two addresses match """ # If the rport is actually reading... and addresses match. diff --git a/compiler/bitcells/bitcell.py b/compiler/bitcells/bitcell_1port.py similarity index 65% rename from compiler/bitcells/bitcell.py rename to compiler/bitcells/bitcell_1port.py index b2a96356..f3ff4d10 100644 --- a/compiler/bitcells/bitcell.py +++ b/compiler/bitcells/bitcell_1port.py @@ -10,7 +10,7 @@ from tech import cell_properties as props import bitcell_base -class bitcell(bitcell_base.bitcell_base): +class bitcell_1port(bitcell_base.bitcell_base): """ A single bit cell (6T, 8T, etc.) This module implements the single memory cell used in the design. It is a hand-made cell, so @@ -18,53 +18,41 @@ class bitcell(bitcell_base.bitcell_base): library. """ - 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'] - def __init__(self, name): - super().__init__(name) + super().__init__(name, prop=props.bitcell_1port) debug.info(2, "Create bitcell") - self.nets_match = self.do_nets_exist(self.storage_nets) - def get_all_wl_names(self): """ Creates a list of all wordline pin names """ - row_pins = [props.bitcell.cell_6t.pin.wl] + row_pins = ["wl"] return row_pins def get_all_bitline_names(self): """ Creates a list of all bitline pin names (both bl and br) """ - pin = props.bitcell.cell_6t.pin - column_pins = [pin.bl, pin.br] - return column_pins + return ["bl", "br"] def get_all_bl_names(self): """ Creates a list of all bl pins names """ - return [props.bitcell.cell_6t.pin.bl] + return ["bl"] def get_all_br_names(self): """ Creates a list of all br pins names """ - return [props.bitcell.cell_6t.pin.br] + return ["br"] def get_bl_name(self, port=0): """Get bl name""" debug.check(port == 0, "One port for bitcell only.") - return props.bitcell.cell_6t.pin.bl + return "bl" def get_br_name(self, port=0): """Get bl name""" debug.check(port == 0, "One port for bitcell only.") - return props.bitcell.cell_6t.pin.br + return "br" def get_wl_name(self, port=0): """Get wl name""" debug.check(port == 0, "One port for bitcell only.") - return props.bitcell.cell_6t.pin.wl + return "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 deleted file mode 100644 index 9c1d3425..00000000 --- a/compiler/bitcells/bitcell_1rw_1r.py +++ /dev/null @@ -1,126 +0,0 @@ -# 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 -from tech import cell_properties as props -import bitcell_base - - -class bitcell_1rw_1r(bitcell_base.bitcell_base): - """ - A single bit cell (6T, 8T, etc.) This module implements the - single memory cell used in the design. It is a hand-made cell, so - the layout and netlist should be available in the technology - library. - """ - - pin_names = [props.bitcell.cell_1rw1r.pin.bl0, - props.bitcell.cell_1rw1r.pin.br0, - props.bitcell.cell_1rw1r.pin.bl1, - props.bitcell.cell_1rw1r.pin.br1, - props.bitcell.cell_1rw1r.pin.wl0, - 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'] - - def __init__(self, name): - super().__init__(name) - debug.info(2, "Create bitcell with 1RW and 1R Port") - - self.nets_match = self.do_nets_exist(self.storage_nets) - - 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, - indexed by column and row, for instance use in bitcell_array - """ - pin_name = props.bitcell.cell_1rw1r.pin - bitcell_pins = ["{0}_{1}".format(pin_name.bl0, col), - "{0}_{1}".format(pin_name.br0, col), - "{0}_{1}".format(pin_name.bl1, col), - "{0}_{1}".format(pin_name.br1, col), - "{0}_{1}".format(pin_name.wl0, row), - "{0}_{1}".format(pin_name.wl1, row), - "vdd", - "gnd"] - return bitcell_pins - - def get_all_wl_names(self): - """ Creates a list of all wordline pin names """ - return [props.bitcell.cell_1rw1r.pin.wl0, - props.bitcell.cell_1rw1r.pin.wl1] - - def get_all_bitline_names(self): - """ Creates a list of all bitline pin names (both bl and br) """ - return [props.bitcell.cell_1rw1r.pin.bl0, - props.bitcell.cell_1rw1r.pin.br0, - props.bitcell.cell_1rw1r.pin.bl1, - props.bitcell.cell_1rw1r.pin.br1] - - def get_all_bl_names(self): - """ Creates a list of all bl pins names """ - return [props.bitcell.cell_1rw1r.pin.bl0, - props.bitcell.cell_1rw1r.pin.bl1] - - def get_all_br_names(self): - """ Creates a list of all br pins names """ - return [props.bitcell.cell_1rw1r.pin.br0, - props.bitcell.cell_1rw1r.pin.br1] - - def get_read_bl_names(self): - """ Creates a list of bl pin names associated with read ports """ - return [props.bitcell.cell_1rw1r.pin.bl0, - props.bitcell.cell_1rw1r.pin.bl1] - - def get_read_br_names(self): - """ Creates a list of br pin names associated with read ports """ - return [props.bitcell.cell_1rw1r.pin.br0, - props.bitcell.cell_1rw1r.pin.br1] - - def get_write_bl_names(self): - """ Creates a list of bl pin names associated with write ports """ - return [props.bitcell.cell_1rw1r.pin.bl0] - - def get_write_br_names(self): - """ Creates a list of br pin names asscociated with write ports""" - return [props.bitcell.cell_1rw1r.pin.br1] - - def get_bl_name(self, port=0): - """Get bl name by port""" - debug.check(port < 2, "Two ports for bitcell_1rw_1r only.") - return self.bl_names[port] - - def get_br_name(self, port=0): - """Get bl name by port""" - debug.check(port < 2, "Two ports for bitcell_1rw_1r only.") - return self.br_names[port] - - def get_wl_name(self, port=0): - """Get wl name by port""" - debug.check(port < 2, "Two ports for bitcell_1rw_1r only.") - return self.wl_names[port] - - def build_graph(self, graph, inst_name, port_nets): - """Adds edges to graph. Multiport bitcell timing graph is too complex - to use the add_graph_edges function.""" - pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)} - # Edges hardcoded here. Essentially wl->bl/br for both ports. - # Port 0 edges - pins = props.bitcell.cell_1rw1r.pin - graph.add_edge(pin_dict[pins.wl0], pin_dict[pins.bl0], self) - graph.add_edge(pin_dict[pins.wl0], pin_dict[pins.br0], self) - # Port 1 edges - graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.bl1], self) - graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.br1], self) diff --git a/compiler/bitcells/bitcell_1w_1r.py b/compiler/bitcells/bitcell_1w_1r.py deleted file mode 100644 index 64a629a2..00000000 --- a/compiler/bitcells/bitcell_1w_1r.py +++ /dev/null @@ -1,122 +0,0 @@ -# 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 -from tech import cell_properties as props -import bitcell_base - - -class bitcell_1w_1r(bitcell_base.bitcell_base): - """ - A single bit cell (6T, 8T, etc.) This module implements the - single memory cell used in the design. It is a hand-made cell, so - the layout and netlist should be available in the technology - library. - """ - - pin_names = [props.bitcell.cell_1w1r.pin.bl0, - props.bitcell.cell_1w1r.pin.br0, - props.bitcell.cell_1w1r.pin.bl1, - props.bitcell.cell_1w1r.pin.br1, - props.bitcell.cell_1w1r.pin.wl0, - 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"] - storage_nets = ['Q', 'Q_bar'] - - def __init__(self, name): - super().__init__(name) - debug.info(2, "Create bitcell with 1W and 1R Port") - - self.nets_match = self.do_nets_exist(self.storage_nets) - - 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, - indexed by column and row, for instance use in bitcell_array - """ - pin_name = props.bitcell.cell_1w1r.pin - bitcell_pins = ["{0}_{1}".format(pin_name.bl0, col), - "{0}_{1}".format(pin_name.br0, col), - "{0}_{1}".format(pin_name.bl1, col), - "{0}_{1}".format(pin_name.br1, col), - "{0}_{1}".format(pin_name.wl0, row), - "{0}_{1}".format(pin_name.wl1, row), - "vdd", - "gnd"] - return bitcell_pins - - def get_all_wl_names(self): - """ Creates a list of all wordline pin names """ - return [props.bitcell.cell_1w1r.pin.wl0, - props.bitcell.cell_1w1r.pin.wl1] - - def get_all_bitline_names(self): - """ Creates a list of all bitline pin names (both bl and br) """ - return [props.bitcell.cell_1w1r.pin.bl0, - props.bitcell.cell_1w1r.pin.br0, - props.bitcell.cell_1w1r.pin.bl1, - props.bitcell.cell_1w1r.pin.br1] - - def get_all_bl_names(self): - """ Creates a list of all bl pins names """ - return [props.bitcell.cell_1w1r.pin.bl0, - props.bitcell.cell_1w1r.pin.bl1] - - def get_all_br_names(self): - """ Creates a list of all br pins names """ - return [props.bitcell.cell_1w1r.pin.br0, - props.bitcell.cell_1w1r.pin.br1] - - def get_read_bl_names(self): - """ Creates a list of bl pin names associated with read ports """ - return [props.bitcell.cell_1w1r.pin.bl0, - props.bitcell.cell_1w1r.pin.bl1] - - def get_read_br_names(self): - """ Creates a list of br pin names associated with read ports """ - return [props.bitcell.cell_1w1r.pin.br0, - props.bitcell.cell_1w1r.pin.br1] - - def get_write_bl_names(self): - """ Creates a list of bl pin names associated with write ports """ - return [props.bitcell.cell_1w1r.pin.bl0] - - def get_write_br_names(self): - """ Creates a list of br pin names asscociated with write ports""" - return [props.bitcell.cell_1w1r.pin.br1] - - def get_bl_name(self, port=0): - """Get bl name by port""" - return self.bl_names[port] - - def get_br_name(self, port=0): - """Get bl name by port""" - return self.br_names[port] - - def get_wl_name(self, port=0): - """Get wl name by port""" - debug.check(port < 2, "Two ports for bitcell_1rw_1r only.") - return self.wl_names[port] - - def build_graph(self, graph, inst_name, port_nets): - """Adds edges to graph. Multiport bitcell timing graph is too complex - to use the add_graph_edges function.""" - pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)} - pins = props.bitcell.cell_1w1r.pin - # Edges hardcoded here. Essentially wl->bl/br for both ports. - # Port 0 edges - graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.bl1], self) - graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.br1], self) - # Port 1 is a write port, so its timing is not considered here. diff --git a/compiler/bitcells/bitcell_2port.py b/compiler/bitcells/bitcell_2port.py new file mode 100644 index 00000000..6a9f0b6f --- /dev/null +++ b/compiler/bitcells/bitcell_2port.py @@ -0,0 +1,101 @@ +# 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 +from tech import cell_properties as props +import bitcell_base + + +class bitcell_2port(bitcell_base.bitcell_base): + """ + A single bit cell (6T, 8T, etc.) This module implements the + single memory cell used in the design. It is a hand-made cell, so + the layout and netlist should be available in the technology + library. + """ + + def __init__(self, name): + super().__init__(name, prop=props.bitcell_2port) + debug.info(2, "Create bitcell with 2 ports") + + self.bl_names = ["bl0", "bl1"] + self.br_names = ["br0", "br1"] + self.wl_names = ["wl0", "wl1"] + + def get_bitcell_pins(self, col, row): + """ + Creates a list of connections in the bitcell, + indexed by column and row, for instance use in bitcell_array + """ + bitcell_pins = ["bl0_{0}".format(col), + "br0_{0}".format(col), + "bl1_{0}".format(col), + "br1_{0}".format(col), + "wl0_{0}".format(row), + "wl1_{0}".format(row), + "vdd", + "gnd"] + return bitcell_pins + + def get_all_wl_names(self): + """ Creates a list of all wordline pin names """ + return self.wl_names + + def get_all_bitline_names(self): + """ Creates a list of all bitline pin names (both bl and br) """ + return ["bl0", "br0", "bl1", "br1"] + + def get_all_bl_names(self): + """ Creates a list of all bl pins names """ + return ["bl0", "bl1"] + + def get_all_br_names(self): + """ Creates a list of all br pins names """ + return ["br0", "br1"] + + def get_read_bl_names(self): + """ Creates a list of bl pin names associated with read ports """ + return ["bl0", "bl1"] + + def get_read_br_names(self): + """ Creates a list of br pin names associated with read ports """ + return ["br0", "br1"] + + def get_write_bl_names(self): + """ Creates a list of bl pin names associated with write ports """ + return ["bl0"] + + def get_write_br_names(self): + """ Creates a list of br pin names asscociated with write ports""" + return ["br1"] + + def get_bl_name(self, port=0): + """Get bl name by port""" + debug.check(port < 2, "Two ports for bitcell_2port only.") + return self.bl_names[port] + + def get_br_name(self, port=0): + """Get bl name by port""" + debug.check(port < 2, "Two ports for bitcell_2port only.") + return self.br_names[port] + + def get_wl_name(self, port=0): + """Get wl name by port""" + debug.check(port < 2, "Two ports for bitcell_2port only.") + return self.wl_names[port] + + def build_graph(self, graph, inst_name, port_nets): + """Adds edges to graph. Multiport bitcell timing graph is too complex + to use the add_graph_edges function.""" + pin_dict = {pin: port for pin, port in zip(self.pin_names, port_nets)} + # Edges hardcoded here. Essentially wl->bl/br for both ports. + # Port 0 edges + graph.add_edge(pin_dict["wl0"], pin_dict["bl0"], self) + graph.add_edge(pin_dict["wl0"], pin_dict["br0"], self) + # Port 1 edges + graph.add_edge(pin_dict["wl1"], pin_dict["bl1"], self) + graph.add_edge(pin_dict["wl1"], pin_dict["br1"], self) diff --git a/compiler/bitcells/bitcell_base.py b/compiler/bitcells/bitcell_base.py index 5ae468b2..09f33482 100644 --- a/compiler/bitcells/bitcell_base.py +++ b/compiler/bitcells/bitcell_base.py @@ -8,30 +8,27 @@ import debug import design -import utils from globals import OPTS import logical_effort -from tech import GDS, parameter, drc, layer +from tech import parameter, drc, layer class bitcell_base(design.design): """ Base bitcell parameters to be over-riden. """ - cell_size_layer = "boundary" + def __init__(self, name, cell_name=None, prop=None): + design.design.__init__(self, name, cell_name, prop) - def __init__(self, name, hard_cell=True): - design.design.__init__(self, name) - - if hard_cell: - (self.width, self.height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[self.cell_size_layer]) - self.pin_map = utils.get_libcell_pins(self.pin_names, - self.cell_name, - GDS["unit"]) - self.add_pin_types(self.type_list) + # Set the bitcell specific properties + if prop: + self.storage_nets = prop.storage_nets + self.nets_match = self.do_nets_exist(prop.storage_nets) + self.mirror = prop.mirror + self.end_caps = prop.end_caps + self.supplies = ["vdd", "gnd"] + 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 deleted file mode 100644 index 910e25ea..00000000 --- a/compiler/bitcells/col_cap_bitcell_1rw_1r.py +++ /dev/null @@ -1,30 +0,0 @@ -# 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 -from tech import cell_properties as props -import bitcell_base - - -class col_cap_bitcell_1rw_1r(bitcell_base.bitcell_base): - """ - Column end cap cell. - """ - - pin_names = [props.bitcell.cell_1rw1r.pin.bl0, - props.bitcell.cell_1rw1r.pin.br0, - 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"] - - def __init__(self, name="col_cap_cell_1rw_1r"): - bitcell_base.bitcell_base.__init__(self, name) - debug.info(2, "Create col_cap bitcell 1rw+1r object") - - self.no_instances = True diff --git a/compiler/bitcells/col_cap_bitcell_2port.py b/compiler/bitcells/col_cap_bitcell_2port.py new file mode 100644 index 00000000..d18d0762 --- /dev/null +++ b/compiler/bitcells/col_cap_bitcell_2port.py @@ -0,0 +1,22 @@ +# 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 +from tech import cell_properties as props +import bitcell_base + + +class col_cap_bitcell_2port(bitcell_base.bitcell_base): + """ + Column end cap cell. + """ + + def __init__(self, name="col_cap_bitcell_2port"): + bitcell_base.bitcell_base.__init__(self, name, prop=props.col_cap_2port) + debug.info(2, "Create col_cap bitcell 2 port object") + + self.no_instances = True diff --git a/compiler/bitcells/dummy_bitcell.py b/compiler/bitcells/dummy_bitcell_1port.py similarity index 63% rename from compiler/bitcells/dummy_bitcell.py rename to compiler/bitcells/dummy_bitcell_1port.py index 679509db..2ff836c1 100644 --- a/compiler/bitcells/dummy_bitcell.py +++ b/compiler/bitcells/dummy_bitcell_1port.py @@ -10,22 +10,15 @@ from tech import cell_properties as props import bitcell_base -class dummy_bitcell(bitcell_base.bitcell_base): +class dummy_bitcell_1port(bitcell_base.bitcell_base): """ A single bit cell (6T, 8T, etc.) This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ - 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"] - def __init__(self, name): - super().__init__(name) + super().__init__(name, prop=props.bitcell_1port) debug.info(2, "Create dummy bitcell") diff --git a/compiler/bitcells/dummy_bitcell_1rw_1r.py b/compiler/bitcells/dummy_bitcell_1rw_1r.py deleted file mode 100644 index 8d8a68d2..00000000 --- a/compiler/bitcells/dummy_bitcell_1rw_1r.py +++ /dev/null @@ -1,35 +0,0 @@ -# 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 -from tech import cell_properties as props -import bitcell_base - - -class dummy_bitcell_1rw_1r(bitcell_base.bitcell_base): - """ - A single bit cell which is forced to store a 0. - This module implements the single memory cell used in the design. It - is a hand-made cell, so the layout and netlist should be available in - the technology library. """ - - pin_names = [props.bitcell.cell_1rw1r.pin.bl0, - props.bitcell.cell_1rw1r.pin.br0, - props.bitcell.cell_1rw1r.pin.bl1, - props.bitcell.cell_1rw1r.pin.br1, - props.bitcell.cell_1rw1r.pin.wl0, - 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"] - - def __init__(self, name): - super().__init__(name) - debug.info(2, "Create dummy bitcell 1rw+1r object") - - diff --git a/compiler/bitcells/dummy_bitcell_1w_1r.py b/compiler/bitcells/dummy_bitcell_1w_1r.py deleted file mode 100644 index 60d87728..00000000 --- a/compiler/bitcells/dummy_bitcell_1w_1r.py +++ /dev/null @@ -1,37 +0,0 @@ -# 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 -from tech import cell_properties as props -import bitcell_base - - -class dummy_bitcell_1w_1r(bitcell_base.bitcell_base): - """ - A single bit cell which is forced to store a 0. - This module implements the single memory cell used in the design. It - is a hand-made cell, so the layout and netlist should be available in - the technology library. """ - - pin_names = [props.bitcell.cell_1w1r.pin.bl0, - props.bitcell.cell_1w1r.pin.br0, - props.bitcell.cell_1w1r.pin.bl1, - props.bitcell.cell_1w1r.pin.br1, - props.bitcell.cell_1w1r.pin.wl0, - 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"] - - def __init__(self, name): - super().__init__(name) - debug.info(2, "Create dummy bitcell 1w+1r object") - - - - diff --git a/compiler/bitcells/dummy_bitcell_2port.py b/compiler/bitcells/dummy_bitcell_2port.py new file mode 100644 index 00000000..5ed56f09 --- /dev/null +++ b/compiler/bitcells/dummy_bitcell_2port.py @@ -0,0 +1,24 @@ +# 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 +from tech import cell_properties as props +import bitcell_base + + +class dummy_bitcell_2port(bitcell_base.bitcell_base): + """ + A single bit cell which is forced to store a 0. + This module implements the single memory cell used in the design. It + is a hand-made cell, so the layout and netlist should be available in + the technology library. """ + + def __init__(self, name): + super().__init__(name, prop=props.bitcell_2port) + debug.info(2, "Create dummy bitcell 2 port object") + + diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py index 120bb48e..c5ac8cb6 100644 --- a/compiler/bitcells/pbitcell.py +++ b/compiler/bitcells/pbitcell.py @@ -8,6 +8,7 @@ import contact import debug from tech import drc, parameter, layer +from tech import cell_properties as props from vector import vector from ptx import ptx from globals import OPTS @@ -29,8 +30,10 @@ class pbitcell(bitcell_base.bitcell_base): self.replica_bitcell = replica_bitcell self.dummy_bitcell = dummy_bitcell + self.mirror = props.bitcell_1port.mirror + self.end_caps = props.bitcell_1port.end_caps - bitcell_base.bitcell_base.__init__(self, name, hard_cell=False) + bitcell_base.bitcell_base.__init__(self, name) 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_1port.py similarity index 83% rename from compiler/bitcells/replica_bitcell.py rename to compiler/bitcells/replica_bitcell_1port.py index 74e121ee..58087b97 100644 --- a/compiler/bitcells/replica_bitcell.py +++ b/compiler/bitcells/replica_bitcell_1port.py @@ -12,22 +12,15 @@ from tech import parameter, drc import logical_effort -class replica_bitcell(bitcell_base.bitcell_base): +class replica_bitcell_1port(bitcell_base.bitcell_base): """ A single bit cell (6T, 8T, etc.) This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ - 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"] - def __init__(self, name): - super().__init__(name) + super().__init__(name, prop=props.bitcell_1port) debug.info(2, "Create replica bitcell object") def get_stage_effort(self, load): diff --git a/compiler/bitcells/replica_bitcell_1w_1r.py b/compiler/bitcells/replica_bitcell_1w_1r.py deleted file mode 100644 index 59fa4676..00000000 --- a/compiler/bitcells/replica_bitcell_1w_1r.py +++ /dev/null @@ -1,61 +0,0 @@ -# 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 bitcell_base -from tech import cell_properties as props -from tech import parameter, drc -import logical_effort - - -class replica_bitcell_1w_1r(bitcell_base.bitcell_base): - """ - A single bit cell which is forced to store a 0. - This module implements the single memory cell used in the design. It - is a hand-made cell, so the layout and netlist should be available in - the technology library. """ - - pin_names = [props.bitcell.cell_1w1r.pin.bl0, - props.bitcell.cell_1w1r.pin.br0, - props.bitcell.cell_1w1r.pin.bl1, - props.bitcell.cell_1w1r.pin.br1, - props.bitcell.cell_1w1r.pin.wl0, - 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"] - - def __init__(self, name): - super().__init__(name) - debug.info(2, "Create replica bitcell 1w+1r object") - - 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 - cin = 3 # Assumes always a minimum sizes inverter. Could be specified in the tech.py file. - read_port_load = 0.5 # min size NMOS gate load - return logical_effort.logical_effort('bitline', size, cin, load + read_port_load, parasitic_delay, False) - - def input_load(self): - """Return the relative capacitance of the access transistor gates""" - - # FIXME: This applies to bitline capacitances as well. - # FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed. - access_tx_cin = parameter["6T_access_size"] / drc["minwidth_tx"] - return 2 * access_tx_cin - - def build_graph(self, graph, inst_name, port_nets): - """Adds edges to graph. Multiport bitcell timing graph is too complex - to use the add_graph_edges function.""" - debug.info(1, 'Adding edges for {}'.format(inst_name)) - pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)} - pins = props.bitcell.cell_1w1r.pin - # Edges hardcoded here. Essentially wl->bl/br for the read port. - # Port 1 edges - graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.bl1], self) - graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.br1], self) - # Port 0 is a write port, so its timing is not considered here. diff --git a/compiler/bitcells/replica_bitcell_1rw_1r.py b/compiler/bitcells/replica_bitcell_2port.py similarity index 63% rename from compiler/bitcells/replica_bitcell_1rw_1r.py rename to compiler/bitcells/replica_bitcell_2port.py index 9dc9aac9..710a18d7 100644 --- a/compiler/bitcells/replica_bitcell_1rw_1r.py +++ b/compiler/bitcells/replica_bitcell_2port.py @@ -12,26 +12,16 @@ from tech import parameter, drc import logical_effort -class replica_bitcell_1rw_1r(bitcell_base.bitcell_base): +class replica_bitcell_2port(bitcell_base.bitcell_base): """ A single bit cell which is forced to store a 0. This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ - pin_names = [props.bitcell.cell_1rw1r.pin.bl0, - props.bitcell.cell_1rw1r.pin.br0, - props.bitcell.cell_1rw1r.pin.bl1, - props.bitcell.cell_1rw1r.pin.br1, - props.bitcell.cell_1rw1r.pin.wl0, - 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"] - def __init__(self, name): - super().__init__(name) - debug.info(2, "Create replica bitcell 1rw+1r object") + super().__init__(name, prop=props.bitcell_2port) + debug.info(2, "Create replica bitcell 2 port object") def get_stage_effort(self, load): parasitic_delay = 1 @@ -51,12 +41,11 @@ class replica_bitcell_1rw_1r(bitcell_base.bitcell_base): def build_graph(self, graph, inst_name, port_nets): """Adds edges to graph. Multiport bitcell timing graph is too complex to use the add_graph_edges function.""" - pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)} - pins = props.bitcell.cell_1rw1r.pin + pin_dict = {pin: port for pin, port in zip(self.pin_names, port_nets)} # Edges hardcoded here. Essentially wl->bl/br for both ports. # Port 0 edges - graph.add_edge(pin_dict[pins.wl0], pin_dict[pins.bl0], self) - graph.add_edge(pin_dict[pins.wl0], pin_dict[pins.br0], self) + graph.add_edge(pin_dict["wl0"], pin_dict["bl0"], self) + graph.add_edge(pin_dict["wl0"], pin_dict["br0"], self) # Port 1 edges - graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.bl1], self) - graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.br1], self) + graph.add_edge(pin_dict["wl1"], pin_dict["bl1"], self) + graph.add_edge(pin_dict["wl1"], pin_dict["br1"], self) diff --git a/compiler/bitcells/row_cap_bitcell_1rw_1r.py b/compiler/bitcells/row_cap_bitcell_1rw_1r.py deleted file mode 100644 index 6d6dfe16..00000000 --- a/compiler/bitcells/row_cap_bitcell_1rw_1r.py +++ /dev/null @@ -1,27 +0,0 @@ -# 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 -from tech import cell_properties as props -import bitcell_base - - -class row_cap_bitcell_1rw_1r(bitcell_base.bitcell_base): - """ - Row end cap cell. - """ - - 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"] - - def __init__(self, name="row_cap_cell_1rw_1r"): - bitcell_base.bitcell_base.__init__(self, name) - debug.info(2, "Create row_cap bitcell 1rw+1r object") - - self.no_instances = True diff --git a/compiler/bitcells/row_cap_bitcell_2port.py b/compiler/bitcells/row_cap_bitcell_2port.py new file mode 100644 index 00000000..2edee57c --- /dev/null +++ b/compiler/bitcells/row_cap_bitcell_2port.py @@ -0,0 +1,22 @@ +# 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 +from tech import cell_properties as props +import bitcell_base + + +class row_cap_bitcell_2port(bitcell_base.bitcell_base): + """ + Row end cap cell. + """ + + def __init__(self, name="row_cap_bitcell_2port"): + bitcell_base.bitcell_base.__init__(self, name, prop=props.row_cap_2port) + debug.info(2, "Create row_cap bitcell 2 port object") + + self.no_instances = True diff --git a/compiler/characterizer/setup_hold.py b/compiler/characterizer/setup_hold.py index f3b9541c..688e6535 100644 --- a/compiler/characterizer/setup_hold.py +++ b/compiler/characterizer/setup_hold.py @@ -5,13 +5,12 @@ # (acting for and on behalf of Oklahoma State University) # All rights reserved. # -import sys import tech from .stimuli import * import debug from .charutils import * -import dff from globals import OPTS +from sram_factory import factory class setup_hold(): @@ -22,9 +21,8 @@ class setup_hold(): def __init__(self, corner): # This must match the spice model order - self.pins = ["data", "dout", "clk", "vdd", "gnd"] - self.model_name = "dff" - self.model_location = OPTS.openram_tech + "sp_lib/dff.sp" + self.dff = factory.create(module_type=OPTS.dff) + self.period = tech.spice["feasible_period"] debug.info(2, "Feasible period from technology file: {0} ".format(self.period)) @@ -50,8 +48,8 @@ class setup_hold(): # instantiate the master-slave d-flip-flop self.sf.write("\n* Instantiation of the Master-Slave D-flip-flop\n") - self.stim.inst_model(pins=self.pins, - model_name=self.model_name) + self.stim.inst_model(pins=self.dff.get_original_pin_names(), + model_name=self.dff.cell_name) self.write_data(mode=mode, target_time=target_time, @@ -71,7 +69,7 @@ class setup_hold(): self.sf.write("\n* Stimulus for setup/hold: data {0} period {1}n\n".format(correct_value, self.period)) # include files in stimulus file - self.stim.write_include(self.model_location) + self.stim.write_include(self.dff.sp_file) # add vdd/gnd statements self.sf.write("\n* Global Power Supplies\n") @@ -94,7 +92,7 @@ class setup_hold(): start_value = incorrect_value end_value = correct_value - self.stim.gen_pwl(sig_name="data", + self.stim.gen_pwl(sig_name="D", clk_times=[0, self.period, target_time], data_values=[init_value, start_value, end_value], period=target_time, @@ -136,7 +134,7 @@ class setup_hold(): self.sf.write("\n* Measure statements for pass/fail verification\n") trig_name = "clk" - targ_name = "dout" + targ_name = "Q" trig_val = targ_val = 0.5 * self.vdd_voltage # Start triggers right before the clock edge at 2*period self.stim.gen_meas_delay(meas_name="clk2q_delay", @@ -149,7 +147,7 @@ class setup_hold(): trig_td=1.9 * self.period, targ_td=1.9 * self.period) - targ_name = "data" + targ_name = "D" # Start triggers right after initialize value is returned to normal # at one period self.stim.gen_meas_delay(meas_name="setup_hold_time", diff --git a/compiler/custom/dff.py b/compiler/custom/dff.py index 38e3bd75..b0c2b5a8 100644 --- a/compiler/custom/dff.py +++ b/compiler/custom/dff.py @@ -6,40 +6,17 @@ # All rights reserved. # import design -from tech import GDS, layer, spice from tech import cell_properties as props -import utils +from tech import spice class dff(design.design): """ Memory address flip-flop """ - if not props.dff.use_custom_ports: - pin_names = ["D", "Q", "clk", "vdd", "gnd"] - type_list = ["INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] - clk_pin = "clk" - else: - pin_names = props.dff.custom_port_list - type_list = props.dff.custom_type_list - clk_pin = props.dff.clk_pin - cell_size_layer = "boundary" def __init__(self, name="dff"): - super().__init__(name) - - (width, height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[self.cell_size_layer]) - - pin_map = utils.get_libcell_pins(self.pin_names, - self.cell_name, - GDS["unit"]) - - self.width = width - self.height = height - self.pin_map = pin_map - self.add_pin_types(self.type_list) + super().__init__(name, prop=props.dff) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" @@ -54,9 +31,9 @@ class dff(design.design): def calculate_effective_capacitance(self, load): """Computes effective capacitance. Results in fF""" c_load = load - c_para = spice["dff_out_cap"]#ff + c_para = spice["dff_out_cap"] # ff transition_prob = 0.5 - return transition_prob*(c_load + c_para) + return transition_prob * (c_load + c_para) def build_graph(self, graph, inst_name, port_nets): """Adds edges based on inputs/outputs. Overrides base class function.""" diff --git a/compiler/custom/inv_dec.py b/compiler/custom/inv_dec.py index b150a38e..a1bb0c83 100644 --- a/compiler/custom/inv_dec.py +++ b/compiler/custom/inv_dec.py @@ -6,9 +6,9 @@ # All rights reserved. # import design -from tech import GDS, layer, spice, parameter import logical_effort -import utils +from tech import cell_properties as props +from tech import spice, parameter class inv_dec(design.design): @@ -16,25 +16,8 @@ class inv_dec(design.design): INV for address decoders. """ - pin_names = ["A", "Z", "vdd", "gnd"] - type_list = ["INPUT", "OUTPUT", "POWER", "GROUND"] - cell_size_layer = "boundary" - def __init__(self, name="inv_dec", height=None): - super().__init__(name) - - (width, height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[self.cell_size_layer]) - - pin_map = utils.get_libcell_pins(self.pin_names, - self.cell_name, - GDS["unit"]) - - self.width = width - self.height = height - self.pin_map = pin_map - self.add_pin_types(self.type_list) + super().__init__(name, prop=props.inv_dec) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" @@ -52,7 +35,7 @@ class inv_dec(design.design): # In fF c_para = spice["min_tx_drain_c"] * (self.nmos_size / parameter["min_tx_size"]) - return transition_prob * (c_load + c_para) + return 0.5 * (c_load + c_para) def input_load(self): """ diff --git a/compiler/custom/nand2_dec.py b/compiler/custom/nand2_dec.py index efec63b6..b5c48a15 100644 --- a/compiler/custom/nand2_dec.py +++ b/compiler/custom/nand2_dec.py @@ -6,9 +6,9 @@ # All rights reserved. # import design -from tech import GDS, layer, spice, parameter, drc +from tech import spice, parameter, drc +from tech import cell_properties as props import logical_effort -import utils class nand2_dec(design.design): @@ -16,25 +16,8 @@ class nand2_dec(design.design): 2-input NAND decoder for address decoders. """ - pin_names = ["A", "B", "Z", "vdd", "gnd"] - type_list = ["INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"] - cell_size_layer = "boundary" - def __init__(self, name="nand2_dec", height=None): - super().__init__(name) - - (width, height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[self.cell_size_layer]) - - pin_map = utils.get_libcell_pins(self.pin_names, - self.cell_name, - GDS["unit"]) - - self.width = width - self.height = height - self.pin_map = pin_map - self.add_pin_types(self.type_list) + super().__init__(name, prop=props.nand2_dec) # FIXME: For now... size = 1 diff --git a/compiler/custom/nand3_dec.py b/compiler/custom/nand3_dec.py index 3fc2b949..2713fde9 100644 --- a/compiler/custom/nand3_dec.py +++ b/compiler/custom/nand3_dec.py @@ -6,9 +6,9 @@ # All rights reserved. # import design -from tech import GDS, layer, spice, parameter, drc +from tech import spice, parameter, drc +from tech import cell_properties as props import logical_effort -import utils class nand3_dec(design.design): @@ -16,25 +16,8 @@ class nand3_dec(design.design): 3-input NAND decoder for address decoders. """ - pin_names = ["A", "B", "C", "Z", "vdd", "gnd"] - type_list = ["INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"] - cell_size_layer = "boundary" - def __init__(self, name="nand3_dec", height=None): - super().__init__(name) - - (width, height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[self.cell_size_layer]) - - pin_map = utils.get_libcell_pins(self.pin_names, - self.cell_name, - GDS["unit"]) - - self.width = width - self.height = height - self.pin_map = pin_map - self.add_pin_types(self.type_list) + super().__init__(name, prop=props.nand3_dec) # FIXME: For now... size = 1 diff --git a/compiler/custom/nand4_dec.py b/compiler/custom/nand4_dec.py index abcfd2f3..5fab2d36 100644 --- a/compiler/custom/nand4_dec.py +++ b/compiler/custom/nand4_dec.py @@ -6,35 +6,18 @@ # All rights reserved. # import design -from tech import GDS, layer, spice, parameter, drc +from tech import spice, parameter, drc +from tech import cell_properties as props import logical_effort -import utils class nand4_dec(design.design): """ - 2-input NAND decoder for address decoders. + 4-input NAND decoder for address decoders. """ - pin_names = ["A", "B", "C", "D", "Z", "vdd", "gnd"] - type_list = ["INPUT", "INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"] - cell_size_layer = "boundary" - def __init__(self, name="nand4_dec", height=None): - super().__init__(name) - - (width, height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[self.cell_size_layer]) - - pin_map = utils.get_libcell_pins(self.pin_names, - self.cell_name, - GDS["unit"]) - - self.width = width - self.height = height - self.pin_map = pin_map - self.add_pin_types(self.type_list) + super().__init__(name, prop=props.nand4_dec) # FIXME: For now... size = 1 diff --git a/compiler/custom/sense_amp.py b/compiler/custom/sense_amp.py index 4e84b7fe..d57bdaac 100644 --- a/compiler/custom/sense_amp.py +++ b/compiler/custom/sense_amp.py @@ -7,8 +7,7 @@ # import design import debug -import utils -from tech import GDS, layer, parameter, drc +from tech import parameter, drc from tech import cell_properties as props import logical_effort @@ -20,45 +19,24 @@ class sense_amp(design.design): the technology library. Sense amplifier to read a pair of bit-lines. """ - pin_names = [props.sense_amp.pin.bl, - props.sense_amp.pin.br, - props.sense_amp.pin.dout, - props.sense_amp.pin.en, - props.sense_amp.pin.vdd, - props.sense_amp.pin.gnd] - type_list = ["INPUT", "INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] - cell_size_layer = "boundary" def __init__(self, name="sense_amp"): - super().__init__(name) + super().__init__(name, prop=props.sense_amp) debug.info(2, "Create sense_amp") - (width, height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[self.cell_size_layer]) - - pin_map = utils.get_libcell_pins(self.pin_names, - self.cell_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 + return "bl" def get_br_names(self): - return props.sense_amp.pin.br + return "br" @property def dout_name(self): - return props.sense_amp.pin.dout + return "dout" @property def en_name(self): - return props.sense_amp.pin.en + return "en" def get_cin(self): diff --git a/compiler/custom/tri_gate.py b/compiler/custom/tri_gate.py index 476cc886..6be58104 100644 --- a/compiler/custom/tri_gate.py +++ b/compiler/custom/tri_gate.py @@ -7,8 +7,7 @@ # import debug import design -import utils -from tech import GDS, layer +from tech import spice class tri_gate(design.design): @@ -18,10 +17,6 @@ class tri_gate(design.design): netlist should be available in the technology library. """ - pin_names = ["in", "out", "en", "en_bar", "vdd", "gnd"] - type_list = ["INPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"] - cell_size_layer = "boundary" - unique_id = 1 def __init__(self, name=""): @@ -31,19 +26,6 @@ class tri_gate(design.design): super().__init__(self, name) debug.info(2, "Create tri_gate") - (width, height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[self.cell_size_layer]) - - pin_map = utils.get_libcell_pins(self.pin_names, - self.cell_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): """Returns dynamic and leakage power. Results in nW""" #Power in this module currently not defined. Returns 0 nW (leakage and dynamic). @@ -51,7 +33,7 @@ class tri_gate(design.design): return total_power def get_cin(self): - return 9*spice["min_tx_gate_c"] + return 9 * spice["min_tx_gate_c"] def build_graph(self, graph, inst_name, port_nets): """Adds edges based on inputs/outputs. Overrides base class function.""" diff --git a/compiler/custom/write_driver.py b/compiler/custom/write_driver.py index 41375ab3..755fdb03 100644 --- a/compiler/custom/write_driver.py +++ b/compiler/custom/write_driver.py @@ -7,8 +7,6 @@ # import debug import design -import utils -from tech import GDS, layer from tech import cell_properties as props @@ -20,51 +18,28 @@ class write_driver(design.design): the technology library. """ - pin_names = [props.write_driver.pin.din, - props.write_driver.pin.bl, - props.write_driver.pin.br, - props.write_driver.pin.en, - props.write_driver.pin.vdd, - props.write_driver.pin.gnd] - - type_list = ["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] - cell_size_layer = "boundary" - def __init__(self, name): - super().__init__(name) + super().__init__(name, prop=props.write_driver) debug.info(2, "Create write_driver") - (width, height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[self.cell_size_layer]) - - pin_map = utils.get_libcell_pins(self.pin_names, - self.cell_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.write_driver.pin.bl + return "bl" def get_br_names(self): - return props.write_driver.pin.br + return "br" @property def din_name(self): - return props.write_driver.pin.din + return "din" @property def en_name(self): - return props.write_driver.pin.en + return "en" def get_w_en_cin(self): """Get the relative capacitance of a single input""" # This is approximated from SCMOS. It has roughly 5 3x transistor gates. - return 5*3 + return 5 * 3 def build_graph(self, graph, inst_name, port_nets): """Adds edges based on inputs/outputs. Overrides base class function.""" diff --git a/compiler/globals.py b/compiler/globals.py index c6980d9e..8c6d7fd5 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -213,28 +213,15 @@ def setup_bitcell(): # If we have non-1rw ports, # and the user didn't over-ride the bitcell manually, # figure out the right bitcell to use - if OPTS.bitcell == "bitcell": - if (OPTS.num_rw_ports == 1 and OPTS.num_w_ports == 0 and OPTS.num_r_ports == 0): - OPTS.bitcell = "bitcell" - else: - ports = "" - if OPTS.num_rw_ports > 0: - ports += "{}rw_".format(OPTS.num_rw_ports) - if OPTS.num_w_ports > 0: - ports += "{}w_".format(OPTS.num_w_ports) - if OPTS.num_r_ports > 0: - ports += "{}r".format(OPTS.num_r_ports) - - if ports != "": - OPTS.bitcell_suffix = "_" + ports - OPTS.bitcell = "bitcell" + OPTS.bitcell_suffix - - OPTS.dummy_bitcell = "dummy_" + OPTS.bitcell - OPTS.replica_bitcell = "replica_" + OPTS.bitcell - elif OPTS.bitcell == "pbitcell": + if OPTS.bitcell == "pbitcell": OPTS.bitcell = "pbitcell" OPTS.dummy_bitcell = "dummy_pbitcell" OPTS.replica_bitcell = "replica_pbitcell" + else: + num_ports = OPTS.num_rw_ports + OPTS.num_w_ports + OPTS.num_r_ports + OPTS.bitcell = "bitcell_{}port".format(num_ports) + OPTS.dummy_bitcell = "dummy_" + OPTS.bitcell + OPTS.replica_bitcell = "replica_" + OPTS.bitcell # See if bitcell exists try: @@ -247,7 +234,8 @@ def setup_bitcell(): OPTS.dummy_bitcell = "dummy_pbitcell" OPTS.replica_bitcell = "replica_pbitcell" if not OPTS.is_unit_test: - debug.warning("Using the parameterized bitcell which may have suboptimal density.") + msg = "Didn't find {0}rw {1}w {2}r port bitcell. ".format(OPTS.num_rw_ports, OPTS.num_w_ports, OPTS.num_r_ports) + debug.warning("{} Using the parameterized bitcell which may have suboptimal density.".format(msg)) debug.info(1, "Using bitcell: {}".format(OPTS.bitcell)) diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index 10abe1e2..5a181ba7 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -62,7 +62,7 @@ class bitcell_array(bitcell_base_array): for row in range(self.row_size): name = "bit_r{0}_c{1}".format(row, col) self.cell_inst[row, col]=self.add_inst(name=name, - mod=self.cell) + mod=self.cell) self.connect_inst(self.get_bitcell_pins(row, col)) def analytical_power(self, corner, load): diff --git a/compiler/modules/bitcell_base_array.py b/compiler/modules/bitcell_base_array.py index b1ee88a4..088308f9 100644 --- a/compiler/modules/bitcell_base_array.py +++ b/compiler/modules/bitcell_base_array.py @@ -7,7 +7,6 @@ # import debug import design -from tech import cell_properties from sram_factory import factory from globals import OPTS @@ -36,10 +35,10 @@ class bitcell_base_array(design.design): self.rbl_wordline_names = [[] for port in self.all_ports] self.all_rbl_wordline_names = [] - # The supply pin namesn - self.bitcell_supplies = ["vdd", "gnd"] + # The supply pin names + self.bitcell_supplies = self.cell.supplies # If the technology needs renaming of the supplies - self.supplies = self.bitcell_supplies + self.supplies = ["vdd", "gnd"] def create_all_bitline_names(self): for col in range(self.column_size): @@ -174,7 +173,7 @@ class bitcell_base_array(design.design): tempx = xoffset dir_y = False # If we mirror the current cell on the y axis adjust the x position - if cell_properties.bitcell.mirror.y and (col + col_offset) % 2: + if self.cell.mirror.y and (col + col_offset) % 2: tempx = xoffset + self.cell.width dir_y = True return (tempx, dir_y) @@ -183,7 +182,7 @@ class bitcell_base_array(design.design): tempy = yoffset dir_x = False # If we mirror the current cell on the x axis adjust the y position - if cell_properties.bitcell.mirror.x and (row + row_offset) % 2: + if self.cell.mirror.x and (row + row_offset) % 2: tempy = yoffset + self.cell.height dir_x = True return (tempy, dir_x) diff --git a/compiler/modules/col_cap_array.py b/compiler/modules/col_cap_array.py index ffbf6413..71a59cf8 100644 --- a/compiler/modules/col_cap_array.py +++ b/compiler/modules/col_cap_array.py @@ -6,7 +6,6 @@ from bitcell_base_array import bitcell_base_array from sram_factory import factory from globals import OPTS -from tech import cell_properties class col_cap_array(bitcell_base_array): @@ -26,12 +25,9 @@ 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 - try: - end_caps_enabled = cell_properties.bitcell.end_caps - except AttributeError: - end_caps_enabled = False + self.cell = factory.create(module_type=OPTS.bitcell) - if not end_caps_enabled: + if not self.cell.end_caps: self.create_all_wordline_names() self.create_all_bitline_names() @@ -51,8 +47,6 @@ class col_cap_array(bitcell_base_array): self.dummy_cell = factory.create(module_type="col_cap_{}".format(OPTS.bitcell)) self.add_mod(self.dummy_cell) - self.cell = factory.create(module_type=OPTS.bitcell) - def create_instances(self): """ Create the module instances used in this design """ self.cell_inst = {} @@ -70,16 +64,14 @@ class col_cap_array(bitcell_base_array): """ 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), + bitcell_pins = ["bl0_{0}".format(col), + "br0_{0}".format(col), "vdd"] else: - pin_name = cell_properties.bitcell.cell_1rw1r.pin - bitcell_pins = ["{0}_{1}".format(pin_name.bl0, col), - "{0}_{1}".format(pin_name.br0, col), - "{0}_{1}".format(pin_name.bl1, col), - "{0}_{1}".format(pin_name.br1, col), + bitcell_pins = ["bl0_{0}".format(col), + "br0_{0}".format(col), + "bl1_{0}".format(col), + "br1_{0}".format(col), "vdd"] return bitcell_pins diff --git a/compiler/modules/column_mux_array.py b/compiler/modules/column_mux_array.py index 2f1ee56e..55d67eee 100644 --- a/compiler/modules/column_mux_array.py +++ b/compiler/modules/column_mux_array.py @@ -11,7 +11,6 @@ from tech import layer, preferred_directions from vector import vector from sram_factory import factory from globals import OPTS -from tech import cell_properties as cell_props from tech import layer_properties as layer_props @@ -99,6 +98,8 @@ class column_mux_array(design.design): bitcell_br=self.bitcell_br) self.add_mod(self.mux) + self.cell = factory.create(module_type=OPTS.bitcell) + def setup_layout_constants(self): self.column_addr_size = int(self.words_per_row / 2) self.width = self.columns * self.mux.width @@ -128,7 +129,7 @@ class column_mux_array(design.design): # For every column, add a pass gate for col_num, xoffset in enumerate(self.offsets[0:self.columns]): - if cell_props.bitcell.mirror.y and (col_num + self.column_offset) % 2: + if self.cell.mirror.y and (col_num + self.column_offset) % 2: mirror = "MY" xoffset = xoffset + self.mux.width else: diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index b0620a38..cbef7dfb 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -6,7 +6,6 @@ # All rights reserved. # import design -from tech import cell_properties as props import debug from sram_factory import factory import math @@ -662,9 +661,6 @@ class control_logic(design.design): self.ctrl_dff_inst=self.add_inst(name="ctrl_dffs", mod=self.ctrl_dff_array) inst_pins = self.input_list + self.dff_output_list + ["clk_buf"] + self.supply_list - if props.dff_buff_array.add_body_contacts: - inst_pins.append("vpb") - inst_pins.append("vnb") self.connect_inst(inst_pins) def place_dffs(self): diff --git a/compiler/modules/dff_array.py b/compiler/modules/dff_array.py index 0cbe8fe5..82746a06 100644 --- a/compiler/modules/dff_array.py +++ b/compiler/modules/dff_array.py @@ -70,7 +70,7 @@ class dff_array(design.design): mod=self.dff) instance_ports = [self.get_din_name(row, col), self.get_dout_name(row, col)] - for port in self.dff.pin_names: + for port in self.dff.pins: if port != 'D' and port != 'Q': instance_ports.append(port) self.connect_inst(instance_ports) @@ -137,7 +137,7 @@ class dff_array(design.design): height=dout_pin.height()) # Create vertical spines to a single horizontal rail - clk_pin = self.dff_insts[0, 0].get_pin(self.dff.clk_pin) + clk_pin = self.dff_insts[0, 0].get_pin("clk") clk_ypos = 2 * self.m3_pitch + self.m3_width debug.check(clk_pin.layer == "m2", "DFF clk pin not on metal2") self.add_layout_pin_segment_center(text="clk", @@ -145,7 +145,7 @@ class dff_array(design.design): start=vector(0, clk_ypos), end=vector(self.width, clk_ypos)) for col in range(self.columns): - clk_pin = self.dff_insts[0, col].get_pin(self.dff.clk_pin) + clk_pin = self.dff_insts[0, col].get_pin("clk") # Make a vertical strip for each column self.add_rect(layer="m2", offset=clk_pin.ll().scale(1, 0), diff --git a/compiler/modules/dff_buf.py b/compiler/modules/dff_buf.py index b218a9bb..58d26007 100644 --- a/compiler/modules/dff_buf.py +++ b/compiler/modules/dff_buf.py @@ -8,7 +8,6 @@ import debug import design from tech import layer -from tech import cell_properties as props from vector import vector from globals import OPTS from sram_factory import factory @@ -72,16 +71,8 @@ class dff_buf(design.design): self.add_mod(self.inv2) def add_pins(self): - self.add_pin("D", "INPUT") - self.add_pin("Q", "OUTPUT") - self.add_pin("Qb", "OUTPUT") - self.add_pin("clk", "INPUT") - self.add_pin("vdd", "POWER") - self.add_pin("gnd", "GROUND") - - if props.dff_buff.add_body_contacts: - self.add_pin("vpb", "INPUT") - self.add_pin("vpn", "INPUT") + self.add_pin_list(["D", "Q", "Qb", "clk", "vdd", "gnd"], + ["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]) def create_instances(self): self.dff_inst=self.add_inst(name="dff_buf_dff", diff --git a/compiler/modules/dff_buf_array.py b/compiler/modules/dff_buf_array.py index 2d885ccc..ea811e76 100644 --- a/compiler/modules/dff_buf_array.py +++ b/compiler/modules/dff_buf_array.py @@ -7,7 +7,6 @@ # import debug import design -from tech import cell_properties as props from vector import vector from globals import OPTS from sram_factory import factory @@ -65,10 +64,6 @@ class dff_buf_array(design.design): self.add_pin("vdd", "POWER") self.add_pin("gnd", "GROUND") - if props.dff_buff_array.add_body_contacts: - self.add_pin("vpb", "INPUT") - self.add_pin("vnb", "INPUT") - def add_modules(self): self.dff = factory.create(module_type="dff_buf", inv1_size=self.inv1_size, @@ -88,9 +83,6 @@ class dff_buf_array(design.design): "clk", "vdd", "gnd"] - if props.dff_buff_array.add_body_contacts: - inst_ports.append("vpb") - inst_ports.append("vnb") self.connect_inst(inst_ports) def place_dff_array(self): diff --git a/compiler/modules/dummy_array.py b/compiler/modules/dummy_array.py index 51b423ae..0a33e7cc 100644 --- a/compiler/modules/dummy_array.py +++ b/compiler/modules/dummy_array.py @@ -5,7 +5,6 @@ # from bitcell_base_array import bitcell_base_array from sram_factory import factory -from tech import cell_properties as props from globals import OPTS @@ -77,15 +76,17 @@ class dummy_array(bitcell_base_array): for col in range(self.column_size): for port in self.all_ports: bl_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port]) - self.add_rect(layer=bl_pin.layer, - offset=bl_pin.ll().scale(1, 0), - width=bl_pin.width(), - height=self.height) + self.add_layout_pin(text="bl_{0}_{1}".format(port, col), + layer=bl_pin.layer, + offset=bl_pin.ll().scale(1, 0), + width=bl_pin.width(), + height=self.height) br_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port + 1]) - self.add_rect(layer=br_pin.layer, - offset=br_pin.ll().scale(1, 0), - width=br_pin.width(), - height=self.height) + self.add_layout_pin(text="br_{0}_{1}".format(port, col), + layer=br_pin.layer, + offset=br_pin.ll().scale(1, 0), + width=br_pin.width(), + height=self.height) wl_names = self.cell.get_all_wl_names() for row in range(self.row_size): diff --git a/compiler/modules/precharge_array.py b/compiler/modules/precharge_array.py index a9cf2824..590dadce 100644 --- a/compiler/modules/precharge_array.py +++ b/compiler/modules/precharge_array.py @@ -10,7 +10,6 @@ import debug from vector import vector from sram_factory import factory from globals import OPTS -from tech import cell_properties class precharge_array(design.design): @@ -79,6 +78,8 @@ class precharge_array(design.design): bitcell_br=self.bitcell_br) self.add_mod(self.pc_cell) + self.cell = factory.create(module_type=OPTS.bitcell) + def add_layout_pins(self): en_pin = self.pc_cell.get_pin("en_bar") @@ -120,7 +121,7 @@ class precharge_array(design.design): self.offsets = [n * self.pc_cell.width for n in range(self.columns)] for i, xoffset in enumerate(self.offsets): - if cell_properties.bitcell.mirror.y and (i + self.column_offset) % 2: + if self.cell.mirror.y and (i + self.column_offset) % 2: mirror = "MY" tempx = xoffset + self.pc_cell.width else: diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index cc6373db..ebfd06ba 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -63,13 +63,8 @@ class replica_bitcell_array(bitcell_base_array): # Two dummy cols plus replica if we add the column 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: + if not self.cell.end_caps: self.extra_rows += 2 self.extra_cols += 2 @@ -144,10 +139,6 @@ class replica_bitcell_array(bitcell_base_array): column_offset=column_offset, replica_bit=replica_bit) self.add_mod(self.replica_columns[port]) - try: - end_caps_enabled = cell_properties.bitcell.end_caps - except AttributeError: - end_caps_enabled = False # Dummy row self.dummy_row = factory.create(module_type="dummy_array", @@ -159,7 +150,7 @@ class replica_bitcell_array(bitcell_base_array): self.add_mod(self.dummy_row) # Dummy Row or Col Cap, depending on bitcell array properties - col_cap_module_type = ("col_cap_array" if end_caps_enabled else "dummy_array") + col_cap_module_type = ("col_cap_array" if self.cell.end_caps else "dummy_array") self.col_cap_top = factory.create(module_type=col_cap_module_type, cols=self.column_size, rows=1, @@ -179,7 +170,7 @@ class replica_bitcell_array(bitcell_base_array): self.add_mod(self.col_cap_bottom) # Dummy Col or Row Cap, depending on bitcell array properties - row_cap_module_type = ("row_cap_array" if end_caps_enabled else "dummy_array") + row_cap_module_type = ("row_cap_array" if self.cell.end_caps else "dummy_array") self.row_cap_left = factory.create(module_type=row_cap_module_type, cols=1, @@ -240,11 +231,6 @@ 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 = [] @@ -385,14 +371,10 @@ class replica_bitcell_array(bitcell_base_array): def add_replica_columns(self): """ Add replica columns on left and right of array """ - try: - end_caps_enabled = cell_properties.bitcell.end_caps - except AttributeError: - end_caps_enabled = False # Grow from left to right, toward the array for bit, port in enumerate(self.left_rbl): - if not end_caps_enabled: + if not self.cell.end_caps: offset = self.bitcell_offset.scale(-len(self.left_rbl) + bit, -self.rbl[0] - 1) + self.strap_offset.scale(-len(self.left_rbl) + bit, 0) + self.unused_offset else: offset = self.bitcell_offset.scale(-len(self.left_rbl) + bit, -self.rbl[0] - (self.col_end_offset.y/self.cell.height)) + self.strap_offset.scale(-len(self.left_rbl) + bit, 0) + self.unused_offset @@ -400,7 +382,7 @@ class replica_bitcell_array(bitcell_base_array): self.replica_col_insts[bit].place(offset) # Grow to the right of the bitcell array, array outward for bit, port in enumerate(self.right_rbl): - if not end_caps_enabled: + if not self.cell.end_caps: offset = self.bitcell_array_inst.lr() + self.bitcell_offset.scale(bit, -self.rbl[0] - 1) + self.strap_offset.scale(bit, -self.rbl[0] - 1) else: offset = self.bitcell_array_inst.lr() + self.bitcell_offset.scale(bit, -self.rbl[0] - (self.col_end_offset.y/self.cell.height)) + self.strap_offset.scale(bit, -self.rbl[0] - 1) @@ -422,15 +404,11 @@ class replica_bitcell_array(bitcell_base_array): def add_end_caps(self): """ Add dummy cells or end caps around the array """ - try: - end_caps_enabled = cell_properties.bitcell.end_caps - except AttributeError: - end_caps_enabled = False # FIXME: These depend on the array size itself # Far top dummy row (first row above array is NOT flipped) flip_dummy = self.rbl[1] % 2 - if not end_caps_enabled: + if not self.cell.end_caps: dummy_row_offset = self.bitcell_offset.scale(0, self.rbl[1] + flip_dummy) + self.bitcell_array_inst.ul() else: dummy_row_offset = self.bitcell_offset.scale(0, self.rbl[1] + flip_dummy) + self.bitcell_array_inst.ul() @@ -440,7 +418,7 @@ class replica_bitcell_array(bitcell_base_array): # FIXME: These depend on the array size itself # Far bottom dummy row (first row below array IS flipped) flip_dummy = (self.rbl[0] + 1) % 2 - if not end_caps_enabled: + if not self.cell.end_caps: dummy_row_offset = self.bitcell_offset.scale(0, -self.rbl[0] - 1 + flip_dummy) + self.unused_offset else: dummy_row_offset = self.bitcell_offset.scale(0, -self.rbl[0] - (self.col_end_offset.y/self.cell.height) + flip_dummy) + self.unused_offset @@ -448,7 +426,7 @@ class replica_bitcell_array(bitcell_base_array): mirror="MX" if flip_dummy else "R0") # Far left dummy col # Shifted down by the number of left RBLs even if we aren't adding replica column to this bitcell array - if not end_caps_enabled: + if not self.cell.end_caps: dummy_col_offset = self.bitcell_offset.scale(-len(self.left_rbl) - 1, -self.rbl[0] - 1) + self.unused_offset else: dummy_col_offset = self.bitcell_offset.scale(-(len(self.left_rbl)*(1+self.strap_offset.x/self.cell.width)) - (self.row_end_offset.x/self.cell.width), -len(self.left_rbl) - (self.col_end_offset.y/self.cell.height)) @@ -456,7 +434,7 @@ class replica_bitcell_array(bitcell_base_array): self.dummy_col_insts[0].place(offset=dummy_col_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 - if not end_caps_enabled: + if not self.cell.end_caps: dummy_col_offset = self.bitcell_offset.scale(len(self.right_rbl), -self.rbl[0] - 1) + self.bitcell_array_inst.lr() else: dummy_col_offset = self.bitcell_offset.scale(len(self.right_rbl)*(1+self.strap_offset.x/self.cell.width), -self.rbl[0] - (self.col_end_offset.y/self.cell.height)) + self.bitcell_array_inst.lr() diff --git a/compiler/modules/replica_column.py b/compiler/modules/replica_column.py index ad6e63dc..f7e0c0fb 100644 --- a/compiler/modules/replica_column.py +++ b/compiler/modules/replica_column.py @@ -5,7 +5,6 @@ # import debug from bitcell_base_array import bitcell_base_array -from tech import cell_properties from sram_factory import factory from vector import vector from globals import OPTS @@ -30,8 +29,13 @@ class replica_column(bitcell_base_array): self.replica_bit = replica_bit # left, right, regular rows plus top/bottom dummy cells self.total_size = self.left_rbl + rows + self.right_rbl + + # Used for pin names and properties + self.cell = factory.create(module_type=OPTS.bitcell) + + # For end caps try: - if not cell_properties.bitcell.end_caps: + if not self.cell.end_caps: self.total_size += 2 except AttributeError: self.total_size += 2 @@ -82,20 +86,14 @@ class replica_column(bitcell_base_array): 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") + edge_module_type = ("col_cap" if self.cell.end_caps else "dummy") except AttributeError: edge_module_type = "dummy" self.edge_cell = factory.create(module_type=edge_module_type + "_" + OPTS.bitcell) self.add_mod(self.edge_cell) - # Used for pin names only - self.cell = factory.create(module_type=OPTS.bitcell) def create_instances(self): self.cell_inst = {} - try: - end_caps_enabled = cell_properties.bitcell.end_caps - except AttributeError: - end_caps_enabled = False for row in range(self.total_size): name="rbc_{0}".format(row) @@ -113,7 +111,7 @@ class replica_column(bitcell_base_array): elif (row == 0 or row == self.total_size - 1): self.cell_inst[row]=self.add_inst(name=name, mod=self.edge_cell) - if end_caps_enabled: + if self.cell.end_caps: self.connect_inst(self.get_bitcell_pins_col_cap(row, 0)) else: self.connect_inst(self.get_bitcell_pins(row, 0)) @@ -131,13 +129,13 @@ class replica_column(bitcell_base_array): # column that needs to be flipped. dir_y = False xoffset = 0 - if cell_properties.bitcell.mirror.y and self.column_offset % 2: + if self.cell.mirror.y and self.column_offset % 2: dir_y = True xoffset = self.replica_cell.width for row in range(self.total_size): # name = "bit_r{0}_{1}".format(row, "rbl") - dir_x = cell_properties.bitcell.mirror.x and (row + rbl_offset) % 2 + dir_x = self.cell.mirror.x and (row + rbl_offset) % 2 offset = vector(xoffset, self.cell.height * (row + (row + rbl_offset) % 2)) @@ -169,12 +167,7 @@ class replica_column(bitcell_base_array): width=bl_pin.width(), height=self.height) - try: - end_caps_enabled = cell_properties.bitcell.end_caps - except AttributeError: - end_caps_enabled = False - - if end_caps_enabled: + if self.cell.end_caps: row_range_max = self.total_size - 1 row_range_min = 1 else: diff --git a/compiler/modules/row_cap_array.py b/compiler/modules/row_cap_array.py index 1995b45c..97776eee 100644 --- a/compiler/modules/row_cap_array.py +++ b/compiler/modules/row_cap_array.py @@ -6,7 +6,6 @@ from bitcell_base_array import bitcell_base_array from sram_factory import factory from globals import OPTS -from tech import cell_properties class row_cap_array(bitcell_base_array): @@ -61,9 +60,8 @@ class row_cap_array(bitcell_base_array): indexed by column and row, for instance use in bitcell_array """ - pin_name = cell_properties.bitcell.cell_1rw1r.pin - bitcell_pins = ["{0}_{1}".format(pin_name.wl0, row), - "{0}_{1}".format(pin_name.wl1, row), + bitcell_pins = ["wl0_{0}".format(row), + "wl1_{0}".format(row), "gnd"] return bitcell_pins diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index ce4e6911..d3ab94a5 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -10,7 +10,6 @@ from vector import vector from sram_factory import factory import debug from globals import OPTS -from tech import cell_properties class sense_amp_array(design.design): @@ -92,7 +91,6 @@ class sense_amp_array(design.design): def add_modules(self): self.amp = factory.create(module_type="sense_amp") - self.add_mod(self.amp) # This is just used for measurements, @@ -122,7 +120,7 @@ class sense_amp_array(design.design): self.offsets.append(i * self.bitcell.width) for i, xoffset in enumerate(self.offsets[0:self.num_cols:self.words_per_row]): - if cell_properties.bitcell.mirror.y and (i * self.words_per_row + self.column_offset) % 2: + if self.bitcell.mirror.y and (i * self.words_per_row + self.column_offset) % 2: mirror = "MY" xoffset = xoffset + self.amp_spacing else: @@ -134,7 +132,7 @@ class sense_amp_array(design.design): # place spare sense amps (will share the same enable as regular sense amps) for i, xoffset in enumerate(self.offsets[self.num_cols:]): index = self.word_size + i - if cell_properties.bitcell.mirror.y and (index + self.column_offset) % 2: + if self.bitcell.mirror.y and (index + self.column_offset) % 2: mirror = "MY" xoffset = xoffset + self.amp_width else: diff --git a/compiler/modules/write_driver_array.py b/compiler/modules/write_driver_array.py index aa0a4e29..afd21de5 100644 --- a/compiler/modules/write_driver_array.py +++ b/compiler/modules/write_driver_array.py @@ -12,7 +12,6 @@ from tech import drc from sram_factory import factory from vector import vector from globals import OPTS -from tech import cell_properties class write_driver_array(design.design): @@ -161,7 +160,7 @@ class write_driver_array(design.design): self.offsets.append(i * self.driver_spacing) for i, xoffset in enumerate(self.offsets[0:self.columns:self.words_per_row]): - if cell_properties.bitcell.mirror.y and (i * self.words_per_row + self.column_offset) % 2: + if self.bitcell.mirror.y and (i * self.words_per_row + self.column_offset) % 2: mirror = "MY" xoffset = xoffset + self.driver.width else: @@ -174,7 +173,7 @@ class write_driver_array(design.design): for i, xoffset in enumerate(self.offsets[self.columns:]): index = self.word_size + i - if cell_properties.bitcell.mirror.y and (index + self.column_offset) % 2: + if self.bitcell.mirror.y and (index + self.column_offset) % 2: mirror = "MY" xoffset = xoffset + self.driver.width else: diff --git a/compiler/options.py b/compiler/options.py index 25111c02..d21e0062 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -144,7 +144,6 @@ class options(optparse.Values): # These are the default modules that can be over-riden - bitcell_suffix = "" bank_select = "bank_select" bitcell_array = "bitcell_array" bitcell = "bitcell" diff --git a/compiler/tests/01_library_drc_test.py b/compiler/tests/01_library_drc_test.py deleted file mode 100755 index 53d50386..00000000 --- a/compiler/tests/01_library_drc_test.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python3 -# 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 unittest -from testutils import * -import sys, os,re -#sys.path.append(os.getenv("OPENRAM_HOME")) -import globals -from globals import OPTS -import debug - -class library_drc_test(openram_test): - - def runTest(self): - config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) - globals.init_openram(config_file) - import verify - - (gds_dir, allnames) = setup_files() - drc_errors = 0 - debug.info(1, "\nPerforming DRC on: " + ", ".join(allnames)) - for f in allnames: - gds_name = "{0}/{1}.gds".format(gds_dir, f) - if not os.path.isfile(gds_name): - drc_errors += 1 - debug.error("Missing GDS file: {}".format(gds_name)) - drc_errors += verify.run_drc(f, gds_name) - - # fails if there are any DRC errors on any cells - self.assertEqual(drc_errors, 0) - globals.end_openram() - - -def setup_files(): - gds_dir = OPTS.openram_tech + "/gds_lib" - files = os.listdir(gds_dir) - nametest = re.compile("\.gds$", re.IGNORECASE) - gds_files = list(filter(nametest.search, files)) - - tempnames = gds_files - - # remove the .gds and .sp suffixes - for i in range(len(tempnames)): - gds_files[i] = re.sub('\.gds$', '', tempnames[i]) - - try: - from tech import blackbox_cells - nameset = list(set(tempnames) - set(blackbox_cells)) - except ImportError: - # remove duplicate base names - nameset = set(tempnames) - - allnames = list(nameset) - - return (gds_dir, allnames) - - -# run the test from the command line -if __name__ == "__main__": - (OPTS, args) = globals.parse_args() - del sys.argv[1:] - header(__file__, OPTS.tech_name) - unittest.main(testRunner=debugTestRunner()) - diff --git a/compiler/tests/02_library_lvs_test.py b/compiler/tests/01_library_test.py similarity index 95% rename from compiler/tests/02_library_lvs_test.py rename to compiler/tests/01_library_test.py index 353c1f88..dbd25f7c 100755 --- a/compiler/tests/02_library_lvs_test.py +++ b/compiler/tests/01_library_test.py @@ -36,13 +36,14 @@ class library_lvs_test(openram_test): if not os.path.isfile(sp_name): lvs_errors += 1 debug.error("Missing SPICE file {}".format(sp_name)) - drc_errors += verify.run_drc(name, gds_name) + drc_errors += verify.run_drc(name, gds_name, sp_name) lvs_errors += verify.run_lvs(f, gds_name, sp_name) # fail if the error count is not zero - self.assertEqual(drc_errors+lvs_errors, 0) + self.assertEqual(drc_errors + lvs_errors, 0) globals.end_openram() + def setup_files(): gds_dir = OPTS.openram_tech + "/gds_lib" sp_dir = OPTS.openram_tech + "/lvs_lib" diff --git a/compiler/tests/30_openram_back_end_test.py b/compiler/tests/30_openram_back_end_test.py index 5df0b55a..342d44b6 100755 --- a/compiler/tests/30_openram_back_end_test.py +++ b/compiler/tests/30_openram_back_end_test.py @@ -8,14 +8,14 @@ # import unittest from testutils import * -import sys, os,re,shutil +import sys, os, re, shutil sys.path.append(os.getenv("OPENRAM_HOME")) import globals from globals import OPTS -from sram_factory import factory import debug import getpass + class openram_back_end_test(openram_test): def runTest(self): @@ -25,12 +25,12 @@ class openram_back_end_test(openram_test): debug.info(1, "Testing top-level back-end openram.py with 2-bit, 16 word SRAM.") out_file = "testsram" - out_path = "/tmp/testsram_{0}_{1}_{2}/".format(OPTS.tech_name,getpass.getuser(),os.getpid()) + out_path = "/tmp/testsram_{0}_{1}_{2}/".format(OPTS.tech_name, getpass.getuser(), os.getpid()) # make sure we start without the files existing if os.path.exists(out_path): shutil.rmtree(out_path, ignore_errors=True) - self.assertEqual(os.path.exists(out_path),False) + self.assertEqual(os.path.exists(out_path), False) try: os.makedirs(out_path, 0o0750) diff --git a/compiler/tests/30_openram_front_end_test.py b/compiler/tests/30_openram_front_end_test.py index befbe850..71d3a98e 100755 --- a/compiler/tests/30_openram_front_end_test.py +++ b/compiler/tests/30_openram_front_end_test.py @@ -8,14 +8,14 @@ # import unittest from testutils import * -import sys, os,re,shutil +import sys, os, re, shutil sys.path.append(os.getenv("OPENRAM_HOME")) import globals from globals import OPTS -from sram_factory import factory import debug import getpass + class openram_front_end_test(openram_test): def runTest(self): @@ -25,12 +25,12 @@ class openram_front_end_test(openram_test): debug.info(1, "Testing top-level front-end openram.py with 2-bit, 16 word SRAM.") out_file = "testsram" - out_path = "/tmp/testsram_{0}_{1}_{2}".format(OPTS.tech_name,getpass.getuser(),os.getpid()) + out_path = "/tmp/testsram_{0}_{1}_{2}".format(OPTS.tech_name, getpass.getuser(), os.getpid()) # make sure we start without the files existing if os.path.exists(out_path): shutil.rmtree(out_path, ignore_errors=True) - self.assertEqual(os.path.exists(out_path),False) + self.assertEqual(os.path.exists(out_path), False) try: os.makedirs(out_path, 0o0750) diff --git a/compiler/tests/50_riscv_phys_test.py b/compiler/tests/50_riscv_phys_test.py index 5f3d7d59..9b202b9e 100755 --- a/compiler/tests/50_riscv_phys_test.py +++ b/compiler/tests/50_riscv_phys_test.py @@ -16,7 +16,7 @@ from sram_factory import factory import debug -#@unittest.skip("SKIPPING 50_riscv_phys_test") +@unittest.skip("SKIPPING 50_riscv_phys_test") class riscv_phys_test(openram_test): def runTest(self): diff --git a/compiler/tests/testutils.py b/compiler/tests/testutils.py index e63b457d..d60dde40 100644 --- a/compiler/tests/testutils.py +++ b/compiler/tests/testutils.py @@ -25,7 +25,7 @@ class openram_test(unittest.TestCase): w.gds_write(tempgds) import verify - result=verify.run_drc(w.name, tempgds) + result=verify.run_drc(w.name, tempgds, None) if result != 0: self.fail("DRC failed: {}".format(w.name)) @@ -48,7 +48,7 @@ class openram_test(unittest.TestCase): # Run both DRC and LVS even if DRC might fail # Magic can still extract despite DRC failing, so it might be ok in some techs # if we ignore things like minimum metal area of pins - drc_result=verify.run_drc(a.name, tempgds, extract=True, final_verification=final_verification) + drc_result=verify.run_drc(a.name, tempgds, tempspice, extract=True, final_verification=final_verification) # We can still run LVS even if DRC fails in Magic OR Calibre lvs_result=verify.run_lvs(a.name, tempgds, tempspice, final_verification=final_verification) diff --git a/compiler/verify/calibre.py b/compiler/verify/calibre.py index d45cfe09..5e49e6e1 100644 --- a/compiler/verify/calibre.py +++ b/compiler/verify/calibre.py @@ -30,9 +30,13 @@ num_lvs_runs = 0 num_pex_runs = 0 -def write_drc_script(cell_name, gds_name, extract, final_verification, output_path): +def write_drc_script(cell_name, gds_name, extract, final_verification=False, output_path=None): """ Write a Calibre runset file and script to run DRC """ # the runset file contains all the options to run calibre + + if not output_path: + output_path = OPTS.openram_temp + from tech import drc drc_rules = drc["drc_rules"] @@ -68,9 +72,12 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa return drc_runset -def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_path): +def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, output_path=None): """ Write a Calibre runset file and script to run LVS """ + if not output_path: + output_path = OPTS.openram_temp + from tech import drc lvs_rules = drc["lvs_rules"] lvs_runset = { @@ -132,8 +139,12 @@ def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_pa return lvs_runset -def write_pex_script(cell_name, extract, output, final_verification, output_path): +def write_pex_script(cell_name, extract, output, final_verification=False, output_path=None): """ Write a pex script that can either just extract the netlist or the netlist+parasitics """ + + if not output_path: + output_path = OPTS.openram_temp + if output == None: output = cell_name + ".pex.sp" @@ -142,7 +153,7 @@ def write_pex_script(cell_name, extract, output, final_verification, output_path if not os.path.isfile(output_path + cell_name + ".lvs.report"): gds_name = output_path +"/"+ cell_name + ".gds" sp_name = output_path +"/"+ cell_name + ".sp" - run_drc(cell_name, gds_name) + run_drc(cell_name, gds_name, sp_name) run_lvs(cell_name, gds_name, sp_name) from tech import drc @@ -181,7 +192,7 @@ def write_pex_script(cell_name, extract, output, final_verification, output_path return pex_runset -def run_drc(cell_name, gds_name, extract=False, final_verification=False): +def run_drc(cell_name, gds_name, sp_name, extract=False, final_verification=False): """Run DRC check on a given top-level name which is implemented in gds_name.""" diff --git a/compiler/verify/magic.py b/compiler/verify/magic.py index c2f13cc4..a8345a96 100644 --- a/compiler/verify/magic.py +++ b/compiler/verify/magic.py @@ -66,7 +66,7 @@ num_pex_runs = 0 # (outfile, errfile, resultsfile) = run_script(cell_name, "filter") -def write_drc_script(cell_name, gds_name, extract, final_verification, output_path): +def write_drc_script(cell_name, gds_name, extract, final_verification, output_path, sp_name=None): """ Write a magic script to perform DRC and optionally extraction. """ global OPTS @@ -102,35 +102,38 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa f.write("drc catchup\n") f.write("drc count total\n") f.write("drc count\n") - f.write("port makeall\n") + if not sp_name: + f.write("port makeall\n") + else: + f.write("readspice {}\n".format(sp_name)) if not extract: pre = "#" else: pre = "" if final_verification and OPTS.route_supplies: - f.write(pre + "extract unique all\n".format(cell_name)) + f.write(pre + "extract unique all\n") # Hack to work around unit scales in SkyWater if OPTS.tech_name=="sky130": f.write(pre + "extract style ngspice(si)\n") - f.write(pre + "extract\n".format(cell_name)) + f.write(pre + "extract\n") # f.write(pre + "ext2spice hierarchy on\n") # f.write(pre + "ext2spice scale off\n") # lvs exists in 8.2.79, but be backword compatible for now - #f.write(pre+"ext2spice lvs\n") - f.write(pre+"ext2spice hierarchy on\n") - f.write(pre+"ext2spice format ngspice\n") - f.write(pre+"ext2spice cthresh infinite\n") - f.write(pre+"ext2spice rthresh infinite\n") - f.write(pre+"ext2spice renumber off\n") - f.write(pre+"ext2spice scale off\n") - f.write(pre+"ext2spice blackbox on\n") - f.write(pre+"ext2spice subcircuit top on\n") - f.write(pre+"ext2spice global off\n") + # f.write(pre + "ext2spice lvs\n") + f.write(pre + "ext2spice hierarchy on\n") + f.write(pre + "ext2spice format ngspice\n") + f.write(pre + "ext2spice cthresh infinite\n") + f.write(pre + "ext2spice rthresh infinite\n") + f.write(pre + "ext2spice renumber off\n") + f.write(pre + "ext2spice scale off\n") + f.write(pre + "ext2spice blackbox on\n") + f.write(pre + "ext2spice subcircuit top on\n") + f.write(pre + "ext2spice global off\n") # Can choose hspice, ngspice, or spice3, # but they all seem compatible enough. - f.write(pre+"ext2spice format ngspice\n") - f.write(pre+"ext2spice {}\n".format(cell_name)) + f.write(pre + "ext2spice format ngspice\n") + f.write(pre + "ext2spice {}\n".format(cell_name)) f.write("quit -noprompt\n") f.write("EOF\n") @@ -138,7 +141,7 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa os.system("chmod u+x {}".format(run_file)) -def run_drc(cell_name, gds_name, extract=True, final_verification=False): +def run_drc(cell_name, gds_name, sp_name=None, extract=True, final_verification=False): """Run DRC check on a cell which is implemented in gds_name.""" global num_drc_runs @@ -148,7 +151,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False): if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): shutil.copy(gds_name, OPTS.openram_temp) - write_drc_script(cell_name, gds_name, extract, final_verification, OPTS.openram_temp) + write_drc_script(cell_name, gds_name, extract, final_verification, OPTS.openram_temp, sp_name=sp_name) (outfile, errfile, resultsfile) = run_script(cell_name, "drc") @@ -161,7 +164,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False): try: f = open(outfile, "r") except FileNotFoundError: - debug.error("Unable to load DRC results file from {}. Is magic set up?".format(outfile),1) + debug.error("Unable to load DRC results file from {}. Is magic set up?".format(outfile), 1) results = f.readlines() f.close() @@ -172,7 +175,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False): errors = int(re.split(": ", line)[1]) break else: - debug.error("Unable to find the total error line in Magic output.",1) + debug.error("Unable to find the total error line in Magic output.", 1) # always display this summary @@ -180,7 +183,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False): if errors > 0: for line in results: if "error tiles" in line: - debug.info(1,line.rstrip("\n")) + debug.info(1, line.rstrip("\n")) debug.warning(result_str) else: debug.info(1, result_str) @@ -188,11 +191,14 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False): return errors -def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_path): +def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, output_path=None): """ Write a netgen script to perform LVS. """ global OPTS + if not output_path: + output_path = OPTS.openram_temp + setup_file = "setup.tcl" full_setup_file = OPTS.openram_tech + "tech/" + setup_file if os.path.exists(full_setup_file): @@ -207,14 +213,14 @@ def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_pa f.write("{} -noconsole << EOF\n".format(OPTS.lvs_exe[1])) # f.write("readnet spice {0}.spice\n".format(cell_name)) # f.write("readnet spice {0}\n".format(sp_name)) - f.write("lvs {{{0}.spice {0}}} {{{1} {0}}} {2} {0}.lvs.report -json\n".format(cell_name, sp_name, setup_file)) + f.write("lvs {{{0}.spice {0}}} {{{1} {0}}} {2} {0}.lvs.report -full -json\n".format(cell_name, sp_name, setup_file)) f.write("quit\n") f.write("EOF\n") f.close() os.system("chmod u+x {}".format(run_file)) -def run_lvs(cell_name, gds_name, sp_name, final_verification=False): +def run_lvs(cell_name, gds_name, sp_name, final_verification=False, output_path=None): """Run LVS check on a given top-level name which is implemented in gds_name and sp_name. Final verification will ensure that there are no remaining virtual conections. """ @@ -222,13 +228,16 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False): global num_lvs_runs num_lvs_runs += 1 + if not output_path: + output_path = OPTS.openram_temp + # Copy file to local dir if it isn't already - if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): - shutil.copy(gds_name, OPTS.openram_temp) - if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'): - shutil.copy(sp_name, OPTS.openram_temp) + if os.path.dirname(gds_name) != output_path.rstrip('/'): + shutil.copy(gds_name, output_path) + if os.path.dirname(sp_name) != output_path.rstrip('/'): + shutil.copy(sp_name, output_path) - write_lvs_script(cell_name, gds_name, sp_name, final_verification, OPTS.openram_temp) + write_lvs_script(cell_name, gds_name, sp_name, final_verification) (outfile, errfile, resultsfile) = run_script(cell_name, "lvs") @@ -289,13 +298,20 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False): return total_errors -def run_pex(name, gds_name, sp_name, output=None, final_verification=False): +def run_pex(name, gds_name, sp_name, output=None, final_verification=False, output_path=None): """Run pex on a given top-level name which is implemented in gds_name and sp_name. """ global num_pex_runs num_pex_runs += 1 - os.chdir(OPTS.openram_temp) + + if not output_path: + output_path = OPTS.openram_temp + + os.chdir(output_path) + + if not output_path: + output_path = OPTS.openram_temp if output == None: output = name + ".pex.netlist" @@ -309,10 +325,10 @@ def run_pex(name, gds_name, sp_name, output=None, final_verification=False): # pex_fix did run the pex using a script while dev orignial method # use batch mode. # the dev old code using batch mode does not run and is split into functions - pex_runset = write_script_pex_rule(gds_name, name, output) + pex_runset = write_script_pex_rule(gds_name, name, sp_name, output) - errfile = "{0}{1}.pex.err".format(OPTS.openram_temp, name) - outfile = "{0}{1}.pex.out".format(OPTS.openram_temp, name) + errfile = "{0}{1}.pex.err".format(output_path, name) + outfile = "{0}{1}.pex.out".format(output_path, name) script_cmd = "{0} 2> {1} 1> {2}".format(pex_runset, errfile, @@ -387,7 +403,7 @@ def write_batch_pex_rule(gds_name, name, sp_name, output): return file -def write_script_pex_rule(gds_name, cell_name, output): +def write_script_pex_rule(gds_name, cell_name, sp_name, output): global OPTS run_file = OPTS.openram_temp + "run_pex.sh" f = open(run_file, "w") @@ -399,26 +415,24 @@ def write_script_pex_rule(gds_name, cell_name, output): f.write("load {}\n".format(cell_name)) f.write("select top cell\n") f.write("expand\n") - f.write("port makeall\n") - extract = True - if not extract: - pre = "#" + if not sp_name: + f.write("port makeall\n") else: - pre = "" - f.write(pre + "extract\n") - f.write(pre + "ext2sim labels on\n") - f.write(pre + "ext2sim\n") - f.write(pre + "extresist simplify off\n") - f.write(pre + "extresist all\n") - f.write(pre + "ext2spice hierarchy off\n") - f.write(pre + "ext2spice format ngspice\n") - f.write(pre + "ext2spice renumber off\n") - f.write(pre + "ext2spice scale off\n") - f.write(pre + "ext2spice blackbox on\n") - f.write(pre + "ext2spice subcircuit top on\n") - f.write(pre + "ext2spice global off\n") - f.write(pre + "ext2spice extresist on\n") - f.write(pre + "ext2spice {}\n".format(cell_name)) + f.write("readspice {}\n".format(sp_name)) + f.write("extract\n") + f.write("ext2sim labels on\n") + f.write("ext2sim\n") + f.write("extresist simplify off\n") + f.write("extresist all\n") + f.write("ext2spice hierarchy off\n") + f.write("ext2spice format ngspice\n") + f.write("ext2spice renumber off\n") + f.write("ext2spice scale off\n") + f.write("ext2spice blackbox on\n") + f.write("ext2spice subcircuit top on\n") + f.write("ext2spice global off\n") + f.write("ext2spice extresist on\n") + f.write("ext2spice {}\n".format(cell_name)) f.write("quit -noprompt\n") f.write("eof\n") f.write("mv {0}.spice {1}\n".format(cell_name, output)) diff --git a/compiler/verify/none.py b/compiler/verify/none.py index 28a5a47b..bd2fb722 100644 --- a/compiler/verify/none.py +++ b/compiler/verify/none.py @@ -17,11 +17,11 @@ lvs_warned = False pex_warned = False -def write_drc_script(cell_name, gds_name, extract, final_verification, output_path): +def write_drc_script(cell_name, gds_name, extract, final_verification=False, output_path=None): pass -def run_drc(cell_name, gds_name, extract=False, final_verification=False): +def run_drc(cell_name, gds_name, sp_name, extract=False, final_verification=False, output_path=None): global drc_warned if not drc_warned: debug.error("DRC unable to run.", -1) @@ -30,11 +30,11 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False): return 1 -def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_path): +def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, output_path=None): pass -def run_lvs(cell_name, gds_name, sp_name, final_verification=False): +def run_lvs(cell_name, gds_name, sp_name, final_verification=False, output_path=None): global lvs_warned if not lvs_warned: debug.error("LVS unable to run.", -1) @@ -43,7 +43,7 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False): return 1 -def run_pex(name, gds_name, sp_name, output=None, final_verification=False): +def run_pex(name, gds_name, sp_name, output=None, final_verification=False, output_path=None): global pex_warned if not pex_warned: debug.error("PEX unable to run.", -1) diff --git a/technology/freepdk45/gds_lib/cell_6t.gds b/technology/freepdk45/gds_lib/cell_1rw.gds similarity index 77% rename from technology/freepdk45/gds_lib/cell_6t.gds rename to technology/freepdk45/gds_lib/cell_1rw.gds index 17b62028..38e53e27 100644 Binary files a/technology/freepdk45/gds_lib/cell_6t.gds and b/technology/freepdk45/gds_lib/cell_1rw.gds differ diff --git a/technology/freepdk45/gds_lib/cell_1rw_1r.gds b/technology/freepdk45/gds_lib/cell_1rw_1r.gds deleted file mode 100644 index 5f3e7213..00000000 Binary files a/technology/freepdk45/gds_lib/cell_1rw_1r.gds and /dev/null differ diff --git a/technology/freepdk45/gds_lib/cell_1w_1r.gds b/technology/freepdk45/gds_lib/cell_2rw.gds similarity index 77% rename from technology/freepdk45/gds_lib/cell_1w_1r.gds rename to technology/freepdk45/gds_lib/cell_2rw.gds index 67498962..3ceea617 100644 Binary files a/technology/freepdk45/gds_lib/cell_1w_1r.gds and b/technology/freepdk45/gds_lib/cell_2rw.gds differ diff --git a/technology/freepdk45/gds_lib/dummy_cell_6t.gds b/technology/freepdk45/gds_lib/dummy_cell_1rw.gds similarity index 75% rename from technology/freepdk45/gds_lib/dummy_cell_6t.gds rename to technology/freepdk45/gds_lib/dummy_cell_1rw.gds index c6575122..28dd8124 100644 Binary files a/technology/freepdk45/gds_lib/dummy_cell_6t.gds and b/technology/freepdk45/gds_lib/dummy_cell_1rw.gds differ diff --git a/technology/freepdk45/gds_lib/dummy_cell_1rw_1r.gds b/technology/freepdk45/gds_lib/dummy_cell_1rw_1r.gds deleted file mode 100644 index 2ac1a287..00000000 Binary files a/technology/freepdk45/gds_lib/dummy_cell_1rw_1r.gds and /dev/null differ diff --git a/technology/freepdk45/gds_lib/dummy_cell_1w_1r.gds b/technology/freepdk45/gds_lib/dummy_cell_2rw.gds similarity index 85% rename from technology/freepdk45/gds_lib/dummy_cell_1w_1r.gds rename to technology/freepdk45/gds_lib/dummy_cell_2rw.gds index fa89439e..f5a4600f 100644 Binary files a/technology/freepdk45/gds_lib/dummy_cell_1w_1r.gds and b/technology/freepdk45/gds_lib/dummy_cell_2rw.gds differ diff --git a/technology/freepdk45/gds_lib/replica_cell_6t.gds b/technology/freepdk45/gds_lib/replica_cell_1rw.gds similarity index 82% rename from technology/freepdk45/gds_lib/replica_cell_6t.gds rename to technology/freepdk45/gds_lib/replica_cell_1rw.gds index f2fe9197..67c9bdf7 100644 Binary files a/technology/freepdk45/gds_lib/replica_cell_6t.gds and b/technology/freepdk45/gds_lib/replica_cell_1rw.gds differ diff --git a/technology/freepdk45/gds_lib/replica_cell_1rw_1r.gds b/technology/freepdk45/gds_lib/replica_cell_1rw_1r.gds deleted file mode 100644 index cdb099ac..00000000 Binary files a/technology/freepdk45/gds_lib/replica_cell_1rw_1r.gds and /dev/null differ diff --git a/technology/freepdk45/gds_lib/replica_cell_1w_1r.gds b/technology/freepdk45/gds_lib/replica_cell_2rw.gds similarity index 77% rename from technology/freepdk45/gds_lib/replica_cell_1w_1r.gds rename to technology/freepdk45/gds_lib/replica_cell_2rw.gds index 31deb82b..1b2564a4 100644 Binary files a/technology/freepdk45/gds_lib/replica_cell_1w_1r.gds and b/technology/freepdk45/gds_lib/replica_cell_2rw.gds differ diff --git a/technology/freepdk45/sp_lib/cell_6t.sp b/technology/freepdk45/sp_lib/cell_1rw.sp similarity index 86% rename from technology/freepdk45/sp_lib/cell_6t.sp rename to technology/freepdk45/sp_lib/cell_1rw.sp index b39427d7..7fdba85a 100644 --- a/technology/freepdk45/sp_lib/cell_6t.sp +++ b/technology/freepdk45/sp_lib/cell_1rw.sp @@ -1,5 +1,5 @@ -.SUBCKT cell_6t bl br wl vdd gnd +.SUBCKT cell_1rw bl br wl vdd gnd * Inverter 1 MM0 Q_bar Q gnd gnd NMOS_VTG W=205.00n L=50n MM4 Q_bar Q vdd vdd PMOS_VTG W=90n L=50n @@ -11,5 +11,5 @@ MM5 Q Q_bar vdd vdd PMOS_VTG W=90n L=50n * Access transistors MM3 bl wl Q gnd NMOS_VTG W=135.00n L=50n MM2 br wl Q_bar gnd NMOS_VTG W=135.00n L=50n -.ENDS cell_6t +.ENDS cell_1rw diff --git a/technology/freepdk45/sp_lib/cell_1rw_1r.sp b/technology/freepdk45/sp_lib/cell_1rw_1r.sp deleted file mode 100644 index f1c45604..00000000 --- a/technology/freepdk45/sp_lib/cell_1rw_1r.sp +++ /dev/null @@ -1,14 +0,0 @@ - -.SUBCKT cell_1rw_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd -MM9 RA_to_R_right wl1 br1 gnd NMOS_VTG W=180.0n L=50n m=1 -MM8 RA_to_R_right Q gnd gnd NMOS_VTG W=180.0n L=50n m=1 -MM7 RA_to_R_left Q_bar gnd gnd NMOS_VTG W=180.0n L=50n m=1 -MM6 RA_to_R_left wl1 bl1 gnd NMOS_VTG W=180.0n L=50n m=1 -MM5 Q wl0 bl0 gnd NMOS_VTG W=135.00n L=50n m=1 -MM4 Q_bar wl0 br0 gnd NMOS_VTG W=135.00n L=50n m=1 -MM1 Q Q_bar gnd gnd NMOS_VTG W=205.0n L=50n m=1 -MM0 Q_bar Q gnd gnd NMOS_VTG W=205.0n L=50n m=1 -MM3 Q Q_bar vdd vdd PMOS_VTG W=90n L=50n m=1 -MM2 Q_bar Q vdd vdd PMOS_VTG W=90n L=50n m=1 -.ENDS - diff --git a/technology/freepdk45/sp_lib/cell_1w_1r.sp b/technology/freepdk45/sp_lib/cell_2rw.sp similarity index 91% rename from technology/freepdk45/sp_lib/cell_1w_1r.sp rename to technology/freepdk45/sp_lib/cell_2rw.sp index eb3803b4..a3a6954a 100644 --- a/technology/freepdk45/sp_lib/cell_1w_1r.sp +++ b/technology/freepdk45/sp_lib/cell_2rw.sp @@ -1,5 +1,5 @@ -.SUBCKT cell_1w_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd +.SUBCKT cell_2rw bl0 br0 bl1 br1 wl0 wl1 vdd gnd MM9 RA_to_R_right wl1 br1 gnd NMOS_VTG W=180.0n L=50n m=1 MM8 RA_to_R_right Q gnd gnd NMOS_VTG W=180.0n L=50n m=1 MM7 RA_to_R_left Q_bar gnd gnd NMOS_VTG W=180.0n L=50n m=1 diff --git a/technology/freepdk45/sp_lib/dummy_cell_6t.sp b/technology/freepdk45/sp_lib/dummy_cell_1rw.sp similarity index 85% rename from technology/freepdk45/sp_lib/dummy_cell_6t.sp rename to technology/freepdk45/sp_lib/dummy_cell_1rw.sp index 6e192049..9181645a 100644 --- a/technology/freepdk45/sp_lib/dummy_cell_6t.sp +++ b/technology/freepdk45/sp_lib/dummy_cell_1rw.sp @@ -1,5 +1,5 @@ -.SUBCKT dummy_cell_6t bl br wl vdd gnd +.SUBCKT dummy_cell_1rw bl br wl vdd gnd * Inverter 1 MM0 Q_bar Q gnd gnd NMOS_VTG W=205.00n L=50n MM4 Q_bar Q vdd vdd PMOS_VTG W=90n L=50n @@ -11,5 +11,5 @@ MM5 Q Q_bar vdd vdd PMOS_VTG W=90n L=50n * Access transistors MM3 bl_noconn wl Q gnd NMOS_VTG W=135.00n L=50n MM2 br_noconn wl Q_bar gnd NMOS_VTG W=135.00n L=50n -.ENDS cell_6t +.ENDS cell_1rw diff --git a/technology/freepdk45/sp_lib/dummy_cell_1rw_1r.sp b/technology/freepdk45/sp_lib/dummy_cell_1rw_1r.sp deleted file mode 100644 index c3c082ee..00000000 --- a/technology/freepdk45/sp_lib/dummy_cell_1rw_1r.sp +++ /dev/null @@ -1,14 +0,0 @@ - -.SUBCKT dummy_cell_1rw_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd -MM9 RA_to_R_right wl1 br1_noconn gnd NMOS_VTG W=180.0n L=50n m=1 -MM8 RA_to_R_right Q gnd gnd NMOS_VTG W=180.0n L=50n m=1 -MM7 RA_to_R_left Q_bar gnd gnd NMOS_VTG W=180.0n L=50n m=1 -MM6 RA_to_R_left wl1 bl1_noconn gnd NMOS_VTG W=180.0n L=50n m=1 -MM5 Q wl0 bl0_noconn gnd NMOS_VTG W=135.00n L=50n m=1 -MM4 Q_bar wl0 br0_noconn gnd NMOS_VTG W=135.00n L=50n m=1 -MM1 Q Q_bar gnd gnd NMOS_VTG W=205.0n L=50n m=1 -MM0 Q_bar Q gnd gnd NMOS_VTG W=205.0n L=50n m=1 -MM3 Q Q_bar vdd vdd PMOS_VTG W=90n L=50n m=1 -MM2 Q_bar Q vdd vdd PMOS_VTG W=90n L=50n m=1 -.ENDS - diff --git a/technology/freepdk45/sp_lib/dummy_cell_1w_1r.sp b/technology/freepdk45/sp_lib/dummy_cell_2rw.sp similarity index 90% rename from technology/freepdk45/sp_lib/dummy_cell_1w_1r.sp rename to technology/freepdk45/sp_lib/dummy_cell_2rw.sp index 72d7553f..426ee3ef 100644 --- a/technology/freepdk45/sp_lib/dummy_cell_1w_1r.sp +++ b/technology/freepdk45/sp_lib/dummy_cell_2rw.sp @@ -1,5 +1,5 @@ -.SUBCKT dummy_cell_1w_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd +.SUBCKT dummy_cell_2rw bl0 br0 bl1 br1 wl0 wl1 vdd gnd MM9 RA_to_R_right wl1 br1_noconn gnd NMOS_VTG W=180.0n L=50n m=1 MM8 RA_to_R_right Q gnd gnd NMOS_VTG W=180.0n L=50n m=1 MM7 RA_to_R_left Q_bar gnd gnd NMOS_VTG W=180.0n L=50n m=1 diff --git a/technology/freepdk45/sp_lib/replica_cell_6t.sp b/technology/freepdk45/sp_lib/replica_cell_1rw.sp similarity index 84% rename from technology/freepdk45/sp_lib/replica_cell_6t.sp rename to technology/freepdk45/sp_lib/replica_cell_1rw.sp index dd29028a..284b1c0a 100644 --- a/technology/freepdk45/sp_lib/replica_cell_6t.sp +++ b/technology/freepdk45/sp_lib/replica_cell_1rw.sp @@ -1,5 +1,5 @@ -.SUBCKT replica_cell_6t bl br wl vdd gnd +.SUBCKT replica_cell_1rw bl br wl vdd gnd * Inverter 1 MM0 vdd Q gnd gnd NMOS_VTG W=205.00n L=50n MM4 vdd Q vdd vdd PMOS_VTG W=90n L=50n @@ -11,5 +11,5 @@ MM5 Q vdd vdd vdd PMOS_VTG W=90n L=50n * Access transistors MM3 bl wl Q gnd NMOS_VTG W=135.00n L=50n MM2 br wl vdd gnd NMOS_VTG W=135.00n L=50n -.ENDS cell_6t +.ENDS cell_1rw diff --git a/technology/freepdk45/sp_lib/replica_cell_1rw_1r.sp b/technology/freepdk45/sp_lib/replica_cell_1rw_1r.sp deleted file mode 100644 index d108b7bf..00000000 --- a/technology/freepdk45/sp_lib/replica_cell_1rw_1r.sp +++ /dev/null @@ -1,14 +0,0 @@ - -.SUBCKT replica_cell_1rw_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd -MM9 RA_to_R_right wl1 br1 gnd NMOS_VTG W=180.0n L=50n m=1 -MM8 RA_to_R_right Q gnd gnd NMOS_VTG W=180.0n L=50n m=1 -MM7 RA_to_R_left vdd gnd gnd NMOS_VTG W=180.0n L=50n m=1 -MM6 RA_to_R_left wl1 bl1 gnd NMOS_VTG W=180.0n L=50n m=1 -MM5 Q wl0 bl0 gnd NMOS_VTG W=135.00n L=50n m=1 -MM4 vdd wl0 br0 gnd NMOS_VTG W=135.00n L=50n m=1 -MM1 Q vdd gnd gnd NMOS_VTG W=205.0n L=50n m=1 -MM0 vdd Q gnd gnd NMOS_VTG W=205.0n L=50n m=1 -MM3 Q vdd vdd vdd PMOS_VTG W=90n L=50n m=1 -MM2 vdd Q vdd vdd PMOS_VTG W=90n L=50n m=1 -.ENDS - diff --git a/technology/freepdk45/sp_lib/replica_cell_1w_1r.sp b/technology/freepdk45/sp_lib/replica_cell_2rw.sp similarity index 89% rename from technology/freepdk45/sp_lib/replica_cell_1w_1r.sp rename to technology/freepdk45/sp_lib/replica_cell_2rw.sp index fd06db8c..97f18252 100644 --- a/technology/freepdk45/sp_lib/replica_cell_1w_1r.sp +++ b/technology/freepdk45/sp_lib/replica_cell_2rw.sp @@ -1,5 +1,5 @@ -.SUBCKT replica_cell_1w_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd +.SUBCKT replica_cell_2rw bl0 br0 bl1 br1 wl0 wl1 vdd gnd MM9 RA_to_R_right wl1 br1 gnd NMOS_VTG W=180.0n L=50n m=1 MM8 RA_to_R_right Q gnd gnd NMOS_VTG W=180.0n L=50n m=1 MM7 RA_to_R_left vdd gnd gnd NMOS_VTG W=180.0n L=50n m=1 diff --git a/technology/freepdk45/tech/tech.py b/technology/freepdk45/tech/tech.py index 1616e9f9..436d2ff4 100644 --- a/technology/freepdk45/tech/tech.py +++ b/technology/freepdk45/tech/tech.py @@ -31,8 +31,6 @@ tech_modules = module_type() # Custom cell properties ################################################### cell_properties = cell_properties() -cell_properties.bitcell.mirror.x = True -cell_properties.bitcell.mirror.y = False cell_properties.bitcell_power_pin_directions = ("V", "V") ################################################### @@ -438,22 +436,23 @@ spice["bitcell_leakage"] = 1 # Leakage power of a single bitcell in nW spice["inv_leakage"] = 1 # Leakage power of inverter in nW spice["nand2_leakage"] = 1 # Leakage power of 2-input nand in nW spice["nand3_leakage"] = 1 # Leakage power of 3-input nand in nW +spice["nand4_leakage"] = 1 # Leakage power of 4-input nand in nW spice["nor2_leakage"] = 1 # Leakage power of 2-input nor in nW spice["dff_leakage"] = 1 # Leakage power of flop in nW spice["default_event_frequency"] = 100 # Default event activity of every gate. MHz -#Parameters related to sense amp enable timing and delay chain/RBL sizing -parameter["le_tau"] = 2.25 #In pico-seconds. -parameter["cap_relative_per_ff"] = 7.5 #Units of Relative Capacitance/ Femto-Farad -parameter["dff_clk_cin"] = 30.6 #relative capacitance -parameter["6tcell_wl_cin"] = 3 #relative capacitance -parameter["min_inv_para_delay"] = 2.4 #Tau delay units -parameter["sa_en_pmos_size"] = 0.72 #micro-meters -parameter["sa_en_nmos_size"] = 0.27 #micro-meters -parameter["sa_inv_pmos_size"] = 0.54 #micro-meters -parameter["sa_inv_nmos_size"] = 0.27 #micro-meters -parameter["bitcell_drain_cap"] = 0.1 #In Femto-Farad, approximation of drain capacitance +# Parameters related to sense amp enable timing and delay chain/RBL sizing +parameter["le_tau"] = 2.25 # In pico-seconds. +parameter["cap_relative_per_ff"] = 7.5 # Units of Relative Capacitance/ Femto-Farad +parameter["dff_clk_cin"] = 30.6 # relative capacitance +parameter["6tcell_wl_cin"] = 3 # relative capacitance +parameter["min_inv_para_delay"] = 2.4 # Tau delay units +parameter["sa_en_pmos_size"] = 0.72 # micro-meters +parameter["sa_en_nmos_size"] = 0.27 # micro-meters +parameter["sa_inv_pmos_size"] = 0.54 # micro-meters +parameter["sa_inv_nmos_size"] = 0.27 # micro-meters +parameter["bitcell_drain_cap"] = 0.1 # In Femto-Farad, approximation of drain capacitance ################################################### # Technology Tool Preferences diff --git a/technology/scn4m_subm/gds_lib/cell_1rw.gds b/technology/scn4m_subm/gds_lib/cell_1rw.gds new file mode 100644 index 00000000..92523dc1 Binary files /dev/null and b/technology/scn4m_subm/gds_lib/cell_1rw.gds differ diff --git a/technology/scn4m_subm/gds_lib/cell_1rw_1r.gds b/technology/scn4m_subm/gds_lib/cell_1rw_1r.gds deleted file mode 100644 index 71a6dfad..00000000 Binary files a/technology/scn4m_subm/gds_lib/cell_1rw_1r.gds and /dev/null differ diff --git a/technology/scn4m_subm/gds_lib/cell_1w_1r.gds b/technology/scn4m_subm/gds_lib/cell_1w_1r.gds deleted file mode 100644 index 06f79ba5..00000000 Binary files a/technology/scn4m_subm/gds_lib/cell_1w_1r.gds and /dev/null differ diff --git a/technology/scn4m_subm/gds_lib/cell_2rw.gds b/technology/scn4m_subm/gds_lib/cell_2rw.gds new file mode 100644 index 00000000..a45c34e9 Binary files /dev/null and b/technology/scn4m_subm/gds_lib/cell_2rw.gds differ diff --git a/technology/scn4m_subm/gds_lib/cell_6t.gds b/technology/scn4m_subm/gds_lib/cell_6t.gds deleted file mode 100644 index 6bfc4431..00000000 Binary files a/technology/scn4m_subm/gds_lib/cell_6t.gds and /dev/null differ diff --git a/technology/scn4m_subm/gds_lib/dummy_cell_1rw.gds b/technology/scn4m_subm/gds_lib/dummy_cell_1rw.gds new file mode 100644 index 00000000..b27e5e02 Binary files /dev/null and b/technology/scn4m_subm/gds_lib/dummy_cell_1rw.gds differ diff --git a/technology/scn4m_subm/gds_lib/dummy_cell_1rw_1r.gds b/technology/scn4m_subm/gds_lib/dummy_cell_1rw_1r.gds deleted file mode 100644 index 42727119..00000000 Binary files a/technology/scn4m_subm/gds_lib/dummy_cell_1rw_1r.gds and /dev/null differ diff --git a/technology/scn4m_subm/gds_lib/dummy_cell_1w_1r.gds b/technology/scn4m_subm/gds_lib/dummy_cell_1w_1r.gds deleted file mode 100644 index 34d692e8..00000000 Binary files a/technology/scn4m_subm/gds_lib/dummy_cell_1w_1r.gds and /dev/null differ diff --git a/technology/scn4m_subm/gds_lib/dummy_cell_2rw.gds b/technology/scn4m_subm/gds_lib/dummy_cell_2rw.gds new file mode 100644 index 00000000..4f0427fd Binary files /dev/null and b/technology/scn4m_subm/gds_lib/dummy_cell_2rw.gds differ diff --git a/technology/scn4m_subm/gds_lib/dummy_cell_6t.gds b/technology/scn4m_subm/gds_lib/dummy_cell_6t.gds deleted file mode 100644 index 4a950a68..00000000 Binary files a/technology/scn4m_subm/gds_lib/dummy_cell_6t.gds and /dev/null differ diff --git a/technology/scn4m_subm/gds_lib/replica_cell_1rw.gds b/technology/scn4m_subm/gds_lib/replica_cell_1rw.gds new file mode 100644 index 00000000..7eee1179 Binary files /dev/null and b/technology/scn4m_subm/gds_lib/replica_cell_1rw.gds differ diff --git a/technology/scn4m_subm/gds_lib/replica_cell_1rw_1r.gds b/technology/scn4m_subm/gds_lib/replica_cell_1rw_1r.gds deleted file mode 100644 index 2697651d..00000000 Binary files a/technology/scn4m_subm/gds_lib/replica_cell_1rw_1r.gds and /dev/null differ diff --git a/technology/scn4m_subm/gds_lib/replica_cell_1w_1r.gds b/technology/scn4m_subm/gds_lib/replica_cell_1w_1r.gds deleted file mode 100644 index ce6e413b..00000000 Binary files a/technology/scn4m_subm/gds_lib/replica_cell_1w_1r.gds and /dev/null differ diff --git a/technology/scn4m_subm/gds_lib/replica_cell_2rw.gds b/technology/scn4m_subm/gds_lib/replica_cell_2rw.gds new file mode 100644 index 00000000..c520422a Binary files /dev/null and b/technology/scn4m_subm/gds_lib/replica_cell_2rw.gds differ diff --git a/technology/scn4m_subm/gds_lib/replica_cell_6t.gds b/technology/scn4m_subm/gds_lib/replica_cell_6t.gds deleted file mode 100644 index 30f5a37e..00000000 Binary files a/technology/scn4m_subm/gds_lib/replica_cell_6t.gds and /dev/null differ diff --git a/technology/scn4m_subm/mag_lib/cell_6t.mag b/technology/scn4m_subm/mag_lib/cell_1rw.mag similarity index 100% rename from technology/scn4m_subm/mag_lib/cell_6t.mag rename to technology/scn4m_subm/mag_lib/cell_1rw.mag diff --git a/technology/scn4m_subm/mag_lib/cell_1w_1r.mag b/technology/scn4m_subm/mag_lib/cell_1w_1r.mag deleted file mode 100644 index 71a3b1bc..00000000 --- a/technology/scn4m_subm/mag_lib/cell_1w_1r.mag +++ /dev/null @@ -1,146 +0,0 @@ -magic -tech scmos -timestamp 1577067400 -<< nwell >> -rect 0 46 54 75 -<< pwell >> -rect 0 0 54 46 -<< ntransistor >> -rect 14 33 16 37 -rect 22 29 24 37 -rect 30 29 32 37 -rect 38 33 40 37 -rect 14 17 16 23 -rect 22 17 24 23 -rect 30 17 32 23 -rect 38 17 40 23 -<< ptransistor >> -rect 22 54 24 57 -rect 30 54 32 57 -<< ndiffusion >> -rect 13 33 14 37 -rect 16 33 17 37 -rect 21 33 22 37 -rect 17 29 22 33 -rect 24 29 25 37 -rect 29 29 30 37 -rect 32 33 33 37 -rect 37 33 38 37 -rect 40 33 41 37 -rect 32 29 37 33 -rect 9 21 14 23 -rect 13 17 14 21 -rect 16 17 22 23 -rect 24 17 25 23 -rect 29 17 30 23 -rect 32 17 38 23 -rect 40 21 45 23 -rect 40 17 41 21 -<< pdiffusion >> -rect 21 54 22 57 -rect 24 54 25 57 -rect 29 54 30 57 -rect 32 54 33 57 -<< ndcontact >> -rect 9 33 13 37 -rect 17 33 21 37 -rect 25 29 29 37 -rect 33 33 37 37 -rect 41 33 45 37 -rect 9 17 13 21 -rect 25 17 29 23 -rect 41 17 45 21 -<< pdcontact >> -rect 17 54 21 58 -rect 25 54 29 58 -rect 33 54 37 58 -<< psubstratepcontact >> -rect 25 9 29 13 -<< nsubstratencontact >> -rect 25 68 29 72 -<< polysilicon >> -rect 22 57 24 60 -rect 30 57 32 60 -rect 22 44 24 54 -rect 30 51 32 54 -rect 31 47 32 51 -rect 14 37 16 44 -rect 22 40 23 44 -rect 22 37 24 40 -rect 30 37 32 47 -rect 38 37 40 44 -rect 14 31 16 33 -rect 38 31 40 33 -rect 14 23 16 24 -rect 22 23 24 29 -rect 30 23 32 29 -rect 38 23 40 24 -rect 14 15 16 17 -rect 22 15 24 17 -rect 30 15 32 17 -rect 38 15 40 17 -<< polycontact >> -rect 27 47 31 51 -rect 10 40 14 44 -rect 23 40 27 44 -rect 40 40 44 44 -rect 12 24 16 28 -rect 38 24 42 28 -<< metal1 >> -rect 0 68 25 72 -rect 29 68 54 72 -rect 0 61 54 65 -rect 10 44 14 61 -rect 17 51 20 54 -rect 17 47 27 51 -rect 17 37 20 47 -rect 34 44 37 54 -rect 27 40 37 44 -rect 40 44 44 61 -rect 34 37 37 40 -rect 6 33 9 37 -rect 45 33 48 37 -rect 25 23 29 29 -rect 25 13 29 17 -rect 0 9 25 13 -rect 29 9 54 13 -rect 0 2 16 6 -rect 20 2 34 6 -rect 38 2 54 6 -<< m2contact >> -rect 25 68 29 72 -rect 25 54 29 58 -rect 2 33 6 37 -rect 48 33 52 37 -rect 16 24 20 28 -rect 34 24 38 28 -rect 9 17 13 21 -rect 41 17 45 21 -rect 16 2 20 6 -rect 34 2 38 6 -<< metal2 >> -rect 2 37 6 72 -rect 2 0 6 33 -rect 9 21 13 72 -rect 25 58 29 68 -rect 9 0 13 17 -rect 16 6 20 24 -rect 34 6 38 24 -rect 41 21 45 72 -rect 41 0 45 17 -rect 48 37 52 72 -rect 48 0 52 33 -<< comment >> -rect 0 0 54 70 -<< labels >> -rlabel metal1 19 63 19 63 1 wl0 -rlabel metal1 19 70 19 70 5 vdd -rlabel metal1 27 4 27 4 1 wl1 -rlabel psubstratepcontact 27 11 27 11 1 gnd -rlabel metal2 4 7 4 7 2 bl0 -rlabel metal2 11 7 11 7 1 bl1 -rlabel metal2 43 7 43 7 1 br1 -rlabel metal2 50 7 50 7 8 br0 -rlabel polycontact 29 49 29 49 1 Q -rlabel polycontact 25 42 25 42 1 Q_bar -<< end >> diff --git a/technology/scn4m_subm/mag_lib/cell_1rw_1r.mag b/technology/scn4m_subm/mag_lib/cell_2rw.mag similarity index 100% rename from technology/scn4m_subm/mag_lib/cell_1rw_1r.mag rename to technology/scn4m_subm/mag_lib/cell_2rw.mag diff --git a/technology/scn4m_subm/mag_lib/cell_6t.ext b/technology/scn4m_subm/mag_lib/cell_6t.ext deleted file mode 100644 index 79f3c8b4..00000000 --- a/technology/scn4m_subm/mag_lib/cell_6t.ext +++ /dev/null @@ -1,41 +0,0 @@ -timestamp 1536091415 -version 8.2 -tech scmos -style TSMC0.35um(tsmc35)from:t11c -scale 1000 1 5 -resistclasses 3700 2800 1018000 1018000 1 6000 6000 80 70 80 40 -node "comment_0_0#" 0 0 0 0 bb 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -node "br" 6 -1.43219e-14 96 -8 ndc 320 72 0 0 0 0 0 0 0 0 0 0 0 0 512 96 3456 464 0 0 0 0 -node "bl" 6 -8.88178e-16 40 -8 ndc 320 72 0 0 0 0 0 0 0 0 0 0 0 0 512 96 3200 432 0 0 0 0 -node "wl" 115 -2.89546e-13 -8 12 p 0 0 0 0 0 0 0 0 0 0 1536 360 0 0 2496 344 0 0 0 0 0 0 -node "a_36_40#" 140 -3.51719e-13 36 40 ndif 960 144 304 72 0 0 0 0 0 0 1984 424 0 0 2048 288 0 0 0 0 0 0 -node "a_28_32#" 160 -8.06466e-13 28 32 p 960 144 304 72 0 0 0 0 0 0 2000 456 0 0 1920 272 0 0 0 0 0 0 -node "gnd" 41 -27.888 -32 -32 pw 1792 240 512 128 0 0 0 0 29600 696 0 0 0 0 2688 400 6400 864 0 0 0 0 -equiv "gnd" "gnd" -node "vdd" 2340 2596 -32 116 nw 256 64 800 176 17600 576 0 0 0 0 0 0 0 0 3456 464 256 64 0 0 0 0 -cap "wl" "bl" 189.768 -cap "a_36_40#" "br" 17.59 -cap "wl" "br" 189.768 -cap "vdd" "bl" 135.015 -cap "bl" "br" 27.492 -cap "vdd" "br" 117.084 -cap "gnd" "a_28_32#" 880.405 -cap "gnd" "a_36_40#" 401.284 -cap "a_28_32#" "a_36_40#" 272.793 -cap "gnd" "wl" 1198.41 -cap "gnd" "bl" 712.11 -cap "a_28_32#" "wl" 108.364 -cap "vdd" "gnd" 510.12 -cap "gnd" "br" 698.471 -cap "a_36_40#" "wl" 108.364 -cap "a_28_32#" "bl" 104.205 -cap "vdd" "a_28_32#" 430.812 -cap "a_36_40#" "bl" 29.396 -cap "a_28_32#" "br" 308.488 -cap "vdd" "a_36_40#" 709.108 -fet nfet 96 12 97 13 128 48 "gnd" "wl" 16 0 "br" 16 0 "a_28_32#" 16 0 -fet nfet 40 12 41 13 128 48 "gnd" "wl" 16 0 "bl" 16 0 "a_36_40#" 16 0 -fet nfet 116 40 117 41 256 80 "gnd" "a_36_40#" 16 0 "a_28_32#" 32 0 "gnd" 32 0 -fet nfet 28 40 29 41 256 80 "gnd" "a_28_32#" 16 0 "gnd" 32 0 "a_36_40#" 32 0 -fet pfet 108 148 109 149 192 56 "vdd" "a_36_40#" 32 0 "a_28_32#" 12 0 "vdd" 12 0 -fet pfet 28 148 29 149 192 56 "vdd" "a_28_32#" 32 0 "vdd" 12 0 "a_36_40#" 12 0 diff --git a/technology/scn4m_subm/mag_lib/cell_6t.spice b/technology/scn4m_subm/mag_lib/cell_6t.spice deleted file mode 100644 index 31eec08a..00000000 --- a/technology/scn4m_subm/mag_lib/cell_6t.spice +++ /dev/null @@ -1,15 +0,0 @@ -* SPICE3 file created from cell_6t.ext - technology: scmos - -M1000 a_36_40# a_28_32# vdd vdd pfet w=0.6u l=0.8u -+ ad=0.76p pd=3.6u as=2p ps=8.8u -M1001 vdd a_36_40# a_28_32# vdd pfet w=0.6u l=0.8u -+ ad=0p pd=0u as=0.76p ps=3.6u -M1002 a_36_40# a_28_32# gnd gnd nfet w=1.6u l=0.4u -+ ad=2.4p pd=7.2u as=4.48p ps=12u -M1003 gnd a_36_40# a_28_32# gnd nfet w=1.6u l=0.4u -+ ad=0p pd=0u as=2.4p ps=7.2u -M1004 a_36_40# wl bl gnd nfet w=0.8u l=0.4u -+ ad=0p pd=0u as=0.8p ps=3.6u -M1005 a_28_32# wl br gnd nfet w=0.8u l=0.4u -+ ad=0p pd=0u as=0.8p ps=3.6u -C0 vdd 0 2.60fF diff --git a/technology/scn4m_subm/mag_lib/dummy_cell_6t.mag b/technology/scn4m_subm/mag_lib/dummy_cell_1rw.mag similarity index 100% rename from technology/scn4m_subm/mag_lib/dummy_cell_6t.mag rename to technology/scn4m_subm/mag_lib/dummy_cell_1rw.mag diff --git a/technology/scn4m_subm/mag_lib/dummy_cell_1w_1r.mag b/technology/scn4m_subm/mag_lib/dummy_cell_1w_1r.mag deleted file mode 100644 index 1931485f..00000000 --- a/technology/scn4m_subm/mag_lib/dummy_cell_1w_1r.mag +++ /dev/null @@ -1,138 +0,0 @@ -magic -tech scmos -timestamp 1577067400 -<< nwell >> -rect 0 46 54 75 -<< pwell >> -rect 0 0 54 46 -<< ntransistor >> -rect 14 33 16 37 -rect 22 29 24 37 -rect 30 29 32 37 -rect 38 33 40 37 -rect 14 17 16 23 -rect 22 17 24 23 -rect 30 17 32 23 -rect 38 17 40 23 -<< ptransistor >> -rect 22 54 24 57 -rect 30 54 32 57 -<< ndiffusion >> -rect 13 33 14 37 -rect 16 33 17 37 -rect 21 33 22 37 -rect 17 29 22 33 -rect 24 29 25 37 -rect 29 29 30 37 -rect 32 33 33 37 -rect 37 33 38 37 -rect 40 33 41 37 -rect 32 29 37 33 -rect 9 21 14 23 -rect 13 17 14 21 -rect 16 17 22 23 -rect 24 17 25 23 -rect 29 17 30 23 -rect 32 17 38 23 -rect 40 21 45 23 -rect 40 17 41 21 -<< pdiffusion >> -rect 21 54 22 57 -rect 24 54 25 57 -rect 29 54 30 57 -rect 32 54 33 57 -<< ndcontact >> -rect 9 33 13 37 -rect 17 33 21 37 -rect 25 29 29 37 -rect 33 33 37 37 -rect 41 33 45 37 -rect 9 17 13 21 -rect 25 17 29 23 -rect 41 17 45 21 -<< pdcontact >> -rect 17 54 21 58 -rect 25 54 29 58 -rect 33 54 37 58 -<< psubstratepcontact >> -rect 25 9 29 13 -<< nsubstratencontact >> -rect 25 68 29 72 -<< polysilicon >> -rect 22 57 24 60 -rect 30 57 32 60 -rect 22 44 24 54 -rect 30 51 32 54 -rect 31 47 32 51 -rect 14 37 16 44 -rect 22 40 23 44 -rect 22 37 24 40 -rect 30 37 32 47 -rect 38 37 40 44 -rect 14 31 16 33 -rect 38 31 40 33 -rect 14 23 16 24 -rect 22 23 24 29 -rect 30 23 32 29 -rect 38 23 40 24 -rect 14 15 16 17 -rect 22 15 24 17 -rect 30 15 32 17 -rect 38 15 40 17 -<< polycontact >> -rect 27 47 31 51 -rect 10 40 14 44 -rect 23 40 27 44 -rect 40 40 44 44 -rect 12 24 16 28 -rect 38 24 42 28 -<< metal1 >> -rect 0 68 25 72 -rect 29 68 54 72 -rect 0 61 54 65 -rect 10 44 14 61 -rect 17 51 20 54 -rect 17 47 27 51 -rect 17 37 20 47 -rect 34 44 37 54 -rect 27 40 37 44 -rect 40 44 44 61 -rect 34 37 37 40 -rect 2 33 9 37 -rect 45 33 52 37 -rect 25 23 29 29 -rect 25 13 29 17 -rect 0 9 25 13 -rect 29 9 54 13 -rect 0 2 16 6 -rect 20 2 34 6 -rect 38 2 54 6 -<< m2contact >> -rect 25 68 29 72 -rect 25 54 29 58 -rect 16 24 20 28 -rect 34 24 38 28 -rect 16 2 20 6 -rect 34 2 38 6 -<< metal2 >> -rect 2 0 6 72 -rect 9 0 13 72 -rect 25 58 29 68 -rect 16 6 20 24 -rect 34 6 38 24 -rect 41 0 45 72 -rect 48 0 52 72 -<< comment >> -rect 0 0 54 70 -<< labels >> -rlabel metal1 19 63 19 63 1 wl0 -rlabel metal1 19 70 19 70 5 vdd -rlabel metal1 27 4 27 4 1 wl1 -rlabel psubstratepcontact 27 11 27 11 1 gnd -rlabel metal2 4 7 4 7 2 bl0 -rlabel metal2 11 7 11 7 1 bl1 -rlabel metal2 43 7 43 7 1 br1 -rlabel metal2 50 7 50 7 8 br0 -rlabel polycontact 29 49 29 49 1 Q -rlabel polycontact 25 42 25 42 1 Q_bar -<< end >> diff --git a/technology/scn4m_subm/mag_lib/dummy_cell_1rw_1r.mag b/technology/scn4m_subm/mag_lib/dummy_cell_2rw.mag similarity index 100% rename from technology/scn4m_subm/mag_lib/dummy_cell_1rw_1r.mag rename to technology/scn4m_subm/mag_lib/dummy_cell_2rw.mag diff --git a/technology/scn4m_subm/mag_lib/replica_cell_6t.mag b/technology/scn4m_subm/mag_lib/replica_cell_1rw.mag similarity index 100% rename from technology/scn4m_subm/mag_lib/replica_cell_6t.mag rename to technology/scn4m_subm/mag_lib/replica_cell_1rw.mag diff --git a/technology/scn4m_subm/mag_lib/replica_cell_1w_1r.mag b/technology/scn4m_subm/mag_lib/replica_cell_1w_1r.mag deleted file mode 100644 index 61add325..00000000 --- a/technology/scn4m_subm/mag_lib/replica_cell_1w_1r.mag +++ /dev/null @@ -1,147 +0,0 @@ -magic -tech scmos -timestamp 1577067446 -<< nwell >> -rect 0 46 54 75 -<< pwell >> -rect 0 0 54 46 -<< ntransistor >> -rect 14 33 16 37 -rect 22 29 24 37 -rect 30 29 32 37 -rect 38 33 40 37 -rect 14 17 16 23 -rect 22 17 24 23 -rect 30 17 32 23 -rect 38 17 40 23 -<< ptransistor >> -rect 22 54 24 57 -rect 30 54 32 57 -<< ndiffusion >> -rect 13 33 14 37 -rect 16 33 17 37 -rect 21 33 22 37 -rect 17 29 22 33 -rect 24 29 25 37 -rect 29 29 30 37 -rect 32 33 33 37 -rect 37 33 38 37 -rect 40 33 41 37 -rect 32 29 37 33 -rect 9 21 14 23 -rect 13 17 14 21 -rect 16 17 22 23 -rect 24 17 25 23 -rect 29 17 30 23 -rect 32 17 38 23 -rect 40 21 45 23 -rect 40 17 41 21 -<< pdiffusion >> -rect 21 54 22 57 -rect 24 54 25 57 -rect 29 54 30 57 -rect 32 54 33 57 -<< ndcontact >> -rect 9 33 13 37 -rect 17 33 21 37 -rect 25 29 29 37 -rect 33 33 37 37 -rect 41 33 45 37 -rect 9 17 13 21 -rect 25 17 29 23 -rect 41 17 45 21 -<< pdcontact >> -rect 17 54 21 58 -rect 25 54 29 58 -rect 33 54 37 58 -<< psubstratepcontact >> -rect 25 9 29 13 -<< nsubstratencontact >> -rect 25 68 29 72 -<< polysilicon >> -rect 22 57 24 60 -rect 30 57 32 60 -rect 22 44 24 54 -rect 30 51 32 54 -rect 31 47 32 51 -rect 14 37 16 44 -rect 22 40 23 44 -rect 22 37 24 40 -rect 30 37 32 47 -rect 38 37 40 44 -rect 14 31 16 33 -rect 38 31 40 33 -rect 14 23 16 24 -rect 22 23 24 29 -rect 30 23 32 29 -rect 38 23 40 24 -rect 14 15 16 17 -rect 22 15 24 17 -rect 30 15 32 17 -rect 38 15 40 17 -<< polycontact >> -rect 27 47 31 51 -rect 10 40 14 44 -rect 23 40 27 44 -rect 40 40 44 44 -rect 12 24 16 28 -rect 38 24 42 28 -<< metal1 >> -rect 0 68 25 72 -rect 29 68 54 72 -rect 0 61 54 65 -rect 10 44 14 61 -rect 29 54 33 58 -rect 17 51 20 54 -rect 17 47 27 51 -rect 17 37 20 47 -rect 34 44 37 54 -rect 27 40 37 44 -rect 40 44 44 61 -rect 34 37 37 40 -rect 6 33 9 37 -rect 45 33 48 37 -rect 25 23 29 29 -rect 25 13 29 17 -rect 0 9 25 13 -rect 29 9 54 13 -rect 0 2 16 6 -rect 20 2 34 6 -rect 38 2 54 6 -<< m2contact >> -rect 25 68 29 72 -rect 25 54 29 58 -rect 2 33 6 37 -rect 48 33 52 37 -rect 16 24 20 28 -rect 34 24 38 28 -rect 9 17 13 21 -rect 41 17 45 21 -rect 16 2 20 6 -rect 34 2 38 6 -<< metal2 >> -rect 2 37 6 72 -rect 2 0 6 33 -rect 9 21 13 72 -rect 25 58 29 68 -rect 9 0 13 17 -rect 16 6 20 24 -rect 34 6 38 24 -rect 41 21 45 72 -rect 41 0 45 17 -rect 48 37 52 72 -rect 48 0 52 33 -<< comment >> -rect 0 0 54 70 -<< labels >> -rlabel metal1 19 63 19 63 1 wl0 -rlabel metal1 19 70 19 70 5 vdd -rlabel metal1 27 4 27 4 1 wl1 -rlabel psubstratepcontact 27 11 27 11 1 gnd -rlabel metal2 4 7 4 7 2 bl0 -rlabel metal2 11 7 11 7 1 bl1 -rlabel metal2 43 7 43 7 1 br1 -rlabel metal2 50 7 50 7 8 br0 -rlabel polycontact 29 49 29 49 1 Q -rlabel polycontact 25 42 25 42 1 Q_bar -<< end >> diff --git a/technology/scn4m_subm/mag_lib/replica_cell_1rw_1r.mag b/technology/scn4m_subm/mag_lib/replica_cell_2rw.mag similarity index 100% rename from technology/scn4m_subm/mag_lib/replica_cell_1rw_1r.mag rename to technology/scn4m_subm/mag_lib/replica_cell_2rw.mag diff --git a/technology/scn4m_subm/mag_lib/replica_cell_6t.ext b/technology/scn4m_subm/mag_lib/replica_cell_6t.ext deleted file mode 100644 index 726cd738..00000000 --- a/technology/scn4m_subm/mag_lib/replica_cell_6t.ext +++ /dev/null @@ -1,35 +0,0 @@ -timestamp 1541443051 -version 8.2 -tech scmos -style TSMC0.35um(tsmc35)from:t11c -scale 1000 1 5 -resistclasses 3700 2800 1018000 1018000 1 6000 6000 80 70 80 40 -node "comment_0_0#" 0 0 0 0 bb 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -node "br" 6 1.40998e-14 96 -8 ndc 320 72 0 0 0 0 0 0 0 0 0 0 0 0 512 96 3456 464 0 0 0 0 -node "bl" 6 -8.88178e-16 40 -8 ndc 320 72 0 0 0 0 0 0 0 0 0 0 0 0 512 96 3200 432 0 0 0 0 -node "wl" 115 -2.89546e-13 -8 12 p 0 0 0 0 0 0 0 0 0 0 1536 360 0 0 2496 344 0 0 0 0 0 0 -node "a_36_40#" 140 -3.51719e-13 36 40 ndif 960 144 304 72 0 0 0 0 0 0 1984 424 0 0 2048 288 0 0 0 0 0 0 -node "gnd" 41 -27.888 -32 -32 pw 1792 240 512 128 0 0 0 0 29600 696 0 0 0 0 2688 400 6400 864 0 0 0 0 -equiv "gnd" "gnd" -node "vdd" 2517 2596 -32 116 nw 1216 208 1104 248 17600 576 0 0 0 0 2000 456 0 0 5632 736 256 64 0 0 0 0 -cap "vdd" "br" 442.06 -cap "bl" "wl" 189.768 -cap "gnd" "br" 698.471 -cap "bl" "a_36_40#" 29.396 -cap "wl" "a_36_40#" 108.364 -cap "bl" "vdd" 239.22 -cap "bl" "gnd" 712.11 -cap "wl" "vdd" 108.364 -cap "wl" "gnd" 1198.41 -cap "bl" "br" 27.492 -cap "a_36_40#" "vdd" 981.901 -cap "wl" "br" 189.768 -cap "a_36_40#" "gnd" 401.284 -cap "vdd" "gnd" 1390.52 -cap "a_36_40#" "br" 17.59 -fet nfet 96 12 97 13 128 48 "gnd" "wl" 16 0 "br" 16 0 "vdd" 16 0 -fet nfet 40 12 41 13 128 48 "gnd" "wl" 16 0 "bl" 16 0 "a_36_40#" 16 0 -fet nfet 116 40 117 41 256 80 "gnd" "a_36_40#" 16 0 "vdd" 32 0 "gnd" 32 0 -fet nfet 28 40 29 41 256 80 "gnd" "vdd" 16 0 "gnd" 32 0 "a_36_40#" 32 0 -fet pfet 108 148 109 149 192 56 "vdd" "a_36_40#" 32 0 "vdd" 24 0 -fet pfet 28 148 29 149 192 56 "vdd" "vdd" 32 0 "vdd" 12 0 "a_36_40#" 12 0 diff --git a/technology/scn4m_subm/mag_lib/replica_cell_6t.spice b/technology/scn4m_subm/mag_lib/replica_cell_6t.spice deleted file mode 100644 index bb64476f..00000000 --- a/technology/scn4m_subm/mag_lib/replica_cell_6t.spice +++ /dev/null @@ -1,16 +0,0 @@ -* SPICE3 file created from replica_cell_6t.ext - technology: scmos - -M1000 a_36_40# vdd vdd vdd pfet w=0.6u l=0.8u -+ ad=0.76p pd=3.6u as=2.76p ps=12.4u -** SOURCE/DRAIN TIED -M1001 vdd a_36_40# vdd vdd pfet w=0.8u l=0.6u -+ ad=0p pd=0u as=0p ps=0u -M1002 a_36_40# vdd gnd gnd nfet w=1.6u l=0.4u -+ ad=2.4p pd=7.2u as=4.48p ps=12u -M1003 gnd a_36_40# vdd gnd nfet w=1.6u l=0.4u -+ ad=0p pd=0u as=3.04p ps=10.4u -M1004 a_36_40# wl bl gnd nfet w=0.8u l=0.4u -+ ad=0p pd=0u as=0.8p ps=3.6u -M1005 vdd wl br gnd nfet w=0.8u l=0.4u -+ ad=0p pd=0u as=0.8p ps=3.6u -C0 vdd 0 2.60fF diff --git a/technology/scn4m_subm/sp_lib/cell_6t.sp b/technology/scn4m_subm/sp_lib/cell_1rw.sp similarity index 63% rename from technology/scn4m_subm/sp_lib/cell_6t.sp rename to technology/scn4m_subm/sp_lib/cell_1rw.sp index dc724007..fafbe7ef 100644 --- a/technology/scn4m_subm/sp_lib/cell_6t.sp +++ b/technology/scn4m_subm/sp_lib/cell_1rw.sp @@ -1,7 +1,7 @@ -*********************** "cell_6t" ****************************** -.SUBCKT cell_6t bl br wl vdd gnd -* SPICE3 file created from cell_6t.ext - technology: scmos +*********************** "cell_1rw" ****************************** +.SUBCKT cell_1rw bl br wl vdd gnd +* SPICE3 file created from cell_1rw.ext - technology: scmos * Inverter 1 M1000 Q Q_bar vdd vdd p w=0.6u l=0.8u diff --git a/technology/scn4m_subm/sp_lib/cell_1rw_1r.sp b/technology/scn4m_subm/sp_lib/cell_1rw_1r.sp deleted file mode 100644 index 37f25f75..00000000 --- a/technology/scn4m_subm/sp_lib/cell_1rw_1r.sp +++ /dev/null @@ -1,14 +0,0 @@ - -.SUBCKT cell_1rw_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd -MM9 RA_to_R_right wl1 br1 gnd n w=1.2u l=0.4u -MM8 RA_to_R_right Q gnd gnd n w=1.2u l=0.4u -MM7 RA_to_R_left Q_bar gnd gnd n w=1.2u l=0.4u -MM6 RA_to_R_left wl1 bl1 gnd n w=1.2u l=0.4u -MM5 Q wl0 bl0 gnd n w=0.8u l=0.4u -MM4 Q_bar wl0 br0 gnd n w=0.8u l=0.4u -MM1 Q Q_bar gnd gnd n w=1.6u l=0.4u -MM0 Q_bar Q gnd gnd n w=1.6u l=0.4u -MM3 Q Q_bar vdd vdd p w=0.6u l=0.4u -MM2 Q_bar Q vdd vdd p w=0.6u l=0.4u -.ENDS - diff --git a/technology/scn4m_subm/sp_lib/cell_1w_1r.sp b/technology/scn4m_subm/sp_lib/cell_2rw.sp similarity index 88% rename from technology/scn4m_subm/sp_lib/cell_1w_1r.sp rename to technology/scn4m_subm/sp_lib/cell_2rw.sp index b40f589a..9984213d 100644 --- a/technology/scn4m_subm/sp_lib/cell_1w_1r.sp +++ b/technology/scn4m_subm/sp_lib/cell_2rw.sp @@ -1,5 +1,5 @@ -.SUBCKT cell_1w_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd +.SUBCKT cell_2rw bl0 br0 bl1 br1 wl0 wl1 vdd gnd MM9 RA_to_R_right wl1 br1 gnd n w=1.2u l=0.4u MM8 RA_to_R_right Q gnd gnd n w=1.2u l=0.4u MM7 RA_to_R_left Q_bar gnd gnd n w=1.2u l=0.4u diff --git a/technology/scn4m_subm/sp_lib/dummy_cell_6t.sp b/technology/scn4m_subm/sp_lib/dummy_cell_1rw.sp similarity index 72% rename from technology/scn4m_subm/sp_lib/dummy_cell_6t.sp rename to technology/scn4m_subm/sp_lib/dummy_cell_1rw.sp index c5b6ff9d..c487b572 100644 --- a/technology/scn4m_subm/sp_lib/dummy_cell_6t.sp +++ b/technology/scn4m_subm/sp_lib/dummy_cell_1rw.sp @@ -1,6 +1,6 @@ -*********************** "dummy_cell_6t" ****************************** -.SUBCKT dummy_cell_6t bl br wl vdd gnd +*********************** "dummy_cell_1rw" ****************************** +.SUBCKT dummy_cell_1rw bl br wl vdd gnd * Inverter 1 M1000 Q Q_bar vdd vdd p w=0.6u l=0.8u diff --git a/technology/scn4m_subm/sp_lib/dummy_cell_1rw_1r.sp b/technology/scn4m_subm/sp_lib/dummy_cell_1rw_1r.sp deleted file mode 100644 index 9766a840..00000000 --- a/technology/scn4m_subm/sp_lib/dummy_cell_1rw_1r.sp +++ /dev/null @@ -1,14 +0,0 @@ - -.SUBCKT dummy_cell_1rw_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd -MM9 RA_to_R_right wl1 br1_noconn gnd n w=1.2u l=0.4u -MM8 RA_to_R_right Q gnd gnd n w=1.2u l=0.4u -MM7 RA_to_R_left Q_bar gnd gnd n w=1.2u l=0.4u -MM6 RA_to_R_left wl1 bl1_noconn gnd n w=1.2u l=0.4u -MM5 Q wl0 bl0_noconn gnd n w=0.8u l=0.4u -MM4 Q_bar wl0 br0_noconn gnd n w=0.8u l=0.4u -MM1 Q Q_bar gnd gnd n w=1.6u l=0.4u -MM0 Q_bar Q gnd gnd n w=1.6u l=0.4u -MM3 Q Q_bar vdd vdd p w=0.6u l=0.4u -MM2 Q_bar Q vdd vdd p w=0.6u l=0.4u -.ENDS - diff --git a/technology/scn4m_subm/sp_lib/dummy_cell_1w_1r.sp b/technology/scn4m_subm/sp_lib/dummy_cell_2rw.sp similarity index 88% rename from technology/scn4m_subm/sp_lib/dummy_cell_1w_1r.sp rename to technology/scn4m_subm/sp_lib/dummy_cell_2rw.sp index f5424998..e07dac48 100644 --- a/technology/scn4m_subm/sp_lib/dummy_cell_1w_1r.sp +++ b/technology/scn4m_subm/sp_lib/dummy_cell_2rw.sp @@ -1,5 +1,5 @@ -.SUBCKT dummy_cell_1w_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd +.SUBCKT dummy_cell_2rw bl0 br0 bl1 br1 wl0 wl1 vdd gnd MM9 RA_to_R_right wl1 br1_noconn gnd n w=1.2u l=0.4u MM8 RA_to_R_right Q gnd gnd n w=1.2u l=0.4u MM7 RA_to_R_left Q_bar gnd gnd n w=1.2u l=0.4u diff --git a/technology/scn4m_subm/sp_lib/replica_cell_6t.sp b/technology/scn4m_subm/sp_lib/replica_cell_1rw.sp similarity index 61% rename from technology/scn4m_subm/sp_lib/replica_cell_6t.sp rename to technology/scn4m_subm/sp_lib/replica_cell_1rw.sp index a9d41398..f453477a 100644 --- a/technology/scn4m_subm/sp_lib/replica_cell_6t.sp +++ b/technology/scn4m_subm/sp_lib/replica_cell_1rw.sp @@ -1,7 +1,7 @@ -*********************** "cell_6t" ****************************** -.SUBCKT replica_cell_6t bl br wl vdd gnd -* SPICE3 file created from cell_6t.ext - technology: scmos +*********************** "cell_1rw" ****************************** +.SUBCKT replica_cell_1rw bl br wl vdd gnd +* SPICE3 file created from cell_1rw.ext - technology: scmos * Inverter 1 M1000 Q vdd vdd vdd p w=0.6u l=0.8u diff --git a/technology/scn4m_subm/sp_lib/replica_cell_1rw_1r.sp b/technology/scn4m_subm/sp_lib/replica_cell_1rw_1r.sp deleted file mode 100644 index 94bdb75e..00000000 --- a/technology/scn4m_subm/sp_lib/replica_cell_1rw_1r.sp +++ /dev/null @@ -1,14 +0,0 @@ - -.SUBCKT replica_cell_1rw_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd -MM9 RA_to_R_right wl1 br1 gnd n w=1.2u l=0.4u -MM8 RA_to_R_right Q gnd gnd n w=1.2u l=0.4u -MM7 RA_to_R_left vdd gnd gnd n w=1.2u l=0.4u -MM6 RA_to_R_left wl1 bl1 gnd n w=1.2u l=0.4u -MM5 Q wl0 bl0 gnd n w=0.8u l=0.4u -MM4 vdd wl0 br0 gnd n w=0.8u l=0.4u -MM1 Q vdd gnd gnd n w=1.6u l=0.4u -MM0 vdd Q gnd gnd n w=1.6u l=0.4u -MM3 Q vdd vdd vdd p w=0.6u l=0.4u -MM2 vdd Q vdd vdd p w=0.6u l=0.4u -.ENDS - diff --git a/technology/scn4m_subm/sp_lib/replica_cell_1w_1r.sp b/technology/scn4m_subm/sp_lib/replica_cell_2rw.sp similarity index 86% rename from technology/scn4m_subm/sp_lib/replica_cell_1w_1r.sp rename to technology/scn4m_subm/sp_lib/replica_cell_2rw.sp index 6c2d3c1b..9a00da3e 100644 --- a/technology/scn4m_subm/sp_lib/replica_cell_1w_1r.sp +++ b/technology/scn4m_subm/sp_lib/replica_cell_2rw.sp @@ -1,5 +1,5 @@ -.SUBCKT replica_cell_1w_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd +.SUBCKT replica_cell_2rw bl0 br0 bl1 br1 wl0 wl1 vdd gnd MM9 RA_to_R_right wl1 br1 gnd n w=1.2u l=0.4u MM8 RA_to_R_right Q gnd gnd n w=1.2u l=0.4u MM7 RA_to_R_left vdd gnd gnd n w=1.2u l=0.4u diff --git a/technology/scn4m_subm/sue_lib/cell_6t.sue b/technology/scn4m_subm/sue_lib/cell_6t.sue deleted file mode 100644 index 427b1d05..00000000 --- a/technology/scn4m_subm/sue_lib/cell_6t.sue +++ /dev/null @@ -1,46 +0,0 @@ -# SUE version MMI_SUE5.0.7 - -proc SCHEMATIC_cell_6t {} { - make inout -name BL -origin {190 360} - make inout -name BR -origin {830 360} - make input -name WL -origin {240 120} - make global -orient RXY -name vdd -origin {520 160} - make global -name gnd -origin {510 600} - make pmos -orient RY -W 0.9u -L 1.2u -origin {630 230} - make pmos -orient RXY -W 0.9u -L 1.2u -origin {400 230} - make nmos -orient R90 -W 1.2 -L 0.6u -origin {740 360} - make nmos -orient R90X -W 1.2 -L 0.6u -origin {270 360} - make nmos -W 2.4u -L 0.6u -origin {630 490} - make nmos -orient RX -W 2.4u -L 0.6u -origin {400 490} - make_wire 630 550 630 530 - make_wire 400 530 400 550 - make_wire 400 190 400 170 - make_wire 630 170 630 190 - make_wire 400 360 400 270 - make_wire 310 360 400 360 - make_wire 630 360 630 450 - make_wire 630 360 700 360 - make_wire 270 300 270 120 - make_wire 270 120 740 120 - make_wire 740 120 740 300 - make_wire 230 360 190 360 - make_wire 780 360 830 360 - make_wire 510 550 400 550 - make_wire 510 550 630 550 - make_wire 510 550 510 600 - make_wire 520 170 400 170 - make_wire 520 170 630 170 - make_wire 520 160 520 170 - make_wire 240 120 270 120 - make_wire 460 290 630 290 - make_wire 460 290 460 490 - make_wire 460 290 460 230 - make_wire 630 290 630 360 - make_wire 630 290 630 270 - make_wire 570 420 400 420 - make_wire 570 420 570 490 - make_wire 570 420 570 230 - make_wire 400 420 400 360 - make_wire 400 420 400 450 -} - diff --git a/technology/scn4m_subm/sue_lib/ms_flop.sue b/technology/scn4m_subm/sue_lib/ms_flop.sue deleted file mode 100644 index 85cc8e03..00000000 --- a/technology/scn4m_subm/sue_lib/ms_flop.sue +++ /dev/null @@ -1,84 +0,0 @@ -# SUE version MMI_SUE5.0.7 - -proc SCHEMATIC_ms_flop {} { - make pmos -orient R90X -W 1.8u -L 0.6u -origin {40 250} - make nmos -orient R270 -W 0.9u -L 0.6u -origin {40 380} - make inverter -WP 1.8u -LP 0.6u -WN 0.9u -LN 0.6u -origin {-270 540} - make inverter -WP 1.8u -LP 0.6u -WN 0.9u -LN 0.6u -origin {310 310} - make inverter -orient RX -WP 1.8u -LP 0.6u -WN 0.9u -LN 0.6u -origin {430 730} - make pmos -orient R90X -W 1.8u -L 0.6u -origin {190 670} - make nmos -orient R270 -W 0.9u -L 0.6u -origin {190 780} - make input -name clk -origin {-380 540} - make input -name din -origin {-370 320} - make pmos -orient R90X -W 1.8u -L 0.6u -origin {720 250} - make nmos -orient R270 -W 0.9u -L 0.6u -origin {720 380} - make inverter -WP 1.8u -LP 0.6u -WN 0.9u -LN 0.6u -origin {990 310} - make pmos -orient R90X -W 1.8u -L 0.6u -origin {870 670} - make nmos -orient R270 -W 0.9u -L 0.6u -origin {870 780} - make inverter -WP 1.8u -LP 0.6u -WN 0.9u -LN 0.6u -origin {620 540} - make output -name dout -origin {1410 310} - make output -name dout_bar -origin {1430 930} - make inverter -orient RX -WP 1.8u -LP 0.6u -WN 0.9u -LN 0.6u -origin {1110 730} - make_wire -330 160 40 160 - make_wire 40 160 40 190 - make_wire -370 320 0 320 - make_wire 360 310 480 310 - make_wire 460 730 480 730 - make_wire 230 730 380 730 - make_wire 100 310 100 720 - make_wire 100 720 150 720 - make_wire 100 310 80 310 - make_wire 100 310 280 310 - make_wire 0 250 0 320 - make_wire 0 320 0 380 - make_wire 80 250 80 310 - make_wire 80 310 80 380 - make_wire 40 440 40 540 - make_wire -330 840 190 840 - make_wire 230 670 230 730 - make_wire 230 730 230 780 - make_wire 150 670 150 720 - make_wire 150 720 150 780 - make_wire 190 540 190 610 - make_wire -330 540 -330 840 - make_wire -220 540 40 540 - make_wire 40 540 190 540 - make_wire -380 540 -330 540 - make_wire -330 540 -300 540 - make_wire -330 540 -330 160 - make_wire 720 160 720 190 - make_wire 1140 730 1160 730 - make_wire 780 310 780 720 - make_wire 780 720 830 720 - make_wire 780 310 760 310 - make_wire 780 310 960 310 - make_wire 680 320 680 380 - make_wire 760 250 760 310 - make_wire 760 310 760 380 - make_wire 720 440 720 540 - make_wire 910 670 910 730 - make_wire 910 730 910 780 - make_wire 830 670 830 720 - make_wire 830 720 830 780 - make_wire 870 540 870 610 - make_wire 720 540 870 540 - make_wire 670 540 720 540 - make_wire 480 310 480 730 - make_wire 1160 310 1160 730 - make_wire 530 540 530 160 - make_wire 530 160 720 160 - make_wire 530 540 190 540 - make_wire 530 540 590 540 - make_wire 530 540 530 840 - make_wire 530 840 870 840 - make_wire 680 310 480 310 - make_wire 680 310 680 250 - make_wire 680 310 680 320 - make_wire 950 730 910 730 - make_wire 950 730 1060 730 - make_wire 1040 310 1160 310 - make_wire 1160 310 1410 310 - make_wire 950 930 1430 930 - make_wire 950 730 950 930 -} - diff --git a/technology/scn4m_subm/sue_lib/replica_cell_6t.sue b/technology/scn4m_subm/sue_lib/replica_cell_6t.sue deleted file mode 100644 index 56e72056..00000000 --- a/technology/scn4m_subm/sue_lib/replica_cell_6t.sue +++ /dev/null @@ -1,49 +0,0 @@ -# SUE version MMI_SUE5.0.7 - -proc SCHEMATIC_replica_cell_6t {} { - make inout -name BL -origin {190 360} - make inout -name BR -origin {830 360} - make input -name WL -origin {240 120} - make global -orient RXY -name vdd -origin {520 160} - make global -name gnd -origin {510 600} - make pmos -orient RY -W 0.9u -L 1.2u -origin {630 230} - make pmos -orient RXY -W 0.9u -L 1.2u -origin {400 230} - make nmos -orient R90 -W 1.2 -L 0.6u -origin {740 360} - make nmos -orient R90X -W 1.2 -L 0.6u -origin {270 360} - make nmos -W 2.4u -L 0.6u -origin {630 490} - make nmos -orient RX -W 2.4u -L 0.6u -origin {400 490} - make_wire 630 550 630 530 - make_wire 400 530 400 550 - make_wire 400 190 400 170 - make_wire 630 170 630 190 - make_wire 400 360 400 270 - make_wire 630 360 630 450 - make_wire 630 360 700 360 - make_wire 270 300 270 120 - make_wire 270 120 740 120 - make_wire 740 120 740 300 - make_wire 230 360 190 360 - make_wire 780 360 830 360 - make_wire 510 550 400 550 - make_wire 510 550 630 550 - make_wire 510 550 510 600 - make_wire 520 170 400 170 - make_wire 520 170 630 170 - make_wire 520 160 520 170 - make_wire 240 120 270 120 - make_wire 460 290 630 290 - make_wire 460 290 460 490 - make_wire 460 290 460 230 - make_wire 630 290 630 360 - make_wire 630 290 630 270 - make_wire 570 420 400 420 - make_wire 570 420 570 490 - make_wire 570 420 570 230 - make_wire 400 420 400 360 - make_wire 400 420 400 450 - make_wire 320 360 320 550 - make_wire 320 550 400 550 - make_wire 320 360 310 360 - make_wire 320 360 400 360 -} - diff --git a/technology/scn4m_subm/sue_lib/sense_amp.sue b/technology/scn4m_subm/sue_lib/sense_amp.sue deleted file mode 100644 index 4d29e11a..00000000 --- a/technology/scn4m_subm/sue_lib/sense_amp.sue +++ /dev/null @@ -1,52 +0,0 @@ -# SUE version MMI_SUE5.0.7 - -proc SCHEMATIC_sense_amp {} { - make inout -name BL -origin {260 10} - make global -orient RXY -name vdd -origin {490 170} - make global -name gnd -origin {480 660} - make input -name sclk -origin {180 610} - make nmos -W 3.9u -L 0.6u -origin {600 500} - make nmos -orient RX -W 3.9u -L 0.6u -origin {370 500} - make pmos -orient RY -W 3u -L 0.6u -origin {600 240} - make pmos -orient RXY -W 3u -L 0.6u -origin {370 240} - make nmos -W 3.9u -L 0.6u -origin {480 610} - make inout -name BR -origin {710 20} - make pmos -W 3.9u -L 0.6u -origin {710 90} - make pmos -orient RX -W 3.9u -L 0.6u -origin {260 90} - make output -orient RXY -name dout -origin {110 370} - make_wire 600 560 600 540 - make_wire 370 540 370 560 - make_wire 370 200 370 180 - make_wire 600 180 600 200 - make_wire 490 180 370 180 - make_wire 490 180 600 180 - make_wire 490 170 490 180 - make_wire 430 300 600 300 - make_wire 430 300 430 500 - make_wire 430 300 430 240 - make_wire 600 300 600 280 - make_wire 540 430 370 430 - make_wire 540 430 540 500 - make_wire 540 430 540 240 - make_wire 370 430 370 460 - make_wire 480 560 600 560 - make_wire 480 560 370 560 - make_wire 480 560 480 570 - make_wire 480 650 480 660 - make_wire 420 610 180 610 - make_wire 650 90 320 90 - make_wire 600 360 710 360 - make_wire 710 360 710 130 - make_wire 600 360 600 300 - make_wire 600 360 600 460 - make_wire 370 370 260 370 - make_wire 260 370 260 130 - make_wire 370 370 370 430 - make_wire 370 370 370 280 - make_wire 260 10 260 50 - make_wire 710 20 710 50 - make_wire 320 90 180 90 - make_wire 180 90 180 610 - make_wire 110 370 260 370 -} - diff --git a/technology/scn4m_subm/sue_lib/tri_gate.sue b/technology/scn4m_subm/sue_lib/tri_gate.sue deleted file mode 100644 index d296171f..00000000 --- a/technology/scn4m_subm/sue_lib/tri_gate.sue +++ /dev/null @@ -1,37 +0,0 @@ -# SUE version MMI_SUE5.0.7 - -proc SCHEMATIC_tri_gate {} { - make global -orient RXY -name vdd -origin {630 150} - make global -name gnd -origin {630 570} - make input -name tri_in -origin {320 340} - make output -name tri_out -origin {690 360} - make input -name en -origin {570 410} - make input -name en_bar -origin {570 310} - make nmos -W 1.2u -L 0.6u -origin {630 490} - make nmos -W 1.2u -L 0.6u -origin {630 410} - make pmos -orient RY -W 2.4u -L 0.6u -origin {630 310} - make pmos -orient RY -W 2.4u -L 0.6u -origin {630 230} - make pmos -orient RY -W 2.4u -L 0.6u -origin {380 290} - make nmos -W 1.2u -L 0.6u -origin {380 400} - make_wire 570 490 470 490 - make_wire 470 230 570 230 - make_wire 630 550 380 550 - make_wire 380 550 380 440 - make_wire 630 550 630 570 - make_wire 630 550 630 530 - make_wire 630 170 380 170 - make_wire 380 170 380 250 - make_wire 630 170 630 190 - make_wire 630 170 630 150 - make_wire 320 340 320 400 - make_wire 320 340 320 290 - make_wire 380 340 470 340 - make_wire 380 340 380 330 - make_wire 380 340 380 360 - make_wire 470 340 470 490 - make_wire 470 340 470 230 - make_wire 630 360 630 350 - make_wire 630 360 630 370 - make_wire 630 360 690 360 -} - diff --git a/technology/scn4m_subm/sue_lib/write_driver.sue b/technology/scn4m_subm/sue_lib/write_driver.sue deleted file mode 100644 index de3909a7..00000000 --- a/technology/scn4m_subm/sue_lib/write_driver.sue +++ /dev/null @@ -1,44 +0,0 @@ -# SUE version MMI_SUE5.0.7 - -proc SCHEMATIC_write_driver {} { - make inout -name BL -origin {550 260} - make inout -name BR -origin {830 250} - make inverter -WP 2.1u -LP 0.6u -WN 1.2u -LN 0.6u -origin {280 520} - make nand2 -WP 2.1u -WN 2.1u -origin {90 360} - make inverter -WP 2.1u -LP 0.6u -WN 1.2u -LN 0.6u -origin {270 360} - make nmos -W 3.6u -L 0.6u -origin {830 410} - make nmos -W 3.6u -L 0.6u -origin {710 610} - make global -name gnd -origin {710 690} - make nand2 -WP 2.1u -WN 2.1u -origin {90 520} - make nmos -W 3.6u -L 0.6u -origin {550 410} - make input -name wen -origin {-290 340} - make input -name din -origin {-290 380} - make inverter -WP 2.1u -LP 0.6u -WN 1.2u -LN 0.6u -origin {-80 540} - make_wire 160 360 240 360 - make_wire 830 250 830 370 - make_wire 550 260 550 370 - make_wire 550 450 550 560 - make_wire 550 560 710 560 - make_wire 710 560 710 570 - make_wire 710 560 830 560 - make_wire 830 560 830 450 - make_wire 710 650 710 690 - make_wire 250 520 160 520 - make_wire 770 410 770 520 - make_wire 770 520 330 520 - make_wire 320 360 490 360 - make_wire 490 360 490 410 - make_wire -180 380 -290 380 - make_wire -180 380 70 380 - make_wire -180 540 -110 540 - make_wire -180 380 -180 540 - make_wire -30 540 70 540 - make_wire 20 340 20 500 - make_wire 20 500 70 500 - make_wire 20 340 70 340 - make_wire -240 340 -240 610 - make_wire -240 610 650 610 - make_wire -240 340 20 340 - make_wire -240 340 -290 340 -} - diff --git a/technology/scn4m_subm/tech/tech.py b/technology/scn4m_subm/tech/tech.py index c7b50272..6591fbbc 100644 --- a/technology/scn4m_subm/tech/tech.py +++ b/technology/scn4m_subm/tech/tech.py @@ -30,8 +30,6 @@ tech_modules = module_type() # Custom cell properties ################################################### cell_properties = cell_properties() -cell_properties.bitcell.mirror.x = True -cell_properties.bitcell.mirror.y = False ################################################### # Custom cell properties @@ -385,22 +383,23 @@ spice["bitcell_leakage"] = 1 # Leakage power of a single bitcell in nW spice["inv_leakage"] = 1 # Leakage power of inverter in nW spice["nand2_leakage"] = 1 # Leakage power of 2-input nand in nW spice["nand3_leakage"] = 1 # Leakage power of 3-input nand in nW +spice["nand4_leakage"] = 1 # Leakage power of 4-input nand in nW spice["nor2_leakage"] = 1 # Leakage power of 2-input nor in nW spice["dff_leakage"] = 1 # Leakage power of flop in nW spice["default_event_frequency"] = 100 # Default event activity of every gate. MHz -#Logical Effort relative values for the Handmade cells -parameter["le_tau"] = 18.17 #In pico-seconds. -parameter["min_inv_para_delay"] = 2.07 #In relative delay units -parameter["cap_relative_per_ff"] = .91 #Units of Relative Capacitance/ Femto-Farad -parameter["dff_clk_cin"] = 27.5 #In relative capacitance units -parameter["6tcell_wl_cin"] = 2 #In relative capacitance units -parameter["sa_en_pmos_size"] = 24*_lambda_ -parameter["sa_en_nmos_size"] = 9*_lambda_ -parameter["sa_inv_pmos_size"] = 18*_lambda_ -parameter["sa_inv_nmos_size"] = 9*_lambda_ -parameter["bitcell_drain_cap"] = 0.2 #In Femto-Farad, approximation of drain capacitance +# Logical Effort relative values for the Handmade cells +parameter["le_tau"] = 18.17 # In pico-seconds. +parameter["min_inv_para_delay"] = 2.07 # In relative delay units +parameter["cap_relative_per_ff"] = .91 # Units of Relative Capacitance/ Femto-Farad +parameter["dff_clk_cin"] = 27.5 # In relative capacitance units +parameter["6tcell_wl_cin"] = 2 # In relative capacitance units +parameter["sa_en_pmos_size"] = 24 * _lambda_ +parameter["sa_en_nmos_size"] = 9 * _lambda_ +parameter["sa_inv_pmos_size"] = 18 * _lambda_ +parameter["sa_inv_nmos_size"] = 9 * _lambda_ +parameter["bitcell_drain_cap"] = 0.2 # In Femto-Farad, approximation of drain capacitance ################################################### # Technology Tool Preferences