Changed CACTI drain cap function to be roughly equivalent but use less parameters. Added drain cap functions to relevant modules. Added drain cap parameters in tech files.

This commit is contained in:
Hunter Nichols 2021-07-21 14:59:02 -07:00
parent 1acc10e9d5
commit 10085d85ab
13 changed files with 154 additions and 51 deletions

View File

@ -540,63 +540,32 @@ class spice():
def drain_c_(self, def drain_c_(self,
width, width,
nchannel,
stack, stack,
next_arg_thresh_folding_width_or_height_cell, folds):
fold_dimension,
_is_cell):
if _is_cell: c_junc_area = tech.spice["c_junc"]
dt = tech.sram_cell # SRAM cell access transistor c_junc_sidewall = tech.spice["c_junc_sw"]
c_fringe = 2*tech.spice["c_overlap"]
else: c_overlap = 2*tech.spice["c_fringe"]
dt = tech.peri_global
c_junc_area = dt.C_junc
c_junc_sidewall = dt.C_junc_sidewall
c_fringe = 2*dt.C_fringe
c_overlap = 2*dt.C_overlap
drain_C_metal_connecting_folded_tr = 0 drain_C_metal_connecting_folded_tr = 0
# determine the width of the transistor after folding (if it is getting folded) w_folded_tr = width/folds
if next_arg_thresh_folding_width_or_height_cell == 0: num_folded_tr = folds
# interpret fold_dimension as the the folding width threshold
# i.e. the value of transistor width above which the transistor gets folded
w_folded_tr = fold_dimension
else:
# interpret fold_dimension as the height of the cell that this transistor is part of.
h_tr_region = fold_dimension - 2 * tech.HPOWERRAIL
# TODO : w_folded_tr must come from Component::compute_gate_area()
ratio_p_to_n = 2.0 / (2.0 + 1.0)
if nchannel:
w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - tech.MIN_GAP_BET_P_AND_N_DIFFS)
else:
w_folded_tr = ratio_p_to_n * (h_tr_region - tech.MIN_GAP_BET_P_AND_N_DIFFS)
num_folded_tr = int(ceil(width / w_folded_tr))
if num_folded_tr < 2:
w_folded_tr = width
# only for drain # only for drain
total_drain_w = (tech.w_poly_contact + 2 * tech.spacing_poly_to_contact) +\ total_drain_w = (tech.spice["w_poly_contact"] + 2 * tech.drc["active_contact_to_gate"]) +\
(stack - 1) * tech.spacing_poly_to_poly (stack - 1) * tech.spice["spacing_poly_to_poly"]
drain_h_for_sidewall = w_folded_tr drain_h_for_sidewall = w_folded_tr
total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1) total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1)
if num_folded_tr > 1: if num_folded_tr > 1:
total_drain_w += (num_folded_tr - 2) * (tech.w_poly_contact + 2 * tech.spacing_poly_to_contact) +\ total_drain_w += (num_folded_tr - 2) * (tech.spice["w_poly_contact"] + 2 * tech.drc["active_contact_to_gate"]) +\
(num_folded_tr - 1) * ((stack - 1) * tech.spacing_poly_to_poly) (num_folded_tr - 1) * ((stack - 1) * tech.spice["spacing_poly_to_poly"])
if num_folded_tr%2 == 0: if num_folded_tr%2 == 0:
drain_h_for_sidewall = 0 drain_h_for_sidewall = 0
total_drain_height_for_cap_wrt_gate *= num_folded_tr total_drain_height_for_cap_wrt_gate *= num_folded_tr
drain_C_metal_connecting_folded_tr = tech.wire_local.C_per_um * total_drain_w drain_C_metal_connecting_folded_tr = tech.spice["wire_c_per_um"] * total_drain_w
drain_C_area = c_junc_area * total_drain_w * w_folded_tr drain_C_area = c_junc_area * total_drain_w * w_folded_tr

View File

@ -213,3 +213,23 @@ class bitcell_base(design.design):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
# Input cap of both access TX connected to the wordline # Input cap of both access TX connected to the wordline
return self.gate_c(2*parameter["6T_access_size"]) return self.gate_c(2*parameter["6T_access_size"])
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
stack = 1
mult = 1
# FIXME: Need to define TX sizes of bitcell storage node. Using
# min_width as a temp value
# Add the inverter drain Cap and the bitline TX drain Cap
nmos_drain_c = self.drain_c_(drc["minwidth_tx"]*mult,
stack,
mult)
pmos_drain_c = self.drain_c_(drc["minwidth_tx"]*mult,
stack,
mult)
bl_nmos_drain_c = self.drain_c_(parameter["6T_access_size"],
stack,
mult)
return nmos_drain_c + pmos_drain_c + bl_nmos_drain_c

View File

@ -85,3 +85,15 @@ class nand2_dec(design.design):
def get_input_capacitance(self): def get_input_capacitance(self):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
return self.gate_c(self.nmos_width+self.pmos_width) return self.gate_c(self.nmos_width+self.pmos_width)
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
nmos_stack = 2
mult = 1
nmos_drain_c = self.drain_c_(self.nmos_width*mult,
nmos_stack,
mult)
pmos_drain_c = self.drain_c_(self.pmos_width*mult,
1,
mult)
return nmos_drain_c + pmos_drain_c

View File

@ -85,3 +85,15 @@ class nand3_dec(design.design):
def get_input_capacitance(self): def get_input_capacitance(self):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
return self.gate_c(self.nmos_width+self.pmos_width) return self.gate_c(self.nmos_width+self.pmos_width)
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
nmos_stack = 3
mult = 1
nmos_drain_c = self.drain_c_(self.nmos_width*mult,
nmos_stack,
mult)
pmos_drain_c = self.drain_c_(self.pmos_width*mult,
1,
mult)
return nmos_drain_c + pmos_drain_c

View File

@ -85,3 +85,15 @@ class nand4_dec(design.design):
def get_input_capacitance(self): def get_input_capacitance(self):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
return self.gate_c(self.nmos_width+self.pmos_width) return self.gate_c(self.nmos_width+self.pmos_width)
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
nmos_stack = 4
mult = 1
nmos_drain_c = self.drain_c_(self.nmos_width*mult,
nmos_stack,
mult)
pmos_drain_c = self.drain_c_(self.pmos_width*mult,
1,
mult)
return nmos_drain_c + pmos_drain_c

View File

@ -90,3 +90,21 @@ class sense_amp(design.design):
def get_input_capacitance(self): def get_input_capacitance(self):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
return self.gate_c(parameter["sa_inv_nmos_size"]) return self.gate_c(parameter["sa_inv_nmos_size"])
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
stack = 1
mult = 1
# Add the inverter drain Cap and the bitline TX drain Cap
nmos_drain_c = self.drain_c_(parameter["sa_inv_nmos_size"]*mult,
stack,
mult)
pmos_drain_c = self.drain_c_(parameter["sa_inv_pmos_size"]*mult,
stack,
mult)
bitline_pmos_size = 8
bl_pmos_drain_c = self.drain_c_(drc("minwidth_tx")*bitline_pmos_size,
stack,
mult)
return nmos_drain_c + pmos_drain_c + bl_pmos_drain_c

View File

@ -353,3 +353,14 @@ class pinv(pgate.pgate):
def get_input_capacitance(self): def get_input_capacitance(self):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
return self.gate_c(self.nmos_width+self.pmos_width) return self.gate_c(self.nmos_width+self.pmos_width)
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
nmos_stack = 1
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
nmos_stack,
self.tx_mults)
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
1,
self.tx_mults)
return nmos_drain_c + pmos_drain_c

View File

@ -331,3 +331,14 @@ class pnand2(pgate.pgate):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
return self.gate_c(self.nmos_width+self.pmos_width) return self.gate_c(self.nmos_width+self.pmos_width)
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
nmos_stack = 2
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
nmos_stack,
self.tx_mults)
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
1,
self.tx_mults)
return nmos_drain_c + pmos_drain_c

View File

@ -363,3 +363,14 @@ class pnand3(pgate.pgate):
def get_input_capacitance(self): def get_input_capacitance(self):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
return self.gate_c(self.nmos_width+self.pmos_width) return self.gate_c(self.nmos_width+self.pmos_width)
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
nmos_stack = 3
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
nmos_stack,
self.tx_mults)
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
1,
self.tx_mults)
return nmos_drain_c + pmos_drain_c

View File

@ -380,3 +380,14 @@ class pnand4(pgate.pgate):
def get_input_capacitance(self): def get_input_capacitance(self):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
return self.gate_c(self.nmos_width+self.pmos_width) return self.gate_c(self.nmos_width+self.pmos_width)
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
nmos_stack = 4
nmos_drain_c = self.drain_c_(self.nmos_width*self.tx_mults,
nmos_stack,
self.tx_mults)
pmos_drain_c = self.drain_c_(self.pmos_width*self.tx_mults,
1,
self.tx_mults)
return nmos_drain_c + pmos_drain_c

View File

@ -563,3 +563,9 @@ class ptx(design.design):
def get_input_capacitance(self): def get_input_capacitance(self):
"""Input cap of input, passes width of gates to gate cap function""" """Input cap of input, passes width of gates to gate cap function"""
return self.gate_c(self.tx_width) return self.gate_c(self.tx_width)
def get_intrinsic_capacitance(self):
"""Get the drain capacitances of the TXs in the gate."""
return self.drain_c_(self.tx_width*self.tx_mults,
1,
self.mults)

View File

@ -466,6 +466,11 @@ spice["c_g_ideal"] = spice["cox"]*drc["minlength_channel"] # F/um
spice["c_overlap"] = 0.2*spice["c_g_ideal"] # F/um spice["c_overlap"] = 0.2*spice["c_g_ideal"] # F/um
spice["c_fringe"] = 0 # F/um, not defined in this technology spice["c_fringe"] = 0 # F/um, not defined in this technology
spice["cpolywire"] = 0 # F/um, replicated from CACTI which is hardcoded to 0 spice["cpolywire"] = 0 # F/um, replicated from CACTI which is hardcoded to 0
spice["c_junc"] = 5e-16 #F/um^2
spice["c_junc_sw"] = 5e-16 #F/um
spice["w_poly_contact"] = 0.065 # um
spice["spacing_poly_to_poly"] = 0.14 # um
spice["wire_c_per_um"] = 0 # Temp value
################################################### ###################################################
# Technology Tool Preferences # Technology Tool Preferences

View File

@ -413,6 +413,11 @@ spice["c_g_ideal"] = spice["cox"]*drc["minlength_channel"] # F/um
spice["c_overlap"] = 0.2*spice["c_g_ideal"] # F/um spice["c_overlap"] = 0.2*spice["c_g_ideal"] # F/um
spice["c_fringe"] = 0 # F/um, not defined in this technology spice["c_fringe"] = 0 # F/um, not defined in this technology
spice["cpolywire"] = 0 # F/um, replicated from CACTI which is hardcoded to 0 spice["cpolywire"] = 0 # F/um, replicated from CACTI which is hardcoded to 0
spice["c_junc"] = 9.276962e-16 #F/um^2
spice["c_junc_sw"] = 3.181055e-16 #F/um
spice["w_poly_contact"] = 2*_lambda_
spice["spacing_poly_to_poly"] = 3*_lambda_
spice["wire_c_per_um"] = 0 # Temp value
################################################### ###################################################
# Technology Tool Preferences # Technology Tool Preferences