mirror of https://github.com/VLSIDA/OpenRAM.git
Added corner information for analytical power estimation.
This commit is contained in:
parent
ddeb40c9bf
commit
80a325fe32
|
|
@ -162,7 +162,7 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
width=well_width,
|
width=well_width,
|
||||||
height=well_height)
|
height=well_height)
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
""" Get total power of a module """
|
""" Get total power of a module """
|
||||||
return self.return_power()
|
return self.return_power()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,11 +88,11 @@ class design(hierarchy_design):
|
||||||
self.readonly_ports.append(port_number)
|
self.readonly_ports.append(port_number)
|
||||||
port_number += 1
|
port_number += 1
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
""" Get total power of a module """
|
""" Get total power of a module """
|
||||||
total_module_power = self.return_power()
|
total_module_power = self.return_power()
|
||||||
for inst in self.insts:
|
for inst in self.insts:
|
||||||
total_module_power += inst.mod.analytical_power(proc, vdd, temp, load)
|
total_module_power += inst.mod.analytical_power(corner, load)
|
||||||
return total_module_power
|
return total_module_power
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
||||||
|
|
@ -235,10 +235,10 @@ class spice():
|
||||||
modeling it as a resistance driving a capacitance
|
modeling it as a resistance driving a capacitance
|
||||||
"""
|
"""
|
||||||
swing_factor = abs(math.log(1-swing)) # time constant based on swing
|
swing_factor = abs(math.log(1-swing)) # time constant based on swing
|
||||||
proc,volt,temp = corner
|
proc,vdd,temp = corner
|
||||||
#FIXME: type of delay is needed to know which process to use.
|
#FIXME: type of delay is needed to know which process to use.
|
||||||
proc_mult = max(self.get_process_delay_factor(proc))
|
proc_mult = max(self.get_process_delay_factor(proc))
|
||||||
volt_mult = self.get_voltage_delay_factor(volt)
|
volt_mult = self.get_voltage_delay_factor(vdd)
|
||||||
temp_mult = self.get_temp_delay_factor(temp)
|
temp_mult = self.get_temp_delay_factor(temp)
|
||||||
delay = swing_factor * r * c #c is in ff and delay is in fs
|
delay = swing_factor * r * c #c is in ff and delay is in fs
|
||||||
delay = delay * proc_mult * volt_mult * temp_mult
|
delay = delay * proc_mult * volt_mult * temp_mult
|
||||||
|
|
@ -291,6 +291,22 @@ class spice():
|
||||||
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 calc_dynamic_power(self, corner, c, freq, swing=1.0):
|
||||||
|
"""
|
||||||
|
Calculate dynamic power using effective capacitance, frequency, and corner (PVT)
|
||||||
|
"""
|
||||||
|
proc,vdd,temp = corner
|
||||||
|
net_vswing = vdd*swing
|
||||||
|
power_dyn = c*vdd*net_vswing*freq
|
||||||
|
|
||||||
|
#Apply process and temperature factors. Roughly, process and Vdd affect the delay which affects the power.
|
||||||
|
#No other estimations are currently used. Increased delay->slower freq.->less power
|
||||||
|
proc_div = max(self.get_process_delay_factor(proc))
|
||||||
|
temp_div = self.get_temp_delay_factor(temp)
|
||||||
|
power_dyn = power_dyn/(proc_div*temp_div)
|
||||||
|
|
||||||
|
return power_dyn
|
||||||
|
|
||||||
def return_power(self, dynamic=0.0, leakage=0.0):
|
def return_power(self, dynamic=0.0, leakage=0.0):
|
||||||
return power_data(dynamic, leakage)
|
return power_data(dynamic, leakage)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ class bitcell(design.design):
|
||||||
column_pins = ["br"]
|
column_pins = ["br"]
|
||||||
return column_pins
|
return column_pins
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Bitcell power in nW. Only characterizes leakage."""
|
"""Bitcell power in nW. Only characterizes leakage."""
|
||||||
from tech import spice
|
from tech import spice
|
||||||
leakage = spice["bitcell_leakage"]
|
leakage = spice["bitcell_leakage"]
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ class bitcell_1rw_1r(design.design):
|
||||||
column_pins = ["br0"]
|
column_pins = ["br0"]
|
||||||
return column_pins
|
return column_pins
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Bitcell power in nW. Only characterizes leakage."""
|
"""Bitcell power in nW. Only characterizes leakage."""
|
||||||
from tech import spice
|
from tech import spice
|
||||||
leakage = spice["bitcell_leakage"]
|
leakage = spice["bitcell_leakage"]
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ class bitcell_1w_1r(design.design):
|
||||||
column_pins = ["br0"]
|
column_pins = ["br0"]
|
||||||
return column_pins
|
return column_pins
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Bitcell power in nW. Only characterizes leakage."""
|
"""Bitcell power in nW. Only characterizes leakage."""
|
||||||
from tech import spice
|
from tech import spice
|
||||||
leakage = spice["bitcell_leakage"]
|
leakage = spice["bitcell_leakage"]
|
||||||
|
|
|
||||||
|
|
@ -874,7 +874,7 @@ class pbitcell(design.design):
|
||||||
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing)
|
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = swing)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Bitcell power in nW. Only characterizes leakage."""
|
"""Bitcell power in nW. Only characterizes leakage."""
|
||||||
from tech import spice
|
from tech import spice
|
||||||
leakage = spice["bitcell_leakage"]
|
leakage = spice["bitcell_leakage"]
|
||||||
|
|
|
||||||
|
|
@ -931,7 +931,7 @@ class delay(simulation):
|
||||||
"""Get the dynamic and leakage power from the SRAM"""
|
"""Get the dynamic and leakage power from the SRAM"""
|
||||||
#slews unused, only last load is used
|
#slews unused, only last load is used
|
||||||
load = loads[-1]
|
load = loads[-1]
|
||||||
power = self.sram.analytical_power(self.process, self.vdd_voltage, self.temperature, load)
|
power = self.sram.analytical_power(self.corner, load)
|
||||||
#convert from nW to mW
|
#convert from nW to mW
|
||||||
power.dynamic /= 1e6
|
power.dynamic /= 1e6
|
||||||
power.leakage /= 1e6
|
power.leakage /= 1e6
|
||||||
|
|
|
||||||
|
|
@ -147,19 +147,19 @@ 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, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Power of Bitcell array and bitline in nW."""
|
"""Power of Bitcell array and bitline in nW."""
|
||||||
from tech import drc
|
from tech import drc, parameter
|
||||||
|
|
||||||
# Dynamic Power from Bitline
|
# Dynamic Power from Bitline
|
||||||
bl_wire = self.gen_bl_wire()
|
bl_wire = self.gen_bl_wire()
|
||||||
cell_load = 2 * bl_wire.return_input_cap()
|
cell_load = 2 * bl_wire.return_input_cap()
|
||||||
bl_swing = 0.1 #This should probably be defined in the tech file or input
|
bl_swing = parameter["rbl_height_percentage"]
|
||||||
freq = spice["default_event_rate"]
|
freq = spice["default_event_rate"]
|
||||||
bitline_dynamic = bl_swing*cell_load*vdd*vdd*freq #not sure if calculation is correct
|
bitline_dynamic = self.calc_dynamic_power(corner, cell_load, freq, swing=bl_swing)
|
||||||
|
|
||||||
#Calculate the bitcell power which currently only includes leakage
|
#Calculate the bitcell power which currently only includes leakage
|
||||||
cell_power = self.cell.analytical_power(proc, vdd, temp, load)
|
cell_power = self.cell.analytical_power(corner, load)
|
||||||
|
|
||||||
#Leakage power grows with entire array and bitlines.
|
#Leakage power grows with entire array and bitlines.
|
||||||
total_power = self.return_power(cell_power.dynamic + bitline_dynamic * self.column_size,
|
total_power = self.return_power(cell_power.dynamic + bitline_dynamic * self.column_size,
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ class dff(design.design):
|
||||||
self.height = dff.height
|
self.height = dff.height
|
||||||
self.pin_map = dff.pin_map
|
self.pin_map = dff.pin_map
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
c_eff = self.calculate_effective_capacitance(load)
|
c_eff = self.calculate_effective_capacitance(load)
|
||||||
f = spice["default_event_rate"]
|
freq = spice["default_event_rate"]
|
||||||
power_dyn = c_eff*vdd*vdd*f
|
power_dyn = self.calc_dynamic_power(corner, c_eff, freq)
|
||||||
power_leak = spice["msflop_leakage"]
|
power_leak = spice["msflop_leakage"]
|
||||||
|
|
||||||
total_power = self.return_power(power_dyn, power_leak)
|
total_power = self.return_power(power_dyn, power_leak)
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class sense_amp(design.design):
|
||||||
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
|
result = self.cal_delay_with_rc(corner, 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, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
#Power in this module currently not defined. Returns 0 nW (leakage and dynamic).
|
#Power in this module currently not defined. Returns 0 nW (leakage and dynamic).
|
||||||
total_power = self.return_power()
|
total_power = self.return_power()
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,11 @@ class single_level_column_mux_array(design.design):
|
||||||
|
|
||||||
def analytical_delay(self, corner, vdd, slew, load=0.0):
|
def analytical_delay(self, corner, vdd, slew, load=0.0):
|
||||||
from tech import spice, parameter
|
from tech import spice, parameter
|
||||||
proc,volt,temp = corner
|
proc,vdd,temp = corner
|
||||||
r = spice["min_tx_r"]/(self.mux.ptx_width/parameter["min_tx_size"])
|
r = spice["min_tx_r"]/(self.mux.ptx_width/parameter["min_tx_size"])
|
||||||
#Drains of mux transistors make up capacitance.
|
#Drains of mux transistors make up capacitance.
|
||||||
c_para = spice["min_tx_drain_c"]*(self.mux.ptx_width/parameter["min_tx_size"])*self.words_per_row#ff
|
c_para = spice["min_tx_drain_c"]*(self.mux.ptx_width/parameter["min_tx_size"])*self.words_per_row#ff
|
||||||
volt_swing = spice["v_threshold_typical"]/volt
|
volt_swing = spice["v_threshold_typical"]/vdd
|
||||||
|
|
||||||
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = volt_swing)
|
result = self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew, swing = volt_swing)
|
||||||
return self.return_delay(result.delay, result.slew)
|
return self.return_delay(result.delay, result.slew)
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ 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(corner, r = r, c = c_para+load, slew = slew)
|
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
#Power in this module currently not defined. Returns 0 nW (leakage and dynamic).
|
#Power in this module currently not defined. Returns 0 nW (leakage and dynamic).
|
||||||
total_power = self.return_power()
|
total_power = self.return_power()
|
||||||
|
|
|
||||||
|
|
@ -266,11 +266,11 @@ 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(corner, r = r, c = c_para+load, slew = slew)
|
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
c_eff = self.calculate_effective_capacitance(load)
|
c_eff = self.calculate_effective_capacitance(load)
|
||||||
freq = spice["default_event_rate"]
|
freq = spice["default_event_rate"]
|
||||||
power_dyn = c_eff*vdd*vdd*freq
|
power_dyn = self.calc_dynamic_power(corner, c_eff, freq)
|
||||||
power_leak = spice["inv_leakage"]
|
power_leak = spice["inv_leakage"]
|
||||||
|
|
||||||
total_power = self.return_power(power_dyn, power_leak)
|
total_power = self.return_power(power_dyn, power_leak)
|
||||||
|
|
|
||||||
|
|
@ -232,11 +232,11 @@ class pnand2(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(corner, r = r, c = c_para+load, slew = slew)
|
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
c_eff = self.calculate_effective_capacitance(load)
|
c_eff = self.calculate_effective_capacitance(load)
|
||||||
freq = spice["default_event_rate"]
|
freq = spice["default_event_rate"]
|
||||||
power_dyn = c_eff*vdd*vdd*freq
|
power_dyn = self.calc_dynamic_power(corner, c_eff, freq)
|
||||||
power_leak = spice["nand2_leakage"]
|
power_leak = spice["nand2_leakage"]
|
||||||
|
|
||||||
total_power = self.return_power(power_dyn, power_leak)
|
total_power = self.return_power(power_dyn, power_leak)
|
||||||
|
|
|
||||||
|
|
@ -245,11 +245,11 @@ class pnand3(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(corner, r = r, c = c_para+load, slew = slew)
|
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
c_eff = self.calculate_effective_capacitance(load)
|
c_eff = self.calculate_effective_capacitance(load)
|
||||||
freq = spice["default_event_rate"]
|
freq = spice["default_event_rate"]
|
||||||
power_dyn = c_eff*vdd*vdd*freq
|
power_dyn = self.calc_dynamic_power(corner, c_eff, freq)
|
||||||
power_leak = spice["nand3_leakage"]
|
power_leak = spice["nand3_leakage"]
|
||||||
|
|
||||||
total_power = self.return_power(power_dyn, power_leak)
|
total_power = self.return_power(power_dyn, power_leak)
|
||||||
|
|
|
||||||
|
|
@ -217,11 +217,11 @@ class pnor2(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(corner, r = r, c = c_para+load, slew = slew)
|
return self.cal_delay_with_rc(corner, r = r, c = c_para+load, slew = slew)
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, corner, load):
|
||||||
"""Returns dynamic and leakage power. Results in nW"""
|
"""Returns dynamic and leakage power. Results in nW"""
|
||||||
c_eff = self.calculate_effective_capacitance(load)
|
c_eff = self.calculate_effective_capacitance(load)
|
||||||
freq = spice["default_event_rate"]
|
freq = spice["default_event_rate"]
|
||||||
power_dyn = c_eff*vdd*vdd*freq
|
power_dyn = self.calc_dynamic_power(corner, c_eff, freq)
|
||||||
power_leak = spice["nor2_leakage"]
|
power_leak = spice["nor2_leakage"]
|
||||||
|
|
||||||
total_power = self.return_power(power_dyn, power_leak)
|
total_power = self.return_power(power_dyn, power_leak)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue