Added power calculations for inverter. Still testing.

This commit is contained in:
Hunter Nichols 2018-02-21 19:51:21 -08:00
parent 179a27b0e3
commit d4a0f48d4f
10 changed files with 101 additions and 46 deletions

View File

@ -122,6 +122,9 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout):
return text
def analytical_power(self, slew, load):
#This function is here return 0 power for every module that does not have a power function defined
#This is a hack and should be made better (also may be a little dangerous)
return 0
""" Get total power of a module """
#print "Getting power for ",self.name," module"
total_module_power = 0
for inst in self.insts:
total_module_power += inst.mod.analytical_power(slew, load)
return total_module_power

View File

@ -214,6 +214,9 @@ class spice(verilog.verilog):
def generate_rc_net(self,lump_num, wire_length, wire_width):
return wire_spice_model(lump_num, wire_length, wire_width)
def return_power(self, dynamic, leakage):
return power_data(dynamic, leakage)
class delay_data:
"""
@ -246,6 +249,37 @@ class delay_data:
assert isinstance(other,delay_data)
return delay_data(other.delay + self.delay,
self.slew)
class power_data:
"""
This is the power class to represent the power information
Dynamic and leakage power are stored as a single object with this class.
"""
def __init__(self, dynamic=0.0, leakage=0.0):
""" init function support two init method"""
# will take single input as a coordinate
self.dynamic = dynamic
self.leakage = leakage
def __str__(self):
""" override print function output """
return "Power Data: Dynamic "+str(self.dynamic)+", Leakage "+str(self.leakage)+" in nW"
def __add__(self, other):
"""
Override - function (left), for power_data: a+b != b+a
"""
assert isinstance(other,power_data)
return delay_data(other.dynamic + self.dynamic,
other.leakage + self.leakage)
def __radd__(self, other):
"""
Override - function (left), for power_data: a+b != b+a
"""
assert isinstance(other,power_data)
return delay_data(other.dynamic + self.dynamic,
other.leakage + self.leakage)
class wire_spice_model:

View File

@ -550,7 +550,9 @@ class delay():
LH_slew.append(bank_delay.slew/1e3)
HL_slew.append(bank_delay.slew/1e3)
power = sram.analytical_power(slew, load)
voltage = 1
temperature = 20
power = sram.analytical_power(voltage, temperature, load)
data = {"min_period": 0,
"delay1": LH_delay,

View File

@ -1229,22 +1229,22 @@ class bank(design.design):
+ bitcell_array_delay + bl_t_data_out_delay + data_t_DATA_delay
return result
def analytical_power(self, slew, load):
""" return analytical power of the bank. Basic skeleton code"""
msf_addr_power = self.msf_address.analytical_power(slew, self.decoder.input_load())
msf_data_in_power = self.msf_data_in.analytical_power(slew, self.decoder.input_load())
# def analytical_power(self, slew, load):
# """ return analytical power of the bank. Basic skeleton code"""
# msf_addr_power = self.msf_address.analytical_power(slew, self.decoder.input_load())
# msf_data_in_power = self.msf_data_in.analytical_power(slew, self.decoder.input_load())
decoder_power = self.decoder.analytical_power(slew, load)
# decoder_power = self.decoder.analytical_power(slew, load)
word_driver_power = self.wordline_driver.analytical_power(slew, self.bitcell_array.input_load())
# word_driver_power = self.wordline_driver.analytical_power(slew, self.bitcell_array.input_load())
bitcell_array_power = self.bitcell_array.analytical_power(slew)
# bitcell_array_power = self.bitcell_array.analytical_power(slew)
bl_t_data_out_power = self.sense_amp_array.analytical_power(slew,
self.bitcell_array.output_load())
# bl_t_data_out_power = self.sense_amp_array.analytical_power(slew,
# self.bitcell_array.output_load())
data_t_DATA_power = self.tri_gate_array.analytical_power(slew, load)
# data_t_DATA_power = self.tri_gate_array.analytical_power(slew, load)
total_power = msf_addr_power + msf_data_in_power + decoder_power + word_driver_power \
+ bitcell_array_power + bl_t_data_out_power + data_t_DATA_power
return total_power
# total_power = msf_addr_power + msf_data_in_power + decoder_power + word_driver_power \
# + bitcell_array_power + bl_t_data_out_power + data_t_DATA_power
# return total_power

View File

@ -688,8 +688,10 @@ class control_logic(design.design):
width=pin.width())
def analytical_power(self, slew, load):
def analytical_power(self, vdd, temp, load):
#This has yet to be fully determined.
msf_power = self.msf_control.analytical_power(slew, load)
print "Instances:"
for inst in self.insts:
print inst.name," Instance"
#currently, only return flop array power
return msf_power
return 0

View File

@ -242,6 +242,18 @@ class pinv(pgate.pgate):
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)
def analytical_power(self, slew, load=0.0):
def analytical_power(self, vdd, temp, load):
#Adding a magic number until I can properly define this.
return 3
c_eff = self.calculate_effective_capacitance(load)
f = spice["default_event_rate"]
power_dyn = c_eff*vdd*vdd*f
power_leak = spice["inv_leakage"]
total_power = self.return_power(power_dyn, power_leak)
return total_power
def calculate_effective_capacitance(self, load):
c_load = load
c_para = spice["min_tx_drain_c"]*(self.nmos_size/parameter["min_tx_size"])#ff
transistion_prob = spice["inv_transisition_prob"]
return transistion_prob*(c_load + c_para)

View File

@ -1015,34 +1015,29 @@ class sram(design.design):
""" LH and HL are the same in analytical model. """
return self.bank.analytical_delay(slew,load)
def analytical_power(self,slew,load):
def analytical_power(self, vdd, temp, load):
""" Just a test function for the power."""
power_sum = 0;
print "Module Powers"
for mod in self.mods:
#print mod.name," Power: ", mod.analytical_power(slew, load)
power_sum += mod.analytical_power(slew, load)
# for mod in self.mods:
# print mod.name," Power: ", mod.analytical_power(slew, load)
# power_sum += mod.analytical_power(slew, load)
print "Instances:"
for inst in self.insts:
print inst.name," Instance"
print "Modules from Instances:"
for inst in self.insts:
print inst.mod.name," Module"
# print "Instances:"
# for inst in self.insts:
# print inst.name," Instance"
print "Instances from Modules of Instances:"
for inst in self.insts:
print inst.mod.name," Module"
for mod_inst in inst.mod.insts:
print mod_inst.name," Instance"
#There is only one instance of the bank module in the mod list so this is too account for the other banks
bank_power = self.bank.analytical_power(slew,load)
# print "Instances from Modules of Instances:"
# for inst in self.insts:
# print inst.mod.name," Module"
# for mod_inst in inst.mod.insts:
# print mod_inst.name," Instance"
return bank_power
power_sum = self.control_logic.analytical_power(vdd, temp, load)
return power_sum
def save_output(self):
""" Save all the output files while reporting time to do it as well. """

View File

@ -92,10 +92,10 @@ cell (sram_2_16_1_freepdk45){
internal_power(){
when : "OEb & !clk";
rise_power(scalar){
values("292");
values("0");
}
fall_power(scalar){
values("292");
values("0");
}
}
timing(){
@ -129,10 +129,10 @@ cell (sram_2_16_1_freepdk45){
internal_power(){
when : "!OEb & !clk";
rise_power(scalar){
values("292");
values("0");
}
fall_power(scalar){
values("292");
values("0");
}
}
timing(){

View File

@ -275,6 +275,13 @@ spice["msflop_delay"] = 20.5 # DFF Clk-to-q delay in ps
spice["msflop_slew"] = 13.1 # DFF output slew in ps w/ no load
spice["msflop_in_cap"] = 0.2091 # Input capacitance of ms_flop (Din) [Femto-farad]
# analytical power parameters
spice["bitcell_leakage"] = 1 # Leakage power of a single bitcell in nano-Watts
spice["inv_leakage"] = 1 # Leakage power of inverter, temporary until a way to calculate is determined, in nW
spice["msflop_power"] = 1 # Total power of a single flop in nano-Watts
spice["default_event_rate"] = 200 # Default event activity of every gate. Temporary value. In Mega-Hz
spice["inv_transisition_prob"] = .5 # Transition probability of inverter. Will be dynamically calculated later.
###################################################
##END Spice Simulation Parameters