diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 0e70db55..4648519a 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -10,6 +10,7 @@ import debug import design from math import log from math import sqrt +from math import ceil import math import contact from sram_factory import factory @@ -31,7 +32,7 @@ class hierarchical_decoder(design.design): self.cell_height = height self.rows = rows - self.num_inputs = int(math.log(self.rows, 2)) + self.num_inputs = math.ceil(math.log(self.rows, 2)) (self.no_of_pre2x4,self.no_of_pre3x8)=self.determine_predecodes(self.num_inputs) self.create_netlist() @@ -338,14 +339,15 @@ class hierarchical_decoder(design.design): for i in range(len(self.predec_groups[0])): for j in range(len(self.predec_groups[1])): row = len(self.predec_groups[0])*j + i - name = self.NAND_FORMAT.format(row) - self.nand_inst.append(self.add_inst(name=name, - mod=self.nand2)) - pins =["out_{0}".format(i), - "out_{0}".format(j + len(self.predec_groups[0])), - "Z_{0}".format(row), - "vdd", "gnd"] - self.connect_inst(pins) + if (row < self.rows): + name = self.NAND_FORMAT.format(row) + self.nand_inst.append(self.add_inst(name=name, + mod=self.nand2)) + pins =["out_{0}".format(i), + "out_{0}".format(j + len(self.predec_groups[0])), + "Z_{0}".format(row), + "vdd", "gnd"] + self.connect_inst(pins) # Row Decoder NAND GATE array for address inputs >5. @@ -356,16 +358,17 @@ class hierarchical_decoder(design.design): row = (len(self.predec_groups[0])*len(self.predec_groups[1])) * k \ + len(self.predec_groups[0])*j + i - name = self.NAND_FORMAT.format(row) - self.nand_inst.append(self.add_inst(name=name, - mod=self.nand3)) + if (row < self.rows): + name = self.NAND_FORMAT.format(row) + self.nand_inst.append(self.add_inst(name=name, + mod=self.nand3)) - pins = ["out_{0}".format(i), - "out_{0}".format(j + len(self.predec_groups[0])), - "out_{0}".format(k + len(self.predec_groups[0]) + len(self.predec_groups[1])), - "Z_{0}".format(row), - "vdd", "gnd"] - self.connect_inst(pins) + pins = ["out_{0}".format(i), + "out_{0}".format(j + len(self.predec_groups[0])), + "out_{0}".format(k + len(self.predec_groups[0]) + len(self.predec_groups[1])), + "Z_{0}".format(row), + "vdd", "gnd"] + self.connect_inst(pins) def create_decoder_inv_array(self): @@ -527,10 +530,11 @@ class hierarchical_decoder(design.design): for index_B in self.predec_groups[1]: for index_A in self.predec_groups[0]: # FIXME: convert to connect_bus? - predecode_name = "predecode_{}".format(index_A) - self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("A")) - predecode_name = "predecode_{}".format(index_B) - self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("B")) + if (row_index < self.rows): + predecode_name = "predecode_{}".format(index_A) + self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("A")) + predecode_name = "predecode_{}".format(index_B) + self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("B")) row_index = row_index + 1 elif (self.num_inputs > 5): @@ -538,12 +542,13 @@ class hierarchical_decoder(design.design): for index_B in self.predec_groups[1]: for index_A in self.predec_groups[0]: # FIXME: convert to connect_bus? - predecode_name = "predecode_{}".format(index_A) - self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("A")) - predecode_name = "predecode_{}".format(index_B) - self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("B")) - predecode_name = "predecode_{}".format(index_C) - self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("C")) + if (row_index < self.rows): + predecode_name = "predecode_{}".format(index_A) + self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("A")) + predecode_name = "predecode_{}".format(index_B) + self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("B")) + predecode_name = "predecode_{}".format(index_C) + self.route_predecode_rail(predecode_name, self.nand_inst[row_index].get_pin("C")) row_index = row_index + 1 def route_vdd_gnd(self): diff --git a/compiler/pgates/pwrite_driver.py b/compiler/pgates/pwrite_driver.py new file mode 100644 index 00000000..a808737b --- /dev/null +++ b/compiler/pgates/pwrite_driver.py @@ -0,0 +1,304 @@ +# See LICENSE for licensing information. +# +#Copyright (c) 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 design +from tech import drc, parameter, spice +import debug +import math +from tech import drc +from vector import vector +from globals import OPTS +from sram_factory import factory + +class pwrite_driver(design.design): + """ + The pwrite_driver is two tristate inverters that drive the bitlines. + The data input is first inverted before one tristate. + The inverted enable is also generated to control one tristate. + """ + def __init__(self, name, size=0): + debug.error("pwrite_driver not implemented yet.", -1) + debug.info(1, "creating pwrite_driver {}".format(name)) + design.design.__init__(self, name) + self.size = size + self.beta = parameter["beta"] + self.pmos_width = self.beta*self.size*parameter["min_tx_size"] + self.nmos_width = self.size*parameter["min_tx_size"] + + # The tech M2 pitch is based on old via orientations + self.m2_pitch = self.m2_space + self.m2_width + + # Width is matched to the bitcell, + # Height will be variable + self.bitcell = factory.create(module_type="bitcell") + self.width = self.bitcell.width + + # Creates the netlist and layout + # Since it has variable height, it is not a pgate. + self.create_netlist() + if not OPTS.netlist_only: + self.create_layout() + self.DRC_LVS() + + + + def create_netlist(self): + self.add_pins() + self.add_modules() + self.create_insts() + + def create_layout(self): + self.place_modules() + self.route_wires() + self.route_supplies() + + + + def add_pins(self): + self.add_pin("din", "INPUT") + self.add_pin("bl", "OUTPUT") + self.add_pin("br", "OUTPUT") + self.add_pin("en", "INPUT") + self.add_pin("vdd", "POWER") + self.add_pin("gnd", "GROUND") + + + def add_modules(self): + + # Tristate inverter + self.tri = factory.create(module_type="ptristate_inv", height="min") + self.add_mod(self.tri) + debug.check(self.tri.width