From 6963a1092f2074fae0b2b27a7d9e2b109f626ede Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 4 Sep 2018 11:55:22 -0700 Subject: [PATCH] Make bitcell width/height not static. Update modules to use it for pbitcell. --- compiler/modules/delay_chain.py | 5 ----- compiler/modules/hierarchical_decoder.py | 3 ++- compiler/modules/sense_amp_array.py | 3 ++- compiler/modules/wordline_driver.py | 12 +++++++----- compiler/modules/write_driver_array.py | 5 +++-- compiler/pgates/pbitcell.py | 17 ++++++----------- compiler/pgates/pgate.py | 11 ++++++++++- compiler/pgates/pinv.py | 8 ++------ compiler/pgates/pinvbuf.py | 8 ++------ compiler/pgates/pnand2.py | 9 ++------- compiler/pgates/pnand3.py | 10 ++-------- compiler/pgates/pnor2.py | 9 ++------- compiler/pgates/single_level_column_mux.py | 2 ++ compiler/tests/19_psingle_bank_test.py | 2 +- 14 files changed, 43 insertions(+), 61 deletions(-) diff --git a/compiler/modules/delay_chain.py b/compiler/modules/delay_chain.py index b8a57f15..90175743 100644 --- a/compiler/modules/delay_chain.py +++ b/compiler/modules/delay_chain.py @@ -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) diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 7c90b1f1..0b44c8fc 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -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}]" diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index a02ffd9d..c48d280d 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -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 = [] diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index 87b0430e..3deac4e1 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -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. """ diff --git a/compiler/modules/write_driver_array.py b/compiler/modules/write_driver_array.py index 88d40c86..eff0c8d8 100644 --- a/compiler/modules/write_driver_array.py +++ b/compiler/modules/write_driver_array.py @@ -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 = {} diff --git a/compiler/pgates/pbitcell.py b/compiler/pgates/pbitcell.py index 3ac0fa74..6f579c06 100644 --- a/compiler/pgates/pbitcell.py +++ b/compiler/pgates/pbitcell.py @@ -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() diff --git a/compiler/pgates/pgate.py b/compiler/pgates/pgate.py index 4e47934d..ec3bed0c 100644 --- a/compiler/pgates/pgate.py +++ b/compiler/pgates/pgate.py @@ -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. """ diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index e2e87053..f0df378d 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -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 diff --git a/compiler/pgates/pinvbuf.py b/compiler/pgates/pinvbuf.py index e55fb649..328836dc 100644 --- a/compiler/pgates/pinvbuf.py +++ b/compiler/pgates/pinvbuf.py @@ -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() diff --git a/compiler/pgates/pnand2.py b/compiler/pgates/pnand2.py index 99ae9f02..d38c7de4 100644 --- a/compiler/pgates/pnand2.py +++ b/compiler/pgates/pnand2.py @@ -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.") diff --git a/compiler/pgates/pnand3.py b/compiler/pgates/pnand3.py index 984ee417..b4e11b32 100644 --- a/compiler/pgates/pnand3.py +++ b/compiler/pgates/pnand3.py @@ -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.") diff --git a/compiler/pgates/pnor2.py b/compiler/pgates/pnor2.py index e19f03cf..8f7dcea4 100644 --- a/compiler/pgates/pnor2.py +++ b/compiler/pgates/pnor2.py @@ -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.") diff --git a/compiler/pgates/single_level_column_mux.py b/compiler/pgates/single_level_column_mux.py index 604c9312..015b434a 100644 --- a/compiler/pgates/single_level_column_mux.py +++ b/compiler/pgates/single_level_column_mux.py @@ -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) diff --git a/compiler/tests/19_psingle_bank_test.py b/compiler/tests/19_psingle_bank_test.py index bdb64f9e..f377a3db 100755 --- a/compiler/tests/19_psingle_bank_test.py +++ b/compiler/tests/19_psingle_bank_test.py @@ -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):