From d4a0f48d4fda2594ea084f560c9e88514d201ca0 Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Wed, 21 Feb 2018 19:51:21 -0800 Subject: [PATCH] Added power calculations for inverter. Still testing. --- compiler/base/design.py | 9 +++-- compiler/base/hierarchy_spice.py | 34 +++++++++++++++++ compiler/characterizer/delay.py | 4 +- compiler/modules/bank.py | 26 ++++++------- compiler/modules/control_logic.py | 8 ++-- compiler/pgates/pinv.py | 16 +++++++- compiler/sram.py | 35 ++++++++---------- compiler/temp/sram_2_16_1_freepdk45.gds | Bin 408550 -> 408550 bytes .../temp/sram_2_16_1_freepdk45_TT_10V_25C.lib | 8 ++-- technology/freepdk45/tech/tech.py | 7 ++++ 10 files changed, 101 insertions(+), 46 deletions(-) diff --git a/compiler/base/design.py b/compiler/base/design.py index 5dd0db14..ad37dfe6 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -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 diff --git a/compiler/base/hierarchy_spice.py b/compiler/base/hierarchy_spice.py index d218227e..dadebdab 100644 --- a/compiler/base/hierarchy_spice.py +++ b/compiler/base/hierarchy_spice.py @@ -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: diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 82515933..8865b71b 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -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, diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index 3d5bcddf..b936670e 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -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 diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index ce99040f..16091b60 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -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 \ No newline at end of file + return 0 \ No newline at end of file diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index b628b4d9..337728ca 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -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) \ No newline at end of file diff --git a/compiler/sram.py b/compiler/sram.py index 3e80d059..91df3704 100644 --- a/compiler/sram.py +++ b/compiler/sram.py @@ -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. """ diff --git a/compiler/temp/sram_2_16_1_freepdk45.gds b/compiler/temp/sram_2_16_1_freepdk45.gds index f9ecf3d877f29c0e9d7b2a742a8a0fe04b8e58ed..3d0a69108aaec5af38e710c610eafac4f39a1879 100644 GIT binary patch delta 1849 zcmaJ?T}V_x6rMYCXG{%SQ@5MCi6-ukKUszqVqsEd59<#}QPFClVL#%FK|Q79TS2nW z4T7-99;Ic26Nngrnc0Iq^`l5gXhFzE&^}1e#?GvJV79l*eDj_2eP_-&cO`1AM6D7c z2ql~p8Z>P=_LWDn2_a?4-yN12!OI_*ONb{9f4K1T}*LqX}-lW`KIOjGFDOJcFJo6dD+!;5BIK(OJpNl*f z0@a3x$s36K??ywFk!!;o_rm8Iqc}~c3bN{q;46us0Py@zDp|sy2TU!eozogF5maEf zpFu+|i6AR*)qmARZpi?9*l^_4FvmHI+iNh(e_lx_?Z||plLjk zAw+*~-!;3nom%$GW;zTL-Sms93f44!iMBbl-nS0YM??RO?}%^<9H01@vWprT9;UNt z?urXUh!Pms2aZNMq1fnAY=0j6E_LBr9e1)}ML}U0rtAhS=BfgiA7E<6Z}AT zE6oR5HE^)UOcV@rZugo^nX=hX9A5L~^-UwMk9xAu)Eh6R}j&Q}(}*c$h%9|DdjB0RD9@WSX{=S>yT TJTB#1w^+#1mgPmQsN#PCos%1o delta 1849 zcmaJ?TSyd97(R2(oMT?FE!S;QH`z^EH8snyY_TvYvxoIUQdG2BXxK%3F{r1Md@D#6 znji>^>`_`a_yv(7Ff)7Dp1LR!5?T;q1nq+ajk`0OXZW|b!};d>&-eYeS&V6mG0jT^ zp@fqHg{CbSCnw1w9#XUZJmlS(vv%zzBzbL|!|g9}DTCB4KY^q+Iw z3BgLGn3-Ql+_f+2Dio&tQ$$k}3gGBb|YstB*EXd9YjsHmlr_&cKhA0qpiKb9)m(biPR=otgaM;ec02+`Z! zb4_nA1y~gz14?_TAJa=jynN4O$c_EG*=+x;&IqUCkykQ#I?RCh7$DVODH4 zx+DZn9bsGWN)H4WKC%#PVUZxJ33$?JCu55j&X;H z$P#b;V4nRLqC3jeLikXm1{BnNfzbO4XrA7-L$%(NBk%R8(|F?;kvN zErU{cIB}8x5@@DVE;yH=Z08sj{JHc_EA}^FZQzPxViW|MB+j3DsL!5 Q&A;`D*=!UUs}>dfFI>Sc@&Et; diff --git a/compiler/temp/sram_2_16_1_freepdk45_TT_10V_25C.lib b/compiler/temp/sram_2_16_1_freepdk45_TT_10V_25C.lib index ed43129e..75a20561 100644 --- a/compiler/temp/sram_2_16_1_freepdk45_TT_10V_25C.lib +++ b/compiler/temp/sram_2_16_1_freepdk45_TT_10V_25C.lib @@ -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(){ diff --git a/technology/freepdk45/tech/tech.py b/technology/freepdk45/tech/tech.py index dacc3644..21cd87a0 100644 --- a/technology/freepdk45/tech/tech.py +++ b/technology/freepdk45/tech/tech.py @@ -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