Make bitcell width/height not static. Update modules to use it for pbitcell.

This commit is contained in:
Matt Guthaus 2018-09-04 11:55:22 -07:00
parent 0adfe66429
commit 6963a1092f
14 changed files with 43 additions and 61 deletions

View File

@ -53,11 +53,6 @@ class delay_chain(design.design):
self.add_pin("gnd")
def add_modules(self):
from importlib import reload
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
self.inv = pinv(route_output=False)
self.add_mod(self.inv)

View File

@ -24,7 +24,8 @@ class hierarchical_decoder(design.design):
from importlib import reload
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell_height = self.mod_bitcell.height
b = self.mod_bitcell()
self.bitcell_height = b.height
self.NAND_FORMAT = "DEC_NAND[{0}]"
self.INV_FORMAT = "DEC_INV_[{0}]"

View File

@ -57,10 +57,11 @@ class sense_amp_array(design.design):
self.amp = self.mod_sense_amp("sense_amp")
self.add_mod(self.amp)
# This is just used for measurements,
# so don't add the module
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
self.add_mod(self.bitcell)
def create_sense_amp_array(self):
self.local_insts = []

View File

@ -50,6 +50,13 @@ class wordline_driver(design.design):
def add_modules(self):
# This is just used for measurements,
# so don't add the module
from importlib import reload
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
self.inv = pinv()
self.add_mod(self.inv)
@ -59,11 +66,6 @@ class wordline_driver(design.design):
self.nand2 = pnand2()
self.add_mod(self.nand2)
from importlib import reload
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
self.add_mod(self.bitcell)
def route_vdd_gnd(self):
""" Add a pin for each row of vdd/gnd which are must-connects next level up. """

View File

@ -58,11 +58,12 @@ class write_driver_array(design.design):
self.mod_write_driver = getattr(c, OPTS.write_driver)
self.driver = self.mod_write_driver("write_driver")
self.add_mod(self.driver)
# This is just used for measurements,
# so don't add the module
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
self.add_mod(self.bitcell)
def create_write_array(self):
self.driver_insts = {}

View File

@ -1,5 +1,4 @@
import contact
import pgate
import design
import debug
from tech import drc, parameter, spice
@ -7,14 +6,11 @@ from vector import vector
from ptx import ptx
from globals import OPTS
class pbitcell(pgate.pgate):
class pbitcell(design.design):
"""
This module implements a parametrically sized multi-port bitcell,
with a variable number of read/write, write, and read ports
"""
width = None
height = None
def __init__(self):
@ -23,18 +19,17 @@ class pbitcell(pgate.pgate):
self.num_r_ports = OPTS.num_r_ports
name = "pbitcell_{0}RW_{1}W_{2}R".format(self.num_rw_ports, self.num_w_ports, self.num_r_ports)
pgate.pgate.__init__(self, name)
# This is not a pgate because pgates depend on the bitcell height!
design.design.__init__(self, name)
debug.info(2, "create a multi-port bitcell with {0} rw ports, {1} w ports and {2} r ports".format(self.num_rw_ports,
self.num_w_ports,
self.num_r_ports))
self.create_netlist()
if not OPTS.netlist_only:
self.create_layout()
# We must always create the bitcell layout because
# some transistor sizes in the other netlists depend on it
self.create_layout()
# FIXME: Why is this static set here?
pbitcell.width = self.width
pbitcell.height = self.height
def create_netlist(self):
self.add_pins()

View File

@ -11,10 +11,19 @@ class pgate(design.design):
This is a module that implements some shared functions for parameterized gates.
"""
def __init__(self, name):
def __init__(self, name, height=None):
""" Creates a generic cell """
design.design.__init__(self, name)
if height:
self.height = height
elif not height:
from importlib import reload
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
b = bitcell()
self.height = b.height
def connect_pin_to_rail(self,inst,pin,supply):
""" Conencts a ptx pin to a supply rail. """

View File

@ -17,26 +17,22 @@ class pinv(pgate.pgate):
from center of rail to rail.. The route_output will route the
output to the right side of the cell for easier access.
"""
from importlib import reload
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
unique_id = 1
def __init__(self, size=1, beta=parameter["beta"], height=bitcell.height, 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
# will use the last record with a given name. I.e., you will
# over-write a design in GDS if one has and the other doesn't
# have poly connected, for example.
name = "pinv_{}".format(pinv.unique_id)
pinv.unique_id += 1
pgate.pgate.__init__(self, name)
pgate.pgate.__init__(self, name, height)
debug.info(2, "create pinv structure {0} with size of {1}".format(name, size))
self.nmos_size = size
self.pmos_size = beta*size
self.beta = beta
self.height = height # Maybe minimize height if not defined in future?
self.route_output = False

View File

@ -11,13 +11,9 @@ class pinvbuf(design.design):
This is a simple inverter/buffer used for driving loads. It is
used in the column decoder for 1:2 decoding and as the clock buffer.
"""
from importlib import reload
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
unique_id = 1
def __init__(self, driver_size=4, height=bitcell.height, name=""):
def __init__(self, driver_size=4, height=None, name=""):
self.stage_effort = 4
self.row_height = height
@ -32,7 +28,7 @@ class pinvbuf(design.design):
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))
self.create_netlist()

View File

@ -12,24 +12,19 @@ class pnand2(pgate.pgate):
This model use ptx to generate a 2-input nand within a cetrain height.
"""
from importlib import reload
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
unique_id = 1
def __init__(self, size=1, height=bitcell.height):
def __init__(self, size=1, height=None):
""" Creates a cell for a simple 2 input nand """
name = "pnand2_{0}".format(pnand2.unique_id)
pnand2.unique_id += 1
pgate.pgate.__init__(self, name)
pgate.pgate.__init__(self, name, height)
debug.info(2, "create pnand2 structure {0} with size of {1}".format(name, size))
self.nmos_size = 2*size
self.pmos_size = parameter["beta"]*size
self.nmos_width = self.nmos_size*drc["minwidth_tx"]
self.pmos_width = self.pmos_size*drc["minwidth_tx"]
self.height = height
# FIXME: Allow these to be sized
debug.check(size==1,"Size 1 pnand2 is only supported now.")

View File

@ -12,18 +12,13 @@ class pnand3(pgate.pgate):
This model use ptx to generate a 2-input nand within a cetrain height.
"""
from importlib import reload
c = reload(__import__(OPTS.bitcell))
mod_bitcell = getattr(c, OPTS.bitcell)
bitcell = mod_bitcell()
unique_id = 1
def __init__(self, size=1, height=bitcell.height):
def __init__(self, size=1, height=None):
""" Creates a cell for a simple 3 input nand """
name = "pnand3_{0}".format(pnand3.unique_id)
pnand3.unique_id += 1
pgate.pgate.__init__(self, name)
pgate.pgate.__init__(self, name, height)
debug.info(2, "create pnand3 structure {0} with size of {1}".format(name, size))
# We have trouble pitch matching a 3x sizes to the bitcell...
@ -32,7 +27,6 @@ class pnand3(pgate.pgate):
self.pmos_size = parameter["beta"]*size
self.nmos_width = self.nmos_size*drc["minwidth_tx"]
self.pmos_width = self.pmos_size*drc["minwidth_tx"]
self.height = height
# FIXME: Allow these to be sized
debug.check(size==1,"Size 1 pnand3 is only supported now.")

View File

@ -12,17 +12,13 @@ class pnor2(pgate.pgate):
This model use ptx to generate a 2-input nor within a cetrain height.
"""
from importlib import reload
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
unique_id = 1
def __init__(self, size=1, height=bitcell.height):
def __init__(self, size=1, height=None):
""" Creates a cell for a simple 2 input nor """
name = "pnor2_{0}".format(pnor2.unique_id)
pnor2.unique_id += 1
pgate.pgate.__init__(self, name)
pgate.pgate.__init__(self, name, height)
debug.info(2, "create pnor2 structure {0} with size of {1}".format(name, size))
self.nmos_size = size
@ -30,7 +26,6 @@ class pnor2(pgate.pgate):
self.pmos_size = 1.5*parameter["beta"]*size
self.nmos_width = self.nmos_size*drc["minwidth_tx"]
self.pmos_width = self.pmos_size*drc["minwidth_tx"]
self.height = height
# FIXME: Allow these to be sized
debug.check(size==1,"Size 1 pnor2 is only supported now.")

View File

@ -39,6 +39,8 @@ class single_level_column_mux(design.design):
self.add_wells()
def add_modules(self):
# This is just used for measurements,
# so don't add the module
from importlib import reload
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)

View File

@ -11,7 +11,7 @@ import globals
from globals import OPTS
import debug
@unittest.skip("SKIPPING 19_psingle_bank_test")
#@unittest.skip("SKIPPING 19_psingle_bank_test")
class psingle_bank_test(openram_test):
def runTest(self):