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") self.add_pin("gnd")
def add_modules(self): 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.inv = pinv(route_output=False)
self.add_mod(self.inv) self.add_mod(self.inv)

View File

@ -24,7 +24,8 @@ class hierarchical_decoder(design.design):
from importlib import reload from importlib import reload
c = reload(__import__(OPTS.bitcell)) c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, 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.NAND_FORMAT = "DEC_NAND[{0}]"
self.INV_FORMAT = "DEC_INV_[{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.amp = self.mod_sense_amp("sense_amp")
self.add_mod(self.amp) self.add_mod(self.amp)
# This is just used for measurements,
# so don't add the module
c = reload(__import__(OPTS.bitcell)) c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell) self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell() self.bitcell = self.mod_bitcell()
self.add_mod(self.bitcell)
def create_sense_amp_array(self): def create_sense_amp_array(self):
self.local_insts = [] self.local_insts = []

View File

@ -50,6 +50,13 @@ class wordline_driver(design.design):
def add_modules(self): 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.inv = pinv()
self.add_mod(self.inv) self.add_mod(self.inv)
@ -59,11 +66,6 @@ class wordline_driver(design.design):
self.nand2 = pnand2() self.nand2 = pnand2()
self.add_mod(self.nand2) 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): def route_vdd_gnd(self):
""" Add a pin for each row of vdd/gnd which are must-connects next level up. """ """ Add a pin for each row of vdd/gnd which are must-connects next level up. """

View File

@ -59,10 +59,11 @@ class write_driver_array(design.design):
self.driver = self.mod_write_driver("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,
# so don't add the module
c = reload(__import__(OPTS.bitcell)) c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell) self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell() self.bitcell = self.mod_bitcell()
self.add_mod(self.bitcell)
def create_write_array(self): def create_write_array(self):
self.driver_insts = {} self.driver_insts = {}

View File

@ -1,5 +1,4 @@
import contact import contact
import pgate
import design import design
import debug import debug
from tech import drc, parameter, spice from tech import drc, parameter, spice
@ -7,15 +6,12 @@ from vector import vector
from ptx import ptx from ptx import ptx
from globals import OPTS from globals import OPTS
class pbitcell(pgate.pgate): class pbitcell(design.design):
""" """
This module implements a parametrically sized multi-port bitcell, This module implements a parametrically sized multi-port bitcell,
with a variable number of read/write, write, and read ports with a variable number of read/write, write, and read ports
""" """
width = None
height = None
def __init__(self): def __init__(self):
self.num_rw_ports = OPTS.num_rw_ports self.num_rw_ports = OPTS.num_rw_ports
@ -23,18 +19,17 @@ class pbitcell(pgate.pgate):
self.num_r_ports = OPTS.num_r_ports 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) 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, 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,
self.num_r_ports)) self.num_r_ports))
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: # We must always create the bitcell layout because
# some transistor sizes in the other netlists depend on it
self.create_layout() self.create_layout()
# FIXME: Why is this static set here?
pbitcell.width = self.width
pbitcell.height = self.height
def create_netlist(self): def create_netlist(self):
self.add_pins() 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. 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 """ """ Creates a generic cell """
design.design.__init__(self, name) 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): def connect_pin_to_rail(self,inst,pin,supply):
""" Conencts a ptx pin to a supply rail. """ """ 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 from center of rail to rail.. The route_output will route the
output to the right side of the cell for easier access. 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 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 # 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) name = "pinv_{}".format(pinv.unique_id)
pinv.unique_id += 1 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)) debug.info(2, "create pinv structure {0} with size of {1}".format(name, size))
self.nmos_size = size self.nmos_size = size
self.pmos_size = beta*size self.pmos_size = beta*size
self.beta = beta self.beta = beta
self.height = height # Maybe minimize height if not defined in future?
self.route_output = False 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 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.
""" """
from importlib import reload
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
unique_id = 1 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.stage_effort = 4
self.row_height = height self.row_height = height

View File

@ -12,24 +12,19 @@ class pnand2(pgate.pgate):
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.
""" """
from importlib import reload
c = reload(__import__(OPTS.bitcell))
bitcell = getattr(c, OPTS.bitcell)
unique_id = 1 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 """ """ Creates a cell for a simple 2 input nand """
name = "pnand2_{0}".format(pnand2.unique_id) name = "pnand2_{0}".format(pnand2.unique_id)
pnand2.unique_id += 1 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)) debug.info(2, "create pnand2 structure {0} with size of {1}".format(name, size))
self.nmos_size = 2*size self.nmos_size = 2*size
self.pmos_size = parameter["beta"]*size self.pmos_size = parameter["beta"]*size
self.nmos_width = self.nmos_size*drc["minwidth_tx"] self.nmos_width = self.nmos_size*drc["minwidth_tx"]
self.pmos_width = self.pmos_size*drc["minwidth_tx"] self.pmos_width = self.pmos_size*drc["minwidth_tx"]
self.height = height
# FIXME: Allow these to be sized # FIXME: Allow these to be sized
debug.check(size==1,"Size 1 pnand2 is only supported now.") 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. 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 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 """ """ Creates a cell for a simple 3 input nand """
name = "pnand3_{0}".format(pnand3.unique_id) name = "pnand3_{0}".format(pnand3.unique_id)
pnand3.unique_id += 1 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)) 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... # 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.pmos_size = parameter["beta"]*size
self.nmos_width = self.nmos_size*drc["minwidth_tx"] self.nmos_width = self.nmos_size*drc["minwidth_tx"]
self.pmos_width = self.pmos_size*drc["minwidth_tx"] self.pmos_width = self.pmos_size*drc["minwidth_tx"]
self.height = height
# FIXME: Allow these to be sized # FIXME: Allow these to be sized
debug.check(size==1,"Size 1 pnand3 is only supported now.") 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. 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 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 """ """ Creates a cell for a simple 2 input nor """
name = "pnor2_{0}".format(pnor2.unique_id) name = "pnor2_{0}".format(pnor2.unique_id)
pnor2.unique_id += 1 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)) debug.info(2, "create pnor2 structure {0} with size of {1}".format(name, size))
self.nmos_size = size self.nmos_size = size
@ -30,7 +26,6 @@ class pnor2(pgate.pgate):
self.pmos_size = 1.5*parameter["beta"]*size self.pmos_size = 1.5*parameter["beta"]*size
self.nmos_width = self.nmos_size*drc["minwidth_tx"] self.nmos_width = self.nmos_size*drc["minwidth_tx"]
self.pmos_width = self.pmos_size*drc["minwidth_tx"] self.pmos_width = self.pmos_size*drc["minwidth_tx"]
self.height = height
# FIXME: Allow these to be sized # FIXME: Allow these to be sized
debug.check(size==1,"Size 1 pnor2 is only supported now.") 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() self.add_wells()
def add_modules(self): def add_modules(self):
# This is just used for measurements,
# so don't add the module
from importlib import reload from importlib import reload
c = reload(__import__(OPTS.bitcell)) c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell) self.mod_bitcell = getattr(c, OPTS.bitcell)

View File

@ -11,7 +11,7 @@ import globals
from globals import OPTS from globals import OPTS
import debug import debug
@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):