blob: 88c76a8c9c2d9c2ebdc5256b77a692be1124d3b7 [file] [log] [blame]
# Created by: ShoanT (taware.shon@gmail.com)
# Saturday 06 March 2021 10∶52∶14 PM
#
import os
from design_rules import *
from module_type import *
from custom_cell_properties import cell_properties
from custom_layer_properties import layer_properties
"""
File containing the process technology parameters for SKY130
"""
###################################################
# Custom modules
###################################################
tech_modules = module_type()
###################################################
# Custom cell properties
###################################################
cell_properties = cell_properties()
###################################################
# Custom cell properties
###################################################
layer_properties = layer_properties()
###################################################
# GDS file info
###################################################
GDS={}
# gds units
GDS["unit"]=(0.001,1e-6)
# default label zoom
GDS["zoom"] = 0.5
###################################################
# Interconnect stacks
###################################################
poly_stack = ("poly", "poly_contact", "li")
li_stack = ("li", "li_contact", "m1")
active_stack = ("active", "active_contact", "li")
m1_stack = ("m1", "via1", "m2")
m2_stack = ("m2", "via2", "m3")
m3_stack = ("m3", "via3", "m4")
layer_indices = {"poly": 0,
"active": 0,
"li": 1,
"m1": 2,
"m2": 3,
"m3": 4,
"m4": 5}
# The FEOL stacks get us up to m1
feol_stacks = [poly_stack,
active_stack,
li_stack]
# The BEOL stacks are m1 and up
beol_stacks = [m1_stack,
m2_stack,
m3_stack]
layer_stacks = feol_stacks + beol_stacks
preferred_directions = {"poly": "V",
"active": "V",
"li": "V",
"m1": "H",
"m2": "V",
"m3": "H",
"m4": "V"}
###################################################
# Power grid
###################################################
# Use M3/M4
power_grid = m3_stack
###################################################
##GDS Layer Map
###################################################
# create the GDS layer map
layer={}
layer["active"] = (65, 20)
layer["active_contact"] = (66, 44)
layer["tap"] = (65, 44)
layer["nwell"] = (64, 20)
layer["poly"] = (66, 20)
layer["nimplant"] = (93, 44)
layer["pimplant"] = (94, 20)
layer["npc"] = (95, 20)
layer["poly_contact"] = (66, 44)
layer["li"] = (67, 20)
layer["li_contact"] = (67, 44)
layer["m1"] = (68, 20)
layer["via1"] = (68, 44)
layer["m2"] = (69, 20)
layer["via2"] = (69, 44)
layer["m3"] = (70, 20)
layer["via3"] = (70, 44)
layer["m4"] = (71, 20)
layer["via4"] = (71, 44)
layer["m5"] = (72, 20)
layer["boundary"] = (235, 4)
layer["text"] = (83, 44)
# Layer names for external PDKs
layer_names = {}
layer_names["active"] = "active"
layer_names["active_contact"] = "active_contact"
layer_names["tap"] = "tap"
layer_names["nwell"] = "nwell"
layer_names["poly"] = "poly"
layer_names["nimplant"] = "nimplant"
layer_names["pimplant"] = "pimplant"
layer_names["npc"] = "npc"
layer_names["poly_contact"] = "poly_contact"
layer_names["li"] = "li"
layer_names["li_contact"] = "li_contact" # MCON
layer_names["m1"] = "m1"
layer_names["via1"] = "via1"
layer_names["m2"] = "m2"
layer_names["via2"] = "via2"
layer_names["m3"] = "m3"
layer_names["via3"] = "via3"
layer_names["m4"] = "m4"
layer_names["via4"] = "via4"
layer_names["m5"] = "m5"
layer_names["boundary"] = "boundary"
layer_names["text"] = "text"
###################################################
# DRC/LVS Rules Setup
###################################################
_lambda_ = 0.01
#technology parameter
parameter={}
parameter["min_tx_size"] = 42 * _lambda_
parameter["beta"] = 2
# These 6T sizes are used in the parameterized bitcell.
parameter["6T_inv_nmos_size"] = 42 * _lambda_
parameter["6T_inv_pmos_size"] = 55 * _lambda_
parameter["6T_access_size"] = 42 * _lambda_
drclvs_home=os.environ.get("DRCLVS_HOME")
drc = design_rules("sky130A")
#grid size
drc["grid"] = _lambda_
#DRC/LVS test set_up
drc["drc_rules"] = None
drc["lvs_rules"] = None
drc["layer_map"] = os.environ.get("OPENRAM_TECH")+"/sky130A/tf/layers.map"
# minwidth_tx with contact
drc["minwidth_tx"] = 42 * _lambda_
drc["minlength_channel"] = 50 * _lambda_
# Minimum spacing between wells of different type (if both are drawn)
drc["pwell_to_nwell"] = 0
# Minimum spacing between wells of same type (if both are drawn)
# Minimum width
drc.add_layer("nwell",
width = 84 * _lambda_,
spacing = 127 * _lambda_)
# Minimum width li_contact (MCON)
drc["minwidth_li_contact"] = 17 * _lambda_
# Local Interconnect
drc.add_layer("li",
width = 29 * _lambda_,
spacing = 20 * _lambda_) # O - 17
#drc["minarea_li"] = 5610 * _lambda_
drc.add_enclosure("li",
layer = "li_contact",
enclosure = 8 * _lambda_)
drc.add_enclosure("m1",
layer = "li_contact",
enclosure = 6 * _lambda_)
drc["li_contact_to_li_contact"] = 17 * _lambda_
# POLY
drc.add_layer("poly",
width = 15 * _lambda_,
spacing = 21 * _lambda_)
drc.add_enclosure("li",
layer = "poly_contact",
enclosure = 8 * _lambda_)
# Minimum gate extension of active
drc["poly_extend_active"] = 21 * _lambda_
# Minimum spacing between poly contact and other poly (alternative rules)
drc["poly_to_poly_contact"] = 21 * _lambda_
# ??
drc["active_enclose_gate"] = 19 * _lambda_ ############### Confirm value | Added temporary value
# Minimum field poly to active
drc["poly_to_active"] = 7.5 * _lambda_
# Active (DIFF)
drc.add_layer("active",
width = 42 * _lambda_,
spacing = 27 * _lambda_)
# Source/drain active to well edge
drc.add_enclosure("nwell",
layer = "active",
enclosure = 127 * _lambda_)
# Minimum select spacing to channel of transistor to ensure adequate source/drain width
drc["implant_to_channel"] = 0 ############### Confirm value | Added temporary value
# Minimum select overlap of active
drc.add_enclosure("implant",
layer = "active",
enclosure = 40 * _lambda_) ############### Confirm value | Added temporary value
# Minimum select overlap of contact
drc.add_enclosure("implant",
layer = "active_contact",
enclosure = 18 * _lambda_) ############### Confirm value | Added temporary value
# Not a rule
drc["implant_to_contact"] = 0
# Not a rule
drc.add_layer("implant",
width = 0,
spacing = 0)
# Active Contact (TAP)
drc.add_layer("active_contact",
width = 17 * _lambda_,
spacing = 17 * _lambda_)
#drc["tap_to_active"] = 0.30
#drc["tap_to_li"] = 0.30
# Minimum active overlap
drc.add_enclosure("active",
layer = "active_contact",
enclosure = 6 * _lambda_) ############### Confirm value | Added temporary value
drc.add_enclosure("active",
layer = "poly_contact",
enclosure = 19 * _lambda_)
# Reserved for other technologies
drc["active_contact_to_gate"] = 5.5 * _lambda_ ############### Confirm value | Added temporary value
# 5.4 Minimum spacing to gate of transistor
drc["poly_contact_to_gate"] = 5.5 * _lambda_ ############### Confirm value | Added temporary value
# 6.1 Exact contact size
# 5.3 Minimum contact spacing
drc.add_layer("poly_contact",
width = 17 * _lambda_,
spacing = 17 * _lambda_)
drc.add_enclosure("npc",
layer = "poly",
enclosure = 5 * _lambda_) ######## Confirm value | Added temporary value
# 8.3 Minimum overlap by m1
drc.add_enclosure("m1",
layer = "via1",
enclosure = 10 * _lambda_)
# 5.2.b Minimum poly overlap
drc.add_enclosure("poly",
layer = "poly_contact",
enclosure = 8 * _lambda_)
# 7.1 Minimum width
# 7.2 Minimum spacing
drc.add_layer("m1",
width = 14 * _lambda_,
spacing = 14 * _lambda_)
# 7.3 Minimum overlap of any contact
drc.add_enclosure("li",
layer = "active_contact",
enclosure = 8 * _lambda_) ######## Confirm value | Added temporary value
# 8.1 Exact size
# 8.2 Minimum via spacing
drc.add_layer("via1",
width = 26 * _lambda_,
spacing = 6 * _lambda_)
# 9.1 Minimum width
# 9.2 Minimum spacing
drc.add_layer("m2",
width = 14 * _lambda_,
spacing = 14 * _lambda_)
# 9.3 Minimum overlap of via
drc.add_enclosure("m2",
layer = "via1",
enclosure = 10 * _lambda_)
# 14.3 Minimum overlap by m2
drc.add_enclosure("m2",
layer = "via2",
enclosure = 9 * _lambda_)
# 14.1 Exact size
# 14.2 Minimum spacing
drc.add_layer("via2",
width = 28 * _lambda_,
spacing = 12 * _lambda_)
# 15.1 Minimum width
# 15.2 Minimum spacing to m3
drc.add_layer("m3",
width = 30 * _lambda_,
spacing = 45 * _lambda_) #O - 30
# 15.3 Minimum overlap of via 2
drc.add_enclosure("m3",
layer = "via2",
enclosure = 8 * _lambda_)
# 21.3 Minimum overlap by m3
drc.add_enclosure("m3",
layer = "via3",
enclosure = 7 * _lambda_)
# 21.1 Exact size
# 21.2 Minimum spacing
drc.add_layer("via3",
width = 32 * _lambda_,
spacing = 14 * _lambda_)
# 22.1 Minimum width
# 22.2 Minimum spacing to m4
drc.add_layer("m4",
width = 30 * _lambda_,
spacing = 30 * _lambda_)
# 22.3 Minimum overlap of via 3
drc.add_enclosure("m4",
layer = "via3",
enclosure = 21 * _lambda_)
###################################################
# Spice Simulation Parameters
###################################################
# spice model info
spice={}
spice["nmos"]="sky130_fd_pr__nfet_01v8"
spice["pmos"]="sky130_fd_pr__pfet_01v8"
# This is a map of corners to model files
SPICE_MODEL_DIR=os.environ.get("SPICE_MODEL_DIR")
spice["fet_models"] = {"TT": [SPICE_MODEL_DIR + "/tt.sp"],
"FF": [SPICE_MODEL_DIR + "/ff.sp"],
"FS": [SPICE_MODEL_DIR + "/ff.sp"],
"SF": [SPICE_MODEL_DIR + "/ss.sp"],
"SS": [SPICE_MODEL_DIR + "/ss.sp"],
"ST": [SPICE_MODEL_DIR + "/ss.sp"],
"TS": [SPICE_MODEL_DIR + "/tt.sp"],
"FT": [SPICE_MODEL_DIR + "/ff.sp"],
"TF": [SPICE_MODEL_DIR + "/tt.sp"],
}
#spice stimulus related variables
spice["feasible_period"] = 20 # estimated feasible period in ns
spice["supply_voltages"] = [1.8, 3.3, 5.0] # Supply voltage corners in [Volts]
spice["nom_supply_voltage"] = 1.8 # Nominal supply voltage in [Volts]
spice["rise_time"] = 0.05 # rise time in [Nano-seconds]
spice["fall_time"] = 0.05 # fall time in [Nano-seconds]
spice["temperatures"] = [0, 25, 100] # Temperature corners (celcius)
spice["nom_temperature"] = 25 # Nominal temperature (celcius)
# analytical delay parameters
spice["nom_threshold"] = 1.3 # Nominal Threshold voltage in Volts
# FIXME: These need to be updated for SKY130A, they are copied from FreePDK45.
spice["wire_unit_r"] = 0.075 # Unit wire resistance in ohms/square
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2
spice["min_tx_drain_c"] = 0.7 # Minimum transistor drain capacitance in ff
spice["min_tx_gate_c"] = 0.1 # Minimum transistor gate capacitance in ff
spice["dff_setup"] = 9 # DFF setup time in ps
spice["dff_hold"] = 1 # DFF hold time in ps
spice["dff_in_cap"] = 9.8242 # Input capacitance (D) [Femto-farad]
spice["dff_out_cap"] = 2 # Output capacitance (Q) [Femto-farad]
# analytical power parameters, many values are temporary
spice["bitcell_leakage"] = 1 # Leakage power of a single bitcell in nW
spice["inv_leakage"] = 1 # Leakage power of inverter in nW
spice["nand2_leakage"] = 1 # Leakage power of 2-input nand in nW
spice["nand3_leakage"] = 1 # Leakage power of 3-input nand in nW
spice["nand4_leakage"] = 1 # Leakage power of 4-input nand in nW
spice["nor2_leakage"] = 1 # Leakage power of 2-input nor in nW
spice["dff_leakage"] = 1 # Leakage power of flop in nW
spice["default_event_frequency"] = 100 # Default event activity of every gate. MHz
# Logical Effort relative values for the Handmade cells
parameter["le_tau"] = 18.17 # In pico-seconds.
parameter["min_inv_para_delay"] = 2.07 # In relative delay units
parameter["cap_relative_per_ff"] = .91 # Units of Relative Capacitance/ Femto-Farad
parameter["dff_clk_cin"] = 27.5 # In relative capacitance units
parameter["6tcell_wl_cin"] = 2 # In relative capacitance units
parameter["sa_en_pmos_size"] = 110 * _lambda_
parameter["sa_en_nmos_size"] = 84 * _lambda_
parameter["sa_inv_pmos_size"] = 55 * _lambda_
parameter["sa_inv_nmos_size"] = 42 * _lambda_
parameter["bitcell_drain_cap"] = 0.2 # In Femto-Farad, approximation of drain capacitance
###################################################
# Technology Tool Preferences
###################################################
drc_name = "magic"
lvs_name = "netgen"
pex_name = "magic"
blackbox_bitcell = False