mirror of https://github.com/VLSIDA/OpenRAM.git
Added skeleton code for analytical power in functions with analytical delay.
This commit is contained in:
parent
74064fc854
commit
db4913dd9c
|
|
@ -1225,3 +1225,22 @@ class bank(design.design):
|
||||||
result = msf_addr_delay + decoder_delay + word_driver_delay \
|
result = msf_addr_delay + decoder_delay + word_driver_delay \
|
||||||
+ 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):
|
||||||
|
""" return analytical power of the bank. Basic skeleton code"""
|
||||||
|
msf_addr_power = self.msf_address.analytical_power(slew, self.decoder.input_load())
|
||||||
|
|
||||||
|
decoder_power = self.decoder.analytical_power(slew, load)
|
||||||
|
|
||||||
|
word_driver_power = self.wordline_driver.analytical_power(slew, self.bitcell_array.input_load())
|
||||||
|
|
||||||
|
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())
|
||||||
|
|
||||||
|
data_t_DATA_power = self.tri_gate_array.analytical_power(slew, load)
|
||||||
|
|
||||||
|
total_power = msf_addr_power + decoder_power + word_driver_power \
|
||||||
|
+ bitcell_array_power + bl_t_data_out_power + data_t_DATA_power
|
||||||
|
return total_power
|
||||||
|
|
|
||||||
|
|
@ -34,3 +34,8 @@ class bitcell(design.design):
|
||||||
c_para = spice["min_tx_drain_c"]
|
c_para = spice["min_tx_drain_c"]
|
||||||
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = swing)
|
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = swing)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def analytical_power(self, slew, load=0, swing = 0.5):
|
||||||
|
#Power of the bitcell. Mostly known for leakage, but dynamic can also be factored in.
|
||||||
|
#Just skeleton code for now which returns a magic number.
|
||||||
|
return 5
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,27 @@ class bitcell_array(design.design):
|
||||||
return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay,
|
return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay,
|
||||||
wl_to_cell_delay.slew)
|
wl_to_cell_delay.slew)
|
||||||
|
|
||||||
|
def analytical_power(self, slew, load=0):
|
||||||
|
#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.
|
||||||
|
from tech import drc
|
||||||
|
|
||||||
|
#calculate wl dynamic power, functions not implemented.
|
||||||
|
#wl_wire = self.gen_wl_wire()
|
||||||
|
#wl_to_cell_power = wl_wire.return_power_over_wire(slew)
|
||||||
|
|
||||||
|
# hypothetical delay from cell to bl end without sense amp
|
||||||
|
bl_wire = self.gen_bl_wire()
|
||||||
|
cell_load = 2 * bl_wire.return_input_cap() # we ingore the wire r
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
#we do not consider the delay over the wire for now
|
||||||
|
return cell_power
|
||||||
|
|
||||||
def gen_wl_wire(self):
|
def gen_wl_wire(self):
|
||||||
wl_wire = self.generate_rc_net(int(self.column_size), self.width, drc["minwidth_metal1"])
|
wl_wire = self.generate_rc_net(int(self.column_size), self.width, drc["minwidth_metal1"])
|
||||||
wl_wire.wire_c = 2*spice["min_tx_gate_c"] + wl_wire.wire_c # 2 access tx gate per cell
|
wl_wire.wire_c = 2*spice["min_tx_gate_c"] + wl_wire.wire_c # 2 access tx gate per cell
|
||||||
|
|
|
||||||
|
|
@ -494,6 +494,22 @@ class hierarchical_decoder(design.design):
|
||||||
result = result + z_t_decodeout_delay
|
result = result + z_t_decodeout_delay
|
||||||
return result
|
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())
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
if self.determine_predecodes(self.num_inputs)[1]==0:
|
if self.determine_predecodes(self.num_inputs)[1]==0:
|
||||||
pre = self.pre2_4
|
pre = self.pre2_4
|
||||||
|
|
|
||||||
|
|
@ -55,5 +55,17 @@ class hierarchical_predecode2x4(hierarchical_predecode):
|
||||||
|
|
||||||
return a_t_b_delay + b_t_z_delay + a_t_out_delay
|
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())
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
return a_t_b_power + b_t_z_power + a_t_out_power
|
||||||
|
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return self.nand.input_load()
|
return self.nand.input_load()
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,17 @@ class hierarchical_predecode3x8(hierarchical_predecode):
|
||||||
|
|
||||||
return a_t_b_delay + b_t_z_delay + a_t_out_delay
|
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())
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
return a_t_b_power + b_t_z_power + a_t_out_power
|
||||||
|
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return self.nand.input_load()
|
return self.nand.input_load()
|
||||||
|
|
|
||||||
|
|
@ -27,3 +27,6 @@ class ms_flop(design.design):
|
||||||
result = self.return_delay(spice["msflop_delay"], spice["msflop_slew"])
|
result = self.return_delay(spice["msflop_delay"], spice["msflop_slew"])
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def analytical_power(self, slew, load = 0.0):
|
||||||
|
return 4
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,3 +134,6 @@ class ms_flop_array(design.design):
|
||||||
|
|
||||||
def analytical_delay(self, slew, load=0.0):
|
def analytical_delay(self, slew, load=0.0):
|
||||||
return self.ms.analytical_delay(slew=slew, load=load)
|
return self.ms.analytical_delay(slew=slew, load=load)
|
||||||
|
|
||||||
|
def analytical_power(self, slew, load):
|
||||||
|
return self.ms.analytical_power(slew=slew, load=load)
|
||||||
|
|
|
||||||
|
|
@ -241,3 +241,7 @@ class pinv(pgate.pgate):
|
||||||
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
|
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
|
||||||
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):
|
||||||
|
#Adding a magic number until I can properly define this.
|
||||||
|
return 3
|
||||||
|
|
|
||||||
|
|
@ -213,3 +213,7 @@ class pnand2(pgate.pgate):
|
||||||
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
|
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
|
||||||
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):
|
||||||
|
#Adding a magic number until I can properly define this.
|
||||||
|
return 1
|
||||||
|
|
|
||||||
|
|
@ -233,3 +233,7 @@ class pnand3(pgate.pgate):
|
||||||
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
|
r = spice["min_tx_r"]/(self.nmos_size/parameter["min_tx_size"])
|
||||||
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):
|
||||||
|
#Adding a magic number until I can properly define this.
|
||||||
|
return 2
|
||||||
|
|
|
||||||
|
|
@ -30,3 +30,7 @@ class sense_amp(design.design):
|
||||||
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
|
result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew)
|
||||||
return self.return_delay(result.delay, result.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
|
||||||
|
|
|
||||||
|
|
@ -117,3 +117,6 @@ class sense_amp_array(design.design):
|
||||||
|
|
||||||
def analytical_delay(self, slew, load=0.0):
|
def analytical_delay(self, slew, load=0.0):
|
||||||
return self.amp.analytical_delay(slew=slew, load=load)
|
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)
|
||||||
|
|
|
||||||
|
|
@ -1006,4 +1006,4 @@ class sram(design.design):
|
||||||
|
|
||||||
def analytical_power(self,slew,load):
|
def analytical_power(self,slew,load):
|
||||||
""" Just a test function for the power."""
|
""" Just a test function for the power."""
|
||||||
return 1
|
return self.bank.analytical_power(slew,load)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,10 @@ class tri_gate(design.design):
|
||||||
c_para = spice["min_tx_drain_c"]
|
c_para = spice["min_tx_drain_c"]
|
||||||
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):
|
||||||
|
#Skeleton code for the power of a trigate. Returns magic number for now.
|
||||||
|
return 2
|
||||||
|
|
||||||
|
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return 9*spice["min_tx_gate_c"]
|
return 9*spice["min_tx_gate_c"]
|
||||||
|
|
|
||||||
|
|
@ -111,3 +111,6 @@ class tri_gate_array(design.design):
|
||||||
|
|
||||||
def analytical_delay(self, slew, load=0.0):
|
def analytical_delay(self, slew, load=0.0):
|
||||||
return self.tri.analytical_delay(slew = slew, load = load)
|
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)
|
||||||
|
|
|
||||||
|
|
@ -206,5 +206,14 @@ class wordline_driver(design.design):
|
||||||
|
|
||||||
return decode_t_net + net_t_wl
|
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())
|
||||||
|
|
||||||
|
# net -> wl
|
||||||
|
net_p_wl = self.inv.analytical_power(slew, load)
|
||||||
|
|
||||||
|
return decode_p_net + net_p_wl
|
||||||
|
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return self.nand2.input_load()
|
return self.nand2.input_load()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue