2019-04-26 21:21:50 +02:00
|
|
|
# See LICENSE for licensing information.
|
|
|
|
|
#
|
2019-06-14 17:43:41 +02:00
|
|
|
# Copyright (c) 2016-2019 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.
|
2019-04-26 21:21:50 +02:00
|
|
|
#
|
2016-11-09 20:35:32 +01:00
|
|
|
import os
|
2018-10-12 18:44:36 +02:00
|
|
|
from design_rules import *
|
2019-12-16 14:40:52 +01:00
|
|
|
from module_type import *
|
2020-01-30 02:45:33 +01:00
|
|
|
from custom_cell_properties import cell_properties
|
2020-02-12 05:09:40 +01:00
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
"""
|
2017-11-14 23:59:14 +01:00
|
|
|
File containing the process technology parameters for FreePDK 45nm.
|
2016-11-08 18:57:35 +01:00
|
|
|
"""
|
2019-12-21 01:35:31 +01:00
|
|
|
|
|
|
|
|
###################################################
|
|
|
|
|
# Custom modules
|
|
|
|
|
###################################################
|
|
|
|
|
|
2019-12-16 14:40:52 +01:00
|
|
|
# This uses the default classes to instantiate module from
|
|
|
|
|
# '$OPENRAM_HOME/compiler/modules'.
|
|
|
|
|
# Using tech_modules['cellname'] you can override each class by providing a custom
|
|
|
|
|
# implementation in '$OPENRAM_TECHDIR/modules/'
|
|
|
|
|
# For example: tech_modules['contact'] = 'contact_freepdk45'
|
2020-01-30 02:45:33 +01:00
|
|
|
tech_modules = module_type()
|
2016-11-09 20:35:32 +01:00
|
|
|
|
2020-02-12 05:09:40 +01:00
|
|
|
|
2020-01-28 11:03:08 +01:00
|
|
|
###################################################
|
|
|
|
|
# Custom cell properties
|
|
|
|
|
###################################################
|
2020-01-30 02:45:33 +01:00
|
|
|
cell_properties = cell_properties()
|
2020-01-28 11:03:08 +01:00
|
|
|
cell_properties.bitcell.mirror.x = True
|
|
|
|
|
cell_properties.bitcell.mirror.y = False
|
2020-05-07 21:35:21 +02:00
|
|
|
cell_properties.bitcell_power_pin_directions = ("V", "V")
|
2020-01-30 02:45:33 +01:00
|
|
|
|
2019-12-21 01:35:31 +01:00
|
|
|
###################################################
|
|
|
|
|
# GDS file info
|
|
|
|
|
###################################################
|
|
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
GDS = {}
|
2019-04-30 19:13:13 +02:00
|
|
|
# gds units
|
|
|
|
|
# From http://www.cnf.cornell.edu/cnf_spie9.html: "The first
|
|
|
|
|
#is the size of a database unit in user units. The second is the size
|
|
|
|
|
#of a database unit in meters. For example, if your library was
|
|
|
|
|
#created with the default units (user unit = 1 m and 1000 database
|
|
|
|
|
#units per user unit), then the first number would be 0.001 and the
|
|
|
|
|
#second number would be 10-9. Typically, the first number is less than
|
|
|
|
|
#1, since you use more than 1 database unit per user unit. To
|
|
|
|
|
#calculate the size of a user unit in meters, divide the second number
|
|
|
|
|
#by the first."
|
2016-11-08 18:57:35 +01:00
|
|
|
GDS["unit"] = (0.0005,1e-9)
|
2017-05-24 01:18:11 +02:00
|
|
|
# default label zoom
|
|
|
|
|
GDS["zoom"] = 0.05
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2017-11-14 23:59:14 +01:00
|
|
|
###################################################
|
2019-12-12 02:56:55 +01:00
|
|
|
# Interconnect stacks
|
|
|
|
|
###################################################
|
|
|
|
|
|
2019-12-17 20:03:36 +01:00
|
|
|
poly_stack = ("poly", "contact", "m1")
|
|
|
|
|
active_stack = ("active", "contact", "m1")
|
|
|
|
|
m1_stack = ("m1", "via1", "m2")
|
|
|
|
|
m2_stack = ("m2", "via2", "m3")
|
|
|
|
|
m3_stack = ("m3", "via3", "m4")
|
2019-12-12 02:56:55 +01:00
|
|
|
|
2020-05-07 21:35:21 +02:00
|
|
|
layer_indices = {"poly": 0,
|
|
|
|
|
"active": 0,
|
|
|
|
|
"m1": 1,
|
|
|
|
|
"m2": 2,
|
|
|
|
|
"m3": 3,
|
|
|
|
|
"m4": 4}
|
|
|
|
|
|
2019-12-17 20:03:36 +01:00
|
|
|
# The FEOL stacks get us up to m1
|
2019-12-12 02:56:55 +01:00
|
|
|
feol_stacks = [poly_stack,
|
|
|
|
|
active_stack]
|
|
|
|
|
|
2019-12-17 20:03:36 +01:00
|
|
|
# The BEOL stacks are m1 and up
|
2019-12-13 23:25:00 +01:00
|
|
|
beol_stacks = [m1_stack,
|
|
|
|
|
m2_stack,
|
|
|
|
|
m3_stack]
|
2019-12-12 02:56:55 +01:00
|
|
|
|
|
|
|
|
layer_stacks = feol_stacks + beol_stacks
|
|
|
|
|
|
2019-12-18 00:45:07 +01:00
|
|
|
preferred_directions = {"poly": "V",
|
2019-12-19 21:54:10 +01:00
|
|
|
"active": "V",
|
2019-12-18 00:45:07 +01:00
|
|
|
"m1": "H",
|
|
|
|
|
"m2": "V",
|
|
|
|
|
"m3": "H",
|
|
|
|
|
"m4": "V"}
|
2019-12-23 17:36:57 +01:00
|
|
|
###################################################
|
|
|
|
|
# Power grid
|
|
|
|
|
###################################################
|
|
|
|
|
# Use M3/M4
|
|
|
|
|
power_grid = m3_stack
|
2019-12-18 00:45:07 +01:00
|
|
|
|
2019-12-12 02:56:55 +01:00
|
|
|
###################################################
|
|
|
|
|
# GDS Layer Map
|
2017-11-14 23:59:14 +01:00
|
|
|
###################################################
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
# create the GDS layer map
|
|
|
|
|
# FIXME: parse the gds layer map from the cadence map?
|
|
|
|
|
layer = {}
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["active"] = (1, 0)
|
|
|
|
|
layer["pwell"] = (2, 0)
|
|
|
|
|
layer["nwell"] = (3, 0)
|
|
|
|
|
layer["nimplant"]= (4, 0)
|
|
|
|
|
layer["pimplant"]= (5, 0)
|
|
|
|
|
layer["vtg"] = (6, 0)
|
|
|
|
|
layer["vth"] = (7, 0)
|
|
|
|
|
layer["thkox"] = (8, 0)
|
|
|
|
|
layer["poly"] = (9, 0)
|
2019-12-12 02:56:55 +01:00
|
|
|
layer["contact"] = (10, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m1"] = (11, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["via1"] = (12, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m2"] = (13, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["via2"] = (14, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m3"] = (15, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["via3"] = (16, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m4"] = (17, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["via4"] = (18, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m5"] = (19, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["via5"] = (20, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m6"] = (21, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["via6"] = (22, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m7"] = (23, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["via7"] = (24, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m8"] = (25, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["via8"] = (26, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m9"] = (27, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["via9"] = (28, 0)
|
2019-12-17 20:03:36 +01:00
|
|
|
layer["m10"] = (29, 0)
|
2019-10-25 19:03:25 +02:00
|
|
|
layer["text"] = (239, 0)
|
|
|
|
|
layer["boundary"]= (239, 0)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2017-11-14 23:59:14 +01:00
|
|
|
###################################################
|
2019-12-12 02:56:55 +01:00
|
|
|
# DRC/LVS Rules Setup
|
2017-11-14 23:59:14 +01:00
|
|
|
###################################################
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
#technology parameter
|
|
|
|
|
parameter={}
|
|
|
|
|
parameter["min_tx_size"] = 0.09
|
2017-12-01 17:31:16 +01:00
|
|
|
parameter["beta"] = 3
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-10-17 16:28:56 +02:00
|
|
|
parameter["6T_inv_nmos_size"] = 0.205
|
|
|
|
|
parameter["6T_inv_pmos_size"] = 0.09
|
|
|
|
|
parameter["6T_access_size"] = 0.135
|
|
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
drclvs_home=os.environ.get("DRCLVS_HOME")
|
2018-10-12 18:44:36 +02:00
|
|
|
|
|
|
|
|
drc = design_rules("freepdk45")
|
|
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
#grid size
|
|
|
|
|
drc["grid"] = 0.0025
|
|
|
|
|
|
|
|
|
|
#DRC/LVS test set_up
|
|
|
|
|
drc["drc_rules"]=drclvs_home+"/calibreDRC.rul"
|
|
|
|
|
drc["lvs_rules"]=drclvs_home+"/calibreLVS.rul"
|
|
|
|
|
drc["xrc_rules"]=drclvs_home+"/calibrexRC.rul"
|
2016-11-19 00:05:17 +01:00
|
|
|
drc["layer_map"]=os.environ.get("OPENRAM_TECH")+"/freepdk45/layers.map"
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# minwidth_tx with contact (no dog bone transistors)
|
2018-10-12 18:44:36 +02:00
|
|
|
drc["minwidth_tx"] = 0.09
|
2016-11-08 18:57:35 +01:00
|
|
|
drc["minlength_channel"] = 0.05
|
|
|
|
|
|
2018-03-17 01:46:29 +01:00
|
|
|
# WELL.2 Minimum spacing of nwell/pwell at different potential
|
2017-08-24 00:02:15 +02:00
|
|
|
drc["pwell_to_nwell"] = 0.225
|
2018-03-17 01:46:29 +01:00
|
|
|
# WELL.3 Minimum spacing of nwell/pwell at the same potential
|
2018-01-08 20:57:51 +01:00
|
|
|
# WELL.4 Minimum width of nwell/pwell
|
2020-01-23 20:43:41 +01:00
|
|
|
drc.add_layer("nwell",
|
|
|
|
|
width = 0.2,
|
|
|
|
|
spacing = 0.135)
|
|
|
|
|
drc.add_layer("pwell",
|
2019-12-12 02:56:55 +01:00
|
|
|
width = 0.2,
|
|
|
|
|
spacing = 0.135)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# POLY.1 Minimum width of poly
|
|
|
|
|
# POLY.2 Minimum spacing of poly AND active
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_layer("poly",
|
|
|
|
|
width = 0.05,
|
|
|
|
|
spacing = 0.14)
|
|
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# POLY.3 Minimum poly extension beyond active
|
2016-11-08 18:57:35 +01:00
|
|
|
drc["poly_extend_active"] = 0.055
|
2018-08-30 01:12:06 +02:00
|
|
|
# Not a rule
|
2019-12-12 02:56:55 +01:00
|
|
|
drc["poly_to_contact"] = 0.075
|
2018-01-08 20:57:51 +01:00
|
|
|
# POLY.4 Minimum enclosure of active around gate
|
2019-12-17 20:03:36 +01:00
|
|
|
drc["active_enclose_gate"] = 0.07
|
2018-01-08 20:57:51 +01:00
|
|
|
# POLY.5 Minimum spacing of field poly to active
|
2016-11-08 18:57:35 +01:00
|
|
|
drc["poly_to_active"] = 0.05
|
2018-01-08 20:57:51 +01:00
|
|
|
# POLY.6 Minimum Minimum spacing of field poly
|
2016-11-08 18:57:35 +01:00
|
|
|
drc["poly_to_field_poly"] = 0.075
|
2018-01-08 20:57:51 +01:00
|
|
|
# Not a rule
|
2016-11-08 18:57:35 +01:00
|
|
|
drc["minarea_poly"] = 0.0
|
|
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# ACTIVE.1 Minimum width of active
|
2019-12-17 20:23:59 +01:00
|
|
|
# ACTIVE.2 Minimum spacing of active
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_layer("active",
|
|
|
|
|
width = 0.09,
|
2019-12-17 20:23:59 +01:00
|
|
|
spacing = 0.08)
|
2018-01-08 20:57:51 +01:00
|
|
|
# ACTIVE.3 Minimum enclosure/spacing of nwell/pwell to active
|
2020-01-23 20:43:41 +01:00
|
|
|
drc.add_enclosure("nwell",
|
|
|
|
|
layer = "active",
|
|
|
|
|
enclosure = 0.055)
|
|
|
|
|
drc.add_enclosure("pwell",
|
2019-12-12 02:56:55 +01:00
|
|
|
layer = "active",
|
|
|
|
|
enclosure = 0.055)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# IMPLANT.1 Minimum spacing of nimplant/ pimplant to channel
|
2016-11-08 18:57:35 +01:00
|
|
|
drc["implant_to_channel"] = 0.07
|
2018-01-08 20:57:51 +01:00
|
|
|
# Not a rule
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_enclosure("implant",
|
|
|
|
|
layer = "active",
|
|
|
|
|
enclosure = 0)
|
2018-01-08 20:57:51 +01:00
|
|
|
# Not a rule
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_enclosure("implant",
|
|
|
|
|
layer = "contact",
|
|
|
|
|
enclosure = 0)
|
2018-01-08 20:57:51 +01:00
|
|
|
# IMPLANT.2 Minimum spacing of nimplant/ pimplant to contact
|
2016-11-08 18:57:35 +01:00
|
|
|
drc["implant_to_contact"] = 0.025
|
2018-01-08 20:57:51 +01:00
|
|
|
# IMPLANT.3 Minimum width/ spacing of nimplant/ pimplant
|
|
|
|
|
# IMPLANT.4 Minimum width/ spacing of nimplant/ pimplant
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_layer("implant",
|
|
|
|
|
width = 0.045,
|
|
|
|
|
spacing = 0.045)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# CONTACT.1 Minimum width of contact
|
|
|
|
|
# CONTACT.2 Minimum spacing of contact
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_layer("contact",
|
|
|
|
|
width = 0.065,
|
|
|
|
|
spacing = 0.075)
|
2018-01-08 20:57:51 +01:00
|
|
|
# CONTACT.4 Minimum enclosure of active around contact
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_enclosure("active",
|
|
|
|
|
layer = "contact",
|
|
|
|
|
enclosure = 0.005)
|
|
|
|
|
|
2019-12-05 01:12:53 +01:00
|
|
|
# CONTACT.6 Minimum spacing of contact and gate
|
2020-06-24 18:17:39 +02:00
|
|
|
drc["active_contact_to_gate"] = 0.0375 #changed from 0.035
|
2019-12-05 01:12:53 +01:00
|
|
|
# CONTACT.7 Minimum spacing of contact and poly
|
2020-06-24 18:17:39 +02:00
|
|
|
drc["poly_contact_to_gate"] = 0.090
|
2019-12-05 01:12:53 +01:00
|
|
|
|
|
|
|
|
# CONTACT.1 Minimum width of contact
|
2019-12-06 01:05:26 +01:00
|
|
|
# CONTACT.2 Minimum spacing of contact
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_layer("contact",
|
|
|
|
|
width = 0.065,
|
|
|
|
|
spacing = 0.075)
|
2018-01-08 20:57:51 +01:00
|
|
|
# CONTACT.5 Minimum enclosure of poly around contact
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_enclosure("poly",
|
|
|
|
|
layer = "contact",
|
|
|
|
|
enclosure = 0.005)
|
2018-01-08 20:57:51 +01:00
|
|
|
# CONTACT.6 Minimum spacing of contact and gate
|
2019-12-12 02:56:55 +01:00
|
|
|
drc["contact_to_gate"] = 0.0375 #changed from 0.035
|
2018-01-08 20:57:51 +01:00
|
|
|
# CONTACT.7 Minimum spacing of contact and poly
|
2019-12-12 02:56:55 +01:00
|
|
|
drc["contact_to_poly"] = 0.090
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# METAL1.1 Minimum width of metal1
|
|
|
|
|
# METAL1.2 Minimum spacing of metal1
|
2019-12-17 20:03:36 +01:00
|
|
|
drc.add_layer("m1",
|
2019-12-12 02:56:55 +01:00
|
|
|
width = 0.065,
|
|
|
|
|
spacing = 0.065)
|
|
|
|
|
|
2019-12-05 01:12:53 +01:00
|
|
|
# METAL1.3 Minimum enclosure around contact on two opposite sides
|
2019-12-17 20:03:36 +01:00
|
|
|
drc.add_enclosure("m1",
|
2019-12-12 02:56:55 +01:00
|
|
|
layer = "contact",
|
|
|
|
|
enclosure = 0,
|
|
|
|
|
extension = 0.035)
|
2018-01-08 20:57:51 +01:00
|
|
|
# METAL1.4 inimum enclosure around via1 on two opposite sides
|
2019-12-17 20:03:36 +01:00
|
|
|
drc.add_enclosure("m1",
|
2019-12-12 02:56:55 +01:00
|
|
|
layer = "via1",
|
|
|
|
|
enclosure = 0,
|
|
|
|
|
extension = 0.035)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# VIA1.1 Minimum width of via1
|
|
|
|
|
# VIA1.2 Minimum spacing of via1
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_layer("via1",
|
|
|
|
|
width = 0.065,
|
|
|
|
|
spacing = 0.075)
|
|
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# METALINT.1 Minimum width of intermediate metal
|
|
|
|
|
# METALINT.2 Minimum spacing of intermediate metal
|
2019-12-17 20:03:36 +01:00
|
|
|
drc.add_layer("m2",
|
2019-12-12 02:56:55 +01:00
|
|
|
width = 0.07,
|
|
|
|
|
spacing = 0.07)
|
|
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# METALINT.3 Minimum enclosure around via1 on two opposite sides
|
2019-12-17 20:03:36 +01:00
|
|
|
drc.add_enclosure("m2",
|
2019-12-12 02:56:55 +01:00
|
|
|
layer = "via1",
|
|
|
|
|
enclosure = 0,
|
|
|
|
|
extension = 0.035)
|
|
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# METALINT.4 Minimum enclosure around via[2-3] on two opposite sides
|
2019-12-17 20:03:36 +01:00
|
|
|
drc.add_enclosure("m2",
|
2019-12-12 02:56:55 +01:00
|
|
|
layer = "via2",
|
|
|
|
|
enclosure = 0,
|
|
|
|
|
extension = 0.035)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# VIA2-3.1 Minimum width of Via[2-3]
|
|
|
|
|
# VIA2-3.2 Minimum spacing of Via[2-3]
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_layer("via2",
|
|
|
|
|
width = 0.065,
|
|
|
|
|
spacing = 0.075)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# METALINT.1 Minimum width of intermediate metal
|
|
|
|
|
# METALINT.2 Minimum spacing of intermediate metal
|
2019-12-17 20:03:36 +01:00
|
|
|
# Minimum spacing of m3 wider than 0.09 & longer than 0.3 = 0.09
|
|
|
|
|
# Minimum spacing of m3 wider than 0.27 & longer than 0.9 = 0.27
|
|
|
|
|
# Minimum spacing of m3 wider than 0.5 & longer than 1.8 = 0.5
|
|
|
|
|
# Minimum spacing of m3 wider than 0.9 & longer than 2.7 = 0.9
|
|
|
|
|
# Minimum spacing of m3 wider than 1.5 & longer than 4.0 = 1.5
|
|
|
|
|
drc.add_layer("m3",
|
2019-12-12 02:56:55 +01:00
|
|
|
width = 0.07,
|
|
|
|
|
spacing = drc_lut({(0.00, 0.0) : 0.07,
|
|
|
|
|
(0.09, 0.3) : 0.09,
|
|
|
|
|
(0.27, 0.9) : 0.27,
|
|
|
|
|
(0.50, 1.8) : 0.5,
|
|
|
|
|
(0.90, 2.7) : 0.9,
|
|
|
|
|
(1.50, 4.0) : 1.5}))
|
2018-01-08 20:57:51 +01:00
|
|
|
# METALINT.3 Minimum enclosure around via1 on two opposite sides
|
2019-12-17 20:03:36 +01:00
|
|
|
drc.add_enclosure("m3",
|
2019-12-12 02:56:55 +01:00
|
|
|
layer = "via2",
|
|
|
|
|
enclosure = 0,
|
|
|
|
|
extension = 0.035)
|
|
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# METALINT.4 Minimum enclosure around via[2-3] on two opposite sides
|
2019-12-17 20:03:36 +01:00
|
|
|
drc.add_enclosure("m3",
|
2019-12-12 02:56:55 +01:00
|
|
|
layer = "via3",
|
|
|
|
|
enclosure = 0,
|
|
|
|
|
extension = 0.035)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# VIA2-3.1 Minimum width of Via[2-3]
|
|
|
|
|
# VIA2-3.2 Minimum spacing of Via[2-3]
|
2019-12-12 02:56:55 +01:00
|
|
|
drc.add_layer("via3",
|
|
|
|
|
width = 0.07,
|
|
|
|
|
spacing = 0.085)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# METALSMG.1 Minimum width of semi-global metal
|
|
|
|
|
# METALSMG.2 Minimum spacing of semi-global metal
|
2019-12-17 20:03:36 +01:00
|
|
|
# Minimum spacing of m4 wider than 0.27 & longer than 0.9 = 0.27
|
|
|
|
|
# Minimum spacing of m4 wider than 0.5 & longer than 1.8 = 0.5
|
|
|
|
|
# Minimum spacing of m4 wider than 0.9 & longer than 2.7 = 0.9
|
|
|
|
|
# Minimum spacing of m4 wider than 1.5 & longer than 4.0 = 1.5
|
|
|
|
|
drc.add_layer("m4",
|
2019-12-12 02:56:55 +01:00
|
|
|
width = 0.14,
|
|
|
|
|
spacing = drc_lut({(0.00, 0.0) : 0.14,
|
|
|
|
|
(0.27, 0.9) : 0.27,
|
|
|
|
|
(0.50, 1.8) : 0.5,
|
|
|
|
|
(0.90, 2.7) : 0.9,
|
|
|
|
|
(1.50, 4.0) : 1.5}))
|
2018-01-08 20:57:51 +01:00
|
|
|
# METALSMG.3 Minimum enclosure around via[3-6] on two opposite sides
|
2019-12-17 20:03:36 +01:00
|
|
|
drc.add_enclosure("m4",
|
2019-12-12 02:56:55 +01:00
|
|
|
layer = "via3",
|
|
|
|
|
enclosure = 0.0025)
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2018-01-08 20:57:51 +01:00
|
|
|
# Metal 5-10 are ommitted
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2017-11-14 23:59:14 +01:00
|
|
|
###################################################
|
2019-12-12 02:56:55 +01:00
|
|
|
# Spice Simulation Parameters
|
2017-11-14 23:59:14 +01:00
|
|
|
###################################################
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
#spice info
|
|
|
|
|
spice = {}
|
|
|
|
|
spice["nmos"] = "nmos_vtg"
|
|
|
|
|
spice["pmos"] = "pmos_vtg"
|
2018-02-10 00:33:03 +01:00
|
|
|
# This is a map of corners to model files
|
2016-11-09 22:29:33 +01:00
|
|
|
SPICE_MODEL_DIR=os.environ.get("SPICE_MODEL_DIR")
|
2018-02-12 18:33:23 +01:00
|
|
|
spice["fet_models"] = { "TT" : [SPICE_MODEL_DIR+"/models_nom/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_nom/NMOS_VTG.inc"],
|
|
|
|
|
"FF" : [SPICE_MODEL_DIR+"/models_ff/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ff/NMOS_VTG.inc"],
|
|
|
|
|
"SF" : [SPICE_MODEL_DIR+"/models_ss/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ff/NMOS_VTG.inc"],
|
|
|
|
|
"FS" : [SPICE_MODEL_DIR+"/models_ff/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ss/NMOS_VTG.inc"],
|
2019-01-23 01:40:46 +01:00
|
|
|
"SS" : [SPICE_MODEL_DIR+"/models_ss/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ss/NMOS_VTG.inc"],
|
|
|
|
|
"ST" : [SPICE_MODEL_DIR+"/models_ss/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_nom/NMOS_VTG.inc"],
|
|
|
|
|
"TS" : [SPICE_MODEL_DIR+"/models_nom/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ss/NMOS_VTG.inc"],
|
|
|
|
|
"FT" : [SPICE_MODEL_DIR+"/models_ff/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_nom/NMOS_VTG.inc"],
|
|
|
|
|
"TF" : [SPICE_MODEL_DIR+"/models_nom/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ff/NMOS_VTG.inc"],
|
|
|
|
|
}
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
#spice stimulus related variables
|
2018-02-12 18:33:23 +01:00
|
|
|
spice["feasible_period"] = 5 # estimated feasible period in ns
|
|
|
|
|
spice["supply_voltages"] = [0.9, 1.0, 1.1] # Supply voltage corners in [Volts]
|
2018-02-23 21:21:32 +01:00
|
|
|
spice["nom_supply_voltage"] = 1.0 # Nominal supply voltage in [Volts]
|
2018-02-10 00:33:03 +01:00
|
|
|
spice["rise_time"] = 0.005 # rise time in [Nano-seconds]
|
|
|
|
|
spice["fall_time"] = 0.005 # fall time in [Nano-seconds]
|
2018-02-23 21:21:32 +01:00
|
|
|
spice["temperatures"] = [0, 25, 100] # Temperature corners (celcius)
|
|
|
|
|
spice["nom_temperature"] = 25 # Nominal temperature (celcius)
|
|
|
|
|
|
2017-07-06 17:42:25 +02:00
|
|
|
# analytical delay parameters
|
2019-09-05 01:53:58 +02:00
|
|
|
spice["nom_threshold"] = 0.4 # Typical Threshold voltage in Volts
|
2017-07-06 17:42:25 +02:00
|
|
|
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.2 # Minimum transistor gate capacitance in ff
|
2018-02-15 00:16:28 +01:00
|
|
|
spice["dff_setup"] = 9 # DFF setup time in ps
|
|
|
|
|
spice["dff_hold"] = 1 # DFF hold time in ps
|
2019-09-05 01:08:18 +02:00
|
|
|
spice["dff_in_cap"] = 0.2091 # Input capacitance (D) [Femto-farad]
|
|
|
|
|
spice["dff_out_cap"] = 2 # Output capacitance (Q) [Femto-farad]
|
2017-11-14 23:59:14 +01:00
|
|
|
|
2018-02-27 01:32:28 +01:00
|
|
|
# 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["nor2_leakage"] = 1 # Leakage power of 2-input nor in nW
|
2019-09-05 01:08:18 +02:00
|
|
|
spice["dff_leakage"] = 1 # Leakage power of flop in nW
|
2018-02-27 01:32:28 +01:00
|
|
|
|
2019-09-05 01:08:18 +02:00
|
|
|
spice["default_event_frequency"] = 100 # Default event activity of every gate. MHz
|
2017-11-14 23:59:14 +01:00
|
|
|
|
2018-12-13 08:59:32 +01:00
|
|
|
#Parameters related to sense amp enable timing and delay chain/RBL sizing
|
2019-09-05 01:08:18 +02:00
|
|
|
parameter["le_tau"] = 2.25 #In pico-seconds.
|
|
|
|
|
parameter["cap_relative_per_ff"] = 7.5 #Units of Relative Capacitance/ Femto-Farad
|
2018-11-09 05:47:34 +01:00
|
|
|
parameter["dff_clk_cin"] = 30.6 #relative capacitance
|
|
|
|
|
parameter["6tcell_wl_cin"] = 3 #relative capacitance
|
2018-12-18 08:32:02 +01:00
|
|
|
parameter["min_inv_para_delay"] = 2.4 #Tau delay units
|
2019-07-25 23:18:08 +02:00
|
|
|
parameter["sa_en_pmos_size"] = 0.72 #micro-meters
|
|
|
|
|
parameter["sa_en_nmos_size"] = 0.27 #micro-meters
|
|
|
|
|
parameter["sa_inv_pmos_size"] = 0.54 #micro-meters
|
|
|
|
|
parameter["sa_inv_nmos_size"] = 0.27 #micro-meters
|
2019-09-05 01:08:18 +02:00
|
|
|
parameter["bitcell_drain_cap"] = 0.1 #In Femto-Farad, approximation of drain capacitance
|
2018-12-15 03:02:19 +01:00
|
|
|
|
2017-11-14 23:59:14 +01:00
|
|
|
###################################################
|
2019-12-12 02:56:55 +01:00
|
|
|
# Technology Tool Preferences
|
2019-11-29 21:01:33 +01:00
|
|
|
###################################################
|
|
|
|
|
|
|
|
|
|
drc_name = "calibre"
|
|
|
|
|
lvs_name = "calibre"
|
|
|
|
|
pex_name = "calibre"
|
|
|
|
|
|
2019-11-30 00:50:32 +01:00
|
|
|
blackbox_bitcell = False
|