From e4bc2c4914d66dc6ec43ea4a39e8254bf4566bd5 Mon Sep 17 00:00:00 2001 From: mrg Date: Sat, 14 Nov 2020 08:08:42 -0800 Subject: [PATCH] Update property settings with getters/setters --- compiler/base/custom_cell_properties.py | 59 +++++++++++++++++++--- compiler/base/design.py | 33 ++++++------ compiler/bitcells/bitcell_1port.py | 2 +- compiler/bitcells/bitcell_2port.py | 2 +- compiler/bitcells/bitcell_base.py | 17 ++----- compiler/bitcells/col_cap_bitcell_2port.py | 14 ++--- compiler/bitcells/dummy_bitcell_1port.py | 2 +- compiler/bitcells/dummy_bitcell_2port.py | 2 +- compiler/bitcells/replica_bitcell_1port.py | 2 +- compiler/bitcells/replica_bitcell_2port.py | 2 +- compiler/bitcells/row_cap_bitcell_2port.py | 9 +--- compiler/custom/dff.py | 3 +- compiler/custom/inv_dec.py | 3 +- compiler/custom/nand2_dec.py | 3 +- compiler/custom/nand3_dec.py | 3 +- compiler/custom/nand4_dec.py | 3 +- compiler/custom/sense_amp.py | 2 +- compiler/custom/write_driver.py | 2 +- 18 files changed, 94 insertions(+), 69 deletions(-) diff --git a/compiler/base/custom_cell_properties.py b/compiler/base/custom_cell_properties.py index dbe62bd0..2fab7a2a 100644 --- a/compiler/base/custom_cell_properties.py +++ b/compiler/base/custom_cell_properties.py @@ -18,16 +18,13 @@ class _cell: if not port_map: port_map = {x: x for x in port_order} - self.set_ports(port_order, port_map) - - def set_ports(self, - port_order, - port_map): # Update mapping of names self._pins = _pins(port_map) self._port_order = port_order + # Update ordered name list self._port_names = [getattr(self._pins, x) for x in self._port_order] + # Update ordered type list self._port_types = [self._port_types_map[x] for x in port_order] @@ -43,6 +40,29 @@ class _cell: def port_names(self): return self._port_names + @property + def port_order(self): + return self._port_order + + @port_order.setter + def port_order(self, x): + self._port_order = x + # Update ordered name list in the new order + self._port_names = [getattr(self._pins, x) for x in self._port_order] + # Update ordered type list in the new order + self._port_types = [self._port_types_map[x] for x in self._port_order] + + @property + def port_map(self): + return self._port_map + + @port_map.setter + def port_map(self, x): + self._port_map = x + self._pins = _pins(x) + # Update ordered name list to use the new names + self._port_names = [getattr(self._pins, x) for x in self._port_order] + @property def port_types(self): return self._port_types @@ -50,7 +70,11 @@ class _cell: @property def boundary_layer(self): return self._boundary_layer - + + @boundary_layer.setter + def boundary_layer(self, x): + self._boundary_layer = x + class _pins: def __init__(self, pin_dict): @@ -116,13 +140,16 @@ class cell_properties(): self._pgate = _pgate(add_implants=False) + self._inv_dec = _cell(["A", "Z", "vdd", "gnd"], + ["INPUT", "OUTPUT", "POWER", "GROUND"]) + self._nand2_dec = _cell(["A", "B", "Z", "vdd", "gnd"], ["INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]) - self._nand2_dec = _cell(["A", "B", "C", "Z", "vdd", "gnd"], + self._nand3_dec = _cell(["A", "B", "C", "Z", "vdd", "gnd"], ["INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]) - self._nand2_dec = _cell(["A", "B", "C", "D", "Z", "vdd", "gnd"], + self._nand4_dec = _cell(["A", "B", "C", "D", "Z", "vdd", "gnd"], ["INPUT", "INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]) self._dff = _cell(["D", "Q", "clk", "vdd", "gnd"], @@ -152,6 +179,22 @@ class cell_properties(): def pgate(self): return self._pgate + @property + def inv_dec(self): + return self._inv_dec + + @property + def nand2_dec(self): + return self._nand2_dec + + @property + def nand3_dec(self): + return self._nand3_dec + + @property + def nand4_dec(self): + return self._nand4_dec + @property def dff(self): return self._dff diff --git a/compiler/base/design.py b/compiler/base/design.py index 98c03981..8b2fe826 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -22,7 +22,7 @@ class design(hierarchy_design): some DRC/layer constants and analytical models for other modules to reuse. """ - def __init__(self, name, cell_name=None): + def __init__(self, name, cell_name=None, prop=None): # This allows us to use different GDS/spice circuits for hard cells instead of the default ones # Except bitcell names are generated automatically by the globals.py setup_bitcells routines # depending on the number of ports. @@ -32,25 +32,24 @@ class design(hierarchy_design): cell_name = name super().__init__(name, cell_name) - # This means it is a custom cell... - if hasattr(props, name): - prop = getattr(props, name) - if prop.hard_cell: - # The pins get added from the spice file - debug.check(prop.port_names == self.pins, - "Custom cell pin names do not match spice file:\n{0} vs {1}".format(prop.port_names, self.pins)) - self.add_pin_types(prop.port_types) + # This means it is a custom cell. + # It could have properties and not be a hard cell too (e.g. dff_buf) + if prop and prop.hard_cell: + # The pins get added from the spice file + debug.check(prop.port_names == self.pins, + "Custom cell pin names do not match spice file:\n{0} vs {1}".format(prop.port_names, self.pins)) + self.add_pin_types(prop.port_types) - (width, height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[prop.boundary_layer]) + (width, height) = utils.get_libcell_size(self.cell_name, + GDS["unit"], + layer[prop.boundary_layer]) - self.pin_map = utils.get_libcell_pins(self.pins, - self.cell_name, - GDS["unit"]) + self.pin_map = utils.get_libcell_pins(self.pins, + self.cell_name, + GDS["unit"]) - self.width = width - self.height = height + self.width = width + self.height = height self.setup_multiport_constants() diff --git a/compiler/bitcells/bitcell_1port.py b/compiler/bitcells/bitcell_1port.py index e8f330f1..947b9435 100644 --- a/compiler/bitcells/bitcell_1port.py +++ b/compiler/bitcells/bitcell_1port.py @@ -19,7 +19,7 @@ class bitcell_1port(bitcell_base.bitcell_base): """ def __init__(self, name): - super().__init__(name, props.bitcell_1port) + super().__init__(name, prop=props.bitcell_1port) debug.info(2, "Create bitcell") def get_all_wl_names(self): diff --git a/compiler/bitcells/bitcell_2port.py b/compiler/bitcells/bitcell_2port.py index 2293cb71..a99f8219 100644 --- a/compiler/bitcells/bitcell_2port.py +++ b/compiler/bitcells/bitcell_2port.py @@ -19,7 +19,7 @@ class bitcell_2port(bitcell_base.bitcell_base): """ def __init__(self, name): - super().__init__(name, props.bitcell_2port) + super().__init__(name, prop=props.bitcell_2port) debug.info(2, "Create bitcell with 2 ports") self.bl_names = [props.bitcell_2port.pin.bl0, props.bitcell_2port.pin.bl1] diff --git a/compiler/bitcells/bitcell_base.py b/compiler/bitcells/bitcell_base.py index 6adc2f48..40e0a02e 100644 --- a/compiler/bitcells/bitcell_base.py +++ b/compiler/bitcells/bitcell_base.py @@ -8,34 +8,25 @@ import debug import design -import utils from globals import OPTS import logical_effort -from tech import GDS, parameter, drc, layer +from tech import parameter, drc, layer class bitcell_base(design.design): """ Base bitcell parameters to be over-riden. """ - def __init__(self, name, prop=None): - design.design.__init__(self, name) + def __init__(self, name, cell_name=None, prop=None): + design.design.__init__(self, name, cell_name, prop) + # Set the bitcell specific properties if prop: - self.pins = prop.port_names - self.add_pin_types(prop.port_types) self.storage_nets = prop.storage_nets self.nets_match = self.do_nets_exist(prop.storage_nets) self.mirror = prop.mirror self.end_caps = prop.end_caps - (self.width, self.height) = utils.get_libcell_size(self.cell_name, - GDS["unit"], - layer[prop.boundary_layer]) - self.pin_map = utils.get_libcell_pins(self.pins, - self.cell_name, - GDS["unit"]) - def get_stage_effort(self, load): parasitic_delay = 1 # This accounts for bitline being drained diff --git a/compiler/bitcells/col_cap_bitcell_2port.py b/compiler/bitcells/col_cap_bitcell_2port.py index 910e25ea..dc3954b0 100644 --- a/compiler/bitcells/col_cap_bitcell_2port.py +++ b/compiler/bitcells/col_cap_bitcell_2port.py @@ -10,21 +10,13 @@ from tech import cell_properties as props import bitcell_base -class col_cap_bitcell_1rw_1r(bitcell_base.bitcell_base): +class col_cap_bitcell_2port(bitcell_base.bitcell_base): """ Column end cap cell. """ - pin_names = [props.bitcell.cell_1rw1r.pin.bl0, - props.bitcell.cell_1rw1r.pin.br0, - props.bitcell.cell_1rw1r.pin.bl1, - props.bitcell.cell_1rw1r.pin.br1, - props.bitcell.cell_1rw1r.pin.vdd] - type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", - "POWER", "GROUND"] - def __init__(self, name="col_cap_cell_1rw_1r"): - bitcell_base.bitcell_base.__init__(self, name) - debug.info(2, "Create col_cap bitcell 1rw+1r object") + bitcell_base.bitcell_base.__init__(self, name, prop=props.bitcell_2port) + debug.info(2, "Create col_cap bitcell 2 port object") self.no_instances = True diff --git a/compiler/bitcells/dummy_bitcell_1port.py b/compiler/bitcells/dummy_bitcell_1port.py index c6f98536..2ff836c1 100644 --- a/compiler/bitcells/dummy_bitcell_1port.py +++ b/compiler/bitcells/dummy_bitcell_1port.py @@ -18,7 +18,7 @@ class dummy_bitcell_1port(bitcell_base.bitcell_base): library. """ def __init__(self, name): - super().__init__(name, props.bitcell_1port) + super().__init__(name, prop=props.bitcell_1port) debug.info(2, "Create dummy bitcell") diff --git a/compiler/bitcells/dummy_bitcell_2port.py b/compiler/bitcells/dummy_bitcell_2port.py index 14b0ce96..5ed56f09 100644 --- a/compiler/bitcells/dummy_bitcell_2port.py +++ b/compiler/bitcells/dummy_bitcell_2port.py @@ -18,7 +18,7 @@ class dummy_bitcell_2port(bitcell_base.bitcell_base): the technology library. """ def __init__(self, name): - super().__init__(name, props.bitcell_2port) + super().__init__(name, prop=props.bitcell_2port) debug.info(2, "Create dummy bitcell 2 port object") diff --git a/compiler/bitcells/replica_bitcell_1port.py b/compiler/bitcells/replica_bitcell_1port.py index 1f2826ec..58087b97 100644 --- a/compiler/bitcells/replica_bitcell_1port.py +++ b/compiler/bitcells/replica_bitcell_1port.py @@ -20,7 +20,7 @@ class replica_bitcell_1port(bitcell_base.bitcell_base): the technology library. """ def __init__(self, name): - super().__init__(name, props.bitcell_1port) + super().__init__(name, prop=props.bitcell_1port) debug.info(2, "Create replica bitcell object") def get_stage_effort(self, load): diff --git a/compiler/bitcells/replica_bitcell_2port.py b/compiler/bitcells/replica_bitcell_2port.py index 3c7225e7..2a3fbb48 100644 --- a/compiler/bitcells/replica_bitcell_2port.py +++ b/compiler/bitcells/replica_bitcell_2port.py @@ -20,7 +20,7 @@ class replica_bitcell_2port(bitcell_base.bitcell_base): the technology library. """ def __init__(self, name): - super().__init__(name, props.bitcell_2port) + super().__init__(name, prop=props.bitcell_2port) debug.info(2, "Create replica bitcell 2 port object") def get_stage_effort(self, load): diff --git a/compiler/bitcells/row_cap_bitcell_2port.py b/compiler/bitcells/row_cap_bitcell_2port.py index 6d6dfe16..cdc49318 100644 --- a/compiler/bitcells/row_cap_bitcell_2port.py +++ b/compiler/bitcells/row_cap_bitcell_2port.py @@ -10,18 +10,13 @@ from tech import cell_properties as props import bitcell_base -class row_cap_bitcell_1rw_1r(bitcell_base.bitcell_base): +class row_cap_bitcell_2port(bitcell_base.bitcell_base): """ Row end cap cell. """ - pin_names = [props.bitcell.cell_1rw1r.pin.wl0, - props.bitcell.cell_1rw1r.pin.wl1, - props.bitcell.cell_1rw1r.pin.gnd] - type_list = ["INPUT", "INPUT", "GROUND"] - def __init__(self, name="row_cap_cell_1rw_1r"): - bitcell_base.bitcell_base.__init__(self, name) + bitcell_base.bitcell_base.__init__(self, name, prop=props.bitcell_2port) debug.info(2, "Create row_cap bitcell 1rw+1r object") self.no_instances = True diff --git a/compiler/custom/dff.py b/compiler/custom/dff.py index 62af01ff..b0c2b5a8 100644 --- a/compiler/custom/dff.py +++ b/compiler/custom/dff.py @@ -6,6 +6,7 @@ # All rights reserved. # import design +from tech import cell_properties as props from tech import spice @@ -15,7 +16,7 @@ class dff(design.design): """ def __init__(self, name="dff"): - super().__init__(name) + super().__init__(name, prop=props.dff) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" diff --git a/compiler/custom/inv_dec.py b/compiler/custom/inv_dec.py index be4099aa..a1bb0c83 100644 --- a/compiler/custom/inv_dec.py +++ b/compiler/custom/inv_dec.py @@ -7,6 +7,7 @@ # import design import logical_effort +from tech import cell_properties as props from tech import spice, parameter @@ -16,7 +17,7 @@ class inv_dec(design.design): """ def __init__(self, name="inv_dec", height=None): - super().__init__(name) + super().__init__(name, prop=props.inv_dec) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" diff --git a/compiler/custom/nand2_dec.py b/compiler/custom/nand2_dec.py index 2ea07ed6..b5c48a15 100644 --- a/compiler/custom/nand2_dec.py +++ b/compiler/custom/nand2_dec.py @@ -7,6 +7,7 @@ # import design from tech import spice, parameter, drc +from tech import cell_properties as props import logical_effort @@ -16,7 +17,7 @@ class nand2_dec(design.design): """ def __init__(self, name="nand2_dec", height=None): - super().__init__(name) + super().__init__(name, prop=props.nand2_dec) # FIXME: For now... size = 1 diff --git a/compiler/custom/nand3_dec.py b/compiler/custom/nand3_dec.py index d362e2d6..2713fde9 100644 --- a/compiler/custom/nand3_dec.py +++ b/compiler/custom/nand3_dec.py @@ -7,6 +7,7 @@ # import design from tech import spice, parameter, drc +from tech import cell_properties as props import logical_effort @@ -16,7 +17,7 @@ class nand3_dec(design.design): """ def __init__(self, name="nand3_dec", height=None): - super().__init__(name) + super().__init__(name, prop=props.nand3_dec) # FIXME: For now... size = 1 diff --git a/compiler/custom/nand4_dec.py b/compiler/custom/nand4_dec.py index 0df86845..5fab2d36 100644 --- a/compiler/custom/nand4_dec.py +++ b/compiler/custom/nand4_dec.py @@ -7,6 +7,7 @@ # import design from tech import spice, parameter, drc +from tech import cell_properties as props import logical_effort @@ -16,7 +17,7 @@ class nand4_dec(design.design): """ def __init__(self, name="nand4_dec", height=None): - super().__init__(name) + super().__init__(name, prop=props.nand4_dec) # FIXME: For now... size = 1 diff --git a/compiler/custom/sense_amp.py b/compiler/custom/sense_amp.py index 592feb57..4376bf85 100644 --- a/compiler/custom/sense_amp.py +++ b/compiler/custom/sense_amp.py @@ -21,7 +21,7 @@ class sense_amp(design.design): """ def __init__(self, name="sense_amp"): - super().__init__(name) + super().__init__(name, prop=props.sense_amp) debug.info(2, "Create sense_amp") def get_bl_names(self): diff --git a/compiler/custom/write_driver.py b/compiler/custom/write_driver.py index bcef46e1..c30501c9 100644 --- a/compiler/custom/write_driver.py +++ b/compiler/custom/write_driver.py @@ -19,7 +19,7 @@ class write_driver(design.design): """ def __init__(self, name): - super().__init__(name) + super().__init__(name, prop=props.write_driver) debug.info(2, "Create write_driver") def get_bl_names(self):