Update property settings with getters/setters

This commit is contained in:
mrg 2020-11-14 08:08:42 -08:00
parent 2f994b8c0a
commit e4bc2c4914
18 changed files with 94 additions and 69 deletions

View File

@ -18,16 +18,13 @@ class _cell:
if not port_map: if not port_map:
port_map = {x: x for x in port_order} 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 # Update mapping of names
self._pins = _pins(port_map) self._pins = _pins(port_map)
self._port_order = port_order self._port_order = port_order
# Update ordered name list # Update ordered name list
self._port_names = [getattr(self._pins, x) for x in self._port_order] self._port_names = [getattr(self._pins, x) for x in self._port_order]
# Update ordered type list # Update ordered type list
self._port_types = [self._port_types_map[x] for x in port_order] self._port_types = [self._port_types_map[x] for x in port_order]
@ -43,6 +40,29 @@ class _cell:
def port_names(self): def port_names(self):
return self._port_names 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 @property
def port_types(self): def port_types(self):
return self._port_types return self._port_types
@ -50,7 +70,11 @@ class _cell:
@property @property
def boundary_layer(self): def boundary_layer(self):
return self._boundary_layer return self._boundary_layer
@boundary_layer.setter
def boundary_layer(self, x):
self._boundary_layer = x
class _pins: class _pins:
def __init__(self, pin_dict): def __init__(self, pin_dict):
@ -116,13 +140,16 @@ class cell_properties():
self._pgate = _pgate(add_implants=False) 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"], self._nand2_dec = _cell(["A", "B", "Z", "vdd", "gnd"],
["INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"]) ["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"]) ["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"]) ["INPUT", "INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"])
self._dff = _cell(["D", "Q", "clk", "vdd", "gnd"], self._dff = _cell(["D", "Q", "clk", "vdd", "gnd"],
@ -152,6 +179,22 @@ class cell_properties():
def pgate(self): def pgate(self):
return self._pgate 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 @property
def dff(self): def dff(self):
return self._dff return self._dff

View File

@ -22,7 +22,7 @@ class design(hierarchy_design):
some DRC/layer constants and analytical models for other modules to reuse. 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 # 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 # Except bitcell names are generated automatically by the globals.py setup_bitcells routines
# depending on the number of ports. # depending on the number of ports.
@ -32,25 +32,24 @@ class design(hierarchy_design):
cell_name = name cell_name = name
super().__init__(name, cell_name) super().__init__(name, cell_name)
# This means it is a custom cell... # This means it is a custom cell.
if hasattr(props, name): # It could have properties and not be a hard cell too (e.g. dff_buf)
prop = getattr(props, name) if prop and prop.hard_cell:
if prop.hard_cell: # The pins get added from the spice file
# The pins get added from the spice file debug.check(prop.port_names == self.pins,
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))
"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)
self.add_pin_types(prop.port_types)
(width, height) = utils.get_libcell_size(self.cell_name, (width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"], GDS["unit"],
layer[prop.boundary_layer]) layer[prop.boundary_layer])
self.pin_map = utils.get_libcell_pins(self.pins, self.pin_map = utils.get_libcell_pins(self.pins,
self.cell_name, self.cell_name,
GDS["unit"]) GDS["unit"])
self.width = width self.width = width
self.height = height self.height = height
self.setup_multiport_constants() self.setup_multiport_constants()

View File

@ -19,7 +19,7 @@ class bitcell_1port(bitcell_base.bitcell_base):
""" """
def __init__(self, name): def __init__(self, name):
super().__init__(name, props.bitcell_1port) super().__init__(name, prop=props.bitcell_1port)
debug.info(2, "Create bitcell") debug.info(2, "Create bitcell")
def get_all_wl_names(self): def get_all_wl_names(self):

View File

@ -19,7 +19,7 @@ class bitcell_2port(bitcell_base.bitcell_base):
""" """
def __init__(self, name): 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") debug.info(2, "Create bitcell with 2 ports")
self.bl_names = [props.bitcell_2port.pin.bl0, props.bitcell_2port.pin.bl1] self.bl_names = [props.bitcell_2port.pin.bl0, props.bitcell_2port.pin.bl1]

View File

@ -8,34 +8,25 @@
import debug import debug
import design import design
import utils
from globals import OPTS from globals import OPTS
import logical_effort import logical_effort
from tech import GDS, parameter, drc, layer from tech import parameter, drc, layer
class bitcell_base(design.design): class bitcell_base(design.design):
""" """
Base bitcell parameters to be over-riden. Base bitcell parameters to be over-riden.
""" """
def __init__(self, name, prop=None): def __init__(self, name, cell_name=None, prop=None):
design.design.__init__(self, name) design.design.__init__(self, name, cell_name, prop)
# Set the bitcell specific properties
if prop: if prop:
self.pins = prop.port_names
self.add_pin_types(prop.port_types)
self.storage_nets = prop.storage_nets self.storage_nets = prop.storage_nets
self.nets_match = self.do_nets_exist(prop.storage_nets) self.nets_match = self.do_nets_exist(prop.storage_nets)
self.mirror = prop.mirror self.mirror = prop.mirror
self.end_caps = prop.end_caps 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): def get_stage_effort(self, load):
parasitic_delay = 1 parasitic_delay = 1
# This accounts for bitline being drained # This accounts for bitline being drained

View File

@ -10,21 +10,13 @@ from tech import cell_properties as props
import bitcell_base 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. 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"): def __init__(self, name="col_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 col_cap bitcell 1rw+1r object") debug.info(2, "Create col_cap bitcell 2 port object")
self.no_instances = True self.no_instances = True

View File

@ -18,7 +18,7 @@ class dummy_bitcell_1port(bitcell_base.bitcell_base):
library. library.
""" """
def __init__(self, name): def __init__(self, name):
super().__init__(name, props.bitcell_1port) super().__init__(name, prop=props.bitcell_1port)
debug.info(2, "Create dummy bitcell") debug.info(2, "Create dummy bitcell")

View File

@ -18,7 +18,7 @@ class dummy_bitcell_2port(bitcell_base.bitcell_base):
the technology library. """ the technology library. """
def __init__(self, name): 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") debug.info(2, "Create dummy bitcell 2 port object")

View File

@ -20,7 +20,7 @@ class replica_bitcell_1port(bitcell_base.bitcell_base):
the technology library. """ the technology library. """
def __init__(self, name): def __init__(self, name):
super().__init__(name, props.bitcell_1port) super().__init__(name, prop=props.bitcell_1port)
debug.info(2, "Create replica bitcell object") debug.info(2, "Create replica bitcell object")
def get_stage_effort(self, load): def get_stage_effort(self, load):

View File

@ -20,7 +20,7 @@ class replica_bitcell_2port(bitcell_base.bitcell_base):
the technology library. """ the technology library. """
def __init__(self, name): 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") debug.info(2, "Create replica bitcell 2 port object")
def get_stage_effort(self, load): def get_stage_effort(self, load):

View File

@ -10,18 +10,13 @@ from tech import cell_properties as props
import bitcell_base 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. 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"): 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") debug.info(2, "Create row_cap bitcell 1rw+1r object")
self.no_instances = True self.no_instances = True

View File

@ -6,6 +6,7 @@
# All rights reserved. # All rights reserved.
# #
import design import design
from tech import cell_properties as props
from tech import spice from tech import spice
@ -15,7 +16,7 @@ class dff(design.design):
""" """
def __init__(self, name="dff"): def __init__(self, name="dff"):
super().__init__(name) super().__init__(name, prop=props.dff)
def analytical_power(self, corner, load): def analytical_power(self, corner, load):
"""Returns dynamic and leakage power. Results in nW""" """Returns dynamic and leakage power. Results in nW"""

View File

@ -7,6 +7,7 @@
# #
import design import design
import logical_effort import logical_effort
from tech import cell_properties as props
from tech import spice, parameter from tech import spice, parameter
@ -16,7 +17,7 @@ class inv_dec(design.design):
""" """
def __init__(self, name="inv_dec", height=None): def __init__(self, name="inv_dec", height=None):
super().__init__(name) super().__init__(name, prop=props.inv_dec)
def analytical_power(self, corner, load): def analytical_power(self, corner, load):
"""Returns dynamic and leakage power. Results in nW""" """Returns dynamic and leakage power. Results in nW"""

View File

@ -7,6 +7,7 @@
# #
import design import design
from tech import spice, parameter, drc from tech import spice, parameter, drc
from tech import cell_properties as props
import logical_effort import logical_effort
@ -16,7 +17,7 @@ class nand2_dec(design.design):
""" """
def __init__(self, name="nand2_dec", height=None): def __init__(self, name="nand2_dec", height=None):
super().__init__(name) super().__init__(name, prop=props.nand2_dec)
# FIXME: For now... # FIXME: For now...
size = 1 size = 1

View File

@ -7,6 +7,7 @@
# #
import design import design
from tech import spice, parameter, drc from tech import spice, parameter, drc
from tech import cell_properties as props
import logical_effort import logical_effort
@ -16,7 +17,7 @@ class nand3_dec(design.design):
""" """
def __init__(self, name="nand3_dec", height=None): def __init__(self, name="nand3_dec", height=None):
super().__init__(name) super().__init__(name, prop=props.nand3_dec)
# FIXME: For now... # FIXME: For now...
size = 1 size = 1

View File

@ -7,6 +7,7 @@
# #
import design import design
from tech import spice, parameter, drc from tech import spice, parameter, drc
from tech import cell_properties as props
import logical_effort import logical_effort
@ -16,7 +17,7 @@ class nand4_dec(design.design):
""" """
def __init__(self, name="nand4_dec", height=None): def __init__(self, name="nand4_dec", height=None):
super().__init__(name) super().__init__(name, prop=props.nand4_dec)
# FIXME: For now... # FIXME: For now...
size = 1 size = 1

View File

@ -21,7 +21,7 @@ class sense_amp(design.design):
""" """
def __init__(self, name="sense_amp"): def __init__(self, name="sense_amp"):
super().__init__(name) super().__init__(name, prop=props.sense_amp)
debug.info(2, "Create sense_amp") debug.info(2, "Create sense_amp")
def get_bl_names(self): def get_bl_names(self):

View File

@ -19,7 +19,7 @@ class write_driver(design.design):
""" """
def __init__(self, name): def __init__(self, name):
super().__init__(name) super().__init__(name, prop=props.write_driver)
debug.info(2, "Create write_driver") debug.info(2, "Create write_driver")
def get_bl_names(self): def get_bl_names(self):