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 return text
def analytical_power(self, slew, load): def analytical_power(self, slew, load):
#This function is here return 0 power for every module that does not have a power function defined """ Get total power of a module """
#This is a hack and should be made better (also may be a little dangerous) #print "Getting power for ",self.name," module"
return 0 total_module_power = 0
for inst in self.insts:
total_module_power += inst.mod.analytical_power(slew, load)
return total_module_power

View File

@ -215,6 +215,9 @@ class spice(verilog.verilog):
def generate_rc_net(self,lump_num, wire_length, wire_width): def generate_rc_net(self,lump_num, wire_length, wire_width):
return wire_spice_model(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: class delay_data:
""" """
This is the delay class to represent the delay information This is the delay class to represent the delay information
@ -247,6 +250,37 @@ class delay_data:
return delay_data(other.delay + self.delay, return delay_data(other.delay + self.delay,
self.slew) 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: class wire_spice_model:
""" """

View File

@ -550,7 +550,9 @@ class delay():
LH_slew.append(bank_delay.slew/1e3) LH_slew.append(bank_delay.slew/1e3)
HL_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, data = {"min_period": 0,
"delay1": LH_delay, "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 + bitcell_array_delay + bl_t_data_out_delay + data_t_DATA_delay
return result return result
def analytical_power(self, slew, load): # def analytical_power(self, slew, load):
""" return analytical power of the bank. Basic skeleton code""" # """ return analytical power of the bank. Basic skeleton code"""
msf_addr_power = self.msf_address.analytical_power(slew, self.decoder.input_load()) # 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()) # 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, # bl_t_data_out_power = self.sense_amp_array.analytical_power(slew,
self.bitcell_array.output_load()) # 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 \ # 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 # + bitcell_array_power + bl_t_data_out_power + data_t_DATA_power
return total_power # return total_power

View File

@ -688,8 +688,10 @@ class control_logic(design.design):
width=pin.width()) width=pin.width())
def analytical_power(self, slew, load): def analytical_power(self, vdd, temp, load):
#This has yet to be fully determined. #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 #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 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(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. #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. """ """ LH and HL are the same in analytical model. """
return self.bank.analytical_delay(slew,load) 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.""" """ Just a test function for the power."""
power_sum = 0; power_sum = 0;
print "Module Powers" print "Module Powers"
for mod in self.mods: # for mod in self.mods:
#print mod.name," Power: ", mod.analytical_power(slew, load) # print mod.name," Power: ", mod.analytical_power(slew, load)
power_sum += mod.analytical_power(slew, load) # power_sum += mod.analytical_power(slew, load)
print "Instances:" # print "Instances:"
for inst in self.insts: # for inst in self.insts:
print inst.name," Instance" # print inst.name," Instance"
print "Modules from Instances:"
for inst in self.insts:
print inst.mod.name," Module"
print "Instances from Modules of Instances:" # print "Instances from Modules of Instances:"
for inst in self.insts: # for inst in self.insts:
print inst.mod.name," Module" # print inst.mod.name," Module"
for mod_inst in inst.mod.insts: # for mod_inst in inst.mod.insts:
print mod_inst.name," Instance" # 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)
return bank_power power_sum = self.control_logic.analytical_power(vdd, temp, load)
return power_sum
def save_output(self): def save_output(self):
""" Save all the output files while reporting time to do it as well. """ """ 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(){ internal_power(){
when : "OEb & !clk"; when : "OEb & !clk";
rise_power(scalar){ rise_power(scalar){
values("292"); values("0");
} }
fall_power(scalar){ fall_power(scalar){
values("292"); values("0");
} }
} }
timing(){ timing(){
@ -129,10 +129,10 @@ cell (sram_2_16_1_freepdk45){
internal_power(){ internal_power(){
when : "!OEb & !clk"; when : "!OEb & !clk";
rise_power(scalar){ rise_power(scalar){
values("292"); values("0");
} }
fall_power(scalar){ fall_power(scalar){
values("292"); values("0");
} }
} }
timing(){ 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_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] 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 ##END Spice Simulation Parameters