/*********************************************************************
 *  The following code is part of the power modelling feature of VTR.
 *
 * For support:
 * http://code.google.com/p/vtr-verilog-to-routing/wiki/Power
 *
 * or email:
 * vtr.power.estimation@gmail.com
 *
 * If you are using power estimation for your researach please cite:
 *
 * Jeffrey Goeders and Steven Wilton.  VersaPower: Power Estimation
 * for Diverse FPGA Architectures.  In International Conference on
 * Field Programmable Technology, 2012.
 *
 ********************************************************************/

/**
 *  This file offers functions to estimate power of major components
 * within the FPGA (flip-flops, LUTs, interconnect structures, etc).
 */

/************************* INCLUDES *********************************/
#include <cstring>
#include <cmath>
using namespace std;

#include "vtr_math.h"
#include "vtr_assert.h"
#include "vtr_memory.h"

#include "power_components.h"
#include "power_lowlevel.h"
#include "power_util.h"
#include "power_callibrate.h"
#include "globals.h"

/************************* STRUCTS **********************************/

/************************* FUNCTION DECLARATIONS ********************/
static void power_usage_mux_rec(t_power_usage * power_usage, float * out_prob,
		float * out_dens, float * v_out, t_mux_node * mux_node,
		t_mux_arch * mux_arch, int * selector_values,
		float * primary_input_prob, float * primary_input_dens,
		bool v_out_restored, float period);

/************************* FUNCTION DEFINITIONS *********************/

/**
 * Module initializer function, called by power_init
 */
void power_components_init() {
	int i;
    auto& power_ctx = g_vpr_ctx.mutable_power();

	power_ctx.by_component.components = (t_power_usage*) vtr::calloc(
			POWER_COMPONENT_MAX_NUM, sizeof(t_power_usage));
	for (i = 0; i < POWER_COMPONENT_MAX_NUM; i++) {
		power_zero_usage(&power_ctx.by_component.components[i]);
	}
}

/**
 * Module un-initializer function, called by power_uninit
 */
void power_components_uninit() {
    auto& power_ctx = g_vpr_ctx.mutable_power();
	free(power_ctx.by_component.components);
}

/**
 * Adds power usage for a component to the global component tracker
 * - power_usage: Power usage to add
 * - component_idx: Type of component
 */
void power_component_add_usage(t_power_usage * power_usage,
		e_power_component_type component_idx) {
    auto& power_ctx = g_vpr_ctx.power();
	power_add_usage(&power_ctx.by_component.components[component_idx],
			power_usage);
}

/**
 * Gets power usage for a component
 * - power_usage: (Return value) Power usage for the given component
 * - component_idx: Type of component
 */
void power_component_get_usage(t_power_usage * power_usage,
		e_power_component_type component_idx) {
    auto& power_ctx = g_vpr_ctx.power();
	memcpy(power_usage, &power_ctx.by_component.components[component_idx],
			sizeof(t_power_usage));
}

/**
 * Returns total power for a given component
 * - component_idx: Type of component
 */
float power_component_get_usage_sum(e_power_component_type component_idx) {
    auto& power_ctx = g_vpr_ctx.power();
	return power_sum_usage(&power_ctx.by_component.components[component_idx]);
}

/**
 * Calculates power of a D flip-flop
 * - power_usage: (Return value) power usage of the flip-flop
 * - D_prob: Signal probability of the input
 * - D_dens: Transition density of the input
 * - Q_prob: Signal probability of the output
 * - Q_dens: Transition density of the output
 * - clk_prob: Signal probability of the clock
 * - clk_dens: Transition density of the clock
 */
void power_usage_ff(t_power_usage * power_usage, float size, float D_prob,
		float D_dens, float Q_prob, float Q_dens, float clk_prob,
		float clk_dens, float period) {
	t_power_usage sub_power_usage;
	float mux_in_dens[2];
	float mux_in_prob[2];
	PowerSpicedComponent * callibration;
	float scale_factor;

	power_zero_usage(power_usage);

	/* DFF is build using a master loop and slave loop.
	 * Each loop begins with a MUX and contains 2 inverters
	 * in a feedback loop to the mux.
	 * Each mux is built using two transmission gates.
	 */

	/* Master */
	mux_in_dens[0] = D_dens;
	mux_in_dens[1] = (1 - clk_prob) * D_dens;
	mux_in_prob[0] = D_prob;
	mux_in_prob[1] = D_prob;
	power_usage_MUX2_transmission(&sub_power_usage, size, mux_in_dens,
			mux_in_prob, clk_dens, (1 - clk_prob) * D_dens, period);
	power_add_usage(power_usage, &sub_power_usage);

	power_usage_inverter(&sub_power_usage, (1 - clk_prob) * D_dens, D_prob,
			size, period);
	power_add_usage(power_usage, &sub_power_usage);

	power_usage_inverter(&sub_power_usage, (1 - clk_prob) * D_dens, 1 - D_prob,
			size, period);
	power_add_usage(power_usage, &sub_power_usage);

	/* Slave */
	mux_in_dens[0] = Q_dens;
	mux_in_dens[1] = (1 - clk_prob) * D_dens;
	mux_in_prob[0] = (1 - Q_prob);
	mux_in_prob[1] = (1 - D_prob);
	power_usage_MUX2_transmission(&sub_power_usage, size, mux_in_dens,
			mux_in_prob, clk_dens, Q_dens, period);
	power_add_usage(power_usage, &sub_power_usage);

	power_usage_inverter(&sub_power_usage, Q_dens, 1 - Q_prob, size, period);
	power_add_usage(power_usage, &sub_power_usage);

	power_usage_inverter(&sub_power_usage, Q_dens, Q_prob, size, period);
	power_add_usage(power_usage, &sub_power_usage);

	/* Callibration */
    auto& power_ctx = g_vpr_ctx.power();
	callibration = power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_FF];
	if (callibration->is_done_callibration()) {
		scale_factor = callibration->scale_factor(1, size);
		power_scale_usage(power_usage, scale_factor);
	}

	return;
}

/**
 * Calculated power of a look-up table (LUT)
 * - power_usage: (Return value) The power usage of the LUT
 * - LUT_size: Number of LUT inputs
 * - SRAM_values: The 2^(LUT_size) truth table values.  String of '0' and '1' characters.
 * 		First characters is for all inputs = 0 and last characters is for all inputs = 1.
 * - input_prob: Array of input signal probabilities
 * - input_dens: Array of input transition densities
 *
 * NOTE: The following provides a diagram of a 3-LUT, the sram bit ordering, and
 *  the input array ordering.
 *
 *	X - NMOS gate controlled by complement of input
 *	Z - NMOS gate controlled by input
 *
 * S
 * R  I   I   I
 * A  N   N   N
 * M  2   1   0
 * |  |   |   |
 * v  v   |   |
 *        v   |
 * 0 _X_      |
 *      |_X_  v
 * 1 _Z_|   |
 *          |_X_
 * 2 _X_    |   |
 *      |_Z_|   |
 * 3 _Z_|       |
 *              |------ out
 * 4 _X_        |
 *      |_X_    |
 * 5 _Z_|   |   |
 *          |_Z_|
 * 6 _X_    |
 *      |_Z_|
 * 7 _Z_|
 *
 */
void power_usage_lut(t_power_usage * power_usage, int lut_size,
		float transistor_size, char * SRAM_values, float * input_prob,
		float * input_dens, float period) {
	float **internal_prob;
	float **internal_dens;
	float **internal_v;
	int i;
	int level_idx;
	PowerSpicedComponent * callibration;
	float scale_factor;

	int num_SRAM_bits;

	bool level_restorer_this_level = false;

    auto& power_ctx = g_vpr_ctx.power();

	power_zero_usage(power_usage);

	num_SRAM_bits = 1 << lut_size;

	/* Initialize internal node data */
	internal_prob = (float**) vtr::calloc(lut_size + 1, sizeof(float*));
	internal_dens = (float**) vtr::calloc(lut_size + 1, sizeof(float*));
	internal_v = (float**) vtr::calloc(lut_size + 1, sizeof(float*));
	for (i = 0; i <= lut_size; i++) {
		internal_prob[i] = (float*) vtr::calloc(1 << (lut_size - i),
				sizeof(float));
		internal_dens[i] = (float*) vtr::calloc(1 << (lut_size - i),
				sizeof(float));
		internal_v[i] = (float*) vtr::calloc(1 << (lut_size - i), sizeof(float));
	}

	/* Initialize internal probabilities/densities from SRAM bits */
	for (i = 0; i < num_SRAM_bits; i++) {
		if (SRAM_values[i] == '0') {
			internal_prob[0][i] = 0.;
		} else {
			internal_prob[0][i] = 1.;
		}
		internal_dens[0][i] = 0.;
		internal_v[0][i] = power_ctx.tech->Vdd;
	}

	for (level_idx = 0; level_idx < lut_size; level_idx++) {
		t_power_usage driver_power_usage;
		int MUXs_this_level;
		int MUX_idx;
		int reverse_idx = lut_size - level_idx - 1;

		MUXs_this_level = 1 << (reverse_idx);

		/* Power of input drivers */
		power_usage_inverter(&driver_power_usage, input_dens[reverse_idx],
				input_prob[reverse_idx], 1.0, period);
		power_add_usage(power_usage, &driver_power_usage);

		power_usage_inverter(&driver_power_usage, input_dens[reverse_idx],
				input_prob[reverse_idx], 2.0, period);
		power_add_usage(power_usage, &driver_power_usage);

		power_usage_inverter(&driver_power_usage, input_dens[reverse_idx],
				1 - input_prob[reverse_idx], 2.0, period);
		power_add_usage(power_usage, &driver_power_usage);

		/* Add level restorer after every 2 stages (level_idx %2 == 1)
		 * But if there is an odd # of stages, just put one at the last
		 * stage (level_idx == LUT_size - 1) and not at the stage just before
		 * the last stage (level_idx != LUT_size - 2)
		 */
		if (((level_idx % 2 == 1) && (level_idx != lut_size - 2))
				|| (level_idx == lut_size - 1)) {
			level_restorer_this_level = true;
		} else {
			level_restorer_this_level = false;
		}

		/* Loop through the 2-muxs at each level */
		for (MUX_idx = 0; MUX_idx < MUXs_this_level; MUX_idx++) {
			t_power_usage sub_power;
			float out_prob;
			float out_dens;
			float sum_prob = 0;
			int sram_offset = MUX_idx * vtr::ipow(2, level_idx + 1);
			int sram_per_branch = vtr::ipow(2, level_idx);
			int branch_lvl_idx;
			int sram_idx;
			float v_out;

			/* Calculate output probability of multiplexer */
			out_prob = internal_prob[level_idx][MUX_idx * 2]
					* (1 - input_prob[reverse_idx])
					+ internal_prob[level_idx][MUX_idx * 2 + 1]
							* input_prob[reverse_idx];

			/* Calculate output density of multiplexer */
			out_dens = internal_dens[level_idx][MUX_idx * 2]
					* (1 - input_prob[reverse_idx])
					+ internal_dens[level_idx][MUX_idx * 2 + 1]
							* input_prob[reverse_idx];

#ifdef POWER_LUT_FAST
			out_dens += ((1 - internal_prob[level_idx][MUX_idx * 2]) * internal_prob[level_idx][MUX_idx * 2 + 1]
					+ internal_prob[level_idx][MUX_idx * 2] * (1 - internal_prob[level_idx][MUX_idx * 2 + 1]))
			* input_dens[reverse_idx];
#elif defined(POWER_LUT_SLOW)
			for (sram_idx = sram_offset;
					sram_idx < sram_offset + sram_per_branch; sram_idx++) {
				float branch_prob = 1.;
				if (SRAM_values[sram_idx]
						== SRAM_values[sram_idx + sram_per_branch]) {
					continue;
				}
				for (branch_lvl_idx = 0; branch_lvl_idx < level_idx;
						branch_lvl_idx++) {
					int branch_lvl_reverse_idx = lut_size - branch_lvl_idx - 1;
					int even_odd = sram_idx / vtr::ipow(2, branch_lvl_idx);
					if (even_odd % 2 == 0) {
						branch_prob *= (1 - input_prob[branch_lvl_reverse_idx]);
					} else {
						branch_prob *= input_prob[branch_lvl_reverse_idx];
					}
				}
				sum_prob += branch_prob;
			}
			out_dens += sum_prob * input_dens[reverse_idx];
#endif

			/* Calculate output voltage of multiplexer */
			if (level_restorer_this_level) {
				v_out = power_ctx.tech->Vdd;
			} else {
				v_out = (1 - input_prob[reverse_idx])
						* power_calc_mux_v_out(2, 1.0,
								internal_v[level_idx][MUX_idx * 2],
								internal_prob[level_idx][MUX_idx * 2 + 1])
						+ input_prob[reverse_idx]
								* power_calc_mux_v_out(2, 1.0,
										internal_v[level_idx][MUX_idx * 2 + 1],
										internal_prob[level_idx][MUX_idx * 2]);
			}

			/* Save internal node info */
			internal_dens[level_idx + 1][MUX_idx] = out_dens;
			internal_prob[level_idx + 1][MUX_idx] = out_prob;
			internal_v[level_idx + 1][MUX_idx] = v_out;

			/* Calculate power of the 2-mux */
			power_usage_mux_singlelevel_dynamic(&sub_power, 2,
					internal_dens[level_idx + 1][MUX_idx],
					internal_v[level_idx + 1][MUX_idx],
					&internal_prob[level_idx][MUX_idx * 2],
					&internal_dens[level_idx][MUX_idx * 2],
					&internal_v[level_idx][MUX_idx * 2],
					input_dens[reverse_idx], input_prob[reverse_idx],
					transistor_size, period);
			power_add_usage(power_usage, &sub_power);

			/* Add the level-restoring buffer if necessary */
			if (level_restorer_this_level) {
				/* Level restorer */
				power_usage_buffer(&sub_power, 1,
						internal_prob[level_idx + 1][MUX_idx],
						internal_dens[level_idx + 1][MUX_idx], true, period);
				power_add_usage(power_usage, &sub_power);
			}
		}

	}

	/* Free allocated memory */
	for (i = 0; i <= lut_size; i++) {
		free(internal_prob[i]);
		free(internal_dens[i]);
		free(internal_v[i]);
	}
	free(internal_prob);
	free(internal_dens);
	free(internal_v);

	/* Callibration */
	callibration =
			power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_LUT];
	if (callibration->is_done_callibration()) {
		scale_factor = callibration->scale_factor(lut_size, transistor_size);
		power_scale_usage(power_usage, scale_factor);
	}

	return;
}

/**
 * This function calculates power of a local interconnect structure
 * - power_usage: (Return value) Power usage of the structure
 * - pb: The physical block to which this interconnect belongs
 * - interc_pins: The interconnect input/ouput pin information
 * - interc_length: The physical length spanned by the interconnect (meters)
 */
void power_usage_local_interc_mux(t_power_usage * power_usage, t_pb * pb,
		t_interconnect_pins * interc_pins, ClusterBlockId iblk) {
	int pin_idx;
	int out_port_idx;
	int in_port_idx;
	float * in_dens;
	float * in_prob;
	t_power_usage MUX_power;
	t_interconnect * interc = interc_pins->interconnect;
	t_interconnect_power * interc_power = interc->interconnect_power;
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& power_ctx = g_vpr_ctx.power();

	power_zero_usage(power_usage);

	/* Ensure port/pins are structured as expected */
	switch (interc_pins->interconnect->type) {
	case DIRECT_INTERC:
		VTR_ASSERT(interc_power->num_input_ports == 1);
		VTR_ASSERT(interc_power->num_output_ports == 1);
		break;
	case MUX_INTERC:
		VTR_ASSERT(interc_power->num_output_ports == 1);
		break;
	case COMPLETE_INTERC:
		break;
    default:
        //pass
        break;
	}

	/* Power of transistors to build interconnect structure */
	switch (interc_pins->interconnect->type) {
	case DIRECT_INTERC:
		/* Direct connections require no transistors */
		break;
	case MUX_INTERC:
	case COMPLETE_INTERC:
		/* Many-to-1, or Many-to-Many
		 * Implemented as a multiplexer for each output
		 * */
		in_dens = (float*) vtr::calloc(
				interc->interconnect_power->num_input_ports, sizeof(float));
		in_prob = (float*) vtr::calloc(
				interc->interconnect_power->num_input_ports, sizeof(float));

		for (out_port_idx = 0;
				out_port_idx < interc->interconnect_power->num_output_ports;
				out_port_idx++) {
			for (pin_idx = 0;
					pin_idx < interc->interconnect_power->num_pins_per_port;
					pin_idx++) {

				int selected_input = OPEN;

				/* Clear input densities */
				for (in_port_idx = 0;
						in_port_idx
								< interc->interconnect_power->num_input_ports;
						in_port_idx++) {
					in_dens[in_port_idx] = 0.;
					in_prob[in_port_idx] = 0.;
				}

				/* Get probability/density of input signals */
				if (pb) {
                    int cluster_pin_idx = interc_pins->output_pins[out_port_idx][pin_idx]->pin_count_in_cluster;
					AtomNetId output_pin_net = cluster_ctx.clb_nlist.block_pb(iblk)->pb_route[cluster_pin_idx].atom_net_id;
					if (!output_pin_net) {
						selected_input = 0;
					} else {
						for (in_port_idx = 0;
								in_port_idx
										< interc->interconnect_power->num_input_ports;
								in_port_idx++) {
							t_pb_graph_pin * input_pin =
									interc_pins->input_pins[in_port_idx][pin_idx];
							AtomNetId input_pin_net = cluster_ctx.clb_nlist.block_pb(iblk)->pb_route[input_pin->pin_count_in_cluster].atom_net_id;
							/* Find input pin that connects through the mux to the output pin */
							if (output_pin_net == input_pin_net) {
								selected_input = in_port_idx;
							}

							/* Initialize input densities */
							if (input_pin_net) {
								in_dens[in_port_idx] = pin_dens(pb, input_pin, iblk);
								in_prob[in_port_idx] = pin_prob(pb, input_pin, iblk);
							}
						}

						/* Check that the input pin was found with a matching net to the output pin */
						VTR_ASSERT(selected_input != OPEN);
					}
				} else {
					selected_input = 0;
				}

				/* Calculate power of the multiplexer */
				power_usage_mux_multilevel(&MUX_power,
						power_get_mux_arch(
								interc_pins->interconnect->interconnect_power->num_input_ports,
								power_ctx.arch->mux_transistor_size), in_prob,
						in_dens, selected_input, true, power_ctx.solution_inf.T_crit);

				power_add_usage(power_usage, &MUX_power);
			}
		}

		free(in_dens);
		free(in_prob);
		break;
	default:
		VTR_ASSERT(0);
	}

	power_add_usage(&interc_pins->interconnect->interconnect_power->power_usage,
			power_usage);
}

/**
 *  This calculates the power of a multilevel multiplexer, with static inputs
 *  - power_usage: (Return value) The power usage of the multiplexer
 *  - mux_arch: The information on the multiplexer architecture
 *  - in_prob: Array of input signal probabilities
 *  - in_dens: Array of input transition densitites
 *  - selected_input: The index of the input that has been statically selected
 *  - output_level_restored: Whether the output is level restored to Vdd.
 */
void power_usage_mux_multilevel(t_power_usage * power_usage,
		t_mux_arch * mux_arch, float * in_prob, float * in_dens,
		int selected_input, bool output_level_restored, float period) {
	float output_density;
	float output_prob;
	float V_out;
	bool found;
	PowerSpicedComponent * callibration;
	float scale_factor;
	int * selector_values = (int*) vtr::calloc(mux_arch->levels, sizeof(int));
    auto& power_ctx = g_vpr_ctx.power();

	VTR_ASSERT(selected_input != OPEN);

	power_zero_usage(power_usage);

	/* Find selection index at each level */
	found = mux_find_selector_values(selector_values, mux_arch->mux_graph_head,
			selected_input);

	VTR_ASSERT(found);

	/* Calculate power of the multiplexor stages, from final stage, to first stages */
	power_usage_mux_rec(power_usage, &output_density, &output_prob, &V_out,
			mux_arch->mux_graph_head, mux_arch, selector_values, in_prob,
			in_dens, output_level_restored, period);

	free(selector_values);

	callibration =
			power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_MUX];
	if (callibration->is_done_callibration()) {
		scale_factor = callibration->scale_factor(mux_arch->num_inputs,
				mux_arch->transistor_size);
		power_scale_usage(power_usage, scale_factor);
	}

}

/**
 * Internal function, used recursively by power_calc_mux
 */
static void power_usage_mux_rec(t_power_usage * power_usage, float * out_prob,
		float * out_dens, float * v_out, t_mux_node * mux_node,
		t_mux_arch * mux_arch, int * selector_values,
		float * primary_input_prob, float * primary_input_dens,
		bool v_out_restored, float period) {
	int input_idx;
	float * in_prob;
	float * in_dens;
	float * v_in;
	t_power_usage sub_power_usage;
    auto& power_ctx = g_vpr_ctx.power();

	/* Single input mux is really just a wire, and has no power.
	 * Ensure that it has no children before returning. */
	if (mux_node->num_inputs == 1) {
		VTR_ASSERT(mux_node->level == 0);
		return;
	}

	v_in = (float*) vtr::calloc(mux_node->num_inputs, sizeof(float));
	if (mux_node->level == 0) {
		/* First level of mux - inputs are primar inputs */
		in_prob = &primary_input_prob[mux_node->starting_pin_idx];
		in_dens = &primary_input_dens[mux_node->starting_pin_idx];

		for (input_idx = 0; input_idx < mux_node->num_inputs; input_idx++) {
			v_in[input_idx] = power_ctx.tech->Vdd;
		}
	} else {
		/* Higher level of mux - inputs recursive from lower levels */
		in_prob = (float*) vtr::calloc(mux_node->num_inputs, sizeof(float));
		in_dens = (float*) vtr::calloc(mux_node->num_inputs, sizeof(float));

		for (input_idx = 0; input_idx < mux_node->num_inputs; input_idx++) {
			/* Call recursively for multiplexer driving the input */
			power_usage_mux_rec(power_usage, &in_prob[input_idx],
					&in_dens[input_idx], &v_in[input_idx],
					&mux_node->children[input_idx], mux_arch, selector_values,
					primary_input_prob, primary_input_dens, false, period);
		}
	}

	power_usage_mux_singlelevel_static(&sub_power_usage, out_prob, out_dens,
			v_out, mux_node->num_inputs, selector_values[mux_node->level],
			in_prob, in_dens, v_in, mux_arch->transistor_size, v_out_restored,
			period);
	power_add_usage(power_usage, &sub_power_usage);

	if (mux_node->level != 0) {
		free(in_prob);
		free(in_dens);
	}

	free(v_in);
}

/**
 * This function calculates the power of a multistage buffer
 * - power_usage: (Return value) Power usage of buffer
 * - size: The size of the final buffer stage, relative to min-sized inverter
 * - in_prob: The signal probability of the input
 * - in_dens: The transition density of the input
 * - level_restored: Whether this buffer must level restore the input
 * - input_mux_size: If fed by a mux, the size of this mutliplexer
 */
void power_usage_buffer(t_power_usage * power_usage, float size, float in_prob,
		float in_dens, bool level_restorer, float period) {
	t_power_usage sub_power_usage;
	int i, num_stages;
	float stage_effort;
	float stage_inv_size;
	float stage_in_prob;
	float input_dyn_power;
	float scale_factor;
	PowerSpicedComponent * callibration;

	power_zero_usage(power_usage);

	if (size == 0.) {
		return;
	}

    auto& power_ctx = g_vpr_ctx.power();

	num_stages = power_calc_buffer_num_stages(size,
			power_ctx.arch->logical_effort_factor);
	stage_effort = calc_buffer_stage_effort(num_stages, size);

	stage_in_prob = in_prob;
	for (i = 0; i < num_stages; i++) {
		stage_inv_size = pow(stage_effort, i);

		if (i == 0) {
			if (level_restorer) {
				/* Sense Buffer */
				power_usage_level_restorer(&sub_power_usage, &input_dyn_power,
						in_dens, stage_in_prob, period);
			} else {
				power_usage_inverter(&sub_power_usage, in_dens, stage_in_prob,
						stage_inv_size, period);
			}
		} else {
			power_usage_inverter(&sub_power_usage, in_dens, stage_in_prob,
					stage_inv_size, period);
		}
		power_add_usage(power_usage, &sub_power_usage);

		stage_in_prob = 1 - stage_in_prob;
	}

	/* Callibration */
	if (level_restorer) {
		callibration =
				power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_BUFFER_WITH_LEVR];
	} else {
		callibration =
				power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_BUFFER];
	}

	if (callibration->is_done_callibration()) {
		scale_factor = callibration->scale_factor(1, size);
		power_scale_usage(power_usage, scale_factor);
	}

	/* Short-circuit: add a factor to dynamic power, but the factor is not in addition to the input power
	 * Need to subtract input before adding factor - this matters for small buffers
	 */
	/*power_usage->dynamic += (power_usage->dynamic - input_dyn_power)
	 * power_calc_buffer_sc(num_stages, stage_effort, level_restorer,
	 input_mux_size); */
}

