mirror of https://github.com/VLSIDA/OpenRAM.git
Add ptx cell properties
This commit is contained in:
parent
25495f3d94
commit
acfec369d6
|
|
@ -36,6 +36,17 @@ class _mirror_axis:
|
|||
self.y = y
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
class _pgate:
|
||||
def __init__(self, add_implants):
|
||||
self.add_implants = add_implants
|
||||
|
||||
|
||||
class _bitcell:
|
||||
def __init__(self, mirror, cell_s8_6t, cell_6t, cell_1rw1r, cell_1w1r):
|
||||
self.mirror = mirror
|
||||
|
|
@ -128,7 +139,12 @@ class cell_properties():
|
|||
self.names = {}
|
||||
|
||||
self._bitcell = _bitcell._default()
|
||||
|
||||
|
||||
self._ptx = _ptx(model_is_subckt=False,
|
||||
bin_spice_models=False)
|
||||
|
||||
self._pgate = _pgate(add_implants=False)
|
||||
|
||||
self._dff = _dff(use_custom_ports=False,
|
||||
custom_port_list=["D", "Q", "clk", "vdd", "gnd"],
|
||||
custom_type_list=["INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"],
|
||||
|
|
@ -157,6 +173,14 @@ class cell_properties():
|
|||
def bitcell(self):
|
||||
return self._bitcell
|
||||
|
||||
@property
|
||||
def ptx(self):
|
||||
return self._ptx
|
||||
|
||||
@property
|
||||
def pgate(self):
|
||||
return self._pgate
|
||||
|
||||
@property
|
||||
def dff(self):
|
||||
return self._dff
|
||||
|
|
|
|||
|
|
@ -111,21 +111,17 @@ class _replica_column:
|
|||
self.even_rows = even_rows
|
||||
|
||||
|
||||
class _wordline_buffer_array:
|
||||
class _wordline_driver:
|
||||
def __init__(self,
|
||||
vertical_supply):
|
||||
# wordline_buffer_array
|
||||
# vertical vdd/gnd (sky130)
|
||||
self.vertical_supply = vertical_supply
|
||||
|
||||
|
||||
class _wordline_driver_array:
|
||||
def __init__(self,
|
||||
vertical_supply):
|
||||
# wordline_driver_array
|
||||
# vertical vdd/gnd (sky130)
|
||||
# wordline_driver
|
||||
# vertical vdd/gnd (sky130)
|
||||
self.vertical_supply = vertical_supply
|
||||
|
||||
|
||||
|
||||
class layer_properties():
|
||||
"""
|
||||
|
|
@ -161,9 +157,7 @@ class layer_properties():
|
|||
|
||||
self._replica_column = _replica_column(even_rows=False)
|
||||
|
||||
self._wordline_buffer_array = _wordline_buffer_array(vertical_supply=False)
|
||||
|
||||
self._wordline_driver_array = _wordline_driver_array(vertical_supply=False)
|
||||
self._wordline_driver = _wordline_driver(vertical_supply=False)
|
||||
|
||||
@property
|
||||
def bank(self):
|
||||
|
|
@ -194,10 +188,6 @@ class layer_properties():
|
|||
return self._replica_column
|
||||
|
||||
@property
|
||||
def wordline_buffer_array(self):
|
||||
return self._wordline_buffer_array
|
||||
|
||||
@property
|
||||
def wordline_driver_array(self):
|
||||
return self._wordline_driver_array
|
||||
def wordline_driver(self):
|
||||
return self._wordline_driver
|
||||
|
||||
|
|
|
|||
|
|
@ -46,8 +46,6 @@ class bitcell(bitcell_base.bitcell_base):
|
|||
self.add_pin_types(self.type_list)
|
||||
self.nets_match = self.do_nets_exist(self.storage_nets)
|
||||
|
||||
#debug.check(OPTS.tech_name != "sky130", "sky130 does not yet support single port cells")
|
||||
|
||||
def get_all_wl_names(self):
|
||||
""" Creates a list of all wordline pin names """
|
||||
row_pins = [props.bitcell.cell_6t.pin.wl]
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class wordline_buffer_array(design.design):
|
|||
Add a pin for each row of vdd/gnd which
|
||||
are must-connects next level up.
|
||||
"""
|
||||
if layer_props.wordline_buffer_array.vertical_supply:
|
||||
if layer_props.wordline_driver.vertical_supply:
|
||||
for name in ["vdd", "gnd"]:
|
||||
supply_pins = self.wld_inst[0].get_pins(name)
|
||||
for pin in supply_pins:
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class wordline_driver_array(design.design):
|
|||
Add a pin for each row of vdd/gnd which
|
||||
are must-connects next level up.
|
||||
"""
|
||||
if layer_props.wordline_buffer_array.vertical_supply:
|
||||
if layer_props.wordline_driver.vertical_supply:
|
||||
for name in ["vdd", "gnd"]:
|
||||
supply_pins = self.wld_inst[0].get_pins(name)
|
||||
for pin in supply_pins:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import debug
|
|||
from tech import drc, layer
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
from tech import cell_properties as cell_props
|
||||
|
||||
|
||||
class column_mux(pgate.pgate):
|
||||
|
|
@ -124,8 +124,8 @@ class column_mux(pgate.pgate):
|
|||
+ vector(0, self.nmos.active_height + max(self.active_space, self.poly_space))
|
||||
self.nmos_upper.place(nmos_upper_position)
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
self.add_implants()
|
||||
if cell_props.pgate.add_implants:
|
||||
self.extend_implants()
|
||||
|
||||
def connect_poly(self):
|
||||
""" Connect the poly gate of the two pass transistors """
|
||||
|
|
@ -198,7 +198,7 @@ class column_mux(pgate.pgate):
|
|||
self.add_path(self.col_mux_stack[2],
|
||||
[br_pin.bc(), mid1, mid2, nmos_lower_d_pin.center()])
|
||||
|
||||
def add_implants(self):
|
||||
def extend_implants(self):
|
||||
"""
|
||||
Add top-to-bottom implants for adjacency issues in s8.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ from bisect import bisect_left
|
|||
from tech import layer, drc
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
|
||||
if(OPTS.tech_name == "sky130"):
|
||||
from tech import cell_properties as cell_props
|
||||
if cell_props.ptx.bin_spice_models:
|
||||
from tech import nmos_bins, pmos_bins
|
||||
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ class pgate(design.design):
|
|||
width=self.width + 2 * self.well_extend_active,
|
||||
height=pwell_height)
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
if cell_props.pgate.add_implants:
|
||||
self.extend_implants()
|
||||
|
||||
def add_nwell_contact(self, pmos, pmos_pos):
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ from utils import round_to_grid
|
|||
import logical_effort
|
||||
from sram_factory import factory
|
||||
from errors import drc_error
|
||||
from tech import cell_properties as cell_props
|
||||
|
||||
|
||||
class pinv(pgate.pgate):
|
||||
|
|
@ -87,7 +88,7 @@ class pinv(pgate.pgate):
|
|||
self.tx_mults = 1
|
||||
self.nmos_width = self.nmos_size * drc("minwidth_tx")
|
||||
self.pmos_width = self.pmos_size * drc("minwidth_tx")
|
||||
if OPTS.tech_name == "sky130":
|
||||
if cell_props.ptx.bin_spice_models:
|
||||
(self.nmos_width, self.tx_mults) = pgate.pgate.best_bin("nmos", self.nmos_width)
|
||||
(self.pmos_width, self.tx_mults) = pgate.pgate.best_bin("pmos", self.pmos_width)
|
||||
return
|
||||
|
|
@ -132,7 +133,7 @@ class pinv(pgate.pgate):
|
|||
|
||||
# Determine the number of mults for each to fit width
|
||||
# into available space
|
||||
if OPTS.tech_name != "sky130":
|
||||
if not cell_props.ptx.bin_spice_models:
|
||||
self.nmos_width = self.nmos_size * drc("minwidth_tx")
|
||||
self.pmos_width = self.pmos_size * drc("minwidth_tx")
|
||||
nmos_required_mults = max(int(ceil(self.nmos_width / nmos_height_available)), 1)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from tech import drc, parameter, layer
|
|||
from vector import vector
|
||||
from globals import OPTS
|
||||
from sram_factory import factory
|
||||
from tech import cell_properties as cell_props
|
||||
|
||||
|
||||
class pinv_dec(pinv.pinv):
|
||||
|
|
@ -50,7 +51,7 @@ class pinv_dec(pinv.pinv):
|
|||
self.tx_mults = 1
|
||||
self.nmos_width = self.nmos_size * drc("minwidth_tx")
|
||||
self.pmos_width = self.pmos_size * drc("minwidth_tx")
|
||||
if OPTS.tech_name == "sky130":
|
||||
if self.bin_spice_models:
|
||||
self.nmos_width = self.nearest_bin("nmos", self.nmos_width)
|
||||
self.pmos_width = self.nearest_bin("pmos", self.pmos_width)
|
||||
|
||||
|
|
@ -140,10 +141,10 @@ class pinv_dec(pinv.pinv):
|
|||
nmos_drain_pos = self.nmos_inst.get_pin("D").center()
|
||||
self.output_pos = vector(0.5 * (pmos_drain_pos.x + nmos_drain_pos.x), nmos_drain_pos.y)
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
self.add_implants()
|
||||
if cell_props.pgate.add_implants:
|
||||
self.extend_implants()
|
||||
|
||||
def add_implants(self):
|
||||
def extend_implants(self):
|
||||
"""
|
||||
Add top-to-bottom implants for adjacency issues in s8.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@
|
|||
import pgate
|
||||
import debug
|
||||
from tech import drc, parameter, spice
|
||||
from globals import OPTS
|
||||
from vector import vector
|
||||
import logical_effort
|
||||
from sram_factory import factory
|
||||
import contact
|
||||
from tech import cell_properties as cell_props
|
||||
|
||||
|
||||
class pnand2(pgate.pgate):
|
||||
|
|
@ -38,7 +38,7 @@ class pnand2(pgate.pgate):
|
|||
debug.check(size == 1, "Size 1 pnand2 is only supported now.")
|
||||
self.tx_mults = 1
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
if cell_props.ptx.bin_spice_models:
|
||||
self.nmos_width = self.nearest_bin("nmos", self.nmos_width)
|
||||
self.pmos_width = self.nearest_bin("pmos", self.pmos_width)
|
||||
|
||||
|
|
@ -212,9 +212,8 @@ class pnand2(pgate.pgate):
|
|||
"B",
|
||||
position="center")
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
if cell_props.pgate.add_implants:
|
||||
self.add_enclosure([apin, bpin], "npc", drc("npc_enclose_poly"))
|
||||
|
||||
|
||||
def route_output(self):
|
||||
""" Route the Z output """
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ from tech import drc, parameter, spice
|
|||
from vector import vector
|
||||
import logical_effort
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
import contact
|
||||
from tech import cell_properties as cell_props
|
||||
|
||||
|
||||
class pnand3(pgate.pgate):
|
||||
|
|
@ -41,7 +41,7 @@ class pnand3(pgate.pgate):
|
|||
"Size 1 pnand3 is only supported now.")
|
||||
self.tx_mults = 1
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
if cell_props.ptx.bin_spice_models:
|
||||
self.nmos_width = self.nearest_bin("nmos", self.nmos_width)
|
||||
self.pmos_width = self.nearest_bin("pmos", self.pmos_width)
|
||||
|
||||
|
|
@ -246,7 +246,7 @@ class pnand3(pgate.pgate):
|
|||
"C",
|
||||
position="right")
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
if cell_props.pgate.add_implants:
|
||||
self.add_enclosure([apin, bpin, cpin], "npc", drc("npc_enclose_poly"))
|
||||
|
||||
def route_output(self):
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ from tech import drc, parameter, spice
|
|||
from vector import vector
|
||||
import logical_effort
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
import contact
|
||||
from tech import cell_properties as cell_props
|
||||
|
||||
|
||||
class pnand4(pgate.pgate):
|
||||
|
|
@ -41,7 +41,7 @@ class pnand4(pgate.pgate):
|
|||
"Size 1 pnand4 is only supported now.")
|
||||
self.tx_mults = 1
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
if cell_props.ptx.bin_spice_models:
|
||||
self.nmos_width = self.nearest_bin("nmos", self.nmos_width)
|
||||
self.pmos_width = self.nearest_bin("pmos", self.pmos_width)
|
||||
|
||||
|
|
@ -268,7 +268,7 @@ class pnand4(pgate.pgate):
|
|||
"D",
|
||||
position="right")
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
if cell_props.pgate.add_implants:
|
||||
self.add_enclosure([apin, bpin, cpin, dpin], "npc", drc("npc_enclose_poly"))
|
||||
|
||||
def route_output(self):
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
#
|
||||
import pgate
|
||||
import debug
|
||||
from globals import OPTS
|
||||
from tech import drc, parameter, spice
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
from tech import cell_properties as cell_props
|
||||
|
||||
|
||||
class pnor2(pgate.pgate):
|
||||
|
|
@ -36,7 +36,7 @@ class pnor2(pgate.pgate):
|
|||
debug.check(size==1, "Size 1 pnor2 is only supported now.")
|
||||
self.tx_mults = 1
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
if self.bin_spice_models:
|
||||
self.nmos_width = self.nearest_bin("nmos", self.nmos_width)
|
||||
self.pmos_width = self.nearest_bin("pmos", self.pmos_width)
|
||||
|
||||
|
|
@ -210,7 +210,7 @@ class pnor2(pgate.pgate):
|
|||
|
||||
self.output_yoffset = self.inputA_yoffset + self.m1_nonpref_pitch
|
||||
|
||||
if OPTS.tech_name == "sky130":
|
||||
if cell_props.pgate.add_implants:
|
||||
self.add_enclosure([apin, bpin], "npc", drc("npc_enclose_poly"))
|
||||
|
||||
def route_output(self):
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from tech import parameter, drc
|
|||
from vector import vector
|
||||
from globals import OPTS
|
||||
from sram_factory import factory
|
||||
from tech import cell_properties as cell_props
|
||||
|
||||
|
||||
class precharge(design.design):
|
||||
|
|
@ -79,7 +80,7 @@ class precharge(design.design):
|
|||
"""
|
||||
Initializes the upper and lower pmos
|
||||
"""
|
||||
if(OPTS.tech_name == "sky130"):
|
||||
if cell_props.ptx.bin_spice_models:
|
||||
self.ptx_width = pgate.nearest_bin("pmos", self.ptx_width)
|
||||
self.pmos = factory.create(module_type="ptx",
|
||||
width=self.ptx_width,
|
||||
|
|
@ -300,4 +301,4 @@ class precharge(design.design):
|
|||
self.add_path(self.bitline_layer,
|
||||
[left_pos, right_pos],
|
||||
width=pmos_pin.height())
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import contact
|
|||
import logical_effort
|
||||
from globals import OPTS
|
||||
from pgate import pgate
|
||||
from tech import cell_properties as cell_props
|
||||
|
||||
|
||||
class ptx(design.design):
|
||||
|
|
@ -129,9 +130,8 @@ class ptx(design.design):
|
|||
# be decided in the layout later.
|
||||
area_sd = 2.5 * self.poly_width * self.tx_width
|
||||
perimeter_sd = 2 * self.poly_width + 2 * self.tx_width
|
||||
if OPTS.tech_name == "sky130":
|
||||
# sky130 simulation cannot use the mult parameter in simulation
|
||||
(self.tx_width, self.mults) = pgate.best_bin(self.tx_type, self.tx_width)
|
||||
if cell_props.ptx.model_is_subckt:
|
||||
# sky130
|
||||
main_str = "X{{0}} {{1}} {0} m={1} w={2} l={3} ".format(spice[self.tx_type],
|
||||
self.mults,
|
||||
self.tx_width,
|
||||
|
|
@ -150,12 +150,13 @@ class ptx(design.design):
|
|||
self.spice_device = main_str + area_str
|
||||
self.spice.append("\n* spice ptx " + self.spice_device)
|
||||
|
||||
if OPTS.tech_name == "sky130" and OPTS.lvs_exe and OPTS.lvs_exe[0] == "calibre":
|
||||
if cell_props.ptx.model_is_subckt and OPTS.lvs_exe and OPTS.lvs_exe[0] == "calibre":
|
||||
# sky130 requires mult parameter too
|
||||
# self.lvs_device = "X{{0}} {{1}} {0} m={1} w={2} l={3} mult={1}".format(spice[self.tx_type],
|
||||
# self.mults,
|
||||
# self.tx_width,
|
||||
# drc("minwidth_poly"))
|
||||
# TEMP FIX: Use old device names if using Calibre.
|
||||
self.lvs_device = "M{{0}} {{1}} {0} m={1} w={2} l={3} mult={1}".format("nshort" if self.tx_type == "nmos" else "pshort",
|
||||
self.mults,
|
||||
self.tx_width,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import design
|
|||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
from tech import layer
|
||||
from tech import layer_properties as layer_props
|
||||
|
||||
|
||||
class wordline_driver(design.design):
|
||||
|
|
@ -104,7 +105,7 @@ class wordline_driver(design.design):
|
|||
|
||||
def route_supply_rails(self):
|
||||
""" Add vdd/gnd rails to the top, (middle), and bottom. """
|
||||
if OPTS.tech_name == "sky130":
|
||||
if layer_props.wordline_driver.vertical_supply:
|
||||
for name in ["vdd", "gnd"]:
|
||||
for inst in [self.nand_inst, self.driver_inst]:
|
||||
self.copy_layout_pin(inst, name)
|
||||
|
|
|
|||
Loading…
Reference in New Issue