Added linear corner factors in analytical delay model.

This commit is contained in:
Hunter Nichols 2019-03-04 00:42:18 -08:00
parent 816669b9ca
commit 0e96648211
36 changed files with 138 additions and 89 deletions

View File

@ -2,6 +2,7 @@ import debug
import re
import os
import math
import tech
class spice():
"""
@ -218,7 +219,7 @@ class spice():
del usedMODS
spfile.close()
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
"""Inform users undefined delay module while building new modules"""
debug.warning("Design Class {0} delay function needs to be defined"
.format(self.__class__.__name__))
@ -228,13 +229,19 @@ class spice():
# return 0 to keep code running while building
return delay_data(0.0, 0.0)
def cal_delay_with_rc(self, r, c ,slew, swing = 0.5):
def cal_delay_with_rc(self, corner, r, c ,slew, swing = 0.5):
"""
Calculate the delay of a mosfet by
modeling it as a resistance driving a capacitance
"""
swing_factor = abs(math.log(1-swing)) # time constant based on swing
proc,volt,temp = corner
#FIXME: type of delay is needed to know which process to use.
proc_mult = max(self.get_process_delay_factor(proc))
volt_mult = self.get_voltage_delay_factor(volt)
temp_mult = self.get_temp_delay_factor(temp)
delay = swing_factor * r * c #c is in ff and delay is in fs
delay = delay * proc_mult * volt_mult * temp_mult
delay = delay * 0.001 #make the unit to ps
# Output slew should be linear to input slew which is described
@ -247,6 +254,36 @@ class spice():
slew = delay * 0.6 * 2 + 0.005 * slew
return delay_data(delay = delay, slew = slew)
def get_process_delay_factor(self, proc):
"""Returns delay increase estimate based off process
Currently does +/-10 for fast/slow corners."""
proc_factors = []
for mos_proc in proc:
if mos_proc == 'T':
proc_factors.append(1.0)
elif mos_proc == 'F':
proc_factors.append(0.9)
elif mos_proc == 'S':
proc_factors.append(1.1)
return proc_factors
def get_voltage_delay_factor(self, voltage):
"""Returns delay increase due to voltage.
Implemented as linear factor based off nominal voltage.
"""
return tech.spice['vdd_nominal']/voltage
def get_temp_delay_factor(self, temp):
"""Returns delay increase due to temperature (in C).
Determines effect on threshold voltage and then linear factor is estimated.
"""
#Some portions of equation condensed (phi_t = k*T/q for T in Kelvin) in mV
#(k/q)/100 = .008625, The division 100 simplifies the conversion from C to K and mV to V
thermal_voltage_nom = .008625*tech.spice["temp_nominal"]
thermal_voltage = .008625*temp
vthresh = (tech.spice["v_threshold_typical"]+2*(thermal_voltage-thermal_voltage_nom))
#Calculate effect on Vdd-Vth. The current vdd is not used here. A separate vdd factor is calculated.
return (tech.spice['vdd_nominal'] - tech.spice["v_threshold_typical"])/(tech.spice['vdd_nominal']-vthresh)
def return_delay(self, delay, slew):
return delay_data(delay, slew)

View File

@ -24,7 +24,7 @@ class bitcell(design.design):
self.height = bitcell.height
self.pin_map = bitcell.pin_map
def analytical_delay(self, slew, load=0, swing = 0.5):
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
# delay of bit cell is not like a driver(from WL)
# so the slew used should be 0
# it should not be slew dependent?
@ -33,7 +33,7 @@ class bitcell(design.design):
from tech import spice
r = spice["min_tx_r"]*3
c_para = spice["min_tx_drain_c"]
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = swing)
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing)
return result

View File

@ -24,7 +24,7 @@ class bitcell_1rw_1r(design.design):
self.height = bitcell_1rw_1r.height
self.pin_map = bitcell_1rw_1r.pin_map
def analytical_delay(self, slew, load=0, swing = 0.5):
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
# delay of bit cell is not like a driver(from WL)
# so the slew used should be 0
# it should not be slew dependent?
@ -33,7 +33,7 @@ class bitcell_1rw_1r(design.design):
from tech import spice
r = spice["min_tx_r"]*3
c_para = spice["min_tx_drain_c"]
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = swing)
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing)
return result

View File

@ -24,7 +24,7 @@ class bitcell_1w_1r(design.design):
self.height = bitcell_1w_1r.height
self.pin_map = bitcell_1w_1r.pin_map
def analytical_delay(self, slew, load=0, swing = 0.5):
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
# delay of bit cell is not like a driver(from WL)
# so the slew used should be 0
# it should not be slew dependent?
@ -33,7 +33,7 @@ class bitcell_1w_1r(design.design):
from tech import spice
r = spice["min_tx_r"]*3
c_para = spice["min_tx_drain_c"]
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = swing)
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing)
return result

View File

@ -866,12 +866,12 @@ class pbitcell(design.design):
vdd_pos = self.inverter_pmos_right.get_pin("D").center()
self.add_path("metal1", [Q_bar_pos, vdd_pos])
def analytical_delay(self, slew, load=0, swing = 0.5):
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
#FIXME: Delay copied exactly over from bitcell
from tech import spice
r = spice["min_tx_r"]*3
c_para = spice["min_tx_drain_c"]
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = swing)
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing)
return result
def analytical_power(self, proc, vdd, temp, load):

View File

@ -907,7 +907,7 @@ class delay(simulation):
for slew in slews:
for load in loads:
self.set_load_slew(load,slew)
bank_delay = self.sram.analytical_delay(self.vdd_voltage, self.slew,self.load)
bank_delay = self.sram.analytical_delay(self.corner, self.slew,self.load)
for port in self.all_ports:
for mname in self.delay_meas_names+self.power_meas_names:
if "power" in mname:
@ -922,7 +922,8 @@ class delay(simulation):
risefall_delay = bank_delay[self.read_ports[0]].delay/1e3
sram_data = { "min_period":risefall_delay*2*period_margin,
"leakage_power": power.leakage}
debug.info(2,"SRAM Data:\n{}".format(sram_data))
debug.info(2,"Port Data:\n{}".format(port_data))
return (sram_data,port_data)

View File

@ -1216,26 +1216,30 @@ class bank(design.design):
rotate=90)
def analytical_delay(self, vdd, slew, load):
def analytical_delay(self, corner, slew, load):
""" return analytical delay of the bank"""
results = []
decoder_delay = self.row_decoder.analytical_delay(slew, self.wordline_driver.input_load())
decoder_delay = self.row_decoder.analytical_delay(corner, slew, self.wordline_driver.input_load())
word_driver_delay = self.wordline_driver.analytical_delay(decoder_delay.slew, self.bitcell_array.input_load())
word_driver_delay = self.wordline_driver.analytical_delay(corner,
decoder_delay.slew,
self.bitcell_array.input_load())
#FIXME: Array delay is the same for every port.
bitcell_array_delay = self.bitcell_array.analytical_delay(word_driver_delay.slew)
bitcell_array_delay = self.bitcell_array.analytical_delay(corner, word_driver_delay.slew)
#This also essentially creates the same delay for each port. Good structure, no substance
for port in self.all_ports:
if self.words_per_row > 1:
column_mux_delay = self.column_mux_array[port].analytical_delay(vdd, bitcell_array_delay.slew,
column_mux_delay = self.column_mux_array[port].analytical_delay(corner,
bitcell_array_delay.slew,
self.sense_amp_array.input_load())
else:
column_mux_delay = self.return_delay(delay = 0.0, slew=word_driver_delay.slew)
bl_t_data_out_delay = self.sense_amp_array.analytical_delay(column_mux_delay.slew,
bl_t_data_out_delay = self.sense_amp_array.analytical_delay(corner,
column_mux_delay.slew,
self.bitcell_array.output_load())
# output load of bitcell_array is set to be only small part of bl for sense amp.
results.append(decoder_delay + word_driver_delay + bitcell_array_delay + column_mux_delay + bl_t_data_out_delay)

View File

@ -130,7 +130,7 @@ class bitcell_array(design.design):
self.add_power_pin(pin_name, pin.center(), 0, pin.layer)
def analytical_delay(self, slew, load=0):
def analytical_delay(self, corner, slew, load=0):
from tech import drc
wl_wire = self.gen_wl_wire()
wl_wire.return_delay_over_wire(slew)
@ -141,7 +141,7 @@ class bitcell_array(design.design):
cell_load = 2 * bl_wire.return_input_cap() # we ingore the wire r
# hence just use the whole c
bl_swing = 0.1
cell_delay = self.cell.analytical_delay(wl_to_cell_delay.slew, cell_load, swing = bl_swing)
cell_delay = self.cell.analytical_delay(corner, wl_to_cell_delay.slew, cell_load, swing = bl_swing)
#we do not consider the delay over the wire for now
return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay,

View File

@ -39,7 +39,7 @@ class dff(design.design):
transition_prob = spice["flop_transition_prob"]
return transition_prob*(c_load + c_para)
def analytical_delay(self, slew, load = 0.0):
def analytical_delay(self, corner, slew, load = 0.0):
# dont know how to calculate this now, use constant in tech file
result = self.return_delay(spice["dff_delay"], spice["dff_slew"])
return result

View File

@ -154,8 +154,8 @@ class dff_array(design.design):
def analytical_delay(self, slew, load=0.0):
return self.dff.analytical_delay(slew=slew, load=load)
def analytical_delay(self, corner, slew, load=0.0):
return self.dff.analytical_delay(corner, slew=slew, load=load)
def get_clk_cin(self):
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""

View File

@ -172,11 +172,11 @@ class dff_buf(design.design):
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
""" Calculate the analytical delay of DFF-> INV -> INV """
dff_delay=self.dff.analytical_delay(slew=slew, load=self.inv1.input_load())
inv1_delay = self.inv1.analytical_delay(slew=dff_delay.slew, load=self.inv2.input_load())
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
dff_delay=self.dff.analytical_delay(corner, slew=slew, load=self.inv1.input_load())
inv1_delay = self.inv1.analytical_delay(corner, slew=dff_delay.slew, load=self.inv2.input_load())
inv2_delay = self.inv2.analytical_delay(corner, slew=inv1_delay.slew, load=load)
return dff_delay + inv1_delay + inv2_delay
def get_clk_cin(self):

View File

@ -187,7 +187,7 @@ class dff_buf_array(design.design):
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
return self.dff.analytical_delay(slew=slew, load=load)
def get_clk_cin(self):

View File

@ -145,10 +145,10 @@ class dff_inv(design.design):
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
""" Calculate the analytical delay of DFF-> INV -> INV """
dff_delay=self.dff.analytical_delay(slew=slew, load=self.inv1.input_load())
inv1_delay = self.inv1.analytical_delay(slew=dff_delay.slew, load=load)
dff_delay=self.dff.analytical_delay(corner, slew=slew, load=self.inv1.input_load())
inv1_delay = self.inv1.analytical_delay(corner, slew=dff_delay.slew, load=load)
return dff_delay + inv1_delay
def get_clk_cin(self):

View File

@ -185,8 +185,8 @@ class dff_inv_array(design.design):
def analytical_delay(self, slew, load=0.0):
return self.dff.analytical_delay(slew=slew, load=load)
def analytical_delay(self, corner, slew, load=0.0):
return self.dff.analytical_delay(corner, slew=slew, load=load)
def get_clk_cin(self):
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""

View File

@ -594,7 +594,7 @@ class hierarchical_decoder(design.design):
rotate=90)
def analytical_delay(self, slew, load = 0.0):
def analytical_delay(self, corner, slew, load = 0.0):
# A -> out
if self.determine_predecodes(self.num_inputs)[1]==0:
pre = self.pre2_4
@ -602,15 +602,15 @@ class hierarchical_decoder(design.design):
else:
pre = self.pre3_8
nand = self.nand3
a_t_out_delay = pre.analytical_delay(slew=slew,load = nand.input_load())
a_t_out_delay = pre.analytical_delay(corner, slew=slew,load = nand.input_load())
# out -> z
out_t_z_delay = nand.analytical_delay(slew= a_t_out_delay.slew,
out_t_z_delay = nand.analytical_delay(corner, slew= a_t_out_delay.slew,
load = self.inv.input_load())
result = a_t_out_delay + out_t_z_delay
# Z -> decode_out
z_t_decodeout_delay = self.inv.analytical_delay(slew = out_t_z_delay.slew , load = load)
z_t_decodeout_delay = self.inv.analytical_delay(corner, slew = out_t_z_delay.slew , load = load)
result = result + z_t_decodeout_delay
return result

View File

@ -51,15 +51,15 @@ class hierarchical_predecode2x4(hierarchical_predecode):
return combination
def analytical_delay(self, slew, load = 0.0 ):
def analytical_delay(self, corner, slew, load = 0.0 ):
# in -> inbar
a_t_b_delay = self.inv.analytical_delay(slew=slew, load=self.nand.input_load())
a_t_b_delay = self.inv.analytical_delay(corner, slew=slew, load=self.nand.input_load())
# inbar -> z
b_t_z_delay = self.nand.analytical_delay(slew=a_t_b_delay.slew, load=self.inv.input_load())
b_t_z_delay = self.nand.analytical_delay(corner, slew=a_t_b_delay.slew, load=self.inv.input_load())
# Z -> out
a_t_out_delay = self.inv.analytical_delay(slew=b_t_z_delay.slew, load=load)
a_t_out_delay = self.inv.analytical_delay(corner, slew=b_t_z_delay.slew, load=load)
return a_t_b_delay + b_t_z_delay + a_t_out_delay

View File

@ -60,15 +60,15 @@ class hierarchical_predecode3x8(hierarchical_predecode):
return combination
def analytical_delay(self, slew, load = 0.0 ):
def analytical_delay(self, corner, slew, load = 0.0 ):
# A -> Abar
a_t_b_delay = self.inv.analytical_delay(slew=slew, load=self.nand.input_load())
a_t_b_delay = self.inv.analytical_delay(corner, slew=slew, load=self.nand.input_load())
# Abar -> z
b_t_z_delay = self.nand.analytical_delay(slew=a_t_b_delay.slew, load=self.inv.input_load())
b_t_z_delay = self.nand.analytical_delay(corner, slew=a_t_b_delay.slew, load=self.inv.input_load())
# Z -> out
a_t_out_delay = self.inv.analytical_delay(slew=b_t_z_delay.slew, load=load)
a_t_out_delay = self.inv.analytical_delay(corner, slew=b_t_z_delay.slew, load=load)
return a_t_b_delay + b_t_z_delay + a_t_out_delay

View File

@ -816,19 +816,19 @@ class multibank(design.design):
offset=in_pin + self.m2m3_via_offset,
rotate=90)
def analytical_delay(self, slew, load):
def analytical_delay(self, corner, slew, load):
""" return analytical delay of the bank"""
decoder_delay = self.row_decoder.analytical_delay(slew, self.wordline_driver.input_load())
decoder_delay = self.row_decoder.analytical_delay(corner, slew, self.wordline_driver.input_load())
word_driver_delay = self.wordline_driver.analytical_delay(decoder_delay.slew, self.bitcell_array.input_load())
word_driver_delay = self.wordline_driver.analytical_delay(corner, decoder_delay.slew, self.bitcell_array.input_load())
bitcell_array_delay = self.bitcell_array.analytical_delay(word_driver_delay.slew)
bitcell_array_delay = self.bitcell_array.analytical_delay(corner, word_driver_delay.slew)
bl_t_data_out_delay = self.sense_amp_array.analytical_delay(bitcell_array_delay.slew,
bl_t_data_out_delay = self.sense_amp_array.analytical_delay(corner, bitcell_array_delay.slew,
self.bitcell_array.output_load())
# output load of bitcell_array is set to be only small part of bl for sense amp.
data_t_DATA_delay = self.tri_gate_array.analytical_delay(bl_t_data_out_delay.slew, load)
data_t_DATA_delay = self.tri_gate_array.analytical_delay(corner, bl_t_data_out_delay.slew, load)
result = decoder_delay + word_driver_delay + bitcell_array_delay + bl_t_data_out_delay + data_t_DATA_delay
return result

View File

@ -31,11 +31,11 @@ class sense_amp(design.design):
bitline_pmos_size = 8 #FIXME: This should be set somewhere and referenced. Probably in tech file.
return spice["min_tx_drain_c"]*(bitline_pmos_size/parameter["min_tx_size"])#ff
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
from tech import spice
r = spice["min_tx_r"]/(10)
c_para = spice["min_tx_drain_c"]
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
return self.return_delay(result.delay, result.slew)
def analytical_power(self, proc, vdd, temp, load):

View File

@ -136,8 +136,8 @@ class sense_amp_array(design.design):
def input_load(self):
return self.amp.input_load()
def analytical_delay(self, slew, load=0.0):
return self.amp.analytical_delay(slew=slew, load=load)
def analytical_delay(self, corner, slew, load=0.0):
return self.amp.analytical_delay(corner, slew=slew, load=load)
def get_en_cin(self):
"""Get the relative capacitance of all the sense amp enable connections in the array"""

View File

@ -216,13 +216,14 @@ class single_level_column_mux_array(design.design):
offset= br_out_offset,
rotate=90)
def analytical_delay(self, vdd, slew, load=0.0):
def analytical_delay(self, corner, vdd, slew, load=0.0):
from tech import spice, parameter
proc,volt,temp = corner
r = spice["min_tx_r"]/(self.mux.ptx_width/parameter["min_tx_size"])
#Drains of mux transistors make up capacitance.
c_para = spice["min_tx_drain_c"]*(self.mux.ptx_width/parameter["min_tx_size"])*self.words_per_row#ff
volt_swing = spice["v_threshold_typical"]/vdd
volt_swing = spice["v_threshold_typical"]/volt
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = volt_swing)
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = volt_swing)
return self.return_delay(result.delay, result.slew)

View File

@ -27,11 +27,11 @@ class tri_gate(design.design):
self.height = tri_gate.height
self.pin_map = tri_gate.pin_map
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
from tech import spice
r = spice["min_tx_r"]
c_para = spice["min_tx_drain_c"]
return self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
def analytical_power(self, proc, vdd, temp, load):
"""Returns dynamic and leakage power. Results in nW"""

View File

@ -116,6 +116,6 @@ class tri_gate_array(design.design):
def analytical_delay(self, slew, load=0.0):
return self.tri.analytical_delay(slew = slew, load = load)
def analytical_delay(self, corner, slew, load=0.0):
return self.tri.analytical_delay(corner, slew = slew, load = load)

View File

@ -210,12 +210,12 @@ class wordline_driver(design.design):
end=wl_offset-vector(self.m1_width,0))
def analytical_delay(self, slew, load=0):
def analytical_delay(self, corner, slew, load=0):
# decode -> net
decode_t_net = self.nand2.analytical_delay(slew, self.inv.input_load())
decode_t_net = self.nand2.analytical_delay(corner, slew, self.inv.input_load())
# net -> wl
net_t_wl = self.inv.analytical_delay(decode_t_net.slew, load)
net_t_wl = self.inv.analytical_delay(corner, decode_t_net.slew, load)
return decode_t_net + net_t_wl

View File

@ -107,10 +107,10 @@ class pand2(pgate.pgate):
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
""" Calculate the analytical delay of DFF-> INV -> INV """
nand_delay = selfnand.analytical_delay(slew=slew, load=self.inv.input_load())
inv_delay = self.inv.analytical_delay(slew=nand_delay.slew, load=load)
nand_delay = self.nand.analytical_delay(corner, slew=slew, load=self.inv.input_load())
inv_delay = self.inv.analytical_delay(corner, slew=nand_delay.slew, load=load)
return nand_delay + inv_delay
def get_stage_efforts(self, external_cout, inp_is_rise=False):

View File

@ -110,10 +110,10 @@ class pbuf(pgate.pgate):
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
""" Calculate the analytical delay of DFF-> INV -> INV """
inv1_delay = self.inv1.analytical_delay(slew=slew, load=self.inv2.input_load())
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
inv1_delay = self.inv1.analytical_delay(corner, slew=slew, load=self.inv2.input_load())
inv2_delay = self.inv2.analytical_delay(corner, slew=inv1_delay.slew, load=load)
return inv1_delay + inv2_delay
def get_stage_efforts(self, external_cout, inp_is_rise=False):

View File

@ -172,7 +172,7 @@ class pdriver(pgate.pgate):
def input_load(self):
return self.inv_list[0].input_load()
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
"""Calculate the analytical delay of INV1 -> ... -> INVn"""
cout_list = []
@ -184,7 +184,7 @@ class pdriver(pgate.pgate):
delays = []
for inv,cout in zip(self.inv_list,cout_list):
delays.append(inv.analytical_delay(slew=input_slew, load=cout))
delays.append(inv.analytical_delay(corner, slew=input_slew, load=cout))
input_slew = delays[-1].slew
delay = delays[0]

View File

@ -261,10 +261,10 @@ class pinv(pgate.pgate):
def input_load(self):
return ((self.nmos_size+self.pmos_size)/parameter["min_tx_size"])*spice["min_tx_gate_c"]
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
c_para = spice["min_tx_drain_c"]*(self.nmos_size/parameter["min_tx_size"])#ff
return self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
def analytical_power(self, proc, vdd, temp, load):
"""Returns dynamic and leakage power. Results in nW"""

View File

@ -177,10 +177,10 @@ class pinvbuf(design.design):
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
""" Calculate the analytical delay of DFF-> INV -> INV """
inv1_delay = self.inv1.analytical_delay(slew=slew, load=self.inv2.input_load())
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
inv1_delay = self.inv1.analytical_delay(corner, slew=slew, load=self.inv2.input_load())
inv2_delay = self.inv2.analytical_delay(corner, slew=inv1_delay.slew, load=load)
return inv1_delay + inv2_delay
def determine_clk_buf_stage_efforts(self, external_cout, inp_is_rise=False):

View File

@ -227,10 +227,10 @@ class pnand2(pgate.pgate):
def input_load(self):
return ((self.nmos_size+self.pmos_size)/parameter["min_tx_size"])*spice["min_tx_gate_c"]
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
c_para = spice["min_tx_drain_c"]*(self.nmos_size/parameter["min_tx_size"])#ff
return self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
def analytical_power(self, proc, vdd, temp, load):
"""Returns dynamic and leakage power. Results in nW"""

View File

@ -240,10 +240,10 @@ class pnand3(pgate.pgate):
def input_load(self):
return ((self.nmos_size+self.pmos_size)/parameter["min_tx_size"])*spice["min_tx_gate_c"]
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
c_para = spice["min_tx_drain_c"]*(self.nmos_size/parameter["min_tx_size"])#ff
return self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
def analytical_power(self, proc, vdd, temp, load):
"""Returns dynamic and leakage power. Results in nW"""

View File

@ -212,10 +212,10 @@ class pnor2(pgate.pgate):
def input_load(self):
return ((self.nmos_size+self.pmos_size)/parameter["min_tx_size"])*spice["min_tx_gate_c"]
def analytical_delay(self, slew, load=0.0):
def analytical_delay(self, corner, slew, load=0.0):
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
c_para = spice["min_tx_drain_c"]*(self.nmos_size/parameter["min_tx_size"])#ff
return self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
def analytical_power(self, proc, vdd, temp, load):
"""Returns dynamic and leakage power. Results in nW"""

View File

@ -499,9 +499,9 @@ class sram_base(design, verilog, lef):
sp.close()
def analytical_delay(self, vdd, slew,load):
def analytical_delay(self, corner, slew,load):
""" LH and HL are the same in analytical model. """
return self.bank.analytical_delay(vdd,slew,load)
return self.bank.analytical_delay(corner,slew,load)
def determine_wordline_stage_efforts(self, inp_is_rise=True):
"""Get the all the stage efforts for each stage in the path from clk_buf to a wordline"""

View File

@ -300,6 +300,8 @@ spice["channel"] = drc["minlength_channel"]
spice["clk"] = "clk"
# analytical delay parameters
spice["vdd_nominal"] = 1.0 # Typical Threshold voltage in Volts
spice["temp_nominal"] = 25.0 # Typical Threshold voltage in Volts
spice["v_threshold_typical"] = 0.4 # Typical Threshold voltage in Volts
spice["wire_unit_r"] = 0.075 # Unit wire resistance in ohms/square
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2

View File

@ -240,6 +240,8 @@ spice["clk"] = "clk"
# analytical delay parameters
# FIXME: These need to be updated for SCMOS, they are copied from FreePDK45.
spice["vdd_nominal"] = 5.0 # Typical Threshold voltage in Volts
spice["temp_nominal"] = 25.0 # Typical Threshold voltage in Volts
spice["v_threshold_typical"] = 1.3 # Typical Threshold voltage in Volts
spice["wire_unit_r"] = 0.075 # Unit wire resistance in ohms/square
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2

View File

@ -266,6 +266,8 @@ spice["clk"] = "clk"
# analytical delay parameters
# FIXME: These need to be updated for SCMOS, they are copied from FreePDK45.
spice["vdd_nominal"] = 5.0 # Typical Threshold voltage in Volts
spice["temp_nominal"] = 25.0 # Typical Threshold voltage in Volts
spice["v_threshold_typical"] = 1.3 # Typical Threshold voltage in Volts
spice["wire_unit_r"] = 0.075 # Unit wire resistance in ohms/square
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2