from ScEpTIC.emulator.energy import energy_utils from ScEpTIC.emulator.energy.voltage_drawner import VoltageDrawner class FBCTEnergyModel(VoltageDrawner): """ Energy model of the changepoint detection circuit of FTBC """ # Charge voltage divider: 0.667 # Discharge voltage divider: 0.947 circuit_components = { 'CHANGEPOINT_DETECTION': { 'R': { # voltage divider for the op-amp that detects a new changepoint (increase of energy buffer) #'voltage_divider_charge': {'R1': '1.5M', 'R2': '2.7M'}, 'voltage_divider_charge': {'R1': '2M', 'R2': '8M'}, # voltage divider for the op-amp that detects a new changepoint (decrease of energy buffer) #'voltage_divider_discharge': {'R1': '2.2M', 'R2': '39M'}, 'voltage_divider_discharge': {'R1': '150K', 'R2': '10M'}, }, 'I': { 'TS881_down': '210n', # op-amp to detect a new changepoint (decrease of energy buffer) 'TS881_up': '210n', # op-amp to detect a new changepoint (increase of energy buffer) } }, 'BOOT_AND_ENABLE_LATCH': { 'R': {}, 'I': { 'BU4918': '0.26u', # Voltage Detector (1.8V) 'BU4936': '0.35u', # Voltage Detector (3.6V) 'NOT_GATE': '0.5u', # NOT port 'LATCH_D': '1u', # Flip Flop D (2 NOR logical gates of 0.5uA each) }, }, 'PULL_UP_RES_GROUP': { 'R': { 'pull_up_bit_0': '10M', # Pull-up resistor for bit 0 'pull_up_bit_1': '10M', # Pull-up resistor for bit 1 'pull_up_bit_2': '10M', # Pull-up resistor for bit 2 'pull_up_bit_3': '10M', # Pull-up resistor for bit 3 }, 'I': {}, } # + TPS62740x modeled in voltage_regulators } def __init__(self): self.parallel_resistors = [] self.current_consumptions = 0.0 for circuit_group in self.circuit_components.values(): for value_type, value_data in circuit_group.items(): if value_type == 'I': # sum all currents for current_draw in value_data.values(): self.current_consumptions += energy_utils.str_to_float(current_draw) elif value_type == 'R': # add all parallel resitors for resistance in value_data.values(): # series of resistors if isinstance(resistance, dict): res_val = sum([energy_utils.str_to_float(val) for val in resistance.values()]) self.parallel_resistors.append(res_val) # single resistor else: self.parallel_resistors.append(energy_utils.str_to_float(resistance)) def get_drained_energy(self, t): """ Calculates the energy consumed by the component. :param t: elapsed time :return: the consumed energy """ voltage = self.voltage_source.get_voltage() energy_from_R = sum([energy_utils.energy_from_R_t(voltage, r, t) for r in self.parallel_resistors]) energy_from_I = energy_utils.energy_from_I_t(voltage, self.current_consumptions, t) return energy_from_R + energy_from_I