diff --git a/compiler/base/contact.py b/compiler/base/contact.py index db415179..f5cfcb0b 100644 --- a/compiler/base/contact.py +++ b/compiler/base/contact.py @@ -16,7 +16,9 @@ class contact(hierarchy_design.hierarchy_design): hierarchy as the contact. """ - def __init__(self, layer_stack, dimensions=[1,1], implant_type=None, well_type=None): + def __init__(self, layer_stack, dimensions=[1,1], implant_type=None, well_type=None, name=""): + # This will ignore the name parameter since we can guarantee a unique name here + if implant_type or well_type: name = "{0}_{1}_{2}_{3}x{4}_{5}{6}".format(layer_stack[0], layer_stack[1], @@ -164,13 +166,13 @@ class contact(hierarchy_design.hierarchy_design): """ Get total power of a module """ return self.return_power() - +from sram_factory import factory # This is not instantiated and used for calculations only. # These are static 1x1 contacts to reuse in all the design modules. -well = contact(layer_stack=("active", "contact", "metal1")) -active = contact(layer_stack=("active", "contact", "poly")) -poly = contact(layer_stack=("poly", "contact", "metal1")) -m1m2 = contact(layer_stack=("metal1", "via1", "metal2")) -m2m3 = contact(layer_stack=("metal2", "via2", "metal3")) -m3m4 = contact(layer_stack=("metal3", "via3", "metal4")) +well = factory.create(module_type="contact", layer_stack=("active", "contact", "metal1")) +active = factory.create(module_type="contact", layer_stack=("active", "contact", "poly")) +poly = factory.create(module_type="contact", layer_stack=("poly", "contact", "metal1")) +m1m2 = factory.create(module_type="contact", layer_stack=("metal1", "via1", "metal2")) +m2m3 = factory.create(module_type="contact", layer_stack=("metal2", "via2", "metal3")) +m3m4 = factory.create(module_type="contact", layer_stack=("metal3", "via3", "metal4")) diff --git a/compiler/base/design.py b/compiler/base/design.py index f52aa100..d07e392a 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -6,7 +6,6 @@ import debug import os from globals import OPTS - class design(hierarchy_design): """ This is the same as the hierarchy_design class except it contains diff --git a/compiler/base/hierarchy_design.py b/compiler/base/hierarchy_design.py index 6031fe2f..7f30fb1c 100644 --- a/compiler/base/hierarchy_design.py +++ b/compiler/base/hierarchy_design.py @@ -17,20 +17,14 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): name_map = [] def __init__(self, name): - try: - self.gds_file - except AttributeError: - self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds" - try: - self.sp_file - except AttributeError: - self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp" + self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds" + self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp" self.name = name hierarchy_layout.layout.__init__(self, name) hierarchy_spice.spice.__init__(self, name) - + # Check if the name already exists, if so, give an error # because each reference must be a unique name. # These modules ensure unique names or have no changes if they diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index c35f0709..60a596bb 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -378,11 +378,12 @@ class layout(): def add_via(self, layers, offset, size=[1,1], mirror="R0", rotate=0, implant_type=None, well_type=None): """ Add a three layer via structure. """ - import contact - via = contact.contact(layer_stack=layers, - dimensions=size, - implant_type=implant_type, - well_type=well_type) + from sram_factory import factory + via = factory.create(module_type="contact", + layer_stack=layers, + dimensions=size, + implant_type=implant_type, + well_type=well_type) self.add_mod(via) inst=self.add_inst(name=via.name, mod=via, @@ -395,11 +396,12 @@ class layout(): def add_via_center(self, layers, offset, size=[1,1], mirror="R0", rotate=0, implant_type=None, well_type=None): """ Add a three layer via structure by the center coordinate accounting for mirroring and rotation. """ - import contact - via = contact.contact(layer_stack=layers, - dimensions=size, - implant_type=implant_type, - well_type=well_type) + from sram_factory import factory + via = factory.create(module_type="contact", + layer_stack=layers, + dimensions=size, + implant_type=implant_type, + well_type=well_type) height = via.height width = via.width debug.check(mirror=="R0","Use rotate to rotate vias instead of mirror.") @@ -1039,9 +1041,11 @@ class layout(): # Find the number of vias for this pitch self.supply_vias = 1 - import contact + from sram_factory import factory while True: - c=contact.contact(("metal1","via1","metal2"), (self.supply_vias, self.supply_vias)) + c=factory.create(module_type="contact", + layer_stack=("metal1","via1","metal2"), + dimensions=(self.supply_vias, self.supply_vias)) if c.second_layer_width < self.supply_rail_width and c.second_layer_height < self.supply_rail_width: self.supply_vias += 1 else: diff --git a/compiler/base/hierarchy_spice.py b/compiler/base/hierarchy_spice.py index 3fda8598..038cf0b7 100644 --- a/compiler/base/hierarchy_spice.py +++ b/compiler/base/hierarchy_spice.py @@ -16,11 +16,14 @@ class spice(): def __init__(self, name): self.name = name - self.mods = [] # Holds subckts/mods for this module - self.pins = [] # Holds the pins for this module - self.pin_type = {} # The type map of each pin: INPUT, OUTPUT, INOUT, POWER, GROUND + # Holds subckts/mods for this module + self.mods = [] + # Holds the pins for this module + 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 - # THIS MUST MATCH THE ORDER OF THE PINS (restriction imposed by the + self.pin_type = {} + # THE CONNECTIONS MUST MATCH THE ORDER OF THE PINS (restriction imposed by the # Spice format) self.conns = [] @@ -93,8 +96,8 @@ class spice(): from pprint import pformat modpins_string=pformat(self.insts[-1].mod.pins) argpins_string=pformat(args) - debug.error("Connections: {}".format(modpins_string)) - debug.error("Connections: {}".format(argpins_string)) + debug.error("Mod connections: {}".format(modpins_string)) + debug.error("Inst connections: {}".format(argpins_string)) debug.error("Number of net connections ({0}) does not match last instance ({1})".format(len(self.insts[-1].mod.pins), len(args)), 1) self.conns.append(args) diff --git a/compiler/base/route.py b/compiler/base/route.py index 09925e07..c6ce906b 100644 --- a/compiler/base/route.py +++ b/compiler/base/route.py @@ -1,10 +1,10 @@ from tech import drc import debug from design import design -from contact import contact from itertools import tee from vector import vector from vector3d import vector3d +from sram_factory import factory class route(design): """ @@ -45,7 +45,9 @@ class route(design): self.horiz_layer_width = drc("minwidth_{0}".format(self.horiz_layer_name)) # offset this by 1/2 the via size - self.c=contact(self.layer_stack, (self.num_vias, self.num_vias)) + self.c=factory.create(module_type="contact", + layer_stack=self.layer_stack, + dimensions=(self.num_vias, self.num_vias)) def create_wires(self): diff --git a/compiler/base/wire.py b/compiler/base/wire.py index 1565d10e..8500e502 100644 --- a/compiler/base/wire.py +++ b/compiler/base/wire.py @@ -1,7 +1,7 @@ from tech import drc import debug -from contact import contact from path import path +from sram_factory import factory class wire(path): """ @@ -37,15 +37,18 @@ class wire(path): self.horiz_layer_name = horiz_layer self.horiz_layer_width = drc("minwidth_{0}".format(horiz_layer)) - via_connect = contact(self.layer_stack, - (1, 1)) + via_connect = factory.create(module_type="contact", + layer_stack=self.layer_stack, + dimensions=(1, 1)) self.node_to_node = [drc("minwidth_" + str(self.horiz_layer_name)) + via_connect.width, drc("minwidth_" + str(self.horiz_layer_name)) + via_connect.height] # create a 1x1 contact def create_vias(self): """ Add a via and corner square at every corner of the path.""" - self.c=contact(self.layer_stack, (1, 1)) + self.c=factory.create(module_type="contact", + layer_stack=self.layer_stack, + dimensions=(1, 1)) c_width = self.c.width c_height = self.c.height diff --git a/compiler/bitcells/bitcell.py b/compiler/bitcells/bitcell.py index 0ac1c207..3c49a959 100644 --- a/compiler/bitcells/bitcell.py +++ b/compiler/bitcells/bitcell.py @@ -15,14 +15,15 @@ class bitcell(design.design): (width,height) = utils.get_libcell_size("cell_6t", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "cell_6t", GDS["unit"]) - def __init__(self): + def __init__(self, name=""): + # Ignore the name argument design.design.__init__(self, "cell_6t") debug.info(2, "Create bitcell") self.width = bitcell.width self.height = bitcell.height self.pin_map = bitcell.pin_map - + def analytical_delay(self, slew, load=0, swing = 0.5): # delay of bit cell is not like a driver(from WL) # so the slew used should be 0 diff --git a/compiler/bitcells/bitcell_1rw_1r.py b/compiler/bitcells/bitcell_1rw_1r.py index 2d740d2b..79dc734c 100644 --- a/compiler/bitcells/bitcell_1rw_1r.py +++ b/compiler/bitcells/bitcell_1rw_1r.py @@ -15,7 +15,8 @@ class bitcell_1rw_1r(design.design): (width,height) = utils.get_libcell_size("cell_1rw_1r", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "cell_1rw_1r", GDS["unit"]) - def __init__(self): + def __init__(self, name=""): + # Ignore the name argument design.design.__init__(self, "cell_1rw_1r") debug.info(2, "Create bitcell with 1RW and 1R Port") @@ -102,4 +103,4 @@ class bitcell_1rw_1r(design.design): #Calculated in the tech file by summing the widths of all the related gates and dividing by the minimum width. #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 \ No newline at end of file + return 2*access_tx_cin diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py index 52156b39..b241471d 100644 --- a/compiler/bitcells/pbitcell.py +++ b/compiler/bitcells/pbitcell.py @@ -12,8 +12,7 @@ class pbitcell(design.design): with a variable number of read/write, write, and read ports """ - def __init__(self, replica_bitcell=False): - + def __init__(self, name, replica_bitcell=False): self.num_rw_ports = OPTS.num_rw_ports self.num_w_ports = OPTS.num_w_ports self.num_r_ports = OPTS.num_r_ports @@ -21,11 +20,6 @@ class pbitcell(design.design): self.replica_bitcell = replica_bitcell - if self.replica_bitcell: - name = "replica_pbitcell_{0}RW_{1}W_{2}R".format(self.num_rw_ports, self.num_w_ports, self.num_r_ports) - else: - name = "pbitcell_{0}RW_{1}W_{2}R".format(self.num_rw_ports, self.num_w_ports, self.num_r_ports) - design.design.__init__(self, name) debug.info(2, "create a multi-port bitcell with {0} rw ports, {1} w ports and {2} r ports".format(self.num_rw_ports, self.num_w_ports, diff --git a/compiler/bitcells/replica_bitcell.py b/compiler/bitcells/replica_bitcell.py index d896e29e..d8b8b76e 100644 --- a/compiler/bitcells/replica_bitcell.py +++ b/compiler/bitcells/replica_bitcell.py @@ -14,7 +14,8 @@ class replica_bitcell(design.design): (width,height) = utils.get_libcell_size("replica_cell_6t", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "replica_cell_6t", GDS["unit"]) - def __init__(self): + def __init__(self, name=""): + # Ignore the name argument design.design.__init__(self, "replica_cell_6t") debug.info(2, "Create replica bitcell object") @@ -27,4 +28,4 @@ class replica_bitcell(design.design): #This is a handmade cell so the value must be entered in the tech.py file or estimated. #Calculated in the tech file by summing the widths of all the related gates and dividing by the minimum width. access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"] - return 2*access_tx_cin \ No newline at end of file + return 2*access_tx_cin diff --git a/compiler/bitcells/replica_bitcell_1rw_1r.py b/compiler/bitcells/replica_bitcell_1rw_1r.py index f5151958..8f7b3b38 100644 --- a/compiler/bitcells/replica_bitcell_1rw_1r.py +++ b/compiler/bitcells/replica_bitcell_1rw_1r.py @@ -14,7 +14,8 @@ class replica_bitcell_1rw_1r(design.design): (width,height) = utils.get_libcell_size("replica_cell_1rw_1r", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "replica_cell_1rw_1r", GDS["unit"]) - def __init__(self): + def __init__(self, name=""): + # Ignore the name argument design.design.__init__(self, "replica_cell_1rw_1r") debug.info(2, "Create replica bitcell 1rw+1r object") @@ -28,4 +29,4 @@ class replica_bitcell_1rw_1r(design.design): #Calculated in the tech file by summing the widths of all the related gates and dividing by the minimum width. #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 \ No newline at end of file + return 2*access_tx_cin diff --git a/compiler/bitcells/replica_pbitcell.py b/compiler/bitcells/replica_pbitcell.py index 666d3646..4d2ecd70 100644 --- a/compiler/bitcells/replica_pbitcell.py +++ b/compiler/bitcells/replica_pbitcell.py @@ -3,21 +3,20 @@ import design from tech import drc, spice,parameter from vector import vector from globals import OPTS -from pbitcell import pbitcell +from sram_factory import factory class replica_pbitcell(design.design): """ Creates a replica bitcell using pbitcell """ - def __init__(self): - + def __init__(self, name): self.num_rw_ports = OPTS.num_rw_ports self.num_w_ports = OPTS.num_w_ports self.num_r_ports = OPTS.num_r_ports self.total_ports = self.num_rw_ports + self.num_w_ports + self.num_r_ports - design.design.__init__(self, "replica_pbitcell") + design.design.__init__(self, name) debug.info(1, "create a replica bitcell using pbitcell with {0} rw ports, {1} w ports and {2} r ports".format(self.num_rw_ports, self.num_w_ports, self.num_r_ports)) @@ -47,7 +46,7 @@ class replica_pbitcell(design.design): self.add_pin("gnd") def add_modules(self): - self.prbc = pbitcell(replica_bitcell=True) + self.prbc = factory.create(module_type="pbitcell",replica_bitcell=True) self.add_mod(self.prbc) self.height = self.prbc.height @@ -83,4 +82,4 @@ class replica_pbitcell(design.design): def get_wl_cin(self): """Return the relative capacitance of the access transistor gates""" #This module is made using a pbitcell. Get the cin from that module - return self.prbc.get_wl_cin() \ No newline at end of file + return self.prbc.get_wl_cin() diff --git a/compiler/gdsMill/gdsMill/vlsiLayout.py b/compiler/gdsMill/gdsMill/vlsiLayout.py index 42921812..8d4816f6 100644 --- a/compiler/gdsMill/gdsMill/vlsiLayout.py +++ b/compiler/gdsMill/gdsMill/vlsiLayout.py @@ -1,7 +1,8 @@ from .gdsPrimitives import * from datetime import * #from mpmath import matrix -from numpy import matrix +#from numpy import matrix +import numpy as np #import gdsPrimitives import debug @@ -170,21 +171,20 @@ class VlsiLayout: else: # MRG: Added negative to make CCW rotate 8/29/18 angle = math.radians(float(rotateAngle)) - mRotate = matrix([[math.cos(angle),-math.sin(angle),0.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 the translation matrix translateX = float(coordinates[0]) translateY = float(coordinates[1]) - mTranslate = matrix([[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 if(transFlags[0]): scaleY = -1.0 else: scaleY = 1.0 - mScale = matrix([[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]]) #we need to keep track of all transforms in the hierarchy #when we add an element to the xy tree, we apply all transforms from the bottom up transformPath.append((mRotate,mScale,mTranslate)) @@ -219,27 +219,26 @@ class VlsiLayout: def populateCoordinateMap(self): def addToXyTree(startingStructureName = None,transformPath = None): - #print("populateCoordinateMap") - uVector = matrix([1.0,0.0,0.0]).transpose() #start with normal basis vectors - vVector = matrix([0.0,1.0,0.0]).transpose() - origin = matrix([0.0,0.0,1.0]).transpose() #and an origin (Z component is 1.0 to indicate position instead of vector) + uVector = np.array([[1.0],[0.0],[0.0]]) #start with normal basis vectors + vVector = np.array([[0.0],[1.0],[0.0]]) + origin = np.array([[0.0],[0.0],[1.0]]) #and an origin (Z component is 1.0 to indicate position instead of vector) #make a copy of all the transforms and reverse it reverseTransformPath = transformPath[:] if len(reverseTransformPath) > 1: - reverseTransformPath.reverse() + reverseTransformPath.reverse() #now go through each transform and apply them to our basis and origin in succession for transform in reverseTransformPath: - origin = transform[0] * origin #rotate - uVector = transform[0] * uVector #rotate - vVector = transform[0] * vVector #rotate - origin = transform[1] * origin #scale - uVector = transform[1] * uVector #scale - vVector = transform[1] * vVector #scale - origin = transform[2] * origin #translate + origin = np.dot(transform[0], origin) #rotate + uVector = np.dot(transform[0], uVector) #rotate + vVector = np.dot(transform[0], vVector) #rotate + origin = np.dot(transform[1], origin) #scale + uVector = np.dot(transform[1], uVector) #scale + vVector = np.dot(transform[1], vVector) #scale + origin = np.dot(transform[2], origin) #translate #we don't need to do a translation on the basis vectors #uVector = transform[2] * uVector #translate #vVector = transform[2] * vVector #translate - #populate the xyTree with each structureName and coordinate space + #populate the xyTree with each structureName and coordinate space self.xyTree.append((startingStructureName,origin,uVector,vVector)) self.traverseTheHierarchy(delegateFunction = addToXyTree) @@ -522,8 +521,7 @@ class VlsiLayout: return True - def fillAreaDensity(self, layerToFill = 0, offsetInMicrons = (0,0), coverageWidth = 100.0, coverageHeight = 100.0, - minSpacing = 0.22, blockSize = 1.0): + def fillAreaDensity(self, layerToFill = 0, offsetInMicrons = (0,0), coverageWidth = 100.0, coverageHeight = 100.0, minSpacing = 0.22, blockSize = 1.0): effectiveBlock = blockSize+minSpacing widthInBlocks = int(coverageWidth/effectiveBlock) heightInBlocks = int(coverageHeight/effectiveBlock) @@ -810,8 +808,8 @@ class VlsiLayout: # This is fixed to be: # |u[0] v[0]| |x| |x'| # |u[1] v[1]|x|y|=|y'| - x=coordinate[0]*uVector[0].item()+coordinate[1]*vVector[0].item() - y=coordinate[0]*uVector[1].item()+coordinate[1]*vVector[1].item() + x=coordinate[0]*uVector[0][0]+coordinate[1]*vVector[0][0] + y=coordinate[0]*uVector[1][0]+coordinate[1]*vVector[1][0] transformCoordinate=[x,y] return transformCoordinate @@ -836,5 +834,3 @@ def boundaryArea(A): area_A=(A[2]-A[0])*(A[3]-A[1]) return area_A - - diff --git a/compiler/globals.py b/compiler/globals.py index f5c36551..f162edda 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -130,6 +130,9 @@ def init_openram(config_file, is_unit_test=True): init_paths() + from sram_factory import factory + factory.reset() + # Reset the static duplicate name checker for unit tests. import hierarchy_design hierarchy_design.hierarchy_design.name_map=[] diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index a0508b51..77cde2cb 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -6,9 +6,7 @@ import math from math import log,sqrt,ceil import contact import pgates -from pinv import pinv -from pnand2 import pnand2 -from pnor2 import pnor2 +from sram_factory import factory from vector import vector from globals import OPTS @@ -396,25 +394,14 @@ class bank(design.design): def add_modules(self): """ Add all the modules using the class loader """ - mod_list = ["bitcell", "decoder", "wordline_driver", - "bitcell_array", "sense_amp_array", "precharge_array", - "column_mux_array", "write_driver_array", - "dff", "bank_select"] - from importlib import reload - for mod_name in mod_list: - config_mod_name = getattr(OPTS, mod_name) - class_file = reload(__import__(config_mod_name)) - mod_class = getattr(class_file , config_mod_name) - setattr (self, "mod_"+mod_name, mod_class) - - - self.bitcell_array = self.mod_bitcell_array(cols=self.num_cols, - rows=self.num_rows) + self.bitcell_array = factory.create(module_type="bitcell_array", + cols=self.num_cols, + rows=self.num_rows) self.add_mod(self.bitcell_array) # create arrays of bitline and bitline_bar names for read, write, or all ports - self.bitcell = self.mod_bitcell() + self.bitcell = factory.create(module_type="bitcell") self.bl_names = self.bitcell.list_all_bl_names() self.br_names = self.bitcell.list_all_br_names() self.wl_names = self.bitcell.list_all_wl_names() @@ -423,7 +410,11 @@ class bank(design.design): self.precharge_array = [] for port in self.all_ports: if port in self.read_ports: - self.precharge_array.append(self.mod_precharge_array(columns=self.num_cols, bitcell_bl=self.bl_names[port], bitcell_br=self.br_names[port])) + temp_pre = factory.create(module_type="precharge_array", + columns=self.num_cols, + bitcell_bl=self.bl_names[port], + bitcell_br=self.br_names[port]) + self.precharge_array.append(temp_pre) self.add_mod(self.precharge_array[port]) else: self.precharge_array.append(None) @@ -431,32 +422,38 @@ class bank(design.design): if self.col_addr_size > 0: self.column_mux_array = [] for port in self.all_ports: - self.column_mux_array.append(self.mod_column_mux_array(columns=self.num_cols, - word_size=self.word_size, - bitcell_bl=self.bl_names[port], - bitcell_br=self.br_names[port])) + temp_col = factory.create(module_type="column_mux_array", + columns=self.num_cols, + word_size=self.word_size, + bitcell_bl=self.bl_names[port], + bitcell_br=self.br_names[port]) + self.column_mux_array.append(temp_col) self.add_mod(self.column_mux_array[port]) - self.sense_amp_array = self.mod_sense_amp_array(word_size=self.word_size, - words_per_row=self.words_per_row) + self.sense_amp_array = factory.create(module_type="sense_amp_array", + word_size=self.word_size, + words_per_row=self.words_per_row) self.add_mod(self.sense_amp_array) - self.write_driver_array = self.mod_write_driver_array(columns=self.num_cols, - word_size=self.word_size) + self.write_driver_array = factory.create(module_type="write_driver_array", + columns=self.num_cols, + word_size=self.word_size) self.add_mod(self.write_driver_array) - self.row_decoder = self.mod_decoder(rows=self.num_rows) + self.row_decoder = factory.create(module_type="decoder", + rows=self.num_rows) self.add_mod(self.row_decoder) - self.wordline_driver = self.mod_wordline_driver(rows=self.num_rows) + self.wordline_driver = factory.create(module_type="wordline_driver", + rows=self.num_rows) self.add_mod(self.wordline_driver) - self.inv = pinv() + self.inv = factory.create(module_type="pinv") self.add_mod(self.inv) if(self.num_banks > 1): - self.bank_select = self.mod_bank_select() + self.bank_select = factory.create(module_type="bank_select") self.add_mod(self.bank_select) @@ -693,18 +690,17 @@ class bank(design.design): """ Create a 2:4 or 3:8 column address decoder. """ + + dff = factory.create(module_type="dff") if self.col_addr_size == 0: return elif self.col_addr_size == 1: - from pinvbuf import pinvbuf - self.column_decoder = pinvbuf(height=self.mod_dff.height) + self.column_decoder = factory.create(module_type="pinvbuf", height=dff.height) elif self.col_addr_size == 2: - from hierarchical_predecode2x4 import hierarchical_predecode2x4 as pre2x4 - self.column_decoder = pre2x4(height=self.mod_dff.height) + self.column_decoder = factory.create(module_type="hierarchical_predecode2x4", height=dff.height) elif self.col_addr_size == 3: - from hierarchical_predecode3x8 import hierarchical_predecode3x8 as pre3x8 - self.column_decoder = pre3x8(height=self.mod_dff.height) + self.column_decoder = factory.create(module_type="hierarchical_predecode3x8", height=dff.height) else: # No error checking before? debug.error("Invalid column decoder?",-1) @@ -1273,4 +1269,4 @@ class bank(design.design): """Get the relative capacitance of all the sense amp enable connections in the bank""" #Current bank only uses sen as an enable for the sense amps. total_sen_cin = self.sense_amp_array.get_en_cin() - return total_sen_cin \ No newline at end of file + return total_sen_cin diff --git a/compiler/modules/bank_select.py b/compiler/modules/bank_select.py index 7141de2a..8e44dfa2 100644 --- a/compiler/modules/bank_select.py +++ b/compiler/modules/bank_select.py @@ -7,6 +7,7 @@ from pinv import pinv from pnand2 import pnand2 from pnor2 import pnor2 from vector import vector +from sram_factory import factory from globals import OPTS class bank_select(design.design): @@ -62,28 +63,25 @@ class bank_select(design.design): def add_modules(self): """ Create modules for later instantiation """ - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell = self.mod_bitcell() + self.bitcell = factory.create(module_type="bitcell") height = self.bitcell.height + drc("poly_to_active") # 1x Inverter - self.inv_sel = pinv(height=height) + self.inv_sel = factory.create(module_type="pinv", height=height) self.add_mod(self.inv_sel) # 4x Inverter - self.inv = self.inv4x = pinv(4) + self.inv4x = factory.create(module_type="pinv", height=height, size=4) self.add_mod(self.inv4x) - self.nor2 = pnor2(height=height) + self.nor2 = factory.create(module_type="pnor2", height=height) self.add_mod(self.nor2) - self.inv4x_nor = pinv(size=4, height=height) + self.inv4x_nor = factory.create(module_type="pinv", height=height, size=4) self.add_mod(self.inv4x_nor) - self.nand2 = pnand2() + self.nand2 = factory.create(module_type="pnand2") self.add_mod(self.nand2) def calculate_module_offsets(self): @@ -94,7 +92,7 @@ class bank_select(design.design): self.xoffset_bank_sel_inv = 0 self.xoffset_inputs = 0 - self.yoffset_maxpoint = self.num_control_lines * self.inv.height + self.yoffset_maxpoint = self.num_control_lines * self.inv4x.height # Include the M1 pitches for the supply rails and spacing self.height = self.yoffset_maxpoint + 2*self.m1_pitch self.width = self.xoffset_inv + self.inv4x.width @@ -170,10 +168,10 @@ class bank_select(design.design): if i == 0: y_offset = 0 else: - y_offset = self.inv4x_nor.height + self.inv.height * (i-1) + y_offset = self.inv4x_nor.height + self.inv4x.height * (i-1) if i%2: - y_offset += self.inv.height + y_offset += self.inv4x.height mirror = "MX" else: mirror = "" @@ -223,7 +221,7 @@ class bank_select(design.design): self.add_label_pin(text="bank_sel_bar", layer="metal2", offset=vector(xoffset_bank_sel_bar, 0), - height=self.inv.height) + height=self.inv4x.height) self.add_via_center(layers=("metal1","via1","metal2"), offset=bank_sel_bar_pin.rc()) diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index 6032fc19..166437fa 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -3,8 +3,7 @@ import design from tech import drc, spice from vector import vector from globals import OPTS - -unique_id = 1 +from sram_factory import factory class bitcell_array(design.design): """ @@ -12,13 +11,7 @@ class bitcell_array(design.design): and word line is connected by abutment. Connects the word lines and bit lines. """ - unique_id = 1 - - def __init__(self, cols, rows, name=""): - - if name == "": - name = "bitcell_array_{0}x{1}_{2}".format(rows,cols,bitcell_array.unique_id) - bitcell_array.unique_id += 1 + def __init__(self, cols, rows, name): design.design.__init__(self, name) debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols)) @@ -83,11 +76,7 @@ class bitcell_array(design.design): def add_modules(self): """ Add the modules used in this design """ - - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.cell = self.mod_bitcell() + self.cell = factory.create(module_type="bitcell") self.add_mod(self.cell) def create_instances(self): @@ -210,4 +199,4 @@ class bitcell_array(design.design): #A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns bitcell_wl_cin = self.cell.get_wl_cin() total_cin = bitcell_wl_cin * self.column_size - return total_cin \ No newline at end of file + return total_cin diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index c30d91a0..52af5bbb 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -3,13 +3,7 @@ import design from tech import drc, parameter import debug import contact -from pinv import pinv -from pbuf import pbuf -from pand2 import pand2 -from pnand2 import pnand2 -from pinvbuf import pinvbuf -from dff_buf import dff_buf -from dff_buf_array import dff_buf_array +from sram_factory import factory import math from vector import vector from globals import OPTS @@ -73,46 +67,56 @@ class control_logic(design.design): def add_modules(self): """ Add all the required modules """ - dff = dff_buf() + dff = factory.create(module_type="dff_buf") dff_height = dff.height - self.ctrl_dff_array = dff_buf_array(rows=self.num_control_signals,columns=1) + self.ctrl_dff_array = factory.create(module_type="dff_buf_array", + rows=self.num_control_signals, + columns=1) + self.add_mod(self.ctrl_dff_array) - self.and2 = pand2(size=4,height=dff_height) + self.and2 = factory.create(module_type="pand2", + size=4, + height=dff_height) self.add_mod(self.and2) # Special gates: inverters for buffering # Size the clock for the number of rows (fanout) clock_driver_size = max(1,int(self.num_rows/4)) - self.clkbuf = pbuf(size=clock_driver_size, height=dff_height) + self.clkbuf = factory.create(module_type="pbuf", + size=clock_driver_size, + height=dff_height) + self.add_mod(self.clkbuf) - self.buf16 = pbuf(size=16, height=dff_height) + self.buf16 = factory.create(module_type="pbuf", + size=16, + height=dff_height) self.add_mod(self.buf16) - self.buf8 = pbuf(size=8, height=dff_height) + self.buf8 = factory.create(module_type="pbuf", + size=8, + height=dff_height) self.add_mod(self.buf8) - self.inv = self.inv1 = pinv(size=1, height=dff_height) + self.inv = self.inv1 = factory.create(module_type="pinv", + size=1, + height=dff_height) self.add_mod(self.inv1) - self.inv8 = pinv(size=8, height=dff_height) + self.inv8 = factory.create(module_type="pinv", + size=8, + height=dff_height) self.add_mod(self.inv8) - # self.inv2 = pinv(size=4, height=dff_height) - # self.add_mod(self.inv2) - #self.inv16 = pinv(size=16, height=dff_height) - #self.add_mod(self.inv16) - if (self.port_type == "rw") or (self.port_type == "r"): - from importlib import reload - c = reload(__import__(OPTS.replica_bitline)) - replica_bitline = getattr(c, OPTS.replica_bitline) - delay_stages_heuristic, delay_fanout_heuristic = self.get_heuristic_delay_chain_size() bitcell_loads = int(math.ceil(self.num_rows / 2.0)) - self.replica_bitline = replica_bitline([delay_fanout_heuristic]*delay_stages_heuristic, bitcell_loads, name="replica_bitline_"+self.port_type) + self.replica_bitline = factory.create(module_type="replica_bitline", + delay_fanout_list=[delay_fanout_heuristic]*delay_stages_heuristic, + bitcell_loads=bitcell_loads) + if self.sram != None: self.set_sen_wl_delays() @@ -124,8 +128,10 @@ class control_logic(design.design): #This resizes based on total delay. delay_stages, delay_fanout = self.get_dynamic_delay_chain_size(delay_stages_heuristic, delay_fanout_heuristic) - self.replica_bitline = replica_bitline([delay_fanout]*delay_stages, bitcell_loads, name="replica_bitline_resized_"+self.port_type) - + self.replica_bitline = factory.create(module_type="replica_bitline", + delay_fanout_list=[delay_fanout]*delay_stages, + bitcell_loads=bitcell_loads) + self.sen_delay_rise,self.sen_delay_fall = self.get_delays_to_sen() #get the new timing self.add_mod(self.replica_bitline) @@ -853,4 +859,4 @@ class control_logic(design.design): last_stage_rise = stage_effort_list[-1].is_rise return stage_effort_list - \ No newline at end of file + diff --git a/compiler/modules/delay_chain.py b/compiler/modules/delay_chain.py index 722328d1..1478dbfc 100644 --- a/compiler/modules/delay_chain.py +++ b/compiler/modules/delay_chain.py @@ -1,10 +1,10 @@ import debug import design from tech import drc -from pinv import pinv from contact import contact from vector import vector from globals import OPTS +from sram_factory import factory class delay_chain(design.design): """ @@ -13,12 +13,8 @@ class delay_chain(design.design): Usually, this will be constant, but it could have varied fanout. """ - unique_id = 1 - - def __init__(self, fanout_list, name="delay_chain"): + def __init__(self, name, fanout_list): """init function""" - name = name+"_{}".format(delay_chain.unique_id) - delay_chain.unique_id += 1 design.design.__init__(self, name) # Two fanouts are needed so that we can route the vdd/gnd connections @@ -57,7 +53,7 @@ class delay_chain(design.design): self.add_pin("gnd") def add_modules(self): - self.inv = pinv(route_output=False) + self.inv = factory.create(module_type="pinv", route_output=False) self.add_mod(self.inv) def create_inverters(self): @@ -238,4 +234,4 @@ class delay_chain(design.design): stage_effort_list.append(stage) last_stage_is_rise = stage.is_rise - return stage_effort_list \ No newline at end of file + return stage_effort_list diff --git a/compiler/modules/dff_array.py b/compiler/modules/dff_array.py index 25ef3090..215d2884 100644 --- a/compiler/modules/dff_array.py +++ b/compiler/modules/dff_array.py @@ -3,6 +3,7 @@ import design from tech import drc from math import log from vector import vector +from sram_factory import factory from globals import OPTS class dff_array(design.design): @@ -38,10 +39,7 @@ class dff_array(design.design): self.DRC_LVS() def add_modules(self): - from importlib import reload - c = reload(__import__(OPTS.dff)) - self.mod_dff = getattr(c, OPTS.dff) - self.dff = self.mod_dff("dff") + self.dff = factory.create(module_type="dff") self.add_mod(self.dff) def add_pins(self): @@ -61,7 +59,7 @@ class dff_array(design.design): for col in range(self.columns): name = "dff_r{0}_c{1}".format(row,col) self.dff_insts[row,col]=self.add_inst(name=name, - mod=self.dff) + mod=self.dff) self.connect_inst([self.get_din_name(row,col), self.get_dout_name(row,col), "clk", @@ -162,4 +160,4 @@ class dff_array(design.design): """Return the total capacitance (in relative units) that the clock is loaded by in the dff array""" dff_clk_cin = self.dff.get_clk_cin() total_cin = dff_clk_cin * self.rows * self.columns - return total_cin \ No newline at end of file + return total_cin diff --git a/compiler/modules/dff_buf.py b/compiler/modules/dff_buf.py index 9ff89603..4f6fff11 100644 --- a/compiler/modules/dff_buf.py +++ b/compiler/modules/dff_buf.py @@ -4,7 +4,7 @@ from tech import drc,parameter from math import log from vector import vector from globals import OPTS -from pinv import pinv +from sram_factory import factory class dff_buf(design.design): """ @@ -50,16 +50,17 @@ class dff_buf(design.design): self.DRC_LVS() def add_modules(self): - from importlib import reload - c = reload(__import__(OPTS.dff)) - self.mod_dff = getattr(c, OPTS.dff) - self.dff = self.mod_dff("dff") + self.dff = factory.create(module_type="dff") self.add_mod(self.dff) - self.inv1 = pinv(size=self.inv1_size,height=self.dff.height) + self.inv1 = factory.create(module_type="pinv", + size=self.inv1_size, + height=self.dff.height) self.add_mod(self.inv1) - self.inv2 = pinv(size=self.inv2_size,height=self.dff.height) + self.inv2 = factory.create(module_type="pinv", + size=self.inv2_size, + height=self.dff.height) self.add_mod(self.inv2) @@ -182,4 +183,4 @@ class dff_buf(design.design): #This is a handmade cell so the value must be entered in the tech.py file or estimated. #Calculated in the tech file by summing the widths of all the gates and dividing by the minimum width. #FIXME: Dff changed in a past commit. The parameter need to be updated. - return parameter["dff_clk_cin"] \ No newline at end of file + return parameter["dff_clk_cin"] diff --git a/compiler/modules/dff_buf_array.py b/compiler/modules/dff_buf_array.py index 8097f207..4d655a64 100644 --- a/compiler/modules/dff_buf_array.py +++ b/compiler/modules/dff_buf_array.py @@ -4,7 +4,7 @@ from tech import drc from math import log from vector import vector from globals import OPTS -import dff_buf +from sram_factory import factory class dff_buf_array(design.design): """ @@ -54,7 +54,9 @@ class dff_buf_array(design.design): self.add_pin("gnd") def add_modules(self): - self.dff = dff_buf.dff_buf(self.inv1_size, self.inv2_size) + self.dff = factory.create(module_type="dff_buf", + inv1_size=self.inv1_size, + inv2_size=self.inv2_size) self.add_mod(self.dff) def create_dff_array(self): @@ -189,4 +191,4 @@ class dff_buf_array(design.design): """Return the total capacitance (in relative units) that the clock is loaded by in the dff array""" dff_clk_cin = self.dff.get_clk_cin() total_cin = dff_clk_cin * self.rows * self.columns - return total_cin \ No newline at end of file + return total_cin diff --git a/compiler/modules/dff_inv.py b/compiler/modules/dff_inv.py index aebe49c2..f8ff00bf 100644 --- a/compiler/modules/dff_inv.py +++ b/compiler/modules/dff_inv.py @@ -55,13 +55,12 @@ class dff_inv(design.design): self.add_pin("gnd") def add_modules(self): - from importlib import reload - c = reload(__import__(OPTS.dff)) - self.mod_dff = getattr(c, OPTS.dff) - self.dff = self.mod_dff("dff") + self.dff = dff_inv.dff_inv(self.inv_size) self.add_mod(self.dff) - self.inv1 = pinv(size=self.inv_size,height=self.dff.height) + self.inv1 = factory.create(module_type="pinv", + size=self.inv_size, + height=self.dff.height) self.add_mod(self.inv1) def create_modules(self): @@ -152,4 +151,4 @@ class dff_inv(design.design): def get_clk_cin(self): """Return the total capacitance (in relative units) that the clock is loaded by in the dff""" - return self.dff.get_clk_cin() \ No newline at end of file + return self.dff.get_clk_cin() diff --git a/compiler/modules/dff_inv_array.py b/compiler/modules/dff_inv_array.py index 8985b99a..629a1d67 100644 --- a/compiler/modules/dff_inv_array.py +++ b/compiler/modules/dff_inv_array.py @@ -42,7 +42,7 @@ class dff_inv_array(design.design): self.DRC_LVS() def add_modules(self): - self.dff = dff_inv.dff_inv(self.inv_size) + self.dff = factory.create(module_type="dff") self.add_mod(self.dff) def add_pins(self): @@ -189,4 +189,4 @@ class dff_inv_array(design.design): """Return the total capacitance (in relative units) that the clock is loaded by in the dff array""" dff_clk_cin = self.dff.get_clk_cin() total_cin = dff_clk_cin * self.rows * self.columns - return total_cin \ No newline at end of file + return total_cin diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 32ed6d7c..4bbb6aca 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -4,12 +4,8 @@ import design from math import log from math import sqrt import math -import contact -from pnand2 import pnand2 -from pnand3 import pnand3 -from pinv import pinv -from hierarchical_predecode2x4 import hierarchical_predecode2x4 as pre2x4 -from hierarchical_predecode3x8 import hierarchical_predecode3x8 as pre3x8 +import contact +from sram_factory import factory from vector import vector from globals import OPTS @@ -17,11 +13,8 @@ class hierarchical_decoder(design.design): """ Dynamically generated hierarchical decoder. """ - unique_id = 1 - - def __init__(self, rows, height=None): - design.design.__init__(self, "hierarchical_decoder_{0}rows_{1}".format(rows,hierarchical_decoder.unique_id)) - hierarchical_decoder.unique_id += 1 + def __init__(self, name, rows, height=None): + design.design.__init__(self, name) self.NAND_FORMAT = "DEC_NAND_{0}" self.INV_FORMAT = "DEC_INV_{0}" @@ -57,21 +50,26 @@ class hierarchical_decoder(design.design): self.DRC_LVS() def add_modules(self): - self.inv = pinv(height=self.cell_height) + self.inv = factory.create(module_type="pinv", + height=self.cell_height) self.add_mod(self.inv) - self.nand2 = pnand2(height=self.cell_height) + self.nand2 = factory.create(module_type="pnand2", + height=self.cell_height) self.add_mod(self.nand2) - self.nand3 = pnand3(height=self.cell_height) + self.nand3 = factory.create(module_type="pnand3", + height=self.cell_height) self.add_mod(self.nand3) self.add_decoders() def add_decoders(self): """ Create the decoders based on the number of pre-decodes """ - self.pre2_4 = pre2x4(height=self.cell_height) + self.pre2_4 = factory.create(module_type="hierarchical_predecode2x4", + height=self.cell_height) self.add_mod(self.pre2_4) - self.pre3_8 = pre3x8(height=self.cell_height) + self.pre3_8 = factory.create(module_type="hierarchical_predecode3x8", + height=self.cell_height) self.add_mod(self.pre3_8) def determine_predecodes(self,num_inputs): diff --git a/compiler/modules/hierarchical_predecode.py b/compiler/modules/hierarchical_predecode.py index 7dfd443d..147c3018 100644 --- a/compiler/modules/hierarchical_predecode.py +++ b/compiler/modules/hierarchical_predecode.py @@ -3,24 +3,19 @@ import design import math from tech import drc import contact -from pinv import pinv from vector import vector from globals import OPTS -from pnand2 import pnand2 -from pnand3 import pnand3 +from sram_factory import factory class hierarchical_predecode(design.design): """ Pre 2x4 and 3x8 decoder shared code. """ - unique_id = 1 - - def __init__(self, input_number, height=None): + def __init__(self, name, input_number, height=None): self.number_of_inputs = input_number self.cell_height = height self.number_of_outputs = int(math.pow(2, self.number_of_inputs)) - design.design.__init__(self, name="pre{0}x{1}_{2}".format(self.number_of_inputs,self.number_of_outputs,hierarchical_predecode.unique_id)) - hierarchical_predecode.unique_id += 1 + design.design.__init__(self, name) def add_pins(self): for k in range(self.number_of_inputs): @@ -33,7 +28,8 @@ class hierarchical_predecode(design.design): def add_modules(self): """ Add the INV and NAND gate modules """ - self.inv = pinv(height=self.cell_height) + self.inv = factory.create(module_type="pinv", + height=self.cell_height) self.add_mod(self.inv) self.add_nand(self.number_of_inputs) @@ -42,9 +38,11 @@ class hierarchical_predecode(design.design): def add_nand(self,inputs): """ Create the NAND for the predecode input stage """ if inputs==2: - self.nand = pnand2(height=self.cell_height) + self.nand = factory.create(module_type="pnand2", + height=self.cell_height) elif inputs==3: - self.nand = pnand3(height=self.cell_height) + self.nand = factory.create(module_type="pnand3", + height=self.cell_height) else: debug.error("Invalid number of predecode inputs: {}".format(inputs),-1) diff --git a/compiler/modules/hierarchical_predecode2x4.py b/compiler/modules/hierarchical_predecode2x4.py index 918172ea..83e93f85 100644 --- a/compiler/modules/hierarchical_predecode2x4.py +++ b/compiler/modules/hierarchical_predecode2x4.py @@ -9,8 +9,8 @@ class hierarchical_predecode2x4(hierarchical_predecode): """ Pre 2x4 decoder used in hierarchical_decoder. """ - def __init__(self, height=None): - hierarchical_predecode.__init__(self, 2, height) + def __init__(self, name, height=None): + hierarchical_predecode.__init__(self, name, 2, height) self.create_netlist() if not OPTS.netlist_only: diff --git a/compiler/modules/hierarchical_predecode3x8.py b/compiler/modules/hierarchical_predecode3x8.py index 88bbbcd7..109e8160 100644 --- a/compiler/modules/hierarchical_predecode3x8.py +++ b/compiler/modules/hierarchical_predecode3x8.py @@ -9,8 +9,8 @@ class hierarchical_predecode3x8(hierarchical_predecode): """ Pre 3x8 decoder used in hierarchical_decoder. """ - def __init__(self, height=None): - hierarchical_predecode.__init__(self, 3, height) + def __init__(self, name, height=None): + hierarchical_predecode.__init__(self, name, 3, height) self.create_netlist() if not OPTS.netlist_only: diff --git a/compiler/modules/multibank.py b/compiler/modules/multibank.py index d402b145..1b9e6194 100644 --- a/compiler/modules/multibank.py +++ b/compiler/modules/multibank.py @@ -5,12 +5,8 @@ import design import math from math import log,sqrt,ceil import contact -from pinv import pinv -from pnand2 import pnand2 -from pnor2 import pnor2 from vector import vector -from pinvbuf import pinvbuf - +from sram_factory import factory from globals import OPTS class multibank(design.design): @@ -21,21 +17,8 @@ class multibank(design.design): This module includes the tristate and bank select logic. """ - def __init__(self, word_size, num_words, words_per_row, num_banks=1, name=""): + def __init__(self, name, word_size, num_words, words_per_row, num_banks=1): - mod_list = ["tri_gate", "bitcell", "decoder", "wordline_driver", - "bitcell_array", "sense_amp_array", "precharge_array", - "column_mux_array", "write_driver_array", "tri_gate_array", - "dff", "bank_select"] - from importlib import reload - for mod_name in mod_list: - config_mod_name = getattr(OPTS, mod_name) - class_file = reload(__import__(config_mod_name)) - mod_class = getattr(class_file , config_mod_name) - setattr (self, "mod_"+mod_name, mod_class) - - if name == "": - name = "bank_{0}_{1}".format(word_size, num_words) design.design.__init__(self, name) debug.info(2, "create sram of size {0} with {1} words".format(word_size,num_words)) diff --git a/compiler/modules/precharge_array.py b/compiler/modules/precharge_array.py index 8bb66cda..ff84cfe6 100644 --- a/compiler/modules/precharge_array.py +++ b/compiler/modules/precharge_array.py @@ -2,7 +2,7 @@ import design import debug from tech import drc from vector import vector -from precharge import precharge +from sram_factory import factory from globals import OPTS class precharge_array(design.design): @@ -11,11 +11,7 @@ class precharge_array(design.design): of bit line columns, height is the height of the bit-cell array. """ - unique_id = 1 - - def __init__(self, columns, size=1, bitcell_bl="bl", bitcell_br="br"): - name = "precharge_array_{}".format(precharge_array.unique_id) - precharge_array.unique_id += 1 + def __init__(self, name, columns, size=1, bitcell_bl="bl", bitcell_br="br"): design.design.__init__(self, name) debug.info(1, "Creating {0}".format(self.name)) @@ -50,10 +46,12 @@ class precharge_array(design.design): self.DRC_LVS() def add_modules(self): - self.pc_cell = precharge(name="precharge", - size=self.size, - bitcell_bl=self.bitcell_bl, - bitcell_br=self.bitcell_br) + self.pc_cell = factory.create(module_type="precharge", + size=self.size, + bitcell_bl=self.bitcell_bl, + bitcell_br=self.bitcell_br) + + self.add_mod(self.pc_cell) @@ -107,4 +105,4 @@ class precharge_array(design.design): """Get the relative capacitance of all the clk connections in the precharge array""" #Assume single port precharge_en_cin = self.pc_cell.get_en_cin() - return precharge_en_cin*self.columns \ No newline at end of file + return precharge_en_cin*self.columns diff --git a/compiler/modules/replica_bitline.py b/compiler/modules/replica_bitline.py index 8538fbee..614e6d42 100644 --- a/compiler/modules/replica_bitline.py +++ b/compiler/modules/replica_bitline.py @@ -1,10 +1,8 @@ import debug import design from tech import drc -from pinv import pinv import contact -from bitcell_array import bitcell_array -from ptx import ptx +from sram_factory import factory from vector import vector from globals import OPTS @@ -15,7 +13,7 @@ class replica_bitline(design.design): line and rows is the height of the replica bit loads. """ - def __init__(self, delay_fanout_list, bitcell_loads, name="replica_bitline"): + def __init__(self, name, delay_fanout_list, bitcell_loads): design.design.__init__(self, name) self.bitcell_loads = bitcell_loads @@ -78,29 +76,25 @@ class replica_bitline(design.design): def add_modules(self): """ Add the modules for later usage """ - from importlib import reload - #g = reload(__import__(OPTS.delay_chain)) - #self.mod_delay_chain = getattr(g, OPTS.delay_chain) - - g = reload(__import__(OPTS.replica_bitcell)) - self.mod_replica_bitcell = getattr(g, OPTS.replica_bitcell) - - self.bitcell = self.replica_bitcell = self.mod_replica_bitcell() - self.add_mod(self.bitcell) + self.replica_bitcell = factory.create(module_type="replica_bitcell") + self.add_mod(self.replica_bitcell) # This is the replica bitline load column that is the height of our array - self.rbl = bitcell_array(cols=1, rows=self.bitcell_loads) + self.rbl = factory.create(module_type="bitcell_array", + cols=1, + rows=self.bitcell_loads) self.add_mod(self.rbl) # FIXME: The FO and depth of this should be tuned - from delay_chain import delay_chain - self.delay_chain = delay_chain(self.delay_fanout_list) + self.delay_chain = factory.create(module_type="delay_chain", + fanout_list=self.delay_fanout_list) self.add_mod(self.delay_chain) - self.inv = pinv() + self.inv = factory.create(module_type="pinv") self.add_mod(self.inv) - self.access_tx = ptx(tx_type="pmos") + self.access_tx = factory.create(module_type="ptx", + tx_type="pmos") self.add_mod(self.access_tx) def create_instances(self): @@ -132,7 +126,6 @@ class replica_bitline(design.design): temp.append("vdd") temp.append("gnd") self.connect_inst(temp) - #self.connect_inst(["bl_0", "br_0", "delayed_en", "vdd", "gnd"]) self.rbl_inst=self.add_inst(name="load", mod=self.rbl) @@ -631,4 +624,4 @@ class replica_bitline(design.design): access_tx_cin = self.access_tx.get_cin() rbc_cin = self.replica_bitcell.get_wl_cin() return access_tx_cin + rbc_cin - \ No newline at end of file + diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index 806acf71..3209377b 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -1,6 +1,7 @@ import design from tech import drc from vector import vector +from sram_factory import factory import debug from globals import OPTS @@ -10,8 +11,8 @@ class sense_amp_array(design.design): Dynamically generated sense amp array for all bitlines. """ - def __init__(self, word_size, words_per_row): - design.design.__init__(self, "sense_amp_array") + def __init__(self, name, word_size, words_per_row): + design.design.__init__(self, name) debug.info(1, "Creating {0}".format(self.name)) self.word_size = word_size @@ -51,17 +52,13 @@ class sense_amp_array(design.design): self.add_pin("gnd") def add_modules(self): - from importlib import reload - c = reload(__import__(OPTS.sense_amp)) - self.mod_sense_amp = getattr(c, OPTS.sense_amp) - self.amp = self.mod_sense_amp("sense_amp") + self.amp = factory.create(module_type="sense_amp") + self.add_mod(self.amp) # This is just used for measurements, # so don't add the module - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell = self.mod_bitcell() + self.bitcell = factory.create(module_type="bitcell") def create_sense_amp_array(self): self.local_insts = [] @@ -143,4 +140,4 @@ class sense_amp_array(design.design): def get_en_cin(self): """Get the relative capacitance of all the sense amp enable connections in the array""" sense_amp_en_cin = self.amp.get_en_cin() - return sense_amp_en_cin * self.words_per_row \ No newline at end of file + return sense_amp_en_cin * self.words_per_row diff --git a/compiler/modules/single_level_column_mux_array.py b/compiler/modules/single_level_column_mux_array.py index 699e1d85..9ce95c66 100644 --- a/compiler/modules/single_level_column_mux_array.py +++ b/compiler/modules/single_level_column_mux_array.py @@ -1,11 +1,11 @@ from math import log import design -from single_level_column_mux import single_level_column_mux import contact from tech import drc import debug import math from vector import vector +from sram_factory import factory from globals import OPTS class single_level_column_mux_array(design.design): @@ -14,11 +14,7 @@ class single_level_column_mux_array(design.design): Array of column mux to read the bitlines through the 6T. """ - unique_id = 1 - - def __init__(self, columns, word_size, bitcell_bl="bl", bitcell_br="br"): - name="single_level_column_mux_array_{}".format(single_level_column_mux_array.unique_id) - single_level_column_mux_array.unique_id += 1 + def __init__(self, name, columns, word_size, bitcell_bl="bl", bitcell_br="br"): design.design.__init__(self, name) debug.info(1, "Creating {0}".format(self.name)) self.columns = columns @@ -61,7 +57,9 @@ class single_level_column_mux_array(design.design): def add_modules(self): - self.mux = single_level_column_mux(bitcell_bl=self.bitcell_bl, bitcell_br=self.bitcell_br) + self.mux = factory.create(module_type="single_level_column_mux", + bitcell_bl=self.bitcell_bl, + bitcell_br=self.bitcell_br) self.add_mod(self.mux) diff --git a/compiler/modules/tri_gate_array.py b/compiler/modules/tri_gate_array.py index 5ca992b3..d56e9c96 100644 --- a/compiler/modules/tri_gate_array.py +++ b/compiler/modules/tri_gate_array.py @@ -2,6 +2,7 @@ import debug from tech import drc import design from vector import vector +from sram_factory import factory from globals import OPTS class tri_gate_array(design.design): @@ -36,10 +37,7 @@ class tri_gate_array(design.design): self.DRC_LVS() def add_modules(self): - from importlib import reload - c = reload(__import__(OPTS.tri_gate)) - self.mod_tri_gate = getattr(c, OPTS.tri_gate) - self.tri = self.mod_tri_gate("tri_gate") + self.tri = factory.create(module_type="tri_gate") self.add_mod(self.tri) def add_pins(self): diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index af82fbc5..021b76d1 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -5,9 +5,8 @@ import contact from math import log from math import sqrt import math -from pinv import pinv -from pnand2 import pnand2 from vector import vector +from sram_factory import factory from globals import OPTS class wordline_driver(design.design): @@ -16,8 +15,8 @@ class wordline_driver(design.design): Generates the wordline-driver to drive the bitcell """ - def __init__(self, rows): - design.design.__init__(self, "wordline_driver") + def __init__(self, name, rows): + design.design.__init__(self, name) self.rows = rows @@ -53,13 +52,14 @@ class wordline_driver(design.design): # This is just used for measurements, # so don't add the module - self.inv = pinv() + self.inv = factory.create(module_type="pinv") self.add_mod(self.inv) - self.inv_no_output = pinv(route_output=False) + self.inv_no_output = factory.create(module_type="pinv", + route_output=False) self.add_mod(self.inv_no_output) - self.nand2 = pnand2() + self.nand2 = factory.create(module_type="pnand2") self.add_mod(self.nand2) @@ -237,4 +237,4 @@ class wordline_driver(design.design): """Get the relative capacitance of all the enable connections in the bank""" #The enable is connected to a nand2 for every row. total_cin = self.nand2.get_cin() * self.rows - return total_cin \ No newline at end of file + return total_cin diff --git a/compiler/modules/write_driver_array.py b/compiler/modules/write_driver_array.py index 3b5e75d9..4bcfbcb0 100644 --- a/compiler/modules/write_driver_array.py +++ b/compiler/modules/write_driver_array.py @@ -2,6 +2,7 @@ from math import log import design from tech import drc import debug +from sram_factory import factory from vector import vector from globals import OPTS @@ -11,8 +12,8 @@ class write_driver_array(design.design): Dynamically generated write driver array of all bitlines. """ - def __init__(self, columns, word_size): - design.design.__init__(self, "write_driver_array") + def __init__(self, name, columns, word_size): + design.design.__init__(self, name) debug.info(1, "Creating {0}".format(self.name)) self.columns = columns @@ -53,17 +54,12 @@ class write_driver_array(design.design): self.add_pin("gnd") def add_modules(self): - from importlib import reload - c = reload(__import__(OPTS.write_driver)) - self.mod_write_driver = getattr(c, OPTS.write_driver) - self.driver = self.mod_write_driver("write_driver") + self.driver = factory.create(module_type="write_driver") self.add_mod(self.driver) # This is just used for measurements, # so don't add the module - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell = self.mod_bitcell() + self.bitcell = factory.create(module_type="bitcell") def create_write_array(self): self.driver_insts = {} diff --git a/compiler/options.py b/compiler/options.py index bd4bf607..fc1eb7d1 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -72,23 +72,24 @@ class options(optparse.Values): num_banks = 1 # These are the default modules that can be over-riden + bank_select = "bank_select" + bitcell_array = "bitcell_array" + bitcell = "bitcell" + column_mux_array = "single_level_column_mux_array" + control_logic = "control_logic" decoder = "hierarchical_decoder" + delay_chain = "delay_chain" dff_array = "dff_array" dff = "dff" - control_logic = "control_logic" - bitcell_array = "bitcell_array" - sense_amp = "sense_amp" - sense_amp_array = "sense_amp_array" precharge_array = "precharge_array" - column_mux_array = "single_level_column_mux_array" - write_driver = "write_driver" - write_driver_array = "write_driver_array" - tri_gate = "tri_gate" - tri_gate_array = "tri_gate_array" - wordline_driver = "wordline_driver" - replica_bitline = "replica_bitline" + ptx = "ptx" replica_bitcell = "replica_bitcell" - bitcell = "bitcell" - delay_chain = "delay_chain" - bank_select = "bank_select" + replica_bitline = "replica_bitline" + sense_amp_array = "sense_amp_array" + sense_amp = "sense_amp" + tri_gate_array = "tri_gate_array" + tri_gate = "tri_gate" + wordline_driver = "wordline_driver" + write_driver_array = "write_driver_array" + write_driver = "write_driver" diff --git a/compiler/pgates/pand2.py b/compiler/pgates/pand2.py index 5eb1ceb9..0e1acde6 100644 --- a/compiler/pgates/pand2.py +++ b/compiler/pgates/pand2.py @@ -3,28 +3,16 @@ from tech import drc from math import log from vector import vector from globals import OPTS -from pnand2 import pnand2 -from pinv import pinv import pgate +from sram_factory import factory class pand2(pgate.pgate): """ This is a simple buffer used for driving loads. """ - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - bitcell = getattr(c, OPTS.bitcell) - - unique_id = 1 - - def __init__(self, size=1, height=None, name=""): - + def __init__(self, name, size=1, height=None): self.size = size - if name=="": - name = "pand2_{0}_{1}".format(size, pand2.unique_id) - pand2.unique_id += 1 - pgate.pgate.__init__(self, name, height) debug.info(1, "Creating {}".format(self.name)) @@ -41,10 +29,10 @@ class pand2(pgate.pgate): def create_modules(self): # Shield the cap, but have at least a stage effort of 4 - self.nand = pnand2(height=self.height) + self.nand = factory.create(module_type="pnand2",height=self.height) self.add_mod(self.nand) - self.inv = pinv(size=self.size, height=self.height) + self.inv = factory.create(module_type="pinv", size=self.size, height=self.height) self.add_mod(self.inv) def create_layout(self): diff --git a/compiler/pgates/pbuf.py b/compiler/pgates/pbuf.py index 9b6c59ff..a86aea1c 100644 --- a/compiler/pgates/pbuf.py +++ b/compiler/pgates/pbuf.py @@ -3,29 +3,19 @@ from tech import drc from math import log from vector import vector from globals import OPTS -from pinv import pinv import pgate +from sram_factory import factory class pbuf(pgate.pgate): """ This is a simple buffer used for driving loads. """ - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - bitcell = getattr(c, OPTS.bitcell) - - unique_id = 1 - - def __init__(self, size=4, height=None, name=""): - + def __init__(self, name, size=4, height=None): + self.stage_effort = 4 self.size = size self.height = height - if name=="": - name = "pbuf_{0}_{1}".format(self.size, pbuf.unique_id) - pbuf.unique_id += 1 - pgate.pgate.__init__(self, name, height) debug.info(1, "creating {0} with size of {1}".format(self.name,self.size)) @@ -54,10 +44,10 @@ class pbuf(pgate.pgate): def create_modules(self): # Shield the cap, but have at least a stage effort of 4 input_size = max(1,int(self.size/self.stage_effort)) - self.inv1 = pinv(size=input_size, height=self.height) + self.inv1 = factory.create(module_type="pinv", size=input_size, height=self.height) self.add_mod(self.inv1) - self.inv2 = pinv(size=self.size, height=self.height) + self.inv2 = factory.create(module_type="pinv", size=self.size, height=self.height) self.add_mod(self.inv2) def create_insts(self): @@ -141,4 +131,4 @@ class pbuf(pgate.pgate): def get_cin(self): """Returns the relative capacitance of the input""" input_cin = self.inv1.get_cin() - return input_cin \ No newline at end of file + return input_cin diff --git a/compiler/pgates/pdriver.py b/compiler/pgates/pdriver.py index 5da68032..934412d6 100644 --- a/compiler/pgates/pdriver.py +++ b/compiler/pgates/pdriver.py @@ -5,15 +5,13 @@ from tech import drc from math import log from vector import vector from globals import OPTS -from pinv import pinv +from sram_factory import factory class pdriver(pgate.pgate): """ This instantiates an even or odd number of inverters sized for driving a load. """ - unique_id = 1 - - def __init__(self, neg_polarity=False, fanout_size=8, size_list = [], height=None, name=""): + def __init__(self, name, neg_polarity=False, fanout_size=8, size_list = [], height=None): self.stage_effort = 4 self.height = height @@ -24,10 +22,6 @@ class pdriver(pgate.pgate): if len(self.size_list) > 0 and (self.fanout_size != 8 or self.neg_polarity): debug.error("Cannot specify both size_list and neg_polarity or fanout_size.", -1) - if name=="": - name = "pdriver_{}".format(pdriver.unique_id) - pdriver.unique_id += 1 - pgate.pgate.__init__(self, name, height) debug.info(1, "Creating {}".format(self.name)) @@ -123,11 +117,13 @@ class pdriver(pgate.pgate): self.inv_list = [] if len(self.size_list) > 0: # size list specified for x in range(len(self.size_list)): - self.inv_list.append(pinv(size=self.size_list[x], height=self.height)) + temp_inv = factory.create(module_type="pinv", size=self.size_list[x], height=self.height) + self.inv_list.append(temp_inv) self.add_mod(self.inv_list[x]) else: # find inv sizes for x in range(len(self.calc_size_list)): - self.inv_list.append(pinv(size=self.calc_size_list[x], height=self.height)) + temp_inv = factory.create(module_type="pinv", size=self.calc_size_list[x], height=self.height) + self.inv_list.append(temp_inv) self.add_mod(self.inv_list[x]) diff --git a/compiler/pgates/pgate.py b/compiler/pgates/pgate.py index fc839270..2f641da9 100644 --- a/compiler/pgates/pgate.py +++ b/compiler/pgates/pgate.py @@ -2,9 +2,9 @@ import contact import design import debug from tech import drc, parameter, spice -from ptx import ptx from vector import vector from globals import OPTS +from sram_factory import factory class pgate(design.design): """ @@ -18,15 +18,12 @@ class pgate(design.design): if height: self.height = height elif not height: - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - bitcell = getattr(c, OPTS.bitcell) - b = bitcell() + b = factory.create(module_type="bitcell") self.height = b.height def connect_pin_to_rail(self,inst,pin,supply): - """ Conencts a ptx pin to a supply rail. """ + """ Connects a ptx pin to a supply rail. """ source_pin = inst.get_pin(pin) supply_pin = self.get_pin(supply) if supply_pin.overlaps(source_pin): diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index 31682360..0dc1b683 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -2,12 +2,12 @@ import contact import pgate import debug from tech import drc, parameter, spice -from ptx import ptx from vector import vector from math import ceil from globals import OPTS from utils import round_to_grid import logical_effort +from sram_factory import factory class pinv(pgate.pgate): """ @@ -19,15 +19,11 @@ class pinv(pgate.pgate): output to the right side of the cell for easier access. """ - unique_id = 1 - - def __init__(self, size=1, beta=parameter["beta"], height=None, route_output=True): + def __init__(self, name, size=1, beta=parameter["beta"], height=None, route_output=True): # We need to keep unique names because outputting to GDSII # will use the last record with a given name. I.e., you will # over-write a design in GDS if one has and the other doesn't # have poly connected, for example. - name = "pinv_{}".format(pinv.unique_id) - pinv.unique_id += 1 pgate.pgate.__init__(self, name, height) debug.info(2, "create pinv structure {0} with size of {1}".format(name, size)) @@ -86,8 +82,8 @@ class pinv(pgate.pgate): # Sanity check. can we make an inverter in the height with minimum tx sizes? # Assume we need 3 metal 1 pitches (2 power rails, one between the tx for the drain) # plus the tx height - nmos = ptx(tx_type="nmos") - pmos = ptx(width=drc("minwidth_tx"), tx_type="pmos") + nmos = factory.create(module_type="ptx", tx_type="nmos") + pmos = factory.create(module_type="ptx", width=drc("minwidth_tx"), tx_type="pmos") tx_height = nmos.poly_height + pmos.poly_height # rotated m1 pitch or poly to active spacing min_channel = max(contact.poly.width + self.m1_space, @@ -147,18 +143,20 @@ class pinv(pgate.pgate): def add_ptx(self): """ Create the PMOS and NMOS transistors. """ - self.nmos = ptx(width=self.nmos_width, - mults=self.tx_mults, - tx_type="nmos", - connect_poly=True, - connect_active=True) + self.nmos = factory.create(module_type="ptx", + width=self.nmos_width, + mults=self.tx_mults, + tx_type="nmos", + connect_poly=True, + connect_active=True) self.add_mod(self.nmos) - self.pmos = ptx(width=self.pmos_width, - mults=self.tx_mults, - tx_type="pmos", - connect_poly=True, - connect_active=True) + self.pmos = factory.create(module_type="ptx", + width=self.pmos_width, + mults=self.tx_mults, + tx_type="pmos", + connect_poly=True, + connect_active=True) self.add_mod(self.pmos) def route_supply_rails(self): diff --git a/compiler/pgates/pinvbuf.py b/compiler/pgates/pinvbuf.py index 13c376cf..adce2d6c 100644 --- a/compiler/pgates/pinvbuf.py +++ b/compiler/pgates/pinvbuf.py @@ -4,16 +4,14 @@ from tech import drc from math import log from vector import vector from globals import OPTS -from pinv import pinv +from sram_factory import factory class pinvbuf(design.design): """ This is a simple inverter/buffer used for driving loads. It is used in the column decoder for 1:2 decoding and as the clock buffer. """ - unique_id = 1 - - def __init__(self, driver_size=4, height=None, name=""): + def __init__(self, name, size=4, height=None): self.stage_effort = 4 self.row_height = height @@ -22,11 +20,8 @@ class pinvbuf(design.design): # stage effort of 4 or less # The pinvbuf has a FO of 2 for the first stage, so the second stage # should be sized "half" to prevent loading of the first stage - self.driver_size = driver_size - self.predriver_size = max(int(self.driver_size/(self.stage_effort/2)),1) - if name=="": - name = "pinvbuf_{0}_{1}_{2}".format(self.predriver_size, self.driver_size, pinvbuf.unique_id) - pinvbuf.unique_id += 1 + self.size = size + self.predriver_size = max(int(self.size/(self.stage_effort/2)),1) design.design.__init__(self, name) debug.info(1, "Creating {}".format(self.name)) @@ -65,13 +60,13 @@ class pinvbuf(design.design): # Shield the cap, but have at least a stage effort of 4 input_size = max(1,int(self.predriver_size/self.stage_effort)) - self.inv = pinv(size=input_size, height=self.row_height) + self.inv = factory.create(module_type="pinv", size=input_size, height=self.row_height) self.add_mod(self.inv) - self.inv1 = pinv(size=self.predriver_size, height=self.row_height) + self.inv1 = factory.create(module_type="pinv", size=self.predriver_size, height=self.row_height) self.add_mod(self.inv1) - self.inv2 = pinv(size=self.driver_size, height=self.row_height) + self.inv2 = factory.create(module_type="pinv", size=self.size, height=self.row_height) self.add_mod(self.inv2) def create_insts(self): @@ -217,4 +212,4 @@ class pinvbuf(design.design): stage3 = self.inv2.get_effort_stage(external_cout, last_stage_is_rise) stage_effort_list.append(stage3) - return stage_effort_list \ No newline at end of file + return stage_effort_list diff --git a/compiler/pgates/pnand2.py b/compiler/pgates/pnand2.py index e767b87e..8ff4b953 100644 --- a/compiler/pgates/pnand2.py +++ b/compiler/pgates/pnand2.py @@ -2,23 +2,18 @@ import contact import pgate import debug from tech import drc, parameter, spice -from ptx import ptx from vector import vector from globals import OPTS import logical_effort +from sram_factory import factory class pnand2(pgate.pgate): """ This module generates gds of a parametrically sized 2-input nand. This model use ptx to generate a 2-input nand within a cetrain height. """ - - unique_id = 1 - - def __init__(self, size=1, height=None): + def __init__(self, name, size=1, height=None): """ Creates a cell for a simple 2 input nand """ - name = "pnand2_{0}".format(pnand2.unique_id) - pnand2.unique_id += 1 pgate.pgate.__init__(self, name, height) debug.info(2, "create pnand2 structure {0} with size of {1}".format(name, size)) @@ -61,18 +56,20 @@ class pnand2(pgate.pgate): def add_ptx(self): """ Create the PMOS and NMOS transistors. """ - self.nmos = ptx(width=self.nmos_width, - mults=self.tx_mults, - tx_type="nmos", - connect_poly=True, - connect_active=True) + self.nmos = factory.create(module_type="ptx", + width=self.nmos_width, + mults=self.tx_mults, + tx_type="nmos", + connect_poly=True, + connect_active=True) self.add_mod(self.nmos) - self.pmos = ptx(width=self.pmos_width, - mults=self.tx_mults, - tx_type="pmos", - connect_poly=True, - connect_active=True) + self.pmos = factory.create(module_type="ptx", + width=self.pmos_width, + mults=self.tx_mults, + tx_type="pmos", + connect_poly=True, + connect_active=True) self.add_mod(self.pmos) def setup_layout_constants(self): @@ -260,4 +257,4 @@ class pnand2(pgate.pgate): Optional is_rise refers to the input direction rise/fall. Input inverted by this stage. """ parasitic_delay = 2 - return logical_effort.logical_effort(self.size, self.get_cin(), cout, parasitic_delay, not inp_is_rise) \ No newline at end of file + return logical_effort.logical_effort(self.size, self.get_cin(), cout, parasitic_delay, not inp_is_rise) diff --git a/compiler/pgates/pnand3.py b/compiler/pgates/pnand3.py index 4dab5264..a4bbb1c0 100644 --- a/compiler/pgates/pnand3.py +++ b/compiler/pgates/pnand3.py @@ -2,22 +2,17 @@ import contact import pgate import debug from tech import drc, parameter, spice -from ptx import ptx from vector import vector from globals import OPTS +from sram_factory import factory class pnand3(pgate.pgate): """ This module generates gds of a parametrically sized 2-input nand. This model use ptx to generate a 2-input nand within a cetrain height. """ - - unique_id = 1 - - def __init__(self, size=1, height=None): + def __init__(self, name, size=1, height=None): """ Creates a cell for a simple 3 input nand """ - name = "pnand3_{0}".format(pnand3.unique_id) - pnand3.unique_id += 1 pgate.pgate.__init__(self, name, height) debug.info(2, "create pnand3 structure {0} with size of {1}".format(name, size)) @@ -61,18 +56,20 @@ class pnand3(pgate.pgate): def add_ptx(self): """ Create the PMOS and NMOS transistors. """ - self.nmos = ptx(width=self.nmos_width, - mults=self.tx_mults, - tx_type="nmos", - connect_poly=True, - connect_active=True) + self.nmos = factory.create(module_type="ptx", + width=self.nmos_width, + mults=self.tx_mults, + tx_type="nmos", + connect_poly=True, + connect_active=True) self.add_mod(self.nmos) - self.pmos = ptx(width=self.pmos_width, - mults=self.tx_mults, - tx_type="pmos", - connect_poly=True, - connect_active=True) + self.pmos = factory.create(module_type="ptx", + width=self.pmos_width, + mults=self.tx_mults, + tx_type="pmos", + connect_poly=True, + connect_active=True) self.add_mod(self.pmos) def setup_layout_constants(self): @@ -93,7 +90,7 @@ class pnand3(pgate.pgate): self.output_pos = vector(0,0.5*self.height) # This is the extra space needed to ensure DRC rules to the active contacts - nmos = ptx(tx_type="nmos") + nmos = factory.create(module_type="ptx", tx_type="nmos") extra_contact_space = max(-nmos.get_pin("D").by(),0) # This is a poly-to-poly of a flipped cell self.top_bottom_space = max(0.5*self.m1_width + self.m1_space + extra_contact_space, @@ -272,4 +269,4 @@ class pnand3(pgate.pgate): Optional is_rise refers to the input direction rise/fall. Input inverted by this stage. """ parasitic_delay = 3 - return logical_effort.logical_effort(self.size, self.get_cin(), cout, parasitic_delay, not inp_is_rise) \ No newline at end of file + return logical_effort.logical_effort(self.size, self.get_cin(), cout, parasitic_delay, not inp_is_rise) diff --git a/compiler/pgates/pnor2.py b/compiler/pgates/pnor2.py index 65aaf7f8..93a0fd36 100644 --- a/compiler/pgates/pnor2.py +++ b/compiler/pgates/pnor2.py @@ -1,23 +1,18 @@ -import contact import pgate import debug from tech import drc, parameter, spice -from ptx import ptx from vector import vector from globals import OPTS +import contact +from sram_factory import factory class pnor2(pgate.pgate): """ This module generates gds of a parametrically sized 2-input nor. This model use ptx to generate a 2-input nor within a cetrain height. """ - - unique_id = 1 - - def __init__(self, size=1, height=None): + def __init__(self, name, size=1, height=None): """ Creates a cell for a simple 2 input nor """ - name = "pnor2_{0}".format(pnor2.unique_id) - pnor2.unique_id += 1 pgate.pgate.__init__(self, name, height) debug.info(2, "create pnor2 structure {0} with size of {1}".format(name, size)) @@ -58,32 +53,30 @@ class pnor2(pgate.pgate): def create_ptx(self): """ Create the PMOS and NMOS transistors. """ - self.nmos = ptx(width=self.nmos_width, - mults=self.tx_mults, - tx_type="nmos", - connect_poly=True, - connect_active=True) + self.nmos = factory.create(module_type="ptx", + width=self.nmos_width, + mults=self.tx_mults, + tx_type="nmos", + connect_poly=True, + connect_active=True) self.add_mod(self.nmos) - self.pmos = ptx(width=self.pmos_width, - mults=self.tx_mults, - tx_type="pmos", - connect_poly=True, - connect_active=True) + self.pmos = factory.create(module_type="ptx", + width=self.pmos_width, + mults=self.tx_mults, + tx_type="pmos", + connect_poly=True, + connect_active=True) self.add_mod(self.pmos) def setup_layout_constants(self): """ Pre-compute some handy layout parameters. """ - poly_contact = contact.contact(("poly","contact","metal1")) - m1m2_via = contact.contact(("metal1","via1","metal2")) - m2m3_via = contact.contact(("metal2","via2","metal3")) - # metal spacing to allow contacts on any layer - self.input_spacing = max(self.poly_space + poly_contact.first_layer_width, - self.m1_space + m1m2_via.first_layer_width, - self.m2_space + m2m3_via.first_layer_width, - self.m3_space + m2m3_via.second_layer_width) + self.input_spacing = max(self.poly_space + contact.poly.first_layer_width, + self.m1_space + contact.m1m2.first_layer_width, + self.m2_space + contact.m2m3.first_layer_width, + self.m3_space + contact.m2m3.second_layer_width) # Compute the other pmos2 location, but determining offset to overlap the # source and drain pins diff --git a/compiler/pgates/precharge.py b/compiler/pgates/precharge.py index a1422cb2..cea9c845 100644 --- a/compiler/pgates/precharge.py +++ b/compiler/pgates/precharge.py @@ -2,28 +2,20 @@ import contact import pgate import debug from tech import drc, parameter -from ptx import ptx from vector import vector from globals import OPTS +from sram_factory import factory class precharge(pgate.pgate): """ Creates a single precharge cell This module implements the precharge bitline cell used in the design. """ - - unique_id = 1 - def __init__(self, name, size=1, bitcell_bl="bl", bitcell_br="br"): - name = name+"_{}".format(precharge.unique_id) - precharge.unique_id += 1 pgate.pgate.__init__(self, name) debug.info(2, "create single precharge cell: {0}".format(name)) - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell = self.mod_bitcell() + self.bitcell = factory.create(module_type="bitcell") self.beta = parameter["beta"] self.ptx_width = self.beta*parameter["min_tx_size"] @@ -57,8 +49,9 @@ class precharge(pgate.pgate): """ Initializes the upper and lower pmos """ - self.pmos = ptx(width=self.ptx_width, - tx_type="pmos") + self.pmos = factory.create(module_type="ptx", + width=self.ptx_width, + tx_type="pmos") self.add_mod(self.pmos) @@ -268,4 +261,4 @@ class precharge(pgate.pgate): #The enable connect to three pmos gates. They all use the same size pmos. pmos_cin = self.pmos.get_cin() return 3*pmos_cin - \ No newline at end of file + diff --git a/compiler/pgates/ptx.py b/compiler/pgates/ptx.py index 82c79aed..3d7ce296 100644 --- a/compiler/pgates/ptx.py +++ b/compiler/pgates/ptx.py @@ -2,9 +2,9 @@ import design import debug from tech import drc, spice from vector import vector -from contact import contact from globals import OPTS import path +from sram_factory import factory class ptx(design.design): """ @@ -15,7 +15,7 @@ class ptx(design.design): you to connect the fingered gates and active for parallel devices. """ - def __init__(self, width=drc("minwidth_tx"), mults=1, tx_type="nmos", connect_active=False, connect_poly=False, num_contacts=None): + def __init__(self, name="", width=drc("minwidth_tx"), mults=1, tx_type="nmos", connect_active=False, connect_poly=False, num_contacts=None): # We need to keep unique names because outputting to GDSII # will use the last record with a given name. I.e., you will # over-write a design in GDS if one has and the other doesn't @@ -97,8 +97,9 @@ class ptx(design.design): # This is not actually instantiated but used for calculations - self.active_contact = contact(layer_stack=("active", "contact", "metal1"), - dimensions=(1, self.num_contacts)) + self.active_contact = factory.create(module_type="contact", + layer_stack=("active", "contact", "metal1"), + dimensions=(1, self.num_contacts)) # The contacted poly pitch (or uncontacted in an odd technology) @@ -355,4 +356,4 @@ class ptx(design.design): def get_cin(self): """Returns the relative gate cin of the tx""" - return self.tx_width/drc("minwidth_tx") \ No newline at end of file + return self.tx_width/drc("minwidth_tx") diff --git a/compiler/pgates/single_level_column_mux.py b/compiler/pgates/single_level_column_mux.py index 197164f3..f03a22e8 100644 --- a/compiler/pgates/single_level_column_mux.py +++ b/compiler/pgates/single_level_column_mux.py @@ -3,8 +3,8 @@ import debug from tech import drc from vector import vector import contact -from ptx import ptx from globals import OPTS +from sram_factory import factory class single_level_column_mux(design.design): """ @@ -13,14 +13,10 @@ class single_level_column_mux(design.design): to minimum size. Default is 8x. Per Samira and Hodges-Jackson book: Column-mux transistors driven by the decoder must be sized for optimal speed """ + def __init__(self, name, tx_size=8, bitcell_bl="bl", bitcell_br="br"): - # This is needed for different bitline spacings - unique_id = 1 - - def __init__(self, tx_size=8, bitcell_bl="bl", bitcell_br="br"): self.tx_size = int(tx_size) - name="single_level_column_mux_{}_{}".format(self.tx_size,single_level_column_mux.unique_id) - single_level_column_mux.unique_id += 1 + design.design.__init__(self, name) debug.info(2, "create single column mux cell: {0}".format(name)) @@ -47,16 +43,11 @@ class single_level_column_mux(design.design): self.add_wells() def add_modules(self): - # This is just used for measurements, - # so don't add the module - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell = self.mod_bitcell() + self.bitcell = factory.create(module_type="bitcell") # Adds nmos_lower,nmos_upper to the module self.ptx_width = self.tx_size*drc("minwidth_tx") - self.nmos = ptx(width=self.ptx_width) + self.nmos = factory.create(module_type="ptx", width=self.ptx_width) self.add_mod(self.nmos) diff --git a/compiler/sram_base.py b/compiler/sram_base.py index b51ebae9..39f139c6 100644 --- a/compiler/sram_base.py +++ b/compiler/sram_base.py @@ -10,6 +10,7 @@ import logical_effort from design import design from verilog import verilog from lef import lef +from sram_factory import factory class sram_base(design, verilog, lef): """ @@ -239,10 +240,7 @@ class sram_base(design, verilog, lef): def add_modules(self): - """ Create all the modules that will be used """ - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell = self.mod_bitcell() + self.bitcell = factory.create(module_type=OPTS.bitcell) # Create the address and control flops (but not the clk) from dff_array import dff_array diff --git a/compiler/sram_config.py b/compiler/sram_config.py index e4f94b4a..24e3cbc9 100644 --- a/compiler/sram_config.py +++ b/compiler/sram_config.py @@ -2,6 +2,7 @@ import debug from math import log,sqrt,ceil from importlib import reload from globals import OPTS +from sram_factory import factory class sram_config: """ This is a structure that is used to hold the SRAM configuration options. """ @@ -29,10 +30,7 @@ class sram_config: def compute_sizes(self): """ Computes the organization of the memory using bitcell size by trying to make it square.""" - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - # pass a copy of myself for the port numbers - self.bitcell = self.mod_bitcell() + self.bitcell = factory.create(module_type="bitcell") debug.check(self.num_banks in [1,2,4], "Valid number of banks are 1 , 2 and 4.") diff --git a/compiler/sram_factory.py b/compiler/sram_factory.py new file mode 100644 index 00000000..21aa7027 --- /dev/null +++ b/compiler/sram_factory.py @@ -0,0 +1,78 @@ +import debug +from globals import OPTS +from importlib import reload + + +class sram_factory: + """ + This is a factory pattern to create modules for usage in an SRAM. + Since GDSII has a flat namespace, it requires modules to have unique + names if their layout differs. This module ensures that any module + with different layouts will have different names. It also ensures that + identical layouts will share the same name to reduce file size and promote + hierarchical sharing. + """ + + def __init__(self): + # A dictionary of modules indexed by module type + self.modules = {} + # These are the indices to append to name to make unique object names + self.module_indices = {} + # A dictionary of instance lists indexed by module type + self.objects = {} + + def reset(self): + """ + Clear the factory instances for testing. + """ + self.__init__() + + def create(self, module_type, **kwargs): + """ + A generic function to create a module with a given module_type. The args + are passed directly to the module constructor. + """ + # if name!="": + # # This is a special case where the name and type don't match + # # Can't be overridden in the config file + # module_name = name + if hasattr(OPTS, module_type): + # Retrieve the name from OPTS if it exists, + # otherwise just use the name + module_name = getattr(OPTS, module_type) + else: + module_name = module_type + + # Either retrieve the already loaded module or load it + try: + mod = self.modules[module_type] + except KeyError: + c = reload(__import__(module_name)) + mod = getattr(c, module_name) + self.modules[module_type] = mod + self.module_indices[module_type] = 0 + self.objects[module_type] = [] + + # Either retreive a previous object or create a new one + for obj in self.objects[module_type]: + (obj_kwargs, obj_item) = obj + # Must have the same dictionary exactly (conservative) + if obj_kwargs == kwargs: + debug.info(1, "Existing module: type={0} name={1} kwargs={2}".format(module_type, obj_item.name, str(kwargs))) + return obj_item + + # Use the default name if there are default arguments + # This is especially for library cells so that the spice and gds files can be found. + if len(kwargs)>0: + # Create a unique name and increment the index + module_name = "{0}_{1}".format(module_name, self.module_indices[module_type]) + self.module_indices[module_type] += 1 + debug.info(1, "New module: type={0} name={1} kwargs={2}".format(module_type,module_name,str(kwargs))) + obj = mod(name=module_name,**kwargs) + self.objects[module_type].append((kwargs,obj)) + return obj + + +# Make a factory +factory = sram_factory() + diff --git a/compiler/tests/00_code_format_check_test.py b/compiler/tests/00_code_format_check_test.py index 869e81bd..98799ee8 100755 --- a/compiler/tests/00_code_format_check_test.py +++ b/compiler/tests/00_code_format_check_test.py @@ -25,17 +25,11 @@ class code_format_test(openram_test): for code in source_codes: if re.search("gdsMill", code): continue - if re.search("options.py$", code): - continue if re.search("debug.py$", code): continue - if re.search("testutils.py$", code): - continue - if re.search("globals.py$", code): - continue if re.search("openram.py$", code): continue - if re.search("sram.py$", code): + if re.search("testutils.py$", code): continue if re.search("gen_stimulus.py$", code): continue diff --git a/compiler/tests/04_pand2_test.py b/compiler/tests/04_pand2_test.py index 68433e96..91b3458e 100755 --- a/compiler/tests/04_pand2_test.py +++ b/compiler/tests/04_pand2_test.py @@ -21,7 +21,7 @@ class pand2_test(openram_test): import pand2 debug.info(2, "Testing pand2 gate 4x") - a = pand2.pand2(4) + a = pand2.pand2(name="pand2x4", size=4) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/04_pbitcell_test.py b/compiler/tests/04_pbitcell_test.py index e5dbbc5e..96e6bba8 100755 --- a/compiler/tests/04_pbitcell_test.py +++ b/compiler/tests/04_pbitcell_test.py @@ -10,8 +10,7 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug - -OPTS = globals.OPTS +from sram_factory import factory #@unittest.skip("SKIPPING 04_pbitcell_test") class pbitcell_test(openram_test): @@ -19,75 +18,85 @@ class pbitcell_test(openram_test): def runTest(self): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) from pbitcell import pbitcell - import tech + OPTS.num_rw_ports=1 OPTS.num_w_ports=1 OPTS.num_r_ports=1 + factory.reset() debug.info(2, "Bitcell with 1 of each port: read/write, write, and read") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) OPTS.num_rw_ports=0 OPTS.num_w_ports=1 OPTS.num_r_ports=1 + factory.reset() debug.info(2, "Bitcell with 0 read/write ports") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) OPTS.num_rw_ports=1 OPTS.num_w_ports=0 OPTS.num_r_ports=1 + factory.reset() debug.info(2, "Bitcell with 0 write ports") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) OPTS.num_rw_ports=1 OPTS.num_w_ports=1 OPTS.num_r_ports=0 + factory.reset() debug.info(2, "Bitcell with 0 read ports") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) OPTS.num_rw_ports=1 OPTS.num_w_ports=0 OPTS.num_r_ports=0 + factory.reset() debug.info(2, "Bitcell with 0 read ports and 0 write ports") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) OPTS.num_rw_ports=2 OPTS.num_w_ports=2 OPTS.num_r_ports=2 + factory.reset() debug.info(2, "Bitcell with 2 of each port: read/write, write, and read") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) OPTS.num_rw_ports=0 OPTS.num_w_ports=2 OPTS.num_r_ports=2 + factory.reset() debug.info(2, "Bitcell with 0 read/write ports") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) OPTS.num_rw_ports=2 OPTS.num_w_ports=0 OPTS.num_r_ports=2 + factory.reset() debug.info(2, "Bitcell with 0 write ports") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) OPTS.num_rw_ports=2 OPTS.num_w_ports=2 OPTS.num_r_ports=0 + factory.reset() debug.info(2, "Bitcell with 0 read ports") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) OPTS.num_rw_ports=2 OPTS.num_w_ports=0 OPTS.num_r_ports=0 + factory.reset() debug.info(2, "Bitcell with 0 read ports and 0 write ports") - tx = pbitcell() + tx = pbitcell(name="pbc") self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/04_pbuf_test.py b/compiler/tests/04_pbuf_test.py index f784c671..ed5b8627 100755 --- a/compiler/tests/04_pbuf_test.py +++ b/compiler/tests/04_pbuf_test.py @@ -21,7 +21,7 @@ class pbuf_test(openram_test): import pbuf debug.info(2, "Testing inverter/buffer 4x 8x") - a = pbuf.pbuf(8) + a = pbuf.pbuf(name="pbufx8", size=8) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/04_pdriver_test.py b/compiler/tests/04_pdriver_test.py index 8db39d8c..ee1b8e1a 100755 --- a/compiler/tests/04_pdriver_test.py +++ b/compiler/tests/04_pdriver_test.py @@ -23,16 +23,21 @@ class pdriver_test(openram_test): debug.info(2, "Testing inverter/buffer 4x 8x") # a tests the error message for specifying conflicting conditions #a = pdriver.pdriver(fanout_size = 4,size_list = [1,2,4,8]) - b = pdriver.pdriver(size_list = [1,2,4,8]) - c = pdriver.pdriver(fanout_size = 50) - d = pdriver.pdriver(fanout_size = 50, neg_polarity = True) - e = pdriver.pdriver(fanout_size = 64) - f = pdriver.pdriver(fanout_size = 64, neg_polarity = True) #self.local_check(a) + + b = pdriver.pdriver(name="pdriver1", size_list = [1,2,4,8]) self.local_check(b) + + c = pdriver.pdriver(name="pdriver2", fanout_size = 50) self.local_check(c) + + d = pdriver.pdriver(name="pdriver3", fanout_size = 50, neg_polarity = True) self.local_check(d) + + e = pdriver.pdriver(name="pdriver4", fanout_size = 64) self.local_check(e) + + f = pdriver.pdriver(name="pdriver5", fanout_size = 64, neg_polarity = True) self.local_check(f) globals.end_openram() diff --git a/compiler/tests/04_pinv_10x_test.py b/compiler/tests/04_pinv_10x_test.py index d457d2a9..42c38ca1 100755 --- a/compiler/tests/04_pinv_10x_test.py +++ b/compiler/tests/04_pinv_10x_test.py @@ -19,7 +19,7 @@ class pinv_test(openram_test): import tech debug.info(2, "Checking 10x inverter") - tx = pinv.pinv(size=8) + tx = pinv.pinv(name="pinvx10",size=8) self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/04_pinv_1x_beta_test.py b/compiler/tests/04_pinv_1x_beta_test.py index 77ff5454..9ac66a65 100755 --- a/compiler/tests/04_pinv_1x_beta_test.py +++ b/compiler/tests/04_pinv_1x_beta_test.py @@ -19,7 +19,7 @@ class pinv_test(openram_test): import tech debug.info(2, "Checking 1x beta=3 size inverter") - tx = pinv.pinv(size=1, beta=3) + tx = pinv.pinv(name="pinvx1b", size=1, beta=3) self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/04_pinv_1x_test.py b/compiler/tests/04_pinv_1x_test.py index 49cb1cb1..850aa78e 100755 --- a/compiler/tests/04_pinv_1x_test.py +++ b/compiler/tests/04_pinv_1x_test.py @@ -18,7 +18,7 @@ class pinv_test(openram_test): import tech debug.info(2, "Checking 1x size inverter") - tx = pinv.pinv(size=1) + tx = pinv.pinv(name="pinvx1", size=1) self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/04_pinv_2x_test.py b/compiler/tests/04_pinv_2x_test.py index 84bc55ee..33950da9 100755 --- a/compiler/tests/04_pinv_2x_test.py +++ b/compiler/tests/04_pinv_2x_test.py @@ -19,7 +19,7 @@ class pinv_test(openram_test): import tech debug.info(2, "Checking 2x size inverter") - tx = pinv.pinv(size=2) + tx = pinv.pinv(name="pinvx2", size=2) self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/04_pinvbuf_test.py b/compiler/tests/04_pinvbuf_test.py index d35f1ec7..53814628 100755 --- a/compiler/tests/04_pinvbuf_test.py +++ b/compiler/tests/04_pinvbuf_test.py @@ -18,7 +18,7 @@ class pinvbuf_test(openram_test): import pinvbuf debug.info(2, "Testing inverter/buffer 4x 8x") - a = pinvbuf.pinvbuf(8) + a = pinvbuf.pinvbuf(name="pinvufx8", size=8) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/04_pnand2_test.py b/compiler/tests/04_pnand2_test.py index a2ac9288..cb0b65c6 100755 --- a/compiler/tests/04_pnand2_test.py +++ b/compiler/tests/04_pnand2_test.py @@ -21,7 +21,7 @@ class pnand2_test(openram_test): import tech debug.info(2, "Checking 2-input nand gate") - tx = pnand2.pnand2(size=1) + tx = pnand2.pnand2(name="pnand2", size=1) self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/04_pnand3_test.py b/compiler/tests/04_pnand3_test.py index f6daedda..f3bbdb73 100755 --- a/compiler/tests/04_pnand3_test.py +++ b/compiler/tests/04_pnand3_test.py @@ -21,7 +21,7 @@ class pnand3_test(openram_test): import tech debug.info(2, "Checking 3-input nand gate") - tx = pnand3.pnand3(size=1) + tx = pnand3.pnand3(name="pnand3", size=1) self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/04_pnor2_test.py b/compiler/tests/04_pnor2_test.py index ce4b19ae..32214ded 100755 --- a/compiler/tests/04_pnor2_test.py +++ b/compiler/tests/04_pnor2_test.py @@ -21,7 +21,7 @@ class pnor2_test(openram_test): import tech debug.info(2, "Checking 2-input nor gate") - tx = pnor2.pnor2(size=1) + tx = pnor2.pnor2(name="pnor2", size=1) self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/04_precharge_test.py b/compiler/tests/04_precharge_test.py index 6c0cfe56..a73595eb 100755 --- a/compiler/tests/04_precharge_test.py +++ b/compiler/tests/04_precharge_test.py @@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory class precharge_test(openram_test): @@ -28,7 +29,8 @@ class precharge_test(openram_test): OPTS.num_rw_ports = 1 OPTS.num_r_ports = 1 OPTS.num_w_ports = 1 - + + factory.reset() debug.info(2, "Checking precharge for pbitcell (innermost connections)") tx = precharge.precharge(name="precharge_driver", size=1, bitcell_bl="bl0", bitcell_br="br0") self.local_check(tx) diff --git a/compiler/tests/04_replica_pbitcell_test.py b/compiler/tests/04_replica_pbitcell_test.py index ce9f00b9..9a672419 100755 --- a/compiler/tests/04_replica_pbitcell_test.py +++ b/compiler/tests/04_replica_pbitcell_test.py @@ -10,29 +10,31 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory class replica_pbitcell_test(openram_test): def runTest(self): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) import replica_pbitcell - import tech OPTS.bitcell = "pbitcell" OPTS.num_rw_ports = 1 OPTS.num_r_ports = 0 OPTS.num_w_ports = 0 - + + factory.reset() debug.info(2, "Checking replica bitcell using pbitcell (small cell)") - tx = replica_pbitcell.replica_pbitcell() + tx = replica_pbitcell.replica_pbitcell(name="rpbc") self.local_check(tx) OPTS.num_rw_ports = 1 OPTS.num_r_ports = 1 OPTS.num_w_ports = 1 - + + factory.reset() debug.info(2, "Checking replica bitcell using pbitcell (large cell)") - tx = replica_pbitcell.replica_pbitcell() + tx = replica_pbitcell.replica_pbitcell(name="rpbc") self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/04_single_level_column_mux_test.py b/compiler/tests/04_single_level_column_mux_test.py index c43b15fd..2a107b9a 100755 --- a/compiler/tests/04_single_level_column_mux_test.py +++ b/compiler/tests/04_single_level_column_mux_test.py @@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory #@unittest.skip("SKIPPING 04_driver_test") @@ -22,7 +23,7 @@ class single_level_column_mux_test(openram_test): # check single level column mux in single port debug.info(2, "Checking column mux") - tx = single_level_column_mux.single_level_column_mux(tx_size=8) + tx = single_level_column_mux.single_level_column_mux(name="mux8", tx_size=8) self.local_check(tx) # check single level column mux in multi-port @@ -30,13 +31,15 @@ class single_level_column_mux_test(openram_test): OPTS.num_rw_ports = 1 OPTS.num_r_ports = 1 OPTS.num_w_ports = 1 - + + factory.reset() debug.info(2, "Checking column mux for pbitcell (innermost connections)") - tx = single_level_column_mux.single_level_column_mux(tx_size=8, bitcell_bl="bl0", bitcell_br="br0") + tx = single_level_column_mux.single_level_column_mux(name="mux8_2", tx_size=8, bitcell_bl="bl0", bitcell_br="br0") self.local_check(tx) + factory.reset() debug.info(2, "Checking column mux for pbitcell (outermost connections)") - tx = single_level_column_mux.single_level_column_mux(tx_size=8, bitcell_bl="bl2", bitcell_br="br2") + tx = single_level_column_mux.single_level_column_mux(name="mux8_3", tx_size=8, bitcell_bl="bl2", bitcell_br="br2") self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/06_hierarchical_decoder_test.py b/compiler/tests/06_hierarchical_decoder_test.py index 09201149..2400d3c2 100755 --- a/compiler/tests/06_hierarchical_decoder_test.py +++ b/compiler/tests/06_hierarchical_decoder_test.py @@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory class hierarchical_decoder_test(openram_test): @@ -20,29 +21,29 @@ class hierarchical_decoder_test(openram_test): # Doesn't require hierarchical decoder # debug.info(1, "Testing 4 row sample for hierarchical_decoder") - # a = hierarchical_decoder.hierarchical_decoder(rows=4) + # a = hierarchical_decoder.hierarchical_decoder(name="hd1, rows=4) # self.local_check(a) # Doesn't require hierarchical decoder # debug.info(1, "Testing 8 row sample for hierarchical_decoder") - # a = hierarchical_decoder.hierarchical_decoder(rows=8) + # a = hierarchical_decoder.hierarchical_decoder(name="hd2", rows=8) # self.local_check(a) # check hierarchical decoder for single port debug.info(1, "Testing 16 row sample for hierarchical_decoder") - a = hierarchical_decoder.hierarchical_decoder(rows=16) + a = hierarchical_decoder.hierarchical_decoder(name="hd3", rows=16) self.local_check(a) debug.info(1, "Testing 32 row sample for hierarchical_decoder") - a = hierarchical_decoder.hierarchical_decoder(rows=32) + a = hierarchical_decoder.hierarchical_decoder(name="hd4", rows=32) self.local_check(a) debug.info(1, "Testing 128 row sample for hierarchical_decoder") - a = hierarchical_decoder.hierarchical_decoder(rows=128) + a = hierarchical_decoder.hierarchical_decoder(name="hd5", rows=128) self.local_check(a) debug.info(1, "Testing 512 row sample for hierarchical_decoder") - a = hierarchical_decoder.hierarchical_decoder(rows=512) + a = hierarchical_decoder.hierarchical_decoder(name="hd6", rows=512) self.local_check(a) # check hierarchical decoder for multi-port @@ -50,21 +51,22 @@ class hierarchical_decoder_test(openram_test): OPTS.num_rw_ports = 1 OPTS.num_w_ports = 0 OPTS.num_r_ports = 0 - + + factory.reset() debug.info(1, "Testing 16 row sample for hierarchical_decoder (multi-port case)") - a = hierarchical_decoder.hierarchical_decoder(rows=16) + a = hierarchical_decoder.hierarchical_decoder(name="hd7", rows=16) self.local_check(a) debug.info(1, "Testing 32 row sample for hierarchical_decoder (multi-port case)") - a = hierarchical_decoder.hierarchical_decoder(rows=32) + a = hierarchical_decoder.hierarchical_decoder(name="hd8", rows=32) self.local_check(a) debug.info(1, "Testing 128 row sample for hierarchical_decoder (multi-port case)") - a = hierarchical_decoder.hierarchical_decoder(rows=128) + a = hierarchical_decoder.hierarchical_decoder(name="hd9", rows=128) self.local_check(a) debug.info(1, "Testing 512 row sample for hierarchical_decoder (multi-port case)") - a = hierarchical_decoder.hierarchical_decoder(rows=512) + a = hierarchical_decoder.hierarchical_decoder(name="hd10", rows=512) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/06_hierarchical_predecode2x4_test.py b/compiler/tests/06_hierarchical_predecode2x4_test.py index e16916d6..6fbba350 100755 --- a/compiler/tests/06_hierarchical_predecode2x4_test.py +++ b/compiler/tests/06_hierarchical_predecode2x4_test.py @@ -20,7 +20,7 @@ class hierarchical_predecode2x4_test(openram_test): # checking hierarchical precode 2x4 for single port debug.info(1, "Testing sample for hierarchy_predecode2x4") - a = pre.hierarchical_predecode2x4() + a = pre.hierarchical_predecode2x4(name="pre1") self.local_check(a) # checking hierarchical precode 2x4 for multi-port @@ -30,7 +30,7 @@ class hierarchical_predecode2x4_test(openram_test): OPTS.num_r_ports = 0 debug.info(1, "Testing sample for hierarchy_predecode2x4 (multi-port case)") - a = pre.hierarchical_predecode2x4() + a = pre.hierarchical_predecode2x4(name="pre2") self.local_check(a) globals.end_openram() diff --git a/compiler/tests/06_hierarchical_predecode3x8_test.py b/compiler/tests/06_hierarchical_predecode3x8_test.py index ed5da57c..b704a50d 100755 --- a/compiler/tests/06_hierarchical_predecode3x8_test.py +++ b/compiler/tests/06_hierarchical_predecode3x8_test.py @@ -20,7 +20,7 @@ class hierarchical_predecode3x8_test(openram_test): # checking hierarchical precode 3x8 for single port debug.info(1, "Testing sample for hierarchy_predecode3x8") - a = pre.hierarchical_predecode3x8() + a = pre.hierarchical_predecode3x8(name="pre1") self.local_check(a) # checking hierarchical precode 3x8 for multi-port @@ -30,7 +30,7 @@ class hierarchical_predecode3x8_test(openram_test): OPTS.num_r_ports = 0 debug.info(1, "Testing sample for hierarchy_predecode3x8 (multi-port case)") - a = pre.hierarchical_predecode3x8() + a = pre.hierarchical_predecode3x8(name="pre2") self.local_check(a) globals.end_openram() diff --git a/compiler/tests/07_single_level_column_mux_array_test.py b/compiler/tests/07_single_level_column_mux_array_test.py index 800292b6..8cc16f56 100755 --- a/compiler/tests/07_single_level_column_mux_array_test.py +++ b/compiler/tests/07_single_level_column_mux_array_test.py @@ -9,6 +9,7 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory class single_level_column_mux_test(openram_test): @@ -18,15 +19,15 @@ class single_level_column_mux_test(openram_test): # check single level column mux array in single port debug.info(1, "Testing sample for 2-way column_mux_array") - a = single_level_column_mux_array.single_level_column_mux_array(columns=16, word_size=8) + a = single_level_column_mux_array.single_level_column_mux_array(name="mux1", columns=16, word_size=8) self.local_check(a) debug.info(1, "Testing sample for 4-way column_mux_array") - a = single_level_column_mux_array.single_level_column_mux_array(columns=16, word_size=4) + a = single_level_column_mux_array.single_level_column_mux_array(name="mux2", columns=16, word_size=4) self.local_check(a) debug.info(1, "Testing sample for 8-way column_mux_array") - a = single_level_column_mux_array.single_level_column_mux_array(columns=32, word_size=4) + a = single_level_column_mux_array.single_level_column_mux_array(name="mux3", columns=32, word_size=4) self.local_check(a) # check single level column mux array in multi-port @@ -34,21 +35,22 @@ class single_level_column_mux_test(openram_test): OPTS.num_rw_ports = 1 OPTS.num_r_ports = 1 OPTS.num_w_ports = 1 - + + factory.reset() debug.info(1, "Testing sample for 2-way column_mux_array in multi-port") - a = single_level_column_mux_array.single_level_column_mux_array(columns=16, word_size=8, bitcell_bl="bl0", bitcell_br="br0") + a = single_level_column_mux_array.single_level_column_mux_array(name="mux4", columns=16, word_size=8, bitcell_bl="bl0", bitcell_br="br0") self.local_check(a) debug.info(1, "Testing sample for 4-way column_mux_array in multi-port") - a = single_level_column_mux_array.single_level_column_mux_array(columns=16, word_size=4, bitcell_bl="bl0", bitcell_br="br0") + a = single_level_column_mux_array.single_level_column_mux_array(name="mux5", columns=16, word_size=4, bitcell_bl="bl0", bitcell_br="br0") self.local_check(a) debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (innermost connections)") - a = single_level_column_mux_array.single_level_column_mux_array(columns=32, word_size=4, bitcell_bl="bl0", bitcell_br="br0") + a = single_level_column_mux_array.single_level_column_mux_array(name="mux6", columns=32, word_size=4, bitcell_bl="bl0", bitcell_br="br0") self.local_check(a) debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (outermost connections)") - a = single_level_column_mux_array.single_level_column_mux_array(columns=32, word_size=4, bitcell_bl="bl2", bitcell_br="br2") + a = single_level_column_mux_array.single_level_column_mux_array(name="mux7", columns=32, word_size=4, bitcell_bl="bl2", bitcell_br="br2") self.local_check(a) globals.end_openram() diff --git a/compiler/tests/08_precharge_array_test.py b/compiler/tests/08_precharge_array_test.py index cdf6100e..c31f133a 100755 --- a/compiler/tests/08_precharge_array_test.py +++ b/compiler/tests/08_precharge_array_test.py @@ -10,17 +10,17 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory class precharge_test(openram_test): def runTest(self): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) import precharge_array - import tech # check precharge array in single port debug.info(2, "Checking 3 column precharge") - pc = precharge_array.precharge_array(columns=3) + pc = precharge_array.precharge_array(name="pre1", columns=3) self.local_check(pc) # check precharge array in multi-port @@ -28,17 +28,18 @@ class precharge_test(openram_test): OPTS.num_rw_ports = 1 OPTS.num_r_ports = 1 OPTS.num_w_ports = 0 - + + factory.reset() debug.info(2, "Checking 3 column precharge array for 1RW/1R bitcell") - pc = precharge_array.precharge_array(columns=3, bitcell_bl="bl0", bitcell_br="br0") + pc = precharge_array.precharge_array(name="pre2", columns=3, bitcell_bl="bl0", bitcell_br="br0") self.local_check(pc) # debug.info(2, "Checking 3 column precharge array for pbitcell (innermost connections)") - # pc = precharge_array.precharge_array(columns=3, bitcell_bl="bl0", bitcell_br="br0") + # pc = precharge_array.precharge_array(name="pre3", columns=3, bitcell_bl="bl0", bitcell_br="br0") # self.local_check(pc) # debug.info(2, "Checking 3 column precharge array for pbitcell (outermost connections)") - # pc = precharge_array.precharge_array(columns=3, bitcell_bl="bl2", bitcell_br="br2") + # pc = precharge_array.precharge_array(name="pre4", columns=3, bitcell_bl="bl2", bitcell_br="br2") # self.local_check(pc) globals.end_openram() diff --git a/compiler/tests/08_wordline_driver_test.py b/compiler/tests/08_wordline_driver_test.py index 369b6774..bfbf54d8 100755 --- a/compiler/tests/08_wordline_driver_test.py +++ b/compiler/tests/08_wordline_driver_test.py @@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory #@unittest.skip("SKIPPING 04_driver_test") @@ -18,11 +19,10 @@ class wordline_driver_test(openram_test): def runTest(self): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) import wordline_driver - import tech # check wordline driver for single port debug.info(2, "Checking driver") - tx = wordline_driver.wordline_driver(rows=8) + tx = wordline_driver.wordline_driver(name="wld1", rows=8) self.local_check(tx) # check wordline driver for multi-port @@ -30,9 +30,10 @@ class wordline_driver_test(openram_test): OPTS.num_rw_ports = 1 OPTS.num_w_ports = 0 OPTS.num_r_ports = 0 - + + factory.reset() debug.info(2, "Checking driver (multi-port case)") - tx = wordline_driver.wordline_driver(rows=8) + tx = wordline_driver.wordline_driver(name="wld2", rows=8) self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/09_sense_amp_array_test.py b/compiler/tests/09_sense_amp_array_test.py index a18631f9..c144b12b 100755 --- a/compiler/tests/09_sense_amp_array_test.py +++ b/compiler/tests/09_sense_amp_array_test.py @@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory class sense_amp_test(openram_test): @@ -19,11 +20,11 @@ class sense_amp_test(openram_test): # check sense amp array for single port debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=2") - a = sense_amp_array.sense_amp_array(word_size=4, words_per_row=2) + a = sense_amp_array.sense_amp_array(name="sa1", word_size=4, words_per_row=2) self.local_check(a) debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=4") - a = sense_amp_array.sense_amp_array(word_size=4, words_per_row=4) + a = sense_amp_array.sense_amp_array(name="sa2", word_size=4, words_per_row=4) self.local_check(a) # check sense amp array for multi-port @@ -31,13 +32,14 @@ class sense_amp_test(openram_test): OPTS.num_rw_ports = 1 OPTS.num_w_ports = 0 OPTS.num_r_ports = 0 - + + factory.reset() debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=2 (multi-port case)") - a = sense_amp_array.sense_amp_array(word_size=4, words_per_row=2) + a = sense_amp_array.sense_amp_array(name="sa3", word_size=4, words_per_row=2) self.local_check(a) debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=4 (multi-port case)") - a = sense_amp_array.sense_amp_array(word_size=4, words_per_row=4) + a = sense_amp_array.sense_amp_array(name="sa4", word_size=4, words_per_row=4) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/10_write_driver_array_test.py b/compiler/tests/10_write_driver_array_test.py index fa374181..98507b60 100755 --- a/compiler/tests/10_write_driver_array_test.py +++ b/compiler/tests/10_write_driver_array_test.py @@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory class write_driver_test(openram_test): @@ -19,11 +20,11 @@ class write_driver_test(openram_test): # check write driver array for single port debug.info(2, "Testing write_driver_array for columns=8, word_size=8") - a = write_driver_array.write_driver_array(columns=8, word_size=8) + a = write_driver_array.write_driver_array(name="wd1", columns=8, word_size=8) self.local_check(a) debug.info(2, "Testing write_driver_array for columns=16, word_size=8") - a = write_driver_array.write_driver_array(columns=16, word_size=8) + a = write_driver_array.write_driver_array(name="wd2", columns=16, word_size=8) self.local_check(a) # check write driver array for multi-port @@ -31,13 +32,14 @@ class write_driver_test(openram_test): OPTS.num_rw_ports = 1 OPTS.num_w_ports = 0 OPTS.num_r_ports = 0 - + + factory.reset() debug.info(2, "Testing write_driver_array for columns=8, word_size=8 (multi-port case)") - a = write_driver_array.write_driver_array(columns=8, word_size=8) + a = write_driver_array.write_driver_array(name="wd3", columns=8, word_size=8) self.local_check(a) debug.info(2, "Testing write_driver_array for columns=16, word_size=8 (multi-port case)") - a = write_driver_array.write_driver_array(columns=16, word_size=8) + a = write_driver_array.write_driver_array(name="wd4", columns=16, word_size=8) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/13_delay_chain_test.py b/compiler/tests/13_delay_chain_test.py index 1052f0de..bfe2b3ff 100755 --- a/compiler/tests/13_delay_chain_test.py +++ b/compiler/tests/13_delay_chain_test.py @@ -18,7 +18,7 @@ class delay_chain_test(openram_test): import delay_chain debug.info(2, "Testing delay_chain") - a = delay_chain.delay_chain(fanout_list=[4, 4, 4, 4]) + a = delay_chain.delay_chain(name="dc", fanout_list=[4, 4, 4, 4]) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/14_replica_bitline_multiport_test.py b/compiler/tests/14_replica_bitline_multiport_test.py index 41c3aa51..f379e0d2 100755 --- a/compiler/tests/14_replica_bitline_multiport_test.py +++ b/compiler/tests/14_replica_bitline_multiport_test.py @@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory class replica_bitline_multiport_test(openram_test): @@ -26,9 +27,10 @@ class replica_bitline_multiport_test(openram_test): OPTS.num_rw_ports = 1 OPTS.num_r_ports = 1 OPTS.num_w_ports = 0 - + + factory.reset() debug.info(2, "Testing 1rw 1r RBL with {0} FO4 stages, {1} rows".format(stages,rows)) - a = replica_bitline.replica_bitline(stages*[fanout],rows) + a = replica_bitline.replica_bitline(name="rbl1", delay_fanout_list=stages*[fanout], bitcell_loads=rows) self.local_check(a) # check replica bitline in pbitcell multi-port @@ -38,16 +40,18 @@ class replica_bitline_multiport_test(openram_test): OPTS.num_w_ports = 0 OPTS.num_r_ports = 0 + factory.reset() debug.info(2, "Testing RBL pbitcell 1rw with {0} FO4 stages, {1} rows".format(stages,rows)) - a = replica_bitline.replica_bitline(stages*[fanout],rows) + a = replica_bitline.replica_bitline(name="rbl2", delay_fanout_list=stages*[fanout], bitcell_loads=rows) self.local_check(a) OPTS.num_rw_ports = 1 OPTS.num_w_ports = 1 OPTS.num_r_ports = 1 + factory.reset() debug.info(2, "Testing RBL pbitcell 1rw 1w 1r with {0} FO4 stages, {1} rows".format(stages,rows)) - a = replica_bitline.replica_bitline(stages*[fanout],rows) + a = replica_bitline.replica_bitline(name="rbl3", delay_fanout_list=stages*[fanout], bitcell_loads=rows) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/14_replica_bitline_test.py b/compiler/tests/14_replica_bitline_test.py index 94a49f55..ca213d5c 100755 --- a/compiler/tests/14_replica_bitline_test.py +++ b/compiler/tests/14_replica_bitline_test.py @@ -22,14 +22,14 @@ class replica_bitline_test(openram_test): fanout=4 rows=13 debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows)) - a = replica_bitline.replica_bitline(stages*[fanout],rows) + a = replica_bitline.replica_bitline(name="rbl1", delay_fanout_list=stages*[fanout], bitcell_loads=rows) self.local_check(a) #debug.error("Exiting...", 1) stages=8 rows=100 debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows)) - a = replica_bitline.replica_bitline(stages*[fanout],rows) + a = replica_bitline.replica_bitline(name="rbl2", delay_fanout_list=stages*[fanout], bitcell_loads=rows) self.local_check(a) diff --git a/compiler/tests/19_psingle_bank_test.py b/compiler/tests/19_psingle_bank_test.py index ff19ac15..8e462318 100755 --- a/compiler/tests/19_psingle_bank_test.py +++ b/compiler/tests/19_psingle_bank_test.py @@ -10,15 +10,13 @@ sys.path.append(os.path.join(sys.path[0],"..")) import globals from globals import OPTS import debug +from sram_factory import factory #@unittest.skip("SKIPPING 19_psingle_bank_test") class psingle_bank_test(openram_test): def runTest(self): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) - global verify - import verify - from bank import bank from sram_config import sram_config OPTS.bitcell = "pbitcell" @@ -31,6 +29,7 @@ class psingle_bank_test(openram_test): num_words=16) c.words_per_row=1 + factory.reset() c.recompute_sizes() debug.info(1, "No column mux") name = "bank1_{0}rw_{1}w_{2}r_single".format(OPTS.num_rw_ports, OPTS.num_w_ports, OPTS.num_r_ports) @@ -39,6 +38,7 @@ class psingle_bank_test(openram_test): c.num_words=32 c.words_per_row=2 + factory.reset() c.recompute_sizes() debug.info(1, "Two way column mux") name = "bank2_{0}rw_{1}w_{2}r_single".format(OPTS.num_rw_ports, OPTS.num_w_ports, OPTS.num_r_ports) @@ -47,6 +47,7 @@ class psingle_bank_test(openram_test): c.num_words=64 c.words_per_row=4 + factory.reset() c.recompute_sizes() debug.info(1, "Four way column mux") name = "bank3_{0}rw_{1}w_{2}r_single".format(OPTS.num_rw_ports, OPTS.num_w_ports, OPTS.num_r_ports) @@ -56,6 +57,7 @@ class psingle_bank_test(openram_test): c.word_size=2 c.num_words=128 c.words_per_row=8 + factory.reset() c.recompute_sizes() debug.info(1, "Four way column mux") name = "bank4_{0}rw_{1}w_{2}r_single".format(OPTS.num_rw_ports, OPTS.num_w_ports, OPTS.num_r_ports) diff --git a/technology/scn4m_subm/mag_lib/setup.tcl b/technology/scn4m_subm/mag_lib/setup.tcl index caf7550b..084428b5 100644 --- a/technology/scn4m_subm/mag_lib/setup.tcl +++ b/technology/scn4m_subm/mag_lib/setup.tcl @@ -4,11 +4,12 @@ equate class {-circuit1 nfet} {-circuit2 n} equate class {-circuit1 pfet} {-circuit2 p} # This circuit has symmetries and needs to be flattened to resolve them # or the banks won't pass -flatten class {-circuit1 bitcell_array} +flatten class {-circuit1 bitcell_array_0} +flatten class {-circuit1 bitcell_array_1} +flatten class {-circuit1 precharge_array_0} flatten class {-circuit1 precharge_array_1} flatten class {-circuit1 precharge_array_2} flatten class {-circuit1 precharge_array_3} -flatten class {-circuit1 precharge_array_4} property {-circuit1 nfet} remove as ad ps pd property {-circuit1 pfet} remove as ad ps pd property {-circuit2 n} remove as ad ps pd