Add ptx cell properties

This commit is contained in:
mrg 2020-10-28 09:54:15 -07:00
parent 25495f3d94
commit acfec369d6
16 changed files with 71 additions and 55 deletions

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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:

View File

@ -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:

View File

@ -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.
"""

View File

@ -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):

View File

@ -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)

View File

@ -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.
"""

View File

@ -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 """

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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())

View File

@ -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,

View File

@ -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)