/*********************************************************************
 *  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); */
}

