Merge branch 'dev' into datasheet_gen

This commit is contained in:
Jesse Cirimelli-Low 2019-01-22 15:24:44 -08:00
commit 886dd4d313
82 changed files with 619 additions and 629 deletions

View File

@ -16,7 +16,9 @@ class contact(hierarchy_design.hierarchy_design):
hierarchy as the contact. 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: if implant_type or well_type:
name = "{0}_{1}_{2}_{3}x{4}_{5}{6}".format(layer_stack[0], name = "{0}_{1}_{2}_{3}x{4}_{5}{6}".format(layer_stack[0],
layer_stack[1], layer_stack[1],
@ -164,13 +166,13 @@ class contact(hierarchy_design.hierarchy_design):
""" Get total power of a module """ """ Get total power of a module """
return self.return_power() return self.return_power()
from sram_factory import factory
# This is not instantiated and used for calculations only. # This is not instantiated and used for calculations only.
# These are static 1x1 contacts to reuse in all the design modules. # These are static 1x1 contacts to reuse in all the design modules.
well = contact(layer_stack=("active", "contact", "metal1")) well = factory.create(module_type="contact", layer_stack=("active", "contact", "metal1"))
active = contact(layer_stack=("active", "contact", "poly")) active = factory.create(module_type="contact", layer_stack=("active", "contact", "poly"))
poly = contact(layer_stack=("poly", "contact", "metal1")) poly = factory.create(module_type="contact", layer_stack=("poly", "contact", "metal1"))
m1m2 = contact(layer_stack=("metal1", "via1", "metal2")) m1m2 = factory.create(module_type="contact", layer_stack=("metal1", "via1", "metal2"))
m2m3 = contact(layer_stack=("metal2", "via2", "metal3")) m2m3 = factory.create(module_type="contact", layer_stack=("metal2", "via2", "metal3"))
m3m4 = contact(layer_stack=("metal3", "via3", "metal4")) m3m4 = factory.create(module_type="contact", layer_stack=("metal3", "via3", "metal4"))

View File

@ -6,7 +6,6 @@ import debug
import os import os
from globals import OPTS from globals import OPTS
class design(hierarchy_design): class design(hierarchy_design):
""" """
This is the same as the hierarchy_design class except it contains This is the same as the hierarchy_design class except it contains

View File

@ -17,14 +17,8 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
name_map = [] name_map = []
def __init__(self, name): def __init__(self, name):
try: self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds"
self.gds_file self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp"
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.name = name self.name = name
hierarchy_layout.layout.__init__(self, name) hierarchy_layout.layout.__init__(self, name)

View File

@ -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): 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. """ """ Add a three layer via structure. """
import contact from sram_factory import factory
via = contact.contact(layer_stack=layers, via = factory.create(module_type="contact",
dimensions=size, layer_stack=layers,
implant_type=implant_type, dimensions=size,
well_type=well_type) implant_type=implant_type,
well_type=well_type)
self.add_mod(via) self.add_mod(via)
inst=self.add_inst(name=via.name, inst=self.add_inst(name=via.name,
mod=via, 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): 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. """ """ Add a three layer via structure by the center coordinate accounting for mirroring and rotation. """
import contact from sram_factory import factory
via = contact.contact(layer_stack=layers, via = factory.create(module_type="contact",
dimensions=size, layer_stack=layers,
implant_type=implant_type, dimensions=size,
well_type=well_type) implant_type=implant_type,
well_type=well_type)
height = via.height height = via.height
width = via.width width = via.width
debug.check(mirror=="R0","Use rotate to rotate vias instead of mirror.") 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 # Find the number of vias for this pitch
self.supply_vias = 1 self.supply_vias = 1
import contact from sram_factory import factory
while True: 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: if c.second_layer_width < self.supply_rail_width and c.second_layer_height < self.supply_rail_width:
self.supply_vias += 1 self.supply_vias += 1
else: else:

View File

@ -16,11 +16,14 @@ class spice():
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
self.mods = [] # Holds subckts/mods for this module # Holds subckts/mods for this module
self.pins = [] # Holds the pins for this module self.mods = []
self.pin_type = {} # The type map of each pin: INPUT, OUTPUT, INOUT, POWER, GROUND # 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 # 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) # Spice format)
self.conns = [] self.conns = []
@ -93,8 +96,8 @@ class spice():
from pprint import pformat from pprint import pformat
modpins_string=pformat(self.insts[-1].mod.pins) modpins_string=pformat(self.insts[-1].mod.pins)
argpins_string=pformat(args) argpins_string=pformat(args)
debug.error("Connections: {}".format(modpins_string)) debug.error("Mod connections: {}".format(modpins_string))
debug.error("Connections: {}".format(argpins_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), debug.error("Number of net connections ({0}) does not match last instance ({1})".format(len(self.insts[-1].mod.pins),
len(args)), 1) len(args)), 1)
self.conns.append(args) self.conns.append(args)

View File

@ -1,10 +1,10 @@
from tech import drc from tech import drc
import debug import debug
from design import design from design import design
from contact import contact
from itertools import tee from itertools import tee
from vector import vector from vector import vector
from vector3d import vector3d from vector3d import vector3d
from sram_factory import factory
class route(design): class route(design):
""" """
@ -45,7 +45,9 @@ class route(design):
self.horiz_layer_width = drc("minwidth_{0}".format(self.horiz_layer_name)) self.horiz_layer_width = drc("minwidth_{0}".format(self.horiz_layer_name))
# offset this by 1/2 the via size # 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): def create_wires(self):

View File

@ -1,7 +1,7 @@
from tech import drc from tech import drc
import debug import debug
from contact import contact
from path import path from path import path
from sram_factory import factory
class wire(path): class wire(path):
""" """
@ -37,15 +37,18 @@ class wire(path):
self.horiz_layer_name = horiz_layer self.horiz_layer_name = horiz_layer
self.horiz_layer_width = drc("minwidth_{0}".format(horiz_layer)) self.horiz_layer_width = drc("minwidth_{0}".format(horiz_layer))
via_connect = contact(self.layer_stack, via_connect = factory.create(module_type="contact",
(1, 1)) layer_stack=self.layer_stack,
dimensions=(1, 1))
self.node_to_node = [drc("minwidth_" + str(self.horiz_layer_name)) + via_connect.width, self.node_to_node = [drc("minwidth_" + str(self.horiz_layer_name)) + via_connect.width,
drc("minwidth_" + str(self.horiz_layer_name)) + via_connect.height] drc("minwidth_" + str(self.horiz_layer_name)) + via_connect.height]
# create a 1x1 contact # create a 1x1 contact
def create_vias(self): def create_vias(self):
""" Add a via and corner square at every corner of the path.""" """ 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_width = self.c.width
c_height = self.c.height c_height = self.c.height

View File

@ -15,7 +15,8 @@ class bitcell(design.design):
(width,height) = utils.get_libcell_size("cell_6t", GDS["unit"], layer["boundary"]) (width,height) = utils.get_libcell_size("cell_6t", GDS["unit"], layer["boundary"])
pin_map = utils.get_libcell_pins(pin_names, "cell_6t", GDS["unit"]) 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") design.design.__init__(self, "cell_6t")
debug.info(2, "Create bitcell") debug.info(2, "Create bitcell")

View File

@ -15,7 +15,8 @@ class bitcell_1rw_1r(design.design):
(width,height) = utils.get_libcell_size("cell_1rw_1r", GDS["unit"], layer["boundary"]) (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"]) 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") design.design.__init__(self, "cell_1rw_1r")
debug.info(2, "Create bitcell with 1RW and 1R Port") debug.info(2, "Create bitcell with 1RW and 1R Port")

View File

@ -12,8 +12,7 @@ class pbitcell(design.design):
with a variable number of read/write, write, and read ports 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_rw_ports = OPTS.num_rw_ports
self.num_w_ports = OPTS.num_w_ports self.num_w_ports = OPTS.num_w_ports
self.num_r_ports = OPTS.num_r_ports self.num_r_ports = OPTS.num_r_ports
@ -21,11 +20,6 @@ class pbitcell(design.design):
self.replica_bitcell = replica_bitcell 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) 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, 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, self.num_w_ports,

View File

@ -14,7 +14,8 @@ class replica_bitcell(design.design):
(width,height) = utils.get_libcell_size("replica_cell_6t", GDS["unit"], layer["boundary"]) (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"]) 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") design.design.__init__(self, "replica_cell_6t")
debug.info(2, "Create replica bitcell object") debug.info(2, "Create replica bitcell object")

View File

@ -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"]) (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"]) 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") design.design.__init__(self, "replica_cell_1rw_1r")
debug.info(2, "Create replica bitcell 1rw+1r object") debug.info(2, "Create replica bitcell 1rw+1r object")

View File

@ -3,21 +3,20 @@ import design
from tech import drc, spice,parameter from tech import drc, spice,parameter
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from pbitcell import pbitcell from sram_factory import factory
class replica_pbitcell(design.design): class replica_pbitcell(design.design):
""" """
Creates a replica bitcell using pbitcell Creates a replica bitcell using pbitcell
""" """
def __init__(self): def __init__(self, name):
self.num_rw_ports = OPTS.num_rw_ports self.num_rw_ports = OPTS.num_rw_ports
self.num_w_ports = OPTS.num_w_ports self.num_w_ports = OPTS.num_w_ports
self.num_r_ports = OPTS.num_r_ports self.num_r_ports = OPTS.num_r_ports
self.total_ports = self.num_rw_ports + self.num_w_ports + self.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, 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_w_ports,
self.num_r_ports)) self.num_r_ports))
@ -47,7 +46,7 @@ class replica_pbitcell(design.design):
self.add_pin("gnd") self.add_pin("gnd")
def add_modules(self): 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.add_mod(self.prbc)
self.height = self.prbc.height self.height = self.prbc.height

View File

@ -1,7 +1,8 @@
from .gdsPrimitives import * from .gdsPrimitives import *
from datetime import * from datetime import *
#from mpmath import matrix #from mpmath import matrix
from numpy import matrix #from numpy import matrix
import numpy as np
#import gdsPrimitives #import gdsPrimitives
import debug import debug
@ -170,21 +171,20 @@ class VlsiLayout:
else: else:
# MRG: Added negative to make CCW rotate 8/29/18 # MRG: Added negative to make CCW rotate 8/29/18
angle = math.radians(float(rotateAngle)) 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], [math.sin(angle),math.cos(angle),0.0],
[0.0,0.0,1.0]]) [0.0,0.0,1.0]])
#set up the translation matrix #set up the translation matrix
translateX = float(coordinates[0]) translateX = float(coordinates[0])
translateY = float(coordinates[1]) 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) #set up the scale matrix (handles mirror X)
scaleX = 1.0 scaleX = 1.0
if(transFlags[0]): if(transFlags[0]):
scaleY = -1.0 scaleY = -1.0
else: else:
scaleY = 1.0 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 #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 #when we add an element to the xy tree, we apply all transforms from the bottom up
transformPath.append((mRotate,mScale,mTranslate)) transformPath.append((mRotate,mScale,mTranslate))
@ -219,23 +219,22 @@ class VlsiLayout:
def populateCoordinateMap(self): def populateCoordinateMap(self):
def addToXyTree(startingStructureName = None,transformPath = None): def addToXyTree(startingStructureName = None,transformPath = None):
#print("populateCoordinateMap") uVector = np.array([[1.0],[0.0],[0.0]]) #start with normal basis vectors
uVector = matrix([1.0,0.0,0.0]).transpose() #start with normal basis vectors vVector = np.array([[0.0],[1.0],[0.0]])
vVector = matrix([0.0,1.0,0.0]).transpose() origin = np.array([[0.0],[0.0],[1.0]]) #and an origin (Z component is 1.0 to indicate position instead of vector)
origin = matrix([0.0,0.0,1.0]).transpose() #and an origin (Z component is 1.0 to indicate position instead of vector)
#make a copy of all the transforms and reverse it #make a copy of all the transforms and reverse it
reverseTransformPath = transformPath[:] reverseTransformPath = transformPath[:]
if len(reverseTransformPath) > 1: if len(reverseTransformPath) > 1:
reverseTransformPath.reverse() reverseTransformPath.reverse()
#now go through each transform and apply them to our basis and origin in succession #now go through each transform and apply them to our basis and origin in succession
for transform in reverseTransformPath: for transform in reverseTransformPath:
origin = transform[0] * origin #rotate origin = np.dot(transform[0], origin) #rotate
uVector = transform[0] * uVector #rotate uVector = np.dot(transform[0], uVector) #rotate
vVector = transform[0] * vVector #rotate vVector = np.dot(transform[0], vVector) #rotate
origin = transform[1] * origin #scale origin = np.dot(transform[1], origin) #scale
uVector = transform[1] * uVector #scale uVector = np.dot(transform[1], uVector) #scale
vVector = transform[1] * vVector #scale vVector = np.dot(transform[1], vVector) #scale
origin = transform[2] * origin #translate origin = np.dot(transform[2], origin) #translate
#we don't need to do a translation on the basis vectors #we don't need to do a translation on the basis vectors
#uVector = transform[2] * uVector #translate #uVector = transform[2] * uVector #translate
#vVector = transform[2] * vVector #translate #vVector = transform[2] * vVector #translate
@ -522,8 +521,7 @@ class VlsiLayout:
return True return True
def fillAreaDensity(self, layerToFill = 0, offsetInMicrons = (0,0), coverageWidth = 100.0, coverageHeight = 100.0, def fillAreaDensity(self, layerToFill = 0, offsetInMicrons = (0,0), coverageWidth = 100.0, coverageHeight = 100.0, minSpacing = 0.22, blockSize = 1.0):
minSpacing = 0.22, blockSize = 1.0):
effectiveBlock = blockSize+minSpacing effectiveBlock = blockSize+minSpacing
widthInBlocks = int(coverageWidth/effectiveBlock) widthInBlocks = int(coverageWidth/effectiveBlock)
heightInBlocks = int(coverageHeight/effectiveBlock) heightInBlocks = int(coverageHeight/effectiveBlock)
@ -810,8 +808,8 @@ class VlsiLayout:
# This is fixed to be: # This is fixed to be:
# |u[0] v[0]| |x| |x'| # |u[0] v[0]| |x| |x'|
# |u[1] v[1]|x|y|=|y'| # |u[1] v[1]|x|y|=|y'|
x=coordinate[0]*uVector[0].item()+coordinate[1]*vVector[0].item() x=coordinate[0]*uVector[0][0]+coordinate[1]*vVector[0][0]
y=coordinate[0]*uVector[1].item()+coordinate[1]*vVector[1].item() y=coordinate[0]*uVector[1][0]+coordinate[1]*vVector[1][0]
transformCoordinate=[x,y] transformCoordinate=[x,y]
return transformCoordinate return transformCoordinate
@ -836,5 +834,3 @@ def boundaryArea(A):
area_A=(A[2]-A[0])*(A[3]-A[1]) area_A=(A[2]-A[0])*(A[3]-A[1])
return area_A return area_A

View File

@ -130,6 +130,9 @@ def init_openram(config_file, is_unit_test=True):
init_paths() init_paths()
from sram_factory import factory
factory.reset()
# Reset the static duplicate name checker for unit tests. # Reset the static duplicate name checker for unit tests.
import hierarchy_design import hierarchy_design
hierarchy_design.hierarchy_design.name_map=[] hierarchy_design.hierarchy_design.name_map=[]

View File

@ -6,9 +6,7 @@ import math
from math import log,sqrt,ceil from math import log,sqrt,ceil
import contact import contact
import pgates import pgates
from pinv import pinv from sram_factory import factory
from pnand2 import pnand2
from pnor2 import pnor2
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
@ -396,25 +394,14 @@ class bank(design.design):
def add_modules(self): def add_modules(self):
""" Add all the modules using the class loader """ """ 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 = factory.create(module_type="bitcell_array",
cols=self.num_cols,
self.bitcell_array = self.mod_bitcell_array(cols=self.num_cols, rows=self.num_rows)
rows=self.num_rows)
self.add_mod(self.bitcell_array) self.add_mod(self.bitcell_array)
# create arrays of bitline and bitline_bar names for read, write, or all ports # 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.bl_names = self.bitcell.list_all_bl_names()
self.br_names = self.bitcell.list_all_br_names() self.br_names = self.bitcell.list_all_br_names()
self.wl_names = self.bitcell.list_all_wl_names() self.wl_names = self.bitcell.list_all_wl_names()
@ -423,7 +410,11 @@ class bank(design.design):
self.precharge_array = [] self.precharge_array = []
for port in self.all_ports: for port in self.all_ports:
if port in self.read_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]) self.add_mod(self.precharge_array[port])
else: else:
self.precharge_array.append(None) self.precharge_array.append(None)
@ -431,32 +422,38 @@ class bank(design.design):
if self.col_addr_size > 0: if self.col_addr_size > 0:
self.column_mux_array = [] self.column_mux_array = []
for port in self.all_ports: for port in self.all_ports:
self.column_mux_array.append(self.mod_column_mux_array(columns=self.num_cols, temp_col = factory.create(module_type="column_mux_array",
word_size=self.word_size, columns=self.num_cols,
bitcell_bl=self.bl_names[port], word_size=self.word_size,
bitcell_br=self.br_names[port])) 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.add_mod(self.column_mux_array[port])
self.sense_amp_array = self.mod_sense_amp_array(word_size=self.word_size, self.sense_amp_array = factory.create(module_type="sense_amp_array",
words_per_row=self.words_per_row) word_size=self.word_size,
words_per_row=self.words_per_row)
self.add_mod(self.sense_amp_array) self.add_mod(self.sense_amp_array)
self.write_driver_array = self.mod_write_driver_array(columns=self.num_cols, self.write_driver_array = factory.create(module_type="write_driver_array",
word_size=self.word_size) columns=self.num_cols,
word_size=self.word_size)
self.add_mod(self.write_driver_array) 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.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.add_mod(self.wordline_driver)
self.inv = pinv() self.inv = factory.create(module_type="pinv")
self.add_mod(self.inv) self.add_mod(self.inv)
if(self.num_banks > 1): 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) self.add_mod(self.bank_select)
@ -694,17 +691,16 @@ class bank(design.design):
Create a 2:4 or 3:8 column address decoder. Create a 2:4 or 3:8 column address decoder.
""" """
dff = factory.create(module_type="dff")
if self.col_addr_size == 0: if self.col_addr_size == 0:
return return
elif self.col_addr_size == 1: elif self.col_addr_size == 1:
from pinvbuf import pinvbuf self.column_decoder = factory.create(module_type="pinvbuf", height=dff.height)
self.column_decoder = pinvbuf(height=self.mod_dff.height)
elif self.col_addr_size == 2: elif self.col_addr_size == 2:
from hierarchical_predecode2x4 import hierarchical_predecode2x4 as pre2x4 self.column_decoder = factory.create(module_type="hierarchical_predecode2x4", height=dff.height)
self.column_decoder = pre2x4(height=self.mod_dff.height)
elif self.col_addr_size == 3: elif self.col_addr_size == 3:
from hierarchical_predecode3x8 import hierarchical_predecode3x8 as pre3x8 self.column_decoder = factory.create(module_type="hierarchical_predecode3x8", height=dff.height)
self.column_decoder = pre3x8(height=self.mod_dff.height)
else: else:
# No error checking before? # No error checking before?
debug.error("Invalid column decoder?",-1) debug.error("Invalid column decoder?",-1)

View File

@ -7,6 +7,7 @@ from pinv import pinv
from pnand2 import pnand2 from pnand2 import pnand2
from pnor2 import pnor2 from pnor2 import pnor2
from vector import vector from vector import vector
from sram_factory import factory
from globals import OPTS from globals import OPTS
class bank_select(design.design): class bank_select(design.design):
@ -62,28 +63,25 @@ class bank_select(design.design):
def add_modules(self): def add_modules(self):
""" Create modules for later instantiation """ """ Create modules for later instantiation """
from importlib import reload self.bitcell = factory.create(module_type="bitcell")
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
height = self.bitcell.height + drc("poly_to_active") height = self.bitcell.height + drc("poly_to_active")
# 1x Inverter # 1x Inverter
self.inv_sel = pinv(height=height) self.inv_sel = factory.create(module_type="pinv", height=height)
self.add_mod(self.inv_sel) self.add_mod(self.inv_sel)
# 4x Inverter # 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.add_mod(self.inv4x)
self.nor2 = pnor2(height=height) self.nor2 = factory.create(module_type="pnor2", height=height)
self.add_mod(self.nor2) 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.add_mod(self.inv4x_nor)
self.nand2 = pnand2() self.nand2 = factory.create(module_type="pnand2")
self.add_mod(self.nand2) self.add_mod(self.nand2)
def calculate_module_offsets(self): def calculate_module_offsets(self):
@ -94,7 +92,7 @@ class bank_select(design.design):
self.xoffset_bank_sel_inv = 0 self.xoffset_bank_sel_inv = 0
self.xoffset_inputs = 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 # Include the M1 pitches for the supply rails and spacing
self.height = self.yoffset_maxpoint + 2*self.m1_pitch self.height = self.yoffset_maxpoint + 2*self.m1_pitch
self.width = self.xoffset_inv + self.inv4x.width self.width = self.xoffset_inv + self.inv4x.width
@ -170,10 +168,10 @@ class bank_select(design.design):
if i == 0: if i == 0:
y_offset = 0 y_offset = 0
else: 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: if i%2:
y_offset += self.inv.height y_offset += self.inv4x.height
mirror = "MX" mirror = "MX"
else: else:
mirror = "" mirror = ""
@ -223,7 +221,7 @@ class bank_select(design.design):
self.add_label_pin(text="bank_sel_bar", self.add_label_pin(text="bank_sel_bar",
layer="metal2", layer="metal2",
offset=vector(xoffset_bank_sel_bar, 0), offset=vector(xoffset_bank_sel_bar, 0),
height=self.inv.height) height=self.inv4x.height)
self.add_via_center(layers=("metal1","via1","metal2"), self.add_via_center(layers=("metal1","via1","metal2"),
offset=bank_sel_bar_pin.rc()) offset=bank_sel_bar_pin.rc())

View File

@ -3,8 +3,7 @@ import design
from tech import drc, spice from tech import drc, spice
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from sram_factory import factory
unique_id = 1
class bitcell_array(design.design): class bitcell_array(design.design):
""" """
@ -12,13 +11,7 @@ class bitcell_array(design.design):
and word line is connected by abutment. and word line is connected by abutment.
Connects the word lines and bit lines. Connects the word lines and bit lines.
""" """
unique_id = 1 def __init__(self, cols, rows, name):
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
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols)) 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): def add_modules(self):
""" Add the modules used in this design """ """ Add the modules used in this design """
self.cell = factory.create(module_type="bitcell")
from importlib import reload
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.cell = self.mod_bitcell()
self.add_mod(self.cell) self.add_mod(self.cell)
def create_instances(self): def create_instances(self):

View File

@ -3,13 +3,7 @@ import design
from tech import drc, parameter from tech import drc, parameter
import debug import debug
import contact import contact
from pinv import pinv from sram_factory import factory
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
import math import math
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
@ -73,46 +67,56 @@ class control_logic(design.design):
def add_modules(self): def add_modules(self):
""" Add all the required modules """ """ Add all the required modules """
dff = dff_buf() dff = factory.create(module_type="dff_buf")
dff_height = dff.height 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.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) self.add_mod(self.and2)
# Special gates: inverters for buffering # Special gates: inverters for buffering
# Size the clock for the number of rows (fanout) # Size the clock for the number of rows (fanout)
clock_driver_size = max(1,int(self.num_rows/4)) 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.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.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.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.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.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"): 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() delay_stages_heuristic, delay_fanout_heuristic = self.get_heuristic_delay_chain_size()
bitcell_loads = int(math.ceil(self.num_rows / 2.0)) 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: if self.sram != None:
self.set_sen_wl_delays() self.set_sen_wl_delays()
@ -124,7 +128,9 @@ class control_logic(design.design):
#This resizes based on total delay. #This resizes based on total delay.
delay_stages, delay_fanout = self.get_dynamic_delay_chain_size(delay_stages_heuristic, delay_fanout_heuristic) 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.sen_delay_rise,self.sen_delay_fall = self.get_delays_to_sen() #get the new timing

View File

@ -1,10 +1,10 @@
import debug import debug
import design import design
from tech import drc from tech import drc
from pinv import pinv
from contact import contact from contact import contact
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from sram_factory import factory
class delay_chain(design.design): 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. Usually, this will be constant, but it could have varied fanout.
""" """
unique_id = 1 def __init__(self, name, fanout_list):
def __init__(self, fanout_list, name="delay_chain"):
"""init function""" """init function"""
name = name+"_{}".format(delay_chain.unique_id)
delay_chain.unique_id += 1
design.design.__init__(self, name) design.design.__init__(self, name)
# Two fanouts are needed so that we can route the vdd/gnd connections # 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") self.add_pin("gnd")
def add_modules(self): 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) self.add_mod(self.inv)
def create_inverters(self): def create_inverters(self):

View File

@ -3,6 +3,7 @@ import design
from tech import drc from tech import drc
from math import log from math import log
from vector import vector from vector import vector
from sram_factory import factory
from globals import OPTS from globals import OPTS
class dff_array(design.design): class dff_array(design.design):
@ -38,10 +39,7 @@ class dff_array(design.design):
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):
from importlib import reload self.dff = factory.create(module_type="dff")
c = reload(__import__(OPTS.dff))
self.mod_dff = getattr(c, OPTS.dff)
self.dff = self.mod_dff("dff")
self.add_mod(self.dff) self.add_mod(self.dff)
def add_pins(self): def add_pins(self):
@ -61,7 +59,7 @@ class dff_array(design.design):
for col in range(self.columns): for col in range(self.columns):
name = "dff_r{0}_c{1}".format(row,col) name = "dff_r{0}_c{1}".format(row,col)
self.dff_insts[row,col]=self.add_inst(name=name, 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.connect_inst([self.get_din_name(row,col),
self.get_dout_name(row,col), self.get_dout_name(row,col),
"clk", "clk",

View File

@ -4,7 +4,7 @@ from tech import drc,parameter
from math import log from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from pinv import pinv from sram_factory import factory
class dff_buf(design.design): class dff_buf(design.design):
""" """
@ -50,16 +50,17 @@ class dff_buf(design.design):
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):
from importlib import reload self.dff = factory.create(module_type="dff")
c = reload(__import__(OPTS.dff))
self.mod_dff = getattr(c, OPTS.dff)
self.dff = self.mod_dff("dff")
self.add_mod(self.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.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) self.add_mod(self.inv2)

View File

@ -4,7 +4,7 @@ from tech import drc
from math import log from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
import dff_buf from sram_factory import factory
class dff_buf_array(design.design): class dff_buf_array(design.design):
""" """
@ -54,7 +54,9 @@ class dff_buf_array(design.design):
self.add_pin("gnd") self.add_pin("gnd")
def add_modules(self): 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) self.add_mod(self.dff)
def create_dff_array(self): def create_dff_array(self):

View File

@ -55,13 +55,12 @@ class dff_inv(design.design):
self.add_pin("gnd") self.add_pin("gnd")
def add_modules(self): def add_modules(self):
from importlib import reload self.dff = dff_inv.dff_inv(self.inv_size)
c = reload(__import__(OPTS.dff))
self.mod_dff = getattr(c, OPTS.dff)
self.dff = self.mod_dff("dff")
self.add_mod(self.dff) 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) self.add_mod(self.inv1)
def create_modules(self): def create_modules(self):

View File

@ -42,7 +42,7 @@ class dff_inv_array(design.design):
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): 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) self.add_mod(self.dff)
def add_pins(self): def add_pins(self):

View File

@ -5,11 +5,7 @@ from math import log
from math import sqrt from math import sqrt
import math import math
import contact import contact
from pnand2 import pnand2 from sram_factory import factory
from pnand3 import pnand3
from pinv import pinv
from hierarchical_predecode2x4 import hierarchical_predecode2x4 as pre2x4
from hierarchical_predecode3x8 import hierarchical_predecode3x8 as pre3x8
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
@ -17,11 +13,8 @@ class hierarchical_decoder(design.design):
""" """
Dynamically generated hierarchical decoder. Dynamically generated hierarchical decoder.
""" """
unique_id = 1 def __init__(self, name, rows, height=None):
design.design.__init__(self, name)
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
self.NAND_FORMAT = "DEC_NAND_{0}" self.NAND_FORMAT = "DEC_NAND_{0}"
self.INV_FORMAT = "DEC_INV_{0}" self.INV_FORMAT = "DEC_INV_{0}"
@ -57,21 +50,26 @@ class hierarchical_decoder(design.design):
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): 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.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.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_mod(self.nand3)
self.add_decoders() self.add_decoders()
def add_decoders(self): def add_decoders(self):
""" Create the decoders based on the number of pre-decodes """ """ 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.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) self.add_mod(self.pre3_8)
def determine_predecodes(self,num_inputs): def determine_predecodes(self,num_inputs):

View File

@ -3,24 +3,19 @@ import design
import math import math
from tech import drc from tech import drc
import contact import contact
from pinv import pinv
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from pnand2 import pnand2 from sram_factory import factory
from pnand3 import pnand3
class hierarchical_predecode(design.design): class hierarchical_predecode(design.design):
""" """
Pre 2x4 and 3x8 decoder shared code. Pre 2x4 and 3x8 decoder shared code.
""" """
unique_id = 1 def __init__(self, name, input_number, height=None):
def __init__(self, input_number, height=None):
self.number_of_inputs = input_number self.number_of_inputs = input_number
self.cell_height = height self.cell_height = height
self.number_of_outputs = int(math.pow(2, self.number_of_inputs)) 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)) design.design.__init__(self, name)
hierarchical_predecode.unique_id += 1
def add_pins(self): def add_pins(self):
for k in range(self.number_of_inputs): for k in range(self.number_of_inputs):
@ -33,7 +28,8 @@ class hierarchical_predecode(design.design):
def add_modules(self): def add_modules(self):
""" Add the INV and NAND gate modules """ """ 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_mod(self.inv)
self.add_nand(self.number_of_inputs) self.add_nand(self.number_of_inputs)
@ -42,9 +38,11 @@ class hierarchical_predecode(design.design):
def add_nand(self,inputs): def add_nand(self,inputs):
""" Create the NAND for the predecode input stage """ """ Create the NAND for the predecode input stage """
if inputs==2: if inputs==2:
self.nand = pnand2(height=self.cell_height) self.nand = factory.create(module_type="pnand2",
height=self.cell_height)
elif inputs==3: elif inputs==3:
self.nand = pnand3(height=self.cell_height) self.nand = factory.create(module_type="pnand3",
height=self.cell_height)
else: else:
debug.error("Invalid number of predecode inputs: {}".format(inputs),-1) debug.error("Invalid number of predecode inputs: {}".format(inputs),-1)

View File

@ -9,8 +9,8 @@ class hierarchical_predecode2x4(hierarchical_predecode):
""" """
Pre 2x4 decoder used in hierarchical_decoder. Pre 2x4 decoder used in hierarchical_decoder.
""" """
def __init__(self, height=None): def __init__(self, name, height=None):
hierarchical_predecode.__init__(self, 2, height) hierarchical_predecode.__init__(self, name, 2, height)
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:

View File

@ -9,8 +9,8 @@ class hierarchical_predecode3x8(hierarchical_predecode):
""" """
Pre 3x8 decoder used in hierarchical_decoder. Pre 3x8 decoder used in hierarchical_decoder.
""" """
def __init__(self, height=None): def __init__(self, name, height=None):
hierarchical_predecode.__init__(self, 3, height) hierarchical_predecode.__init__(self, name, 3, height)
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:

View File

@ -5,12 +5,8 @@ import design
import math import math
from math import log,sqrt,ceil from math import log,sqrt,ceil
import contact import contact
from pinv import pinv
from pnand2 import pnand2
from pnor2 import pnor2
from vector import vector from vector import vector
from pinvbuf import pinvbuf from sram_factory import factory
from globals import OPTS from globals import OPTS
class multibank(design.design): class multibank(design.design):
@ -21,21 +17,8 @@ class multibank(design.design):
This module includes the tristate and bank select logic. 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) design.design.__init__(self, name)
debug.info(2, "create sram of size {0} with {1} words".format(word_size,num_words)) debug.info(2, "create sram of size {0} with {1} words".format(word_size,num_words))

View File

@ -2,7 +2,7 @@ import design
import debug import debug
from tech import drc from tech import drc
from vector import vector from vector import vector
from precharge import precharge from sram_factory import factory
from globals import OPTS from globals import OPTS
class precharge_array(design.design): 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. of bit line columns, height is the height of the bit-cell array.
""" """
unique_id = 1 def __init__(self, name, columns, size=1, bitcell_bl="bl", bitcell_br="br"):
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
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
@ -50,10 +46,12 @@ class precharge_array(design.design):
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):
self.pc_cell = precharge(name="precharge", self.pc_cell = factory.create(module_type="precharge",
size=self.size, size=self.size,
bitcell_bl=self.bitcell_bl, bitcell_bl=self.bitcell_bl,
bitcell_br=self.bitcell_br) bitcell_br=self.bitcell_br)
self.add_mod(self.pc_cell) self.add_mod(self.pc_cell)

View File

@ -1,10 +1,8 @@
import debug import debug
import design import design
from tech import drc from tech import drc
from pinv import pinv
import contact import contact
from bitcell_array import bitcell_array from sram_factory import factory
from ptx import ptx
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
@ -15,7 +13,7 @@ class replica_bitline(design.design):
line and rows is the height of the replica bit loads. 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) design.design.__init__(self, name)
self.bitcell_loads = bitcell_loads self.bitcell_loads = bitcell_loads
@ -78,29 +76,25 @@ class replica_bitline(design.design):
def add_modules(self): def add_modules(self):
""" Add the modules for later usage """ """ Add the modules for later usage """
from importlib import reload self.replica_bitcell = factory.create(module_type="replica_bitcell")
#g = reload(__import__(OPTS.delay_chain)) self.add_mod(self.replica_bitcell)
#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)
# This is the replica bitline load column that is the height of our array # 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) self.add_mod(self.rbl)
# FIXME: The FO and depth of this should be tuned # FIXME: The FO and depth of this should be tuned
from delay_chain import delay_chain self.delay_chain = factory.create(module_type="delay_chain",
self.delay_chain = delay_chain(self.delay_fanout_list) fanout_list=self.delay_fanout_list)
self.add_mod(self.delay_chain) self.add_mod(self.delay_chain)
self.inv = pinv() self.inv = factory.create(module_type="pinv")
self.add_mod(self.inv) 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) self.add_mod(self.access_tx)
def create_instances(self): def create_instances(self):
@ -132,7 +126,6 @@ class replica_bitline(design.design):
temp.append("vdd") temp.append("vdd")
temp.append("gnd") temp.append("gnd")
self.connect_inst(temp) self.connect_inst(temp)
#self.connect_inst(["bl_0", "br_0", "delayed_en", "vdd", "gnd"])
self.rbl_inst=self.add_inst(name="load", self.rbl_inst=self.add_inst(name="load",
mod=self.rbl) mod=self.rbl)

View File

@ -1,6 +1,7 @@
import design import design
from tech import drc from tech import drc
from vector import vector from vector import vector
from sram_factory import factory
import debug import debug
from globals import OPTS from globals import OPTS
@ -10,8 +11,8 @@ class sense_amp_array(design.design):
Dynamically generated sense amp array for all bitlines. Dynamically generated sense amp array for all bitlines.
""" """
def __init__(self, word_size, words_per_row): def __init__(self, name, word_size, words_per_row):
design.design.__init__(self, "sense_amp_array") design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
self.word_size = word_size self.word_size = word_size
@ -51,17 +52,13 @@ class sense_amp_array(design.design):
self.add_pin("gnd") self.add_pin("gnd")
def add_modules(self): def add_modules(self):
from importlib import reload self.amp = factory.create(module_type="sense_amp")
c = reload(__import__(OPTS.sense_amp))
self.mod_sense_amp = getattr(c, OPTS.sense_amp)
self.amp = self.mod_sense_amp("sense_amp")
self.add_mod(self.amp) self.add_mod(self.amp)
# This is just used for measurements, # This is just used for measurements,
# so don't add the module # so don't add the module
c = reload(__import__(OPTS.bitcell)) self.bitcell = factory.create(module_type="bitcell")
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
def create_sense_amp_array(self): def create_sense_amp_array(self):
self.local_insts = [] self.local_insts = []

View File

@ -1,11 +1,11 @@
from math import log from math import log
import design import design
from single_level_column_mux import single_level_column_mux
import contact import contact
from tech import drc from tech import drc
import debug import debug
import math import math
from vector import vector from vector import vector
from sram_factory import factory
from globals import OPTS from globals import OPTS
class single_level_column_mux_array(design.design): 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. Array of column mux to read the bitlines through the 6T.
""" """
unique_id = 1 def __init__(self, name, columns, word_size, bitcell_bl="bl", bitcell_br="br"):
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
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
self.columns = columns self.columns = columns
@ -61,7 +57,9 @@ class single_level_column_mux_array(design.design):
def add_modules(self): 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) self.add_mod(self.mux)

View File

@ -2,6 +2,7 @@ import debug
from tech import drc from tech import drc
import design import design
from vector import vector from vector import vector
from sram_factory import factory
from globals import OPTS from globals import OPTS
class tri_gate_array(design.design): class tri_gate_array(design.design):
@ -36,10 +37,7 @@ class tri_gate_array(design.design):
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):
from importlib import reload self.tri = factory.create(module_type="tri_gate")
c = reload(__import__(OPTS.tri_gate))
self.mod_tri_gate = getattr(c, OPTS.tri_gate)
self.tri = self.mod_tri_gate("tri_gate")
self.add_mod(self.tri) self.add_mod(self.tri)
def add_pins(self): def add_pins(self):

View File

@ -5,9 +5,8 @@ import contact
from math import log from math import log
from math import sqrt from math import sqrt
import math import math
from pinv import pinv
from pnand2 import pnand2
from vector import vector from vector import vector
from sram_factory import factory
from globals import OPTS from globals import OPTS
class wordline_driver(design.design): class wordline_driver(design.design):
@ -16,8 +15,8 @@ class wordline_driver(design.design):
Generates the wordline-driver to drive the bitcell Generates the wordline-driver to drive the bitcell
""" """
def __init__(self, rows): def __init__(self, name, rows):
design.design.__init__(self, "wordline_driver") design.design.__init__(self, name)
self.rows = rows self.rows = rows
@ -53,13 +52,14 @@ class wordline_driver(design.design):
# This is just used for measurements, # This is just used for measurements,
# so don't add the module # so don't add the module
self.inv = pinv() self.inv = factory.create(module_type="pinv")
self.add_mod(self.inv) 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.add_mod(self.inv_no_output)
self.nand2 = pnand2() self.nand2 = factory.create(module_type="pnand2")
self.add_mod(self.nand2) self.add_mod(self.nand2)

View File

@ -2,6 +2,7 @@ from math import log
import design import design
from tech import drc from tech import drc
import debug import debug
from sram_factory import factory
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
@ -11,8 +12,8 @@ class write_driver_array(design.design):
Dynamically generated write driver array of all bitlines. Dynamically generated write driver array of all bitlines.
""" """
def __init__(self, columns, word_size): def __init__(self, name, columns, word_size):
design.design.__init__(self, "write_driver_array") design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
self.columns = columns self.columns = columns
@ -53,17 +54,12 @@ class write_driver_array(design.design):
self.add_pin("gnd") self.add_pin("gnd")
def add_modules(self): def add_modules(self):
from importlib import reload self.driver = factory.create(module_type="write_driver")
c = reload(__import__(OPTS.write_driver))
self.mod_write_driver = getattr(c, OPTS.write_driver)
self.driver = self.mod_write_driver("write_driver")
self.add_mod(self.driver) self.add_mod(self.driver)
# This is just used for measurements, # This is just used for measurements,
# so don't add the module # so don't add the module
c = reload(__import__(OPTS.bitcell)) self.bitcell = factory.create(module_type="bitcell")
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
def create_write_array(self): def create_write_array(self):
self.driver_insts = {} self.driver_insts = {}

View File

@ -72,23 +72,24 @@ class options(optparse.Values):
num_banks = 1 num_banks = 1
# These are the default modules that can be over-riden # 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" decoder = "hierarchical_decoder"
delay_chain = "delay_chain"
dff_array = "dff_array" dff_array = "dff_array"
dff = "dff" dff = "dff"
control_logic = "control_logic"
bitcell_array = "bitcell_array"
sense_amp = "sense_amp"
sense_amp_array = "sense_amp_array"
precharge_array = "precharge_array" precharge_array = "precharge_array"
column_mux_array = "single_level_column_mux_array" ptx = "ptx"
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"
replica_bitcell = "replica_bitcell" replica_bitcell = "replica_bitcell"
bitcell = "bitcell" replica_bitline = "replica_bitline"
delay_chain = "delay_chain" sense_amp_array = "sense_amp_array"
bank_select = "bank_select" 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"

View File

@ -3,28 +3,16 @@ from tech import drc
from math import log from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from pnand2 import pnand2
from pinv import pinv
import pgate import pgate
from sram_factory import factory
class pand2(pgate.pgate): class pand2(pgate.pgate):
""" """
This is a simple buffer used for driving loads. This is a simple buffer used for driving loads.
""" """
from importlib import reload def __init__(self, name, size=1, height=None):
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
unique_id = 1
def __init__(self, size=1, height=None, name=""):
self.size = size self.size = size
if name=="":
name = "pand2_{0}_{1}".format(size, pand2.unique_id)
pand2.unique_id += 1
pgate.pgate.__init__(self, name, height) pgate.pgate.__init__(self, name, height)
debug.info(1, "Creating {}".format(self.name)) debug.info(1, "Creating {}".format(self.name))
@ -41,10 +29,10 @@ class pand2(pgate.pgate):
def create_modules(self): def create_modules(self):
# Shield the cap, but have at least a stage effort of 4 # 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.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) self.add_mod(self.inv)
def create_layout(self): def create_layout(self):

View File

@ -3,29 +3,19 @@ from tech import drc
from math import log from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from pinv import pinv
import pgate import pgate
from sram_factory import factory
class pbuf(pgate.pgate): class pbuf(pgate.pgate):
""" """
This is a simple buffer used for driving loads. This is a simple buffer used for driving loads.
""" """
from importlib import reload def __init__(self, name, size=4, height=None):
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
unique_id = 1
def __init__(self, size=4, height=None, name=""):
self.stage_effort = 4 self.stage_effort = 4
self.size = size self.size = size
self.height = height 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) pgate.pgate.__init__(self, name, height)
debug.info(1, "creating {0} with size of {1}".format(self.name,self.size)) 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): def create_modules(self):
# Shield the cap, but have at least a stage effort of 4 # Shield the cap, but have at least a stage effort of 4
input_size = max(1,int(self.size/self.stage_effort)) 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.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) self.add_mod(self.inv2)
def create_insts(self): def create_insts(self):

View File

@ -5,15 +5,13 @@ from tech import drc
from math import log from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from pinv import pinv from sram_factory import factory
class pdriver(pgate.pgate): class pdriver(pgate.pgate):
""" """
This instantiates an even or odd number of inverters sized for driving a load. This instantiates an even or odd number of inverters sized for driving a load.
""" """
unique_id = 1 def __init__(self, name, neg_polarity=False, fanout_size=8, size_list = [], height=None):
def __init__(self, neg_polarity=False, fanout_size=8, size_list = [], height=None, name=""):
self.stage_effort = 4 self.stage_effort = 4
self.height = height 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): 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) 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) pgate.pgate.__init__(self, name, height)
debug.info(1, "Creating {}".format(self.name)) debug.info(1, "Creating {}".format(self.name))
@ -123,11 +117,13 @@ class pdriver(pgate.pgate):
self.inv_list = [] self.inv_list = []
if len(self.size_list) > 0: # size list specified if len(self.size_list) > 0: # size list specified
for x in range(len(self.size_list)): 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]) self.add_mod(self.inv_list[x])
else: # find inv sizes else: # find inv sizes
for x in range(len(self.calc_size_list)): 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]) self.add_mod(self.inv_list[x])

View File

@ -2,9 +2,9 @@ import contact
import design import design
import debug import debug
from tech import drc, parameter, spice from tech import drc, parameter, spice
from ptx import ptx
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from sram_factory import factory
class pgate(design.design): class pgate(design.design):
""" """
@ -18,15 +18,12 @@ class pgate(design.design):
if height: if height:
self.height = height self.height = height
elif not height: elif not height:
from importlib import reload b = factory.create(module_type="bitcell")
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
b = bitcell()
self.height = b.height self.height = b.height
def connect_pin_to_rail(self,inst,pin,supply): 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) source_pin = inst.get_pin(pin)
supply_pin = self.get_pin(supply) supply_pin = self.get_pin(supply)
if supply_pin.overlaps(source_pin): if supply_pin.overlaps(source_pin):

View File

@ -2,12 +2,12 @@ import contact
import pgate import pgate
import debug import debug
from tech import drc, parameter, spice from tech import drc, parameter, spice
from ptx import ptx
from vector import vector from vector import vector
from math import ceil from math import ceil
from globals import OPTS from globals import OPTS
from utils import round_to_grid from utils import round_to_grid
import logical_effort import logical_effort
from sram_factory import factory
class pinv(pgate.pgate): class pinv(pgate.pgate):
""" """
@ -19,15 +19,11 @@ class pinv(pgate.pgate):
output to the right side of the cell for easier access. output to the right side of the cell for easier access.
""" """
unique_id = 1 def __init__(self, name, size=1, beta=parameter["beta"], height=None, route_output=True):
def __init__(self, size=1, beta=parameter["beta"], height=None, route_output=True):
# We need to keep unique names because outputting to GDSII # We need to keep unique names because outputting to GDSII
# will use the last record with a given name. I.e., you will # 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 # over-write a design in GDS if one has and the other doesn't
# have poly connected, for example. # have poly connected, for example.
name = "pinv_{}".format(pinv.unique_id)
pinv.unique_id += 1
pgate.pgate.__init__(self, name, height) pgate.pgate.__init__(self, name, height)
debug.info(2, "create pinv structure {0} with size of {1}".format(name, size)) 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? # 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) # Assume we need 3 metal 1 pitches (2 power rails, one between the tx for the drain)
# plus the tx height # plus the tx height
nmos = ptx(tx_type="nmos") nmos = factory.create(module_type="ptx", tx_type="nmos")
pmos = ptx(width=drc("minwidth_tx"), tx_type="pmos") pmos = factory.create(module_type="ptx", width=drc("minwidth_tx"), tx_type="pmos")
tx_height = nmos.poly_height + pmos.poly_height tx_height = nmos.poly_height + pmos.poly_height
# rotated m1 pitch or poly to active spacing # rotated m1 pitch or poly to active spacing
min_channel = max(contact.poly.width + self.m1_space, min_channel = max(contact.poly.width + self.m1_space,
@ -147,18 +143,20 @@ class pinv(pgate.pgate):
def add_ptx(self): def add_ptx(self):
""" Create the PMOS and NMOS transistors. """ """ Create the PMOS and NMOS transistors. """
self.nmos = ptx(width=self.nmos_width, self.nmos = factory.create(module_type="ptx",
mults=self.tx_mults, width=self.nmos_width,
tx_type="nmos", mults=self.tx_mults,
connect_poly=True, tx_type="nmos",
connect_active=True) connect_poly=True,
connect_active=True)
self.add_mod(self.nmos) self.add_mod(self.nmos)
self.pmos = ptx(width=self.pmos_width, self.pmos = factory.create(module_type="ptx",
mults=self.tx_mults, width=self.pmos_width,
tx_type="pmos", mults=self.tx_mults,
connect_poly=True, tx_type="pmos",
connect_active=True) connect_poly=True,
connect_active=True)
self.add_mod(self.pmos) self.add_mod(self.pmos)
def route_supply_rails(self): def route_supply_rails(self):

View File

@ -4,16 +4,14 @@ from tech import drc
from math import log from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from pinv import pinv from sram_factory import factory
class pinvbuf(design.design): class pinvbuf(design.design):
""" """
This is a simple inverter/buffer used for driving loads. It is 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. used in the column decoder for 1:2 decoding and as the clock buffer.
""" """
unique_id = 1 def __init__(self, name, size=4, height=None):
def __init__(self, driver_size=4, height=None, name=""):
self.stage_effort = 4 self.stage_effort = 4
self.row_height = height self.row_height = height
@ -22,11 +20,8 @@ class pinvbuf(design.design):
# stage effort of 4 or less # stage effort of 4 or less
# The pinvbuf has a FO of 2 for the first stage, so the second stage # 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 # should be sized "half" to prevent loading of the first stage
self.driver_size = driver_size self.size = size
self.predriver_size = max(int(self.driver_size/(self.stage_effort/2)),1) self.predriver_size = max(int(self.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
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {}".format(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 # Shield the cap, but have at least a stage effort of 4
input_size = max(1,int(self.predriver_size/self.stage_effort)) 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.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.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) self.add_mod(self.inv2)
def create_insts(self): def create_insts(self):

View File

@ -2,23 +2,18 @@ import contact
import pgate import pgate
import debug import debug
from tech import drc, parameter, spice from tech import drc, parameter, spice
from ptx import ptx
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
import logical_effort import logical_effort
from sram_factory import factory
class pnand2(pgate.pgate): class pnand2(pgate.pgate):
""" """
This module generates gds of a parametrically sized 2-input nand. 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. This model use ptx to generate a 2-input nand within a cetrain height.
""" """
def __init__(self, name, size=1, height=None):
unique_id = 1
def __init__(self, size=1, height=None):
""" Creates a cell for a simple 2 input nand """ """ 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) pgate.pgate.__init__(self, name, height)
debug.info(2, "create pnand2 structure {0} with size of {1}".format(name, size)) 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): def add_ptx(self):
""" Create the PMOS and NMOS transistors. """ """ Create the PMOS and NMOS transistors. """
self.nmos = ptx(width=self.nmos_width, self.nmos = factory.create(module_type="ptx",
mults=self.tx_mults, width=self.nmos_width,
tx_type="nmos", mults=self.tx_mults,
connect_poly=True, tx_type="nmos",
connect_active=True) connect_poly=True,
connect_active=True)
self.add_mod(self.nmos) self.add_mod(self.nmos)
self.pmos = ptx(width=self.pmos_width, self.pmos = factory.create(module_type="ptx",
mults=self.tx_mults, width=self.pmos_width,
tx_type="pmos", mults=self.tx_mults,
connect_poly=True, tx_type="pmos",
connect_active=True) connect_poly=True,
connect_active=True)
self.add_mod(self.pmos) self.add_mod(self.pmos)
def setup_layout_constants(self): def setup_layout_constants(self):

View File

@ -2,22 +2,17 @@ import contact
import pgate import pgate
import debug import debug
from tech import drc, parameter, spice from tech import drc, parameter, spice
from ptx import ptx
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from sram_factory import factory
class pnand3(pgate.pgate): class pnand3(pgate.pgate):
""" """
This module generates gds of a parametrically sized 2-input nand. 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. This model use ptx to generate a 2-input nand within a cetrain height.
""" """
def __init__(self, name, size=1, height=None):
unique_id = 1
def __init__(self, size=1, height=None):
""" Creates a cell for a simple 3 input nand """ """ 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) pgate.pgate.__init__(self, name, height)
debug.info(2, "create pnand3 structure {0} with size of {1}".format(name, size)) 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): def add_ptx(self):
""" Create the PMOS and NMOS transistors. """ """ Create the PMOS and NMOS transistors. """
self.nmos = ptx(width=self.nmos_width, self.nmos = factory.create(module_type="ptx",
mults=self.tx_mults, width=self.nmos_width,
tx_type="nmos", mults=self.tx_mults,
connect_poly=True, tx_type="nmos",
connect_active=True) connect_poly=True,
connect_active=True)
self.add_mod(self.nmos) self.add_mod(self.nmos)
self.pmos = ptx(width=self.pmos_width, self.pmos = factory.create(module_type="ptx",
mults=self.tx_mults, width=self.pmos_width,
tx_type="pmos", mults=self.tx_mults,
connect_poly=True, tx_type="pmos",
connect_active=True) connect_poly=True,
connect_active=True)
self.add_mod(self.pmos) self.add_mod(self.pmos)
def setup_layout_constants(self): def setup_layout_constants(self):
@ -93,7 +90,7 @@ class pnand3(pgate.pgate):
self.output_pos = vector(0,0.5*self.height) self.output_pos = vector(0,0.5*self.height)
# This is the extra space needed to ensure DRC rules to the active contacts # 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) extra_contact_space = max(-nmos.get_pin("D").by(),0)
# This is a poly-to-poly of a flipped cell # 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, self.top_bottom_space = max(0.5*self.m1_width + self.m1_space + extra_contact_space,

View File

@ -1,23 +1,18 @@
import contact
import pgate import pgate
import debug import debug
from tech import drc, parameter, spice from tech import drc, parameter, spice
from ptx import ptx
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
import contact
from sram_factory import factory
class pnor2(pgate.pgate): class pnor2(pgate.pgate):
""" """
This module generates gds of a parametrically sized 2-input nor. 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. This model use ptx to generate a 2-input nor within a cetrain height.
""" """
def __init__(self, name, size=1, height=None):
unique_id = 1
def __init__(self, size=1, height=None):
""" Creates a cell for a simple 2 input nor """ """ 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) pgate.pgate.__init__(self, name, height)
debug.info(2, "create pnor2 structure {0} with size of {1}".format(name, size)) 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): def create_ptx(self):
""" Create the PMOS and NMOS transistors. """ """ Create the PMOS and NMOS transistors. """
self.nmos = ptx(width=self.nmos_width, self.nmos = factory.create(module_type="ptx",
mults=self.tx_mults, width=self.nmos_width,
tx_type="nmos", mults=self.tx_mults,
connect_poly=True, tx_type="nmos",
connect_active=True) connect_poly=True,
connect_active=True)
self.add_mod(self.nmos) self.add_mod(self.nmos)
self.pmos = ptx(width=self.pmos_width, self.pmos = factory.create(module_type="ptx",
mults=self.tx_mults, width=self.pmos_width,
tx_type="pmos", mults=self.tx_mults,
connect_poly=True, tx_type="pmos",
connect_active=True) connect_poly=True,
connect_active=True)
self.add_mod(self.pmos) self.add_mod(self.pmos)
def setup_layout_constants(self): def setup_layout_constants(self):
""" Pre-compute some handy layout parameters. """ """ 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 # metal spacing to allow contacts on any layer
self.input_spacing = max(self.poly_space + poly_contact.first_layer_width, self.input_spacing = max(self.poly_space + contact.poly.first_layer_width,
self.m1_space + m1m2_via.first_layer_width, self.m1_space + contact.m1m2.first_layer_width,
self.m2_space + m2m3_via.first_layer_width, self.m2_space + contact.m2m3.first_layer_width,
self.m3_space + m2m3_via.second_layer_width) self.m3_space + contact.m2m3.second_layer_width)
# Compute the other pmos2 location, but determining offset to overlap the # Compute the other pmos2 location, but determining offset to overlap the
# source and drain pins # source and drain pins

View File

@ -2,28 +2,20 @@ import contact
import pgate import pgate
import debug import debug
from tech import drc, parameter from tech import drc, parameter
from ptx import ptx
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from sram_factory import factory
class precharge(pgate.pgate): class precharge(pgate.pgate):
""" """
Creates a single precharge cell Creates a single precharge cell
This module implements the precharge bitline cell used in the design. 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"): 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) pgate.pgate.__init__(self, name)
debug.info(2, "create single precharge cell: {0}".format(name)) debug.info(2, "create single precharge cell: {0}".format(name))
from importlib import reload self.bitcell = factory.create(module_type="bitcell")
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
self.beta = parameter["beta"] self.beta = parameter["beta"]
self.ptx_width = self.beta*parameter["min_tx_size"] self.ptx_width = self.beta*parameter["min_tx_size"]
@ -57,8 +49,9 @@ class precharge(pgate.pgate):
""" """
Initializes the upper and lower pmos Initializes the upper and lower pmos
""" """
self.pmos = ptx(width=self.ptx_width, self.pmos = factory.create(module_type="ptx",
tx_type="pmos") width=self.ptx_width,
tx_type="pmos")
self.add_mod(self.pmos) self.add_mod(self.pmos)

View File

@ -2,9 +2,9 @@ import design
import debug import debug
from tech import drc, spice from tech import drc, spice
from vector import vector from vector import vector
from contact import contact
from globals import OPTS from globals import OPTS
import path import path
from sram_factory import factory
class ptx(design.design): class ptx(design.design):
""" """
@ -15,7 +15,7 @@ class ptx(design.design):
you to connect the fingered gates and active for parallel devices. 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 # We need to keep unique names because outputting to GDSII
# will use the last record with a given name. I.e., you will # 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 # 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 # This is not actually instantiated but used for calculations
self.active_contact = contact(layer_stack=("active", "contact", "metal1"), self.active_contact = factory.create(module_type="contact",
dimensions=(1, self.num_contacts)) layer_stack=("active", "contact", "metal1"),
dimensions=(1, self.num_contacts))
# The contacted poly pitch (or uncontacted in an odd technology) # The contacted poly pitch (or uncontacted in an odd technology)

View File

@ -3,8 +3,8 @@ import debug
from tech import drc from tech import drc
from vector import vector from vector import vector
import contact import contact
from ptx import ptx
from globals import OPTS from globals import OPTS
from sram_factory import factory
class single_level_column_mux(design.design): 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: 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 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) 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) design.design.__init__(self, name)
debug.info(2, "create single column mux cell: {0}".format(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() self.add_wells()
def add_modules(self): def add_modules(self):
# This is just used for measurements, self.bitcell = factory.create(module_type="bitcell")
# 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()
# Adds nmos_lower,nmos_upper to the module # Adds nmos_lower,nmos_upper to the module
self.ptx_width = self.tx_size*drc("minwidth_tx") 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) self.add_mod(self.nmos)

View File

@ -10,6 +10,7 @@ import logical_effort
from design import design from design import design
from verilog import verilog from verilog import verilog
from lef import lef from lef import lef
from sram_factory import factory
class sram_base(design, verilog, lef): class sram_base(design, verilog, lef):
""" """
@ -239,10 +240,7 @@ class sram_base(design, verilog, lef):
def add_modules(self): def add_modules(self):
""" Create all the modules that will be used """ self.bitcell = factory.create(module_type=OPTS.bitcell)
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
# Create the address and control flops (but not the clk) # Create the address and control flops (but not the clk)
from dff_array import dff_array from dff_array import dff_array

View File

@ -2,6 +2,7 @@ import debug
from math import log,sqrt,ceil from math import log,sqrt,ceil
from importlib import reload from importlib import reload
from globals import OPTS from globals import OPTS
from sram_factory import factory
class sram_config: class sram_config:
""" This is a structure that is used to hold the SRAM configuration options. """ """ This is a structure that is used to hold the SRAM configuration options. """
@ -29,10 +30,7 @@ class sram_config:
def compute_sizes(self): def compute_sizes(self):
""" Computes the organization of the memory using bitcell size by trying to make it square.""" """ Computes the organization of the memory using bitcell size by trying to make it square."""
c = reload(__import__(OPTS.bitcell)) self.bitcell = factory.create(module_type="bitcell")
self.mod_bitcell = getattr(c, OPTS.bitcell)
# pass a copy of myself for the port numbers
self.bitcell = self.mod_bitcell()
debug.check(self.num_banks in [1,2,4], "Valid number of banks are 1 , 2 and 4.") debug.check(self.num_banks in [1,2,4], "Valid number of banks are 1 , 2 and 4.")

78
compiler/sram_factory.py Normal file
View File

@ -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()

View File

@ -25,17 +25,11 @@ class code_format_test(openram_test):
for code in source_codes: for code in source_codes:
if re.search("gdsMill", code): if re.search("gdsMill", code):
continue continue
if re.search("options.py$", code):
continue
if re.search("debug.py$", code): if re.search("debug.py$", code):
continue continue
if re.search("testutils.py$", code):
continue
if re.search("globals.py$", code):
continue
if re.search("openram.py$", code): if re.search("openram.py$", code):
continue continue
if re.search("sram.py$", code): if re.search("testutils.py$", code):
continue continue
if re.search("gen_stimulus.py$", code): if re.search("gen_stimulus.py$", code):
continue continue

View File

@ -21,7 +21,7 @@ class pand2_test(openram_test):
import pand2 import pand2
debug.info(2, "Testing pand2 gate 4x") debug.info(2, "Testing pand2 gate 4x")
a = pand2.pand2(4) a = pand2.pand2(name="pand2x4", size=4)
self.local_check(a) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -10,8 +10,7 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
OPTS = globals.OPTS
#@unittest.skip("SKIPPING 04_pbitcell_test") #@unittest.skip("SKIPPING 04_pbitcell_test")
class pbitcell_test(openram_test): class pbitcell_test(openram_test):
@ -19,75 +18,85 @@ class pbitcell_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
from pbitcell import pbitcell from pbitcell import pbitcell
import tech
OPTS.num_rw_ports=1 OPTS.num_rw_ports=1
OPTS.num_w_ports=1 OPTS.num_w_ports=1
OPTS.num_r_ports=1 OPTS.num_r_ports=1
factory.reset()
debug.info(2, "Bitcell with 1 of each port: read/write, write, and read") debug.info(2, "Bitcell with 1 of each port: read/write, write, and read")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
OPTS.num_rw_ports=0 OPTS.num_rw_ports=0
OPTS.num_w_ports=1 OPTS.num_w_ports=1
OPTS.num_r_ports=1 OPTS.num_r_ports=1
factory.reset()
debug.info(2, "Bitcell with 0 read/write ports") debug.info(2, "Bitcell with 0 read/write ports")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
OPTS.num_rw_ports=1 OPTS.num_rw_ports=1
OPTS.num_w_ports=0 OPTS.num_w_ports=0
OPTS.num_r_ports=1 OPTS.num_r_ports=1
factory.reset()
debug.info(2, "Bitcell with 0 write ports") debug.info(2, "Bitcell with 0 write ports")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
OPTS.num_rw_ports=1 OPTS.num_rw_ports=1
OPTS.num_w_ports=1 OPTS.num_w_ports=1
OPTS.num_r_ports=0 OPTS.num_r_ports=0
factory.reset()
debug.info(2, "Bitcell with 0 read ports") debug.info(2, "Bitcell with 0 read ports")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
OPTS.num_rw_ports=1 OPTS.num_rw_ports=1
OPTS.num_w_ports=0 OPTS.num_w_ports=0
OPTS.num_r_ports=0 OPTS.num_r_ports=0
factory.reset()
debug.info(2, "Bitcell with 0 read ports and 0 write ports") debug.info(2, "Bitcell with 0 read ports and 0 write ports")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
OPTS.num_rw_ports=2 OPTS.num_rw_ports=2
OPTS.num_w_ports=2 OPTS.num_w_ports=2
OPTS.num_r_ports=2 OPTS.num_r_ports=2
factory.reset()
debug.info(2, "Bitcell with 2 of each port: read/write, write, and read") debug.info(2, "Bitcell with 2 of each port: read/write, write, and read")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
OPTS.num_rw_ports=0 OPTS.num_rw_ports=0
OPTS.num_w_ports=2 OPTS.num_w_ports=2
OPTS.num_r_ports=2 OPTS.num_r_ports=2
factory.reset()
debug.info(2, "Bitcell with 0 read/write ports") debug.info(2, "Bitcell with 0 read/write ports")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
OPTS.num_rw_ports=2 OPTS.num_rw_ports=2
OPTS.num_w_ports=0 OPTS.num_w_ports=0
OPTS.num_r_ports=2 OPTS.num_r_ports=2
factory.reset()
debug.info(2, "Bitcell with 0 write ports") debug.info(2, "Bitcell with 0 write ports")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
OPTS.num_rw_ports=2 OPTS.num_rw_ports=2
OPTS.num_w_ports=2 OPTS.num_w_ports=2
OPTS.num_r_ports=0 OPTS.num_r_ports=0
factory.reset()
debug.info(2, "Bitcell with 0 read ports") debug.info(2, "Bitcell with 0 read ports")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
OPTS.num_rw_ports=2 OPTS.num_rw_ports=2
OPTS.num_w_ports=0 OPTS.num_w_ports=0
OPTS.num_r_ports=0 OPTS.num_r_ports=0
factory.reset()
debug.info(2, "Bitcell with 0 read ports and 0 write ports") debug.info(2, "Bitcell with 0 read ports and 0 write ports")
tx = pbitcell() tx = pbitcell(name="pbc")
self.local_check(tx) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -21,7 +21,7 @@ class pbuf_test(openram_test):
import pbuf import pbuf
debug.info(2, "Testing inverter/buffer 4x 8x") debug.info(2, "Testing inverter/buffer 4x 8x")
a = pbuf.pbuf(8) a = pbuf.pbuf(name="pbufx8", size=8)
self.local_check(a) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -23,16 +23,21 @@ class pdriver_test(openram_test):
debug.info(2, "Testing inverter/buffer 4x 8x") debug.info(2, "Testing inverter/buffer 4x 8x")
# a tests the error message for specifying conflicting conditions # a tests the error message for specifying conflicting conditions
#a = pdriver.pdriver(fanout_size = 4,size_list = [1,2,4,8]) #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) #self.local_check(a)
b = pdriver.pdriver(name="pdriver1", size_list = [1,2,4,8])
self.local_check(b) self.local_check(b)
c = pdriver.pdriver(name="pdriver2", fanout_size = 50)
self.local_check(c) self.local_check(c)
d = pdriver.pdriver(name="pdriver3", fanout_size = 50, neg_polarity = True)
self.local_check(d) self.local_check(d)
e = pdriver.pdriver(name="pdriver4", fanout_size = 64)
self.local_check(e) self.local_check(e)
f = pdriver.pdriver(name="pdriver5", fanout_size = 64, neg_polarity = True)
self.local_check(f) self.local_check(f)
globals.end_openram() globals.end_openram()

View File

@ -19,7 +19,7 @@ class pinv_test(openram_test):
import tech import tech
debug.info(2, "Checking 10x inverter") debug.info(2, "Checking 10x inverter")
tx = pinv.pinv(size=8) tx = pinv.pinv(name="pinvx10",size=8)
self.local_check(tx) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -19,7 +19,7 @@ class pinv_test(openram_test):
import tech import tech
debug.info(2, "Checking 1x beta=3 size inverter") 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) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -18,7 +18,7 @@ class pinv_test(openram_test):
import tech import tech
debug.info(2, "Checking 1x size inverter") debug.info(2, "Checking 1x size inverter")
tx = pinv.pinv(size=1) tx = pinv.pinv(name="pinvx1", size=1)
self.local_check(tx) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -19,7 +19,7 @@ class pinv_test(openram_test):
import tech import tech
debug.info(2, "Checking 2x size inverter") debug.info(2, "Checking 2x size inverter")
tx = pinv.pinv(size=2) tx = pinv.pinv(name="pinvx2", size=2)
self.local_check(tx) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -18,7 +18,7 @@ class pinvbuf_test(openram_test):
import pinvbuf import pinvbuf
debug.info(2, "Testing inverter/buffer 4x 8x") debug.info(2, "Testing inverter/buffer 4x 8x")
a = pinvbuf.pinvbuf(8) a = pinvbuf.pinvbuf(name="pinvufx8", size=8)
self.local_check(a) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -21,7 +21,7 @@ class pnand2_test(openram_test):
import tech import tech
debug.info(2, "Checking 2-input nand gate") debug.info(2, "Checking 2-input nand gate")
tx = pnand2.pnand2(size=1) tx = pnand2.pnand2(name="pnand2", size=1)
self.local_check(tx) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -21,7 +21,7 @@ class pnand3_test(openram_test):
import tech import tech
debug.info(2, "Checking 3-input nand gate") debug.info(2, "Checking 3-input nand gate")
tx = pnand3.pnand3(size=1) tx = pnand3.pnand3(name="pnand3", size=1)
self.local_check(tx) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -21,7 +21,7 @@ class pnor2_test(openram_test):
import tech import tech
debug.info(2, "Checking 2-input nor gate") debug.info(2, "Checking 2-input nor gate")
tx = pnor2.pnor2(size=1) tx = pnor2.pnor2(name="pnor2", size=1)
self.local_check(tx) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
class precharge_test(openram_test): class precharge_test(openram_test):
@ -29,6 +30,7 @@ class precharge_test(openram_test):
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
factory.reset()
debug.info(2, "Checking precharge for pbitcell (innermost connections)") debug.info(2, "Checking precharge for pbitcell (innermost connections)")
tx = precharge.precharge(name="precharge_driver", size=1, bitcell_bl="bl0", bitcell_br="br0") tx = precharge.precharge(name="precharge_driver", size=1, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(tx) self.local_check(tx)

View File

@ -10,29 +10,31 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
class replica_pbitcell_test(openram_test): class replica_pbitcell_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
import replica_pbitcell import replica_pbitcell
import tech
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
factory.reset()
debug.info(2, "Checking replica bitcell using pbitcell (small cell)") 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) self.local_check(tx)
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
factory.reset()
debug.info(2, "Checking replica bitcell using pbitcell (large cell)") 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) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
#@unittest.skip("SKIPPING 04_driver_test") #@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 # check single level column mux in single port
debug.info(2, "Checking column mux") 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) self.local_check(tx)
# check single level column mux in multi-port # check single level column mux in multi-port
@ -31,12 +32,14 @@ class single_level_column_mux_test(openram_test):
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
factory.reset()
debug.info(2, "Checking column mux for pbitcell (innermost connections)") 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) self.local_check(tx)
factory.reset()
debug.info(2, "Checking column mux for pbitcell (outermost connections)") 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) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
class hierarchical_decoder_test(openram_test): class hierarchical_decoder_test(openram_test):
@ -20,29 +21,29 @@ class hierarchical_decoder_test(openram_test):
# Doesn't require hierarchical decoder # Doesn't require hierarchical decoder
# debug.info(1, "Testing 4 row sample for 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) # self.local_check(a)
# Doesn't require hierarchical decoder # Doesn't require hierarchical decoder
# debug.info(1, "Testing 8 row sample for 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) # self.local_check(a)
# check hierarchical decoder for single port # check hierarchical decoder for single port
debug.info(1, "Testing 16 row sample for hierarchical_decoder") 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) self.local_check(a)
debug.info(1, "Testing 32 row sample for hierarchical_decoder") 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) self.local_check(a)
debug.info(1, "Testing 128 row sample for hierarchical_decoder") 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) self.local_check(a)
debug.info(1, "Testing 512 row sample for hierarchical_decoder") 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) self.local_check(a)
# check hierarchical decoder for multi-port # check hierarchical decoder for multi-port
@ -51,20 +52,21 @@ class hierarchical_decoder_test(openram_test):
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
factory.reset()
debug.info(1, "Testing 16 row sample for hierarchical_decoder (multi-port case)") 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) self.local_check(a)
debug.info(1, "Testing 32 row sample for hierarchical_decoder (multi-port case)") 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) self.local_check(a)
debug.info(1, "Testing 128 row sample for hierarchical_decoder (multi-port case)") 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) self.local_check(a)
debug.info(1, "Testing 512 row sample for hierarchical_decoder (multi-port case)") 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) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -20,7 +20,7 @@ class hierarchical_predecode2x4_test(openram_test):
# checking hierarchical precode 2x4 for single port # checking hierarchical precode 2x4 for single port
debug.info(1, "Testing sample for hierarchy_predecode2x4") debug.info(1, "Testing sample for hierarchy_predecode2x4")
a = pre.hierarchical_predecode2x4() a = pre.hierarchical_predecode2x4(name="pre1")
self.local_check(a) self.local_check(a)
# checking hierarchical precode 2x4 for multi-port # checking hierarchical precode 2x4 for multi-port
@ -30,7 +30,7 @@ class hierarchical_predecode2x4_test(openram_test):
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
debug.info(1, "Testing sample for hierarchy_predecode2x4 (multi-port case)") 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) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -20,7 +20,7 @@ class hierarchical_predecode3x8_test(openram_test):
# checking hierarchical precode 3x8 for single port # checking hierarchical precode 3x8 for single port
debug.info(1, "Testing sample for hierarchy_predecode3x8") debug.info(1, "Testing sample for hierarchy_predecode3x8")
a = pre.hierarchical_predecode3x8() a = pre.hierarchical_predecode3x8(name="pre1")
self.local_check(a) self.local_check(a)
# checking hierarchical precode 3x8 for multi-port # checking hierarchical precode 3x8 for multi-port
@ -30,7 +30,7 @@ class hierarchical_predecode3x8_test(openram_test):
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
debug.info(1, "Testing sample for hierarchy_predecode3x8 (multi-port case)") 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) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -9,6 +9,7 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
class single_level_column_mux_test(openram_test): 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 # check single level column mux array in single port
debug.info(1, "Testing sample for 2-way column_mux_array") 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) self.local_check(a)
debug.info(1, "Testing sample for 4-way column_mux_array") 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) self.local_check(a)
debug.info(1, "Testing sample for 8-way column_mux_array") 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) self.local_check(a)
# check single level column mux array in multi-port # check single level column mux array in multi-port
@ -35,20 +36,21 @@ class single_level_column_mux_test(openram_test):
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
factory.reset()
debug.info(1, "Testing sample for 2-way column_mux_array in multi-port") 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) self.local_check(a)
debug.info(1, "Testing sample for 4-way column_mux_array in multi-port") 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) self.local_check(a)
debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (innermost connections)") 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) self.local_check(a)
debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (outermost connections)") 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) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -10,17 +10,17 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
class precharge_test(openram_test): class precharge_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
import precharge_array import precharge_array
import tech
# check precharge array in single port # check precharge array in single port
debug.info(2, "Checking 3 column precharge") 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) self.local_check(pc)
# check precharge array in multi-port # check precharge array in multi-port
@ -29,16 +29,17 @@ class precharge_test(openram_test):
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
factory.reset()
debug.info(2, "Checking 3 column precharge array for 1RW/1R bitcell") 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) self.local_check(pc)
# debug.info(2, "Checking 3 column precharge array for pbitcell (innermost connections)") # 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) # self.local_check(pc)
# debug.info(2, "Checking 3 column precharge array for pbitcell (outermost connections)") # 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) # self.local_check(pc)
globals.end_openram() globals.end_openram()

View File

@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
#@unittest.skip("SKIPPING 04_driver_test") #@unittest.skip("SKIPPING 04_driver_test")
@ -18,11 +19,10 @@ class wordline_driver_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
import wordline_driver import wordline_driver
import tech
# check wordline driver for single port # check wordline driver for single port
debug.info(2, "Checking driver") 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) self.local_check(tx)
# check wordline driver for multi-port # check wordline driver for multi-port
@ -31,8 +31,9 @@ class wordline_driver_test(openram_test):
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
factory.reset()
debug.info(2, "Checking driver (multi-port case)") 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) self.local_check(tx)
globals.end_openram() globals.end_openram()

View File

@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
class sense_amp_test(openram_test): class sense_amp_test(openram_test):
@ -19,11 +20,11 @@ class sense_amp_test(openram_test):
# check sense amp array for single port # check sense amp array for single port
debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=2") 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) self.local_check(a)
debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=4") 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) self.local_check(a)
# check sense amp array for multi-port # check sense amp array for multi-port
@ -32,12 +33,13 @@ class sense_amp_test(openram_test):
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_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)") 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) self.local_check(a)
debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=4 (multi-port case)") 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) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
class write_driver_test(openram_test): class write_driver_test(openram_test):
@ -19,11 +20,11 @@ class write_driver_test(openram_test):
# check write driver array for single port # check write driver array for single port
debug.info(2, "Testing write_driver_array for columns=8, word_size=8") 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) self.local_check(a)
debug.info(2, "Testing write_driver_array for columns=16, word_size=8") 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) self.local_check(a)
# check write driver array for multi-port # check write driver array for multi-port
@ -32,12 +33,13 @@ class write_driver_test(openram_test):
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_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)") 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) self.local_check(a)
debug.info(2, "Testing write_driver_array for columns=16, word_size=8 (multi-port case)") 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) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -18,7 +18,7 @@ class delay_chain_test(openram_test):
import delay_chain import delay_chain
debug.info(2, "Testing 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) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -10,6 +10,7 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
class replica_bitline_multiport_test(openram_test): class replica_bitline_multiport_test(openram_test):
@ -27,8 +28,9 @@ class replica_bitline_multiport_test(openram_test):
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
factory.reset()
debug.info(2, "Testing 1rw 1r RBL with {0} FO4 stages, {1} rows".format(stages,rows)) 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) self.local_check(a)
# check replica bitline in pbitcell multi-port # 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_w_ports = 0
OPTS.num_r_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)) 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) self.local_check(a)
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
OPTS.num_r_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)) 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) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -22,14 +22,14 @@ class replica_bitline_test(openram_test):
fanout=4 fanout=4
rows=13 rows=13
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows)) 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) self.local_check(a)
#debug.error("Exiting...", 1) #debug.error("Exiting...", 1)
stages=8 stages=8
rows=100 rows=100
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows)) 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) self.local_check(a)

View File

@ -10,15 +10,13 @@ sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
import debug import debug
from sram_factory import factory
#@unittest.skip("SKIPPING 19_psingle_bank_test") #@unittest.skip("SKIPPING 19_psingle_bank_test")
class psingle_bank_test(openram_test): class psingle_bank_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
from bank import bank from bank import bank
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
@ -31,6 +29,7 @@ class psingle_bank_test(openram_test):
num_words=16) num_words=16)
c.words_per_row=1 c.words_per_row=1
factory.reset()
c.recompute_sizes() c.recompute_sizes()
debug.info(1, "No column mux") 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) 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.num_words=32
c.words_per_row=2 c.words_per_row=2
factory.reset()
c.recompute_sizes() c.recompute_sizes()
debug.info(1, "Two way column mux") 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) 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.num_words=64
c.words_per_row=4 c.words_per_row=4
factory.reset()
c.recompute_sizes() c.recompute_sizes()
debug.info(1, "Four way column mux") 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) 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.word_size=2
c.num_words=128 c.num_words=128
c.words_per_row=8 c.words_per_row=8
factory.reset()
c.recompute_sizes() c.recompute_sizes()
debug.info(1, "Four way column mux") 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) name = "bank4_{0}rw_{1}w_{2}r_single".format(OPTS.num_rw_ports, OPTS.num_w_ports, OPTS.num_r_ports)

View File

@ -4,11 +4,12 @@ equate class {-circuit1 nfet} {-circuit2 n}
equate class {-circuit1 pfet} {-circuit2 p} equate class {-circuit1 pfet} {-circuit2 p}
# This circuit has symmetries and needs to be flattened to resolve them # This circuit has symmetries and needs to be flattened to resolve them
# or the banks won't pass # 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_1}
flatten class {-circuit1 precharge_array_2} flatten class {-circuit1 precharge_array_2}
flatten class {-circuit1 precharge_array_3} flatten class {-circuit1 precharge_array_3}
flatten class {-circuit1 precharge_array_4}
property {-circuit1 nfet} remove as ad ps pd property {-circuit1 nfet} remove as ad ps pd
property {-circuit1 pfet} remove as ad ps pd property {-circuit1 pfet} remove as ad ps pd
property {-circuit2 n} remove as ad ps pd property {-circuit2 n} remove as ad ps pd