Added initial version of analytical power esitmation. Loops through instances but power estimate is not accurate.

This commit is contained in:
Hunter Nichols
2018-02-22 19:35:54 -08:00
parent beb7dad9bc
commit 62ad30e741
16 changed files with 333 additions and 77 deletions
+3 -2
View File
@@ -35,10 +35,11 @@ class bitcell(design.design):
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = swing)
return result
def analytical_power(self, slew, load=0, swing = 0.5):
def analytical_power(self, vdd, temp, load):
#Power of the bitcell. Mostly known for leakage, but dynamic can also be factored in.
#Only consider leakage power for now. Value defined in tech file rather than calculated.
from tech import spice
leakage = spice["bitcell_leakage"]
total_power = leakage
dynamic = 0 #temporary
total_power = self.return_power(dynamic, leakage)
return total_power
+6 -4
View File
@@ -178,7 +178,7 @@ class bitcell_array(design.design):
return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay,
wl_to_cell_delay.slew)
def analytical_power(self, slew, load=0):
def analytical_power(self, vdd, temp, load):
#This will be pretty bare bones as the power needs to be determined from the dynamic power
#of the word line, leakage power from the cell, and dynamic power of the bitlines as a few
#sources for power. These features are tbd.
@@ -194,10 +194,12 @@ class bitcell_array(design.design):
# hence just use the whole c
bl_swing = 0.1
#Calculate the bitcell power which can include leakage as well as bitline dynamic
cell_power = self.cell.analytical_power(slew, cell_load, swing = bl_swing)
cell_power = self.cell.analytical_power(vdd, temp, load)
#Leakage power grows with entire array. Dynamic currently not accounted for.
total_power = self.return_power(cell_power.dynamic, cell_power.leakage * self.column_size * self.row_size)
#calculate power for entire array based off a single cell
return cell_power * self.column_size * self.row_size
return total_power
def gen_wl_wire(self):
wl_wire = self.generate_rc_net(int(self.column_size), self.width, drc["minwidth_metal1"])
+13 -13
View File
@@ -494,21 +494,21 @@ class hierarchical_decoder(design.design):
result = result + z_t_decodeout_delay
return result
def analytical_power(self, slew, load = 0.0):
# A -> out
if self.determine_predecodes(self.num_inputs)[1]==0:
pre = self.pre2_4
nand = self.nand2
else:
pre = self.pre3_8
nand = self.nand3
a_t_out_power = pre.analytical_power(slew=slew,load = nand.input_load())
# def analytical_power(self, slew, load = 0.0):
# # A -> out
# if self.determine_predecodes(self.num_inputs)[1]==0:
# pre = self.pre2_4
# nand = self.nand2
# else:
# pre = self.pre3_8
# nand = self.nand3
# a_t_out_power = pre.analytical_power(slew=slew,load = nand.input_load())
out_t_z_power = nand.analytical_power(slew,
load = self.inv.input_load())
# out_t_z_power = nand.analytical_power(slew,
# load = self.inv.input_load())
z_t_decodeout_power = self.inv.analytical_power(slew, load = load)
return a_t_out_power + out_t_z_power + z_t_decodeout_power
# z_t_decodeout_power = self.inv.analytical_power(slew, load = load)
# return a_t_out_power + out_t_z_power + z_t_decodeout_power
def input_load(self):
if self.determine_predecodes(self.num_inputs)[1]==0:
@@ -55,17 +55,17 @@ class hierarchical_predecode2x4(hierarchical_predecode):
return a_t_b_delay + b_t_z_delay + a_t_out_delay
def analytical_power(self, slew, load = 0.0 ):
# in -> inbar
a_t_b_power = self.inv.analytical_power(slew=slew, load=self.nand.input_load())
# def analytical_power(self, slew, load = 0.0 ):
# # in -> inbar
# a_t_b_power = self.inv.analytical_power(slew=slew, load=self.nand.input_load())
# inbar -> z
b_t_z_power = self.nand.analytical_power(slew, load=self.inv.input_load())
# # inbar -> z
# b_t_z_power = self.nand.analytical_power(slew, load=self.inv.input_load())
# Z -> out
a_t_out_power = self.inv.analytical_power(slew, load=load)
# # Z -> out
# a_t_out_power = self.inv.analytical_power(slew, load=load)
return a_t_b_power + b_t_z_power + a_t_out_power
# return a_t_b_power + b_t_z_power + a_t_out_power
def input_load(self):
return self.nand.input_load()
@@ -63,17 +63,17 @@ class hierarchical_predecode3x8(hierarchical_predecode):
return a_t_b_delay + b_t_z_delay + a_t_out_delay
def analytical_power(self, slew, load = 0.0 ):
# in -> inbar
a_t_b_power = self.inv.analytical_power(slew=slew, load=self.nand.input_load())
# def analytical_power(self, slew, load = 0.0 ):
# # in -> inbar
# a_t_b_power = self.inv.analytical_power(slew=slew, load=self.nand.input_load())
# inbar -> z
b_t_z_power = self.nand.analytical_power(slew, load=self.inv.input_load())
# # inbar -> z
# b_t_z_power = self.nand.analytical_power(slew, load=self.inv.input_load())
# Z -> out
a_t_out_power = self.inv.analytical_power(slew, load=load)
# # Z -> out
# a_t_out_power = self.inv.analytical_power(slew, load=load)
return a_t_b_power + b_t_z_power + a_t_out_power
# return a_t_b_power + b_t_z_power + a_t_out_power
def input_load(self):
return self.nand.input_load()
+5 -4
View File
@@ -347,11 +347,12 @@ class replica_bitline(design.design):
# def analytical_power(self, vdd, temp, load):
# #This has yet to be fully determined.
# print "Instances:"
# total_power = 0
# print self.name," Instances:"
# total_power = self.return_power()
# for inst in self.insts:
# print inst.name," Instance"
# #total_power += inst.mod.analytical_power(vdd, temp, load)
# total_power += inst.mod.analytical_power(vdd, temp, load)
# print self.name," Instances End"
# #currently, only return flop array power
# return total_power
+4 -4
View File
@@ -30,7 +30,7 @@ class sense_amp(design.design):
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
return self.return_delay(result.delay, result.slew)
def analytical_power(self, slew, load=0.0):
#This is just skeleton code which returns a magic number. The sense amp consumes static
#power during its operation and some dynamic power due to the switching.
return 2
def analytical_power(self, vdd, temp, load):
#Not sure how to determine this yet. Sense amps return zero power for now
total_power = self.return_power()
return total_power
+2 -2
View File
@@ -118,5 +118,5 @@ class sense_amp_array(design.design):
def analytical_delay(self, slew, load=0.0):
return self.amp.analytical_delay(slew=slew, load=load)
def analytical_power(self, slew, load=0.0):
return self.amp.analytical_power(slew=slew, load=load)
# def analytical_power(self, slew, load=0.0):
# return self.amp.analytical_power(slew=slew, load=load)
+4 -3
View File
@@ -33,9 +33,10 @@ class tri_gate(design.design):
c_para = spice["min_tx_drain_c"]
return self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
def analytical_power(self, slew, load=0.0):
#Skeleton code for the power of a trigate. Returns magic number for now.
return 2
def analytical_power(self, vdd, temp, load):
#Not sure how to determine this yet. Tri-gates return zero power for now
total_power = self.return_power()
return total_power
def input_load(self):
+2 -2
View File
@@ -112,5 +112,5 @@ class tri_gate_array(design.design):
def analytical_delay(self, slew, load=0.0):
return self.tri.analytical_delay(slew = slew, load = load)
def analytical_power(self, slew, load=0.0):
return self.tri.analytical_power(slew = slew, load = load)
# def analytical_power(self, slew, load=0.0):
# return self.tri.analytical_power(slew = slew, load = load)
+6 -6
View File
@@ -206,14 +206,14 @@ class wordline_driver(design.design):
return decode_t_net + net_t_wl
def analytical_power(self, slew, load=0):
# decode -> net
decode_p_net = self.nand2.analytical_power(slew, self.inv.input_load())
# def analytical_power(self, slew, load=0):
# # decode -> net
# decode_p_net = self.nand2.analytical_power(slew, self.inv.input_load())
# net -> wl
net_p_wl = self.inv.analytical_power(slew, load)
# # net -> wl
# net_p_wl = self.inv.analytical_power(slew, load)
return decode_p_net + net_p_wl
# return decode_p_net + net_p_wl
def input_load(self):
return self.nand2.input_load()