OpenRAM/compiler/base/custom_cell_properties.py

168 lines
5.4 KiB
Python
Raw Normal View History

# See LICENSE for licensing information.
#
# Copyright (c) 2016-2020 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
2020-11-14 00:55:55 +01:00
class _cell:
def __init__(self, port_order, port_types, port_map=None, hard_cell=True, boundary_layer="boundary"):
# Specifies if this is a hard (i.e. GDS) cell
self._hard_cell = hard_cell
# Specifies the order in the spice modules
self._port_order = port_order
# Specifies the port directions
2020-11-14 01:41:02 +01:00
self._port_types = {x: y for (x, y) in zip(port_order, port_types)}
2020-11-14 00:55:55 +01:00
# Specifies a map from OpenRAM names to cell names
# by default it is 1:1
if not port_map:
2020-11-14 01:41:02 +01:00
port_map = {x: x for x in port_order}
2020-11-14 01:23:27 +01:00
self._pins = _pins(port_map)
2020-11-14 00:55:55 +01:00
self._boundary_layer = boundary_layer
2020-10-26 21:13:38 +01:00
2020-11-14 00:55:55 +01:00
@property
def pin(self):
return self._pins
@property
def hard_cell(self):
return self._hard_cell
def port_names(self):
2020-11-14 01:23:27 +01:00
return [getattr(self._pins, x) for x in self._port_order]
2020-11-14 00:55:55 +01:00
def port_types(self):
2020-11-14 01:41:02 +01:00
return [self._port_types[x] for x in self._port_order]
2020-11-14 00:55:55 +01:00
@property
def boundary_layer(self):
return self._boundary_layer
class _pins:
def __init__(self, pin_dict):
# make the pins elements of the class to allow "." access.
# For example: props.bitcell.cell_1port.pin.bl = "foobar"
2020-10-26 21:13:38 +01:00
for k, v in pin_dict.items():
self.__dict__[k] = v
2020-11-03 15:29:17 +01:00
class _mirror_axis:
def __init__(self, x, y):
self.x = x
self.y = y
2020-11-03 15:29:17 +01:00
2020-10-28 17:54:15 +01:00
class _ptx:
def __init__(self, model_is_subckt, bin_spice_models):
self.model_is_subckt = model_is_subckt
self.bin_spice_models = bin_spice_models
2020-11-03 15:29:17 +01:00
2020-10-28 17:54:15 +01:00
class _pgate:
def __init__(self, add_implants):
self.add_implants = add_implants
2020-11-03 15:29:17 +01:00
2020-11-14 00:55:55 +01:00
class _bitcell(_cell):
def __init__(self, port_order, port_types, port_map=None, storage_nets=["Q", "Q_bar"], mirror=None, end_caps=False):
super().__init__(port_order, port_types, port_map)
2020-11-14 02:29:20 +01:00
self.end_caps = end_caps
2020-11-14 00:55:55 +01:00
if not mirror:
2020-11-14 02:29:20 +01:00
self.mirror = _mirror_axis(True, False)
2020-11-14 00:55:55 +01:00
else:
2020-11-14 02:29:20 +01:00
self.mirror = mirror
2020-11-14 02:29:20 +01:00
self.storage_nets = storage_nets
2020-11-14 01:23:27 +01:00
class cell_properties():
"""
This contains meta information about the custom designed cells. For
instance, pin names, or the axis on which they need to be mirrored. These
can be overriden in the tech.py file.
"""
def __init__(self):
self.names = {}
self.names["bitcell_1port"] = "cell_1rw"
self.names["bitcell_2port"] = "cell_2rw"
self.names["dummy_bitcell_1port"] = "dummy_cell_1rw"
self.names["dummy_bitcell_2port"] = "dummy_cell_2rw"
self.names["replica_bitcell_1port"] = "replica_cell_1rw"
self.names["replica_bitcell_2port"] = "replica_cell_2rw"
self.names["col_cap_bitcell_1port"] = "col_cap_cell_1rw"
self.names["col_cap_bitcell_2port"] = "col_cap_cell_2rw"
self.names["row_cap_bitcell_1port"] = "row_cap_cell_1rw"
self.names["row_cap_bitcell_2port"] = "row_cap_cell_2rw"
2020-10-28 17:54:15 +01:00
self._ptx = _ptx(model_is_subckt=False,
bin_spice_models=False)
2020-11-03 15:29:17 +01:00
2020-10-28 17:54:15 +01:00
self._pgate = _pgate(add_implants=False)
2020-11-03 15:29:17 +01:00
2020-11-14 00:55:55 +01:00
self._nand2_dec = _cell(["A", "B", "Z", "vdd", "gnd"],
["INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"])
self._nand2_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"],
["INPUT", "INPUT", "INPUT", "INPUT", "OUTPUT", "POWER", "GROUND"])
2020-11-14 01:23:27 +01:00
self._dff = _cell(["D", "Q", "clk", "vdd", "gnd"],
["INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"])
self._dff_buf = _cell(["D", "Q", "Qb", "clk", "vdd", "gnd"],
["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"],
hard_cell=False)
2020-11-14 00:55:55 +01:00
self._write_driver = _cell(['din', 'bl', 'br', 'en', 'vdd', 'gnd'],
["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"])
2020-09-23 03:33:03 +02:00
2020-11-14 00:55:55 +01:00
self._sense_amp = _cell(['bl', 'br', 'dout', 'en', 'vdd', 'gnd'],
["INPUT", "INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"])
2020-11-14 00:55:55 +01:00
self._bitcell_1port = _bitcell(["bl", "br", "wl", "vdd", "gnd"],
2020-11-14 01:41:02 +01:00
["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"])
2020-09-23 03:33:03 +02:00
2020-11-14 00:55:55 +01:00
self._bitcell_2port = _bitcell(["bl0", "br0", "bl1", "br1", "wl0", "wl1", "vdd", "gnd"],
["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"])
2020-10-28 17:54:15 +01:00
@property
def ptx(self):
return self._ptx
2020-11-03 15:29:17 +01:00
2020-10-28 17:54:15 +01:00
@property
def pgate(self):
return self._pgate
@property
def dff(self):
return self._dff
2020-11-03 15:29:17 +01:00
@property
2020-11-14 00:55:55 +01:00
def dff_buf(self):
return self._dff_buf
@property
def write_driver(self):
return self._write_driver
@property
def sense_amp(self):
return self._sense_amp
2020-11-03 15:29:17 +01:00
2020-09-23 03:33:03 +02:00
@property
2020-11-14 00:55:55 +01:00
def bitcell_1port(self):
return self._bitcell_1port
@property
def bitcell_2port(self):
return self._bitcell_2port
2020-09-23 03:33:03 +02:00