mirror of https://github.com/VLSIDA/OpenRAM.git
Added linear corner factors in analytical delay model.
This commit is contained in:
parent
816669b9ca
commit
0e96648211
|
|
@ -2,6 +2,7 @@ import debug
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import math
|
import math
|
||||||
|
import tech
|
||||||
|
|
||||||
class spice():
|
class spice():
|
||||||
"""
|
"""
|
||||||
|
|
@ -218,7 +219,7 @@ class spice():
|
||||||
del usedMODS
|
del usedMODS
|
||||||
spfile.close()
|
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"""
|
"""Inform users undefined delay module while building new modules"""
|
||||||
debug.warning("Design Class {0} delay function needs to be defined"
|
debug.warning("Design Class {0} delay function needs to be defined"
|
||||||
.format(self.__class__.__name__))
|
.format(self.__class__.__name__))
|
||||||
|
|
@ -228,15 +229,21 @@ class spice():
|
||||||
# return 0 to keep code running while building
|
# return 0 to keep code running while building
|
||||||
return delay_data(0.0, 0.0)
|
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
|
Calculate the delay of a mosfet by
|
||||||
modeling it as a resistance driving a capacitance
|
modeling it as a resistance driving a capacitance
|
||||||
"""
|
"""
|
||||||
swing_factor = abs(math.log(1-swing)) # time constant based on swing
|
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 = 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
|
delay = delay * 0.001 #make the unit to ps
|
||||||
|
|
||||||
# Output slew should be linear to input slew which is described
|
# Output slew should be linear to input slew which is described
|
||||||
# as 0.005* slew.
|
# as 0.005* slew.
|
||||||
|
|
||||||
|
|
@ -247,6 +254,36 @@ class spice():
|
||||||
slew = delay * 0.6 * 2 + 0.005 * slew
|
slew = delay * 0.6 * 2 + 0.005 * slew
|
||||||
return delay_data(delay = delay, slew = 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):
|
def return_delay(self, delay, slew):
|
||||||
return delay_data(delay, slew)
|
return delay_data(delay, slew)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class bitcell(design.design):
|
||||||
self.height = bitcell.height
|
self.height = bitcell.height
|
||||||
self.pin_map = bitcell.pin_map
|
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)
|
# delay of bit cell is not like a driver(from WL)
|
||||||
# so the slew used should be 0
|
# so the slew used should be 0
|
||||||
# it should not be slew dependent?
|
# it should not be slew dependent?
|
||||||
|
|
@ -33,7 +33,7 @@ class bitcell(design.design):
|
||||||
from tech import spice
|
from tech import spice
|
||||||
r = spice["min_tx_r"]*3
|
r = spice["min_tx_r"]*3
|
||||||
c_para = spice["min_tx_drain_c"]
|
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
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class bitcell_1rw_1r(design.design):
|
||||||
self.height = bitcell_1rw_1r.height
|
self.height = bitcell_1rw_1r.height
|
||||||
self.pin_map = bitcell_1rw_1r.pin_map
|
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)
|
# delay of bit cell is not like a driver(from WL)
|
||||||
# so the slew used should be 0
|
# so the slew used should be 0
|
||||||
# it should not be slew dependent?
|
# it should not be slew dependent?
|
||||||
|
|
@ -33,7 +33,7 @@ class bitcell_1rw_1r(design.design):
|
||||||
from tech import spice
|
from tech import spice
|
||||||
r = spice["min_tx_r"]*3
|
r = spice["min_tx_r"]*3
|
||||||
c_para = spice["min_tx_drain_c"]
|
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
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class bitcell_1w_1r(design.design):
|
||||||
self.height = bitcell_1w_1r.height
|
self.height = bitcell_1w_1r.height
|
||||||
self.pin_map = bitcell_1w_1r.pin_map
|
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)
|
# delay of bit cell is not like a driver(from WL)
|
||||||
# so the slew used should be 0
|
# so the slew used should be 0
|
||||||
# it should not be slew dependent?
|
# it should not be slew dependent?
|
||||||
|
|
@ -33,7 +33,7 @@ class bitcell_1w_1r(design.design):
|
||||||
from tech import spice
|
from tech import spice
|
||||||
r = spice["min_tx_r"]*3
|
r = spice["min_tx_r"]*3
|
||||||
c_para = spice["min_tx_drain_c"]
|
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
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -866,12 +866,12 @@ class pbitcell(design.design):
|
||||||
vdd_pos = self.inverter_pmos_right.get_pin("D").center()
|
vdd_pos = self.inverter_pmos_right.get_pin("D").center()
|
||||||
self.add_path("metal1", [Q_bar_pos, vdd_pos])
|
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
|
#FIXME: Delay copied exactly over from bitcell
|
||||||
from tech import spice
|
from tech import spice
|
||||||
r = spice["min_tx_r"]*3
|
r = spice["min_tx_r"]*3
|
||||||
c_para = spice["min_tx_drain_c"]
|
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
|
return result
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, proc, vdd, temp, load):
|
||||||
|
|
|
||||||
|
|
@ -907,7 +907,7 @@ class delay(simulation):
|
||||||
for slew in slews:
|
for slew in slews:
|
||||||
for load in loads:
|
for load in loads:
|
||||||
self.set_load_slew(load,slew)
|
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 port in self.all_ports:
|
||||||
for mname in self.delay_meas_names+self.power_meas_names:
|
for mname in self.delay_meas_names+self.power_meas_names:
|
||||||
if "power" in mname:
|
if "power" in mname:
|
||||||
|
|
@ -921,8 +921,9 @@ class delay(simulation):
|
||||||
period_margin = 0.1
|
period_margin = 0.1
|
||||||
risefall_delay = bank_delay[self.read_ports[0]].delay/1e3
|
risefall_delay = bank_delay[self.read_ports[0]].delay/1e3
|
||||||
sram_data = { "min_period":risefall_delay*2*period_margin,
|
sram_data = { "min_period":risefall_delay*2*period_margin,
|
||||||
"leakage_power": power.leakage}
|
"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)
|
return (sram_data,port_data)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1216,26 +1216,30 @@ class bank(design.design):
|
||||||
rotate=90)
|
rotate=90)
|
||||||
|
|
||||||
|
|
||||||
def analytical_delay(self, vdd, slew, load):
|
def analytical_delay(self, corner, slew, load):
|
||||||
""" return analytical delay of the bank"""
|
""" return analytical delay of the bank"""
|
||||||
results = []
|
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.
|
#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
|
#This also essentially creates the same delay for each port. Good structure, no substance
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
if self.words_per_row > 1:
|
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,
|
||||||
self.sense_amp_array.input_load())
|
bitcell_array_delay.slew,
|
||||||
|
self.sense_amp_array.input_load())
|
||||||
else:
|
else:
|
||||||
column_mux_delay = self.return_delay(delay = 0.0, slew=word_driver_delay.slew)
|
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())
|
self.bitcell_array.output_load())
|
||||||
# output load of bitcell_array is set to be only small part of bl for sense amp.
|
# 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)
|
results.append(decoder_delay + word_driver_delay + bitcell_array_delay + column_mux_delay + bl_t_data_out_delay)
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ class bitcell_array(design.design):
|
||||||
self.add_power_pin(pin_name, pin.center(), 0, pin.layer)
|
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
|
from tech import drc
|
||||||
wl_wire = self.gen_wl_wire()
|
wl_wire = self.gen_wl_wire()
|
||||||
wl_wire.return_delay_over_wire(slew)
|
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
|
cell_load = 2 * bl_wire.return_input_cap() # we ingore the wire r
|
||||||
# hence just use the whole c
|
# hence just use the whole c
|
||||||
bl_swing = 0.1
|
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
|
#we do not consider the delay over the wire for now
|
||||||
return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay,
|
return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay,
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class dff(design.design):
|
||||||
transition_prob = spice["flop_transition_prob"]
|
transition_prob = spice["flop_transition_prob"]
|
||||||
return transition_prob*(c_load + c_para)
|
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
|
# dont know how to calculate this now, use constant in tech file
|
||||||
result = self.return_delay(spice["dff_delay"], spice["dff_slew"])
|
result = self.return_delay(spice["dff_delay"], spice["dff_slew"])
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,8 @@ class dff_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)
|
return self.dff.analytical_delay(corner, slew=slew, load=load)
|
||||||
|
|
||||||
def get_clk_cin(self):
|
def get_clk_cin(self):
|
||||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
||||||
|
|
|
||||||
|
|
@ -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 """
|
""" Calculate the analytical delay of DFF-> INV -> INV """
|
||||||
dff_delay=self.dff.analytical_delay(slew=slew, load=self.inv1.input_load())
|
dff_delay=self.dff.analytical_delay(corner, slew=slew, load=self.inv1.input_load())
|
||||||
inv1_delay = self.inv1.analytical_delay(slew=dff_delay.slew, load=self.inv2.input_load())
|
inv1_delay = self.inv1.analytical_delay(corner, slew=dff_delay.slew, load=self.inv2.input_load())
|
||||||
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
|
inv2_delay = self.inv2.analytical_delay(corner, slew=inv1_delay.slew, load=load)
|
||||||
return dff_delay + inv1_delay + inv2_delay
|
return dff_delay + inv1_delay + inv2_delay
|
||||||
|
|
||||||
def get_clk_cin(self):
|
def get_clk_cin(self):
|
||||||
|
|
|
||||||
|
|
@ -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)
|
return self.dff.analytical_delay(slew=slew, load=load)
|
||||||
|
|
||||||
def get_clk_cin(self):
|
def get_clk_cin(self):
|
||||||
|
|
|
||||||
|
|
@ -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 """
|
""" Calculate the analytical delay of DFF-> INV -> INV """
|
||||||
dff_delay=self.dff.analytical_delay(slew=slew, load=self.inv1.input_load())
|
dff_delay=self.dff.analytical_delay(corner, slew=slew, load=self.inv1.input_load())
|
||||||
inv1_delay = self.inv1.analytical_delay(slew=dff_delay.slew, load=load)
|
inv1_delay = self.inv1.analytical_delay(corner, slew=dff_delay.slew, load=load)
|
||||||
return dff_delay + inv1_delay
|
return dff_delay + inv1_delay
|
||||||
|
|
||||||
def get_clk_cin(self):
|
def get_clk_cin(self):
|
||||||
|
|
|
||||||
|
|
@ -185,8 +185,8 @@ class dff_inv_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)
|
return self.dff.analytical_delay(corner, slew=slew, load=load)
|
||||||
|
|
||||||
def get_clk_cin(self):
|
def get_clk_cin(self):
|
||||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
||||||
|
|
|
||||||
|
|
@ -594,7 +594,7 @@ class hierarchical_decoder(design.design):
|
||||||
rotate=90)
|
rotate=90)
|
||||||
|
|
||||||
|
|
||||||
def analytical_delay(self, slew, load = 0.0):
|
def analytical_delay(self, corner, slew, load = 0.0):
|
||||||
# A -> out
|
# A -> out
|
||||||
if self.determine_predecodes(self.num_inputs)[1]==0:
|
if self.determine_predecodes(self.num_inputs)[1]==0:
|
||||||
pre = self.pre2_4
|
pre = self.pre2_4
|
||||||
|
|
@ -602,15 +602,15 @@ class hierarchical_decoder(design.design):
|
||||||
else:
|
else:
|
||||||
pre = self.pre3_8
|
pre = self.pre3_8
|
||||||
nand = self.nand3
|
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 -> 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())
|
load = self.inv.input_load())
|
||||||
result = a_t_out_delay + out_t_z_delay
|
result = a_t_out_delay + out_t_z_delay
|
||||||
|
|
||||||
# Z -> decode_out
|
# 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
|
result = result + z_t_decodeout_delay
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,15 +51,15 @@ class hierarchical_predecode2x4(hierarchical_predecode):
|
||||||
return combination
|
return combination
|
||||||
|
|
||||||
|
|
||||||
def analytical_delay(self, slew, load = 0.0 ):
|
def analytical_delay(self, corner, slew, load = 0.0 ):
|
||||||
# in -> inbar
|
# 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
|
# 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
|
# 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
|
return a_t_b_delay + b_t_z_delay + a_t_out_delay
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,15 +60,15 @@ class hierarchical_predecode3x8(hierarchical_predecode):
|
||||||
return combination
|
return combination
|
||||||
|
|
||||||
|
|
||||||
def analytical_delay(self, slew, load = 0.0 ):
|
def analytical_delay(self, corner, slew, load = 0.0 ):
|
||||||
# A -> Abar
|
# 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
|
# 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
|
# 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
|
return a_t_b_delay + b_t_z_delay + a_t_out_delay
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -816,19 +816,19 @@ class multibank(design.design):
|
||||||
offset=in_pin + self.m2m3_via_offset,
|
offset=in_pin + self.m2m3_via_offset,
|
||||||
rotate=90)
|
rotate=90)
|
||||||
|
|
||||||
def analytical_delay(self, slew, load):
|
def analytical_delay(self, corner, slew, load):
|
||||||
""" return analytical delay of the bank"""
|
""" 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())
|
self.bitcell_array.output_load())
|
||||||
# output load of bitcell_array is set to be only small part of bl for sense amp.
|
# 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
|
result = decoder_delay + word_driver_delay + bitcell_array_delay + bl_t_data_out_delay + data_t_DATA_delay
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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
|
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
|
from tech import spice
|
||||||
r = spice["min_tx_r"]/(10)
|
r = spice["min_tx_r"]/(10)
|
||||||
c_para = spice["min_tx_drain_c"]
|
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)
|
return self.return_delay(result.delay, result.slew)
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, proc, vdd, temp, load):
|
||||||
|
|
|
||||||
|
|
@ -136,8 +136,8 @@ class sense_amp_array(design.design):
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return self.amp.input_load()
|
return self.amp.input_load()
|
||||||
|
|
||||||
def analytical_delay(self, slew, load=0.0):
|
def analytical_delay(self, corner, slew, load=0.0):
|
||||||
return self.amp.analytical_delay(slew=slew, load=load)
|
return self.amp.analytical_delay(corner, slew=slew, load=load)
|
||||||
|
|
||||||
def get_en_cin(self):
|
def get_en_cin(self):
|
||||||
"""Get the relative capacitance of all the sense amp enable connections in the array"""
|
"""Get the relative capacitance of all the sense amp enable connections in the array"""
|
||||||
|
|
|
||||||
|
|
@ -216,13 +216,14 @@ class single_level_column_mux_array(design.design):
|
||||||
offset= br_out_offset,
|
offset= br_out_offset,
|
||||||
rotate=90)
|
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
|
from tech import spice, parameter
|
||||||
|
proc,volt,temp = corner
|
||||||
r = spice["min_tx_r"]/(self.mux.ptx_width/parameter["min_tx_size"])
|
r = spice["min_tx_r"]/(self.mux.ptx_width/parameter["min_tx_size"])
|
||||||
#Drains of mux transistors make up capacitance.
|
#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
|
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)
|
return self.return_delay(result.delay, result.slew)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@ class tri_gate(design.design):
|
||||||
self.height = tri_gate.height
|
self.height = tri_gate.height
|
||||||
self.pin_map = tri_gate.pin_map
|
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
|
from tech import spice
|
||||||
r = spice["min_tx_r"]
|
r = spice["min_tx_r"]
|
||||||
c_para = spice["min_tx_drain_c"]
|
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):
|
def analytical_power(self, proc, vdd, temp, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,6 @@ class tri_gate_array(design.design):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def analytical_delay(self, slew, load=0.0):
|
def analytical_delay(self, corner, slew, load=0.0):
|
||||||
return self.tri.analytical_delay(slew = slew, load = load)
|
return self.tri.analytical_delay(corner, slew = slew, load = load)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -210,12 +210,12 @@ class wordline_driver(design.design):
|
||||||
end=wl_offset-vector(self.m1_width,0))
|
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 -> 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 -> 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
|
return decode_t_net + net_t_wl
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 """
|
""" Calculate the analytical delay of DFF-> INV -> INV """
|
||||||
nand_delay = selfnand.analytical_delay(slew=slew, load=self.inv.input_load())
|
nand_delay = self.nand.analytical_delay(corner, slew=slew, load=self.inv.input_load())
|
||||||
inv_delay = self.inv.analytical_delay(slew=nand_delay.slew, load=load)
|
inv_delay = self.inv.analytical_delay(corner, slew=nand_delay.slew, load=load)
|
||||||
return nand_delay + inv_delay
|
return nand_delay + inv_delay
|
||||||
|
|
||||||
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||||
|
|
|
||||||
|
|
@ -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 """
|
""" Calculate the analytical delay of DFF-> INV -> INV """
|
||||||
inv1_delay = self.inv1.analytical_delay(slew=slew, load=self.inv2.input_load())
|
inv1_delay = self.inv1.analytical_delay(corner, slew=slew, load=self.inv2.input_load())
|
||||||
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
|
inv2_delay = self.inv2.analytical_delay(corner, slew=inv1_delay.slew, load=load)
|
||||||
return inv1_delay + inv2_delay
|
return inv1_delay + inv2_delay
|
||||||
|
|
||||||
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ class pdriver(pgate.pgate):
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return self.inv_list[0].input_load()
|
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"""
|
"""Calculate the analytical delay of INV1 -> ... -> INVn"""
|
||||||
|
|
||||||
cout_list = []
|
cout_list = []
|
||||||
|
|
@ -184,7 +184,7 @@ class pdriver(pgate.pgate):
|
||||||
|
|
||||||
delays = []
|
delays = []
|
||||||
for inv,cout in zip(self.inv_list,cout_list):
|
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
|
input_slew = delays[-1].slew
|
||||||
|
|
||||||
delay = delays[0]
|
delay = delays[0]
|
||||||
|
|
|
||||||
|
|
@ -261,10 +261,10 @@ class pinv(pgate.pgate):
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return ((self.nmos_size+self.pmos_size)/parameter["min_tx_size"])*spice["min_tx_gate_c"]
|
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"])
|
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
|
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):
|
def analytical_power(self, proc, vdd, temp, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
|
|
|
||||||
|
|
@ -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 """
|
""" Calculate the analytical delay of DFF-> INV -> INV """
|
||||||
inv1_delay = self.inv1.analytical_delay(slew=slew, load=self.inv2.input_load())
|
inv1_delay = self.inv1.analytical_delay(corner, slew=slew, load=self.inv2.input_load())
|
||||||
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
|
inv2_delay = self.inv2.analytical_delay(corner, slew=inv1_delay.slew, load=load)
|
||||||
return inv1_delay + inv2_delay
|
return inv1_delay + inv2_delay
|
||||||
|
|
||||||
def determine_clk_buf_stage_efforts(self, external_cout, inp_is_rise=False):
|
def determine_clk_buf_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||||
|
|
|
||||||
|
|
@ -227,10 +227,10 @@ class pnand2(pgate.pgate):
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return ((self.nmos_size+self.pmos_size)/parameter["min_tx_size"])*spice["min_tx_gate_c"]
|
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"])
|
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
|
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):
|
def analytical_power(self, proc, vdd, temp, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
|
|
|
||||||
|
|
@ -240,10 +240,10 @@ class pnand3(pgate.pgate):
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return ((self.nmos_size+self.pmos_size)/parameter["min_tx_size"])*spice["min_tx_gate_c"]
|
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"])
|
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
|
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):
|
def analytical_power(self, proc, vdd, temp, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
|
|
|
||||||
|
|
@ -212,10 +212,10 @@ class pnor2(pgate.pgate):
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return ((self.nmos_size+self.pmos_size)/parameter["min_tx_size"])*spice["min_tx_gate_c"]
|
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"])
|
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
|
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):
|
def analytical_power(self, proc, vdd, temp, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
|
|
|
||||||
|
|
@ -499,9 +499,9 @@ class sram_base(design, verilog, lef):
|
||||||
sp.close()
|
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. """
|
""" 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):
|
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"""
|
"""Get the all the stage efforts for each stage in the path from clk_buf to a wordline"""
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,8 @@ spice["channel"] = drc["minlength_channel"]
|
||||||
spice["clk"] = "clk"
|
spice["clk"] = "clk"
|
||||||
|
|
||||||
# analytical delay parameters
|
# 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["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_r"] = 0.075 # Unit wire resistance in ohms/square
|
||||||
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2
|
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,8 @@ spice["clk"] = "clk"
|
||||||
|
|
||||||
# analytical delay parameters
|
# analytical delay parameters
|
||||||
# FIXME: These need to be updated for SCMOS, they are copied from FreePDK45.
|
# 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["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_r"] = 0.075 # Unit wire resistance in ohms/square
|
||||||
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2
|
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2
|
||||||
|
|
|
||||||
|
|
@ -266,6 +266,8 @@ spice["clk"] = "clk"
|
||||||
|
|
||||||
# analytical delay parameters
|
# analytical delay parameters
|
||||||
# FIXME: These need to be updated for SCMOS, they are copied from FreePDK45.
|
# 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["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_r"] = 0.075 # Unit wire resistance in ohms/square
|
||||||
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2
|
spice["wire_unit_c"] = 0.64 # Unit wire capacitance ff/um^2
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue