diff --git a/compiler/characterizer/stimuli.py b/compiler/characterizer/stimuli.py index 58a9e3ed..fc2a106f 100644 --- a/compiler/characterizer/stimuli.py +++ b/compiler/characterizer/stimuli.py @@ -34,6 +34,10 @@ class stimuli(): self.sf = stim_file (self.process, self.voltage, self.temperature) = corner + try: + self.device_libraries = tech.spice["fet_libraries"][self.process] + except: + debug.info(2, "Not using spice library") self.device_models = tech.spice["fet_models"][self.process] self.sram_name = "Xsram" @@ -247,8 +251,15 @@ class stimuli(): def write_include(self, circuit): """Writes include statements, inputs are lists of model files""" + libraries = self.device_libraries includes = self.device_models + [circuit] self.sf.write("* {} process corner\n".format(self.process)) + for item in list(libraries): + if os.path.isfile(item[0]): + self.sf.write(".lib \"{0}\" {1}\n".format(item[0], item[1])) + else: + debug.error("Could not find spice library: {0}\nSet SPICE_MODEL_DIR to over-ride path.\n".format(item[0])) + for item in list(includes): if os.path.isfile(item): self.sf.write(".include \"{0}\"\n".format(item)) diff --git a/compiler/pgates/pgate.py b/compiler/pgates/pgate.py index d83825ea..ba5fef75 100644 --- a/compiler/pgates/pgate.py +++ b/compiler/pgates/pgate.py @@ -8,10 +8,14 @@ import contact import design import debug -from tech import layer +import math +from bisect import bisect_left +from tech import layer, drc from vector import vector from globals import OPTS +if(OPTS.tech_name == "s8"): + from tech import nmos_bins, pmos_bins class pgate(design.design): """ @@ -282,5 +286,48 @@ class pgate(design.design): self.width = max(self.nwell_contact.rx(), self.pwell_contact.rx()) + self.m1_space + 0.5 * contact.m1_via.width self.well_width = self.width + 2 * self.nwell_enclose_active # Height is an input parameter, so it is not recomputed. + + def bin_width(self, tx_type, target_width): + + if tx_type == "nmos": + bins = nmos_bins[drc("minwidth_poly")] + elif tx_type == "pmos": + bins = pmos_bins[drc("minwidth_poly")] + else: + debug.error("invalid tx type") + + + bins = bins[0:bisect_left(bins, target_width) + 1] + if len(bins) == 1: + selected_bin = bins[0] + scaling_factor = 1 + scaled_bin = bins[0] + + else: + scaled_bins = [] + scaling_factors = [] + for width in bins[0:-1]: + m = math.ceil(target_width / width) + scaling_factors.append(m) + scaled_bins.append(m * width) + + scaled_bins.append(bins[-1]) + scaling_factors.append(1) + select = bisect_left(scaled_bins, target_width) + + selected_bin = bins[select] + scaling_factor = scaling_factors[select] + scaled_bin = scaled_bins[select] + + debug.info(2, "binning {0} tx, target: {4}, found {1} x {2} = {3}".format(tx_type, selected_bin, scaling_factor, scaled_bin, target_width)) + + return(selected_bin, scaling_factor) + + + + + + + diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index 3c2e41a2..1ccad6ca 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -81,6 +81,9 @@ class pinv(pgate.pgate): self.tx_mults = 1 self.nmos_width = self.nmos_size * drc("minwidth_tx") self.pmos_width = self.pmos_size * drc("minwidth_tx") + if OPTS.tech_name == "s8": + (self.nmos_width, self.tx_mults) = self.bin_width("nmos", self.nmos_width) + (self.pmos_width, self.tx_mults) = self.bin_width("pmos", self.pmos_width) return # Do a quick sanity check and bail if unlikely feasible height diff --git a/compiler/pgates/precharge.py b/compiler/pgates/precharge.py index afe14a05..45128421 100644 --- a/compiler/pgates/precharge.py +++ b/compiler/pgates/precharge.py @@ -8,6 +8,7 @@ import contact import design import debug +from pgate import pgate from tech import parameter from vector import vector from globals import OPTS @@ -28,6 +29,7 @@ class precharge(design.design): self.bitcell = factory.create(module_type="bitcell") self.beta = parameter["beta"] self.ptx_width = self.beta * parameter["min_tx_size"] + self.ptx_mults = 1 self.width = self.bitcell.width self.bitcell_bl = bitcell_bl self.bitcell_br = bitcell_br @@ -77,8 +79,11 @@ class precharge(design.design): """ Initializes the upper and lower pmos """ + if(OPTS.tech_name == "s8"): + (self.ptx_width, self.ptx_mults) = pgate.bin_width(self, "pmos", self.ptx_width) self.pmos = factory.create(module_type="ptx", width=self.ptx_width, + mults=self.ptx_mults, tx_type="pmos") self.add_mod(self.pmos) diff --git a/compiler/pgates/ptx.py b/compiler/pgates/ptx.py index 357e1ce4..ffd61a48 100644 --- a/compiler/pgates/ptx.py +++ b/compiler/pgates/ptx.py @@ -107,7 +107,9 @@ class ptx(design.design): # be decided in the layout later. area_sd = 2.5 * self.poly_width * self.tx_width perimeter_sd = 2 * self.poly_width + 2 * self.tx_width - if OPTS.tech_name == "s8": + + + if OPTS.tech_name == None: print("here {0}".format(self.name)) # s8 technology is in microns main_str = "M{{0}} {{1}} {0} m={1} w={2} l={3} ".format(spice[self.tx_type],