96 lines
4.0 KiB
Plaintext
96 lines
4.0 KiB
Plaintext
|
|
class EnergyCalculator:
|
|
"""
|
|
Skeleton for energy calculator class
|
|
A class needs to expose the following attributes:
|
|
- voltage: nominal operating voltage
|
|
- frequency: nominal operating frequency
|
|
- nvm_extra_cycles: number of wait cycles for NVM accesses
|
|
- energy_clock_cycle: energy consumption per clock cycle
|
|
- energy_volatile_memory_access: extra energy consumption per clock cycle for volatile memory accesses
|
|
- energy_non_volatile_memory_access: extra energy consumption per clock cycle for non-volatile memory accesses
|
|
- non_volatile_increase: % increase in energy of a single clock cycle accessing non-volatile memory vs volatile memory
|
|
note: must not to account for nvm_extra_cycles
|
|
- adc_active_cycles: number of clock cycles while the ADC is active for checkpoint trigger calls
|
|
- energy_clock_cycle_adc: extra energy consumption per cycle due to ADC on
|
|
- adc_instructions: number of instructions executed to initialize, query, and power off the ADC
|
|
|
|
The class needs to expose the following method:
|
|
- n_min_function(n_writes): function to calculate the n_min parameter for applying the read consolidaton for the virtual_memory trasformation
|
|
"""
|
|
|
|
multipliers = {'G': 1000000000.0, 'M': 1000000.0, 'K': 1000.0, 'm': 0.001, 'u': 0.000001, 'n': 0.000000001}
|
|
|
|
def __init__(self, datasheet, n_registers, adc_datasheet):
|
|
raise NotImplementedError(f"{self.__class__.__name__} needs to overwrite the init method!")
|
|
|
|
|
|
def n_min_function(self, n_writes):
|
|
"""
|
|
Function to calculate the minimum number of read instructions required to create a volatile copy of a memory location.
|
|
Necessary for virtual_memory transformation
|
|
:param n_writes: number of writes required for creating a volatile copy
|
|
:return: number of minimum reads
|
|
"""
|
|
raise NotImplementedError(f"{self.__class__.__name__} does not implement n_min_function(self, n_writes)")
|
|
|
|
|
|
def _str_to_float(self, value):
|
|
"""
|
|
Converts a string to a float, accounting for unit multipliers such as M/k/m/u
|
|
"""
|
|
multiplier = value[-1]
|
|
|
|
# account for multiplier
|
|
if multiplier in self.multipliers:
|
|
number = float(value[:-1])
|
|
multiplier = float(self.multipliers[multiplier])
|
|
value = number * multiplier
|
|
|
|
return float(value)
|
|
|
|
|
|
def _str_to_int(self, value):
|
|
"""
|
|
Converts a string to an int, accounting for unit multipliers such as M/k/m/u
|
|
"""
|
|
multiplier = value[-1]
|
|
|
|
# account for multiplier
|
|
if multiplier in self.multipliers:
|
|
number = float(value[:-1])
|
|
multiplier = float(self.multipliers[multiplier])
|
|
value = number * multiplier
|
|
|
|
return int(value)
|
|
|
|
|
|
@staticmethod
|
|
def _I_to_e(I, V, f):
|
|
"""
|
|
Converts current consumption I to energy consumption
|
|
"""
|
|
return (float(V) * float(I)) / float(f)
|
|
|
|
def __str__(self):
|
|
retstr = f"{self.__class__.__name__}():\n"
|
|
|
|
elements = {
|
|
"voltage": {"name": "Voltage", "unit": "V"},
|
|
"frequency": {"name": "MCU Frequency", "unit": "Hz"},
|
|
"nvm_extra_cycles": {"name": "NVM Wait Cycles", "unit": "clock cycles"},
|
|
"energy_clock_cycle": {"name": "Energy consumption", "unit": "J/clock cycle"},
|
|
"energy_volatile_memory_access": {"name": "Extra energy consumption for volatile accesses", "unit": "J/clock cycle"},
|
|
"energy_non_volatile_memory_access": {"name": "Extra energy consumption for non-volatile accesses", "unit": "J/clock cycle"},
|
|
}
|
|
|
|
for element in dir(self):
|
|
if element in elements:
|
|
value = getattr(self, element)
|
|
name = elements[element]["name"]
|
|
unit = elements[element]["unit"]
|
|
retstr += f" - {name}: {value} {unit}\n"
|
|
|
|
return retstr
|
|
|