mirror of https://github.com/VLSIDA/OpenRAM.git
Added power calculations for inverter. Still testing.
This commit is contained in:
parent
179a27b0e3
commit
d4a0f48d4f
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,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:
|
||||||
"""
|
"""
|
||||||
|
|
@ -246,6 +249,37 @@ class delay_data:
|
||||||
assert isinstance(other,delay_data)
|
assert isinstance(other,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:
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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. """
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -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(){
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue