/*********************************************************************
 *  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 provides functions that calculate the power of low-level
 * components (inverters, simple multiplexers, etc)
 */

/************************* INCLUDES *********************************/
#include "vtr_assert.h"

#include "power_lowlevel.h"
#include "power_util.h"
#include "power_cmos_tech.h"
#include "globals.h"

/************************* FUNCTION DECLARATIONS ********************/
static float power_calc_node_switching_v(float capacitance, float density,
		float period, float voltage);
static void power_calc_transistor_capacitance(float *C_d, float *C_s,
		float *C_g, e_tx_type transistor_type, float size);
static float power_calc_leakage_st(e_tx_type transistor_type, float size);
static float power_calc_leakage_st_pass_transistor(float size, float v_ds);
static float power_calc_leakage_gate(e_tx_type transistor_type, float size);
/*static float power_calc_buffer_sc_levr(
 t_power_buffer_strength_inf * buffer_strength, int input_mux_size);*/

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

/**
 * Initializer function for this module, called by power_init
 */
void power_lowlevel_init() {
	float C_d, C_s, C_g;

    auto& power_ctx = g_vpr_ctx.power();

	power_calc_transistor_capacitance(&C_d, &C_s, &C_g, NMOS, 1.0);
	power_ctx.commonly_used->NMOS_1X_C_d = C_d;
	power_ctx.commonly_used->NMOS_1X_C_g = C_g;
	power_ctx.commonly_used->NMOS_1X_C_s = C_s;

	power_calc_transistor_capacitance(&C_d, &C_s, &C_g, PMOS,
			power_ctx.tech->PN_ratio);
	power_ctx.commonly_used->PMOS_1X_C_d = C_d;
	power_ctx.commonly_used->PMOS_1X_C_g = C_g;
	power_ctx.commonly_used->PMOS_1X_C_s = C_s;

	power_ctx.commonly_used->NMOS_1X_st_leakage = power_calc_leakage_st(NMOS,
			1.0);
	power_ctx.commonly_used->PMOS_1X_st_leakage = power_calc_leakage_st(PMOS,
			1.0 * power_ctx.tech->PN_ratio);

	power_ctx.commonly_used->INV_1X_C_in = power_ctx.commonly_used->NMOS_1X_C_g
			+ power_ctx.commonly_used->PMOS_1X_C_g;
	power_ctx.commonly_used->INV_1X_C = power_ctx.commonly_used->NMOS_1X_C_g
			+ power_ctx.commonly_used->PMOS_1X_C_g
			+ power_ctx.commonly_used->NMOS_1X_C_d
			+ power_ctx.commonly_used->PMOS_1X_C_d;

	power_calc_transistor_capacitance(&C_d, &C_s, &C_g, NMOS, 2.0);
	power_ctx.commonly_used->INV_2X_C = C_g + C_d;
	power_calc_transistor_capacitance(&C_d, &C_s, &C_g, PMOS,
			2.0 * power_ctx.tech->PN_ratio);
	power_ctx.commonly_used->INV_2X_C += C_g + C_d;

}

/**
 * Calculates the switching power of a node
 * - capacitance: The capacitance of the nodoe
 * - density: The transition density of the node
 */
float power_calc_node_switching(float capacitance, float density,
		float period) {
    auto& power_ctx = g_vpr_ctx.power();
	return 0.5 * power_ctx.tech->Vdd * power_ctx.tech->Vdd * capacitance * density
			/ period;
}

/**
 * Calculates the switching power of a node, with non-Vdd voltage
 * - capacitance: The capacitance of the nodoe
 * - density: The transition density of the node
 * - voltage: The voltage when the node is charged
 */
static float power_calc_node_switching_v(float capacitance, float density,
		float period, float voltage) {
    auto& power_ctx = g_vpr_ctx.power();
	return 0.5 * voltage * power_ctx.tech->Vdd * capacitance * density / period;
}

/**
 * Calculates the power of an inverter
 * - power_usage: (Return value) The power usage of the inverter
 * - in_dens: The transition density of the input
 * - in_prob: The signal probability of the input
 * - size: The inverter size, relative to a min-size inverter
 */
void power_usage_inverter(t_power_usage * power_usage, float in_dens,
		float in_prob, float size, float period) {
	float C_drain, C_gate, C_source;
	float C_inv;

    auto& power_ctx = g_vpr_ctx.power();
	float PMOS_size = power_ctx.tech->PN_ratio * size;
	float NMOS_size = size;

	power_usage->dynamic = 0.;
	power_usage->leakage = 0.;

	C_inv = 0.;

	power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, NMOS,
			NMOS_size);
	C_inv += C_gate + C_drain;

	power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, PMOS,
			PMOS_size);
	C_inv += C_gate + C_drain;

	power_usage->dynamic = power_calc_node_switching(C_inv, in_dens, period);

	power_usage->leakage = in_prob * power_calc_leakage_st(PMOS, PMOS_size)
			+ (1 - in_prob) * power_calc_leakage_st(NMOS, NMOS_size);

	power_usage->leakage += in_prob * power_calc_leakage_gate(NMOS, NMOS_size)
			+ (1 - in_prob) * power_calc_leakage_gate(PMOS, PMOS_size);
}

/**
 * Calculates the power of an inverter, with irregular P/N ratio
 * - power_usage: (Return value) The power usage of the inverter
 * - dy_power_input: (Return value) The dynamic power of the input node
 * - in_dens: The transition density of the input
 * - in_prob: The signal probability of the input
 * - PMOS_size: (W/L) of the PMOS
 * - NMOS_size: (W/L) of the NMOS
 */
void power_usage_inverter_irregular(t_power_usage * power_usage,
		float * dyn_power_input, float in_density, float in_probability,
		float PMOS_size, float NMOS_size, float period) {
	float C_drain, C_gate, C_source;
	float C_inv;
	float C_in;

	power_usage->dynamic = 0.;
	power_usage->leakage = 0.;

	C_inv = 0.;
	C_in = 0.;

	power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, NMOS,
			NMOS_size);
	C_inv += C_gate + C_drain;
	C_in += C_gate;

	power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, PMOS,
			PMOS_size);
	C_inv += C_gate + C_drain;
	C_in += C_gate;

	power_usage->dynamic = power_calc_node_switching(C_inv, in_density, period);
	*dyn_power_input = power_calc_node_switching(C_in, in_density, period);

	power_usage->leakage = in_probability
			* power_calc_leakage_st(PMOS, PMOS_size)
			+ (1 - in_probability) * power_calc_leakage_st(NMOS, NMOS_size);
}

/**
 * Calculates the power of an inverter, also returning dynamic power of the input
 * - power_usage: (Return value) The power usage of the inverter
 * - input_dynamic_power: (Return value) The dynamic power of the input node
 * - in_dens: The transition density of the input
 * - in_prob: The signal probability of the input
 * - size: The inverter size, relative to a min-size inverter
 */
#if 0
void power_calc_inverter_with_input(t_power_usage * power_usage,
		float * input_dynamic_power, float in_density, float in_prob,
		float size) {
	float C_drain, C_gate, C_source;
	float C_inv;
	float C_in;

    auto& power_ctx = g_vpr_ctx.power();
	float PMOS_size = power_ctx.tech->PN_ratio * size;
	float NMOS_size = size;

	power_usage->dynamic = 0.;
	power_usage->leakage = 0.;

	C_inv = 0.;
	C_in = 0.;

	power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, NMOS,
			NMOS_size);
	C_inv += C_gate + C_drain;
	C_in += C_gate;

	power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, PMOS,
			PMOS_size);
	C_inv += C_gate + C_drain;
	C_in += C_gate;

	power_usage->dynamic = power_calc_node_switching(C_inv, in_density);
	*input_dynamic_power = power_calc_node_switching(C_in, in_density);

	power_usage->leakage = in_prob * power_calc_leakage_st(PMOS, PMOS_size)
	+ (1 - in_prob) * power_calc_leakage_st(NMOS, NMOS_size);

	power_usage->leakage += in_prob * power_calc_leakage_gate(NMOS, NMOS_size)
	+ (1 - in_prob) * power_calc_leakage_gate(PMOS, PMOS_size);
}
#endif

/**
 * Calculate the capacitance for a transistor
 * - C_d: (Return value) Drain capacitance
 * - C_s: (Return value) Source capacitance
 * - C_g: (Return value) Gate capacitance
 * - transistor_type: NMOS or PMOS
 * - size: (W/L) size of the transistor
 */
static void power_calc_transistor_capacitance(float *C_d, float *C_s,
		float *C_g, e_tx_type transistor_type, float size) {
	t_transistor_size_inf * tx_info_lower;
	t_transistor_size_inf * tx_info_upper;
	bool error;

	/* Initialize to 0 */
	*C_d = 0.;
	*C_s = 0.;
	*C_g = 0.;

	error = power_find_transistor_info(&tx_info_lower, &tx_info_upper,
			transistor_type, size);
	if (error) {
		return;
	}

	if (tx_info_lower == nullptr) {
		/* No lower bound */
		*C_d = tx_info_upper->C_d;
		*C_s = tx_info_upper->C_s;
		*C_g = tx_info_upper->C_g;
	} else if (tx_info_upper == nullptr) {
		/* No upper bound */
		*C_d = tx_info_lower->C_d;
		*C_s = tx_info_lower->C_s;
		*C_g = tx_info_lower->C_g;
	} else {
		/* Linear approximation between sizes */
		float percent_upper = (size - tx_info_lower->size)
				/ (tx_info_upper->size - tx_info_lower->size);
		*C_d = (1 - percent_upper) * tx_info_lower->C_d
				+ percent_upper * tx_info_upper->C_d;
		*C_s = (1 - percent_upper) * tx_info_lower->C_s
				+ percent_upper * tx_info_upper->C_s;
		*C_g = (1 - percent_upper) * tx_info_lower->C_g
				+ percent_upper * tx_info_upper->C_g;
	}

	return;
}

/**
 * Returns the subthreshold leakage power of a transistor,
 * for V_ds = V_dd
 * - transistor_type: NMOS or PMOS
 * - size: (W/L) of transistor
 */
static float power_calc_leakage_st(e_tx_type transistor_type, float size) {
	t_transistor_size_inf * tx_info_lower;
	t_transistor_size_inf * tx_info_upper;
	bool error;
	float current;

	error = power_find_transistor_info(&tx_info_lower, &tx_info_upper,
			transistor_type, size);
	if (error) {
		return 0;
	}

	if (tx_info_lower == nullptr) {
		/* No lower bound */
		current = tx_info_upper->leakage_subthreshold;

	} else if (tx_info_upper == nullptr) {
		/* No upper bound */
		current = tx_info_lower->leakage_subthreshold;
	} else {
		/* Linear approximation between sizes */
		float percent_upper = (size - tx_info_lower->size)
				/ (tx_info_upper->size - tx_info_lower->size);
		current = (1 - percent_upper) * tx_info_lower->leakage_subthreshold
				+ percent_upper * tx_info_upper->leakage_subthreshold;
	}

    auto& power_ctx = g_vpr_ctx.power();
	return current * power_ctx.tech->Vdd;
}

/**
 * Returns the gate gate leakage power of a transistor
 * - transistor_type: NMOS or PMOS
 * - size: (W/L) of transistor
 */
static float power_calc_leakage_gate(e_tx_type transistor_type, float size) {
	t_transistor_size_inf * tx_info_lower;
	t_transistor_size_inf * tx_info_upper;
	bool error;
	float current;

	error = power_find_transistor_info(&tx_info_lower, &tx_info_upper,
			transistor_type, size);
	if (error) {
		return 0;
	}

	if (tx_info_lower == nullptr) {
		/* No lower bound */
		current = tx_info_upper->leakage_gate;

	} else if (tx_info_upper == nullptr) {
		/* No upper bound */
		current = tx_info_lower->leakage_gate;
	} else {
		/* Linear approximation between sizes */
		float percent_upper = (size - tx_info_lower->size)
				/ (tx_info_upper->size - tx_info_lower->size);
		current = (1 - percent_upper) * tx_info_lower->leakage_gate
				+ percent_upper * tx_info_upper->leakage_gate;
	}

    auto& power_ctx = g_vpr_ctx.power();
	return current * power_ctx.tech->Vdd;
}

/**
 * Returns the subthreshold leakage power of a pass-transistor,
 * assumed to be a minimum-sized NMOS
 * - size: (W/L) size of transistor (Must be 1.0)
 * - v_ds: Drain-source voltage
 */
static float power_calc_leakage_st_pass_transistor(float size, float v_ds) {
	t_power_nmos_leakage_inf * nmos_low = nullptr;
	t_power_nmos_leakage_inf * nmos_high = nullptr;

	t_power_nmos_leakage_pair * lower;
	t_power_nmos_leakage_pair * upper;
	float i_ds;
	float power_low;
	float power_high;
	bool over_range = false;

	VTR_ASSERT(size >= 1.0);

    auto& power_ctx = g_vpr_ctx.power();

	// Check if nmos size is beyond range
	if (size >= power_ctx.tech->nmos_leakage_info[power_ctx.tech->num_nmos_leakage_info - 1].nmos_size) {
		nmos_low = &power_ctx.tech->nmos_leakage_info[power_ctx.tech->num_nmos_leakage_info - 1];
		over_range = true;
	} else {
		for (int i = 1; i < power_ctx.tech->num_nmos_leakage_info; i++) {
			if (size < power_ctx.tech->nmos_leakage_info[i].nmos_size) {
				nmos_low = &power_ctx.tech->nmos_leakage_info[i - 1];
				nmos_high = &power_ctx.tech->nmos_leakage_info[i];
				break;
			}
		}
	}

	if (size
			> power_ctx.tech->nmos_leakage_info[power_ctx.tech->num_nmos_leakage_info
					- 1].nmos_size) {
		power_log_msg(POWER_LOG_ERROR,
				"The architectures uses multiplexers with \
				transistors sizes larger than what is defined in the <nmos_leakages> \
				section of the technology file.");
	}

	VTR_ASSERT(nmos_low != nullptr);
	power_find_nmos_leakage(nmos_low, &lower, &upper, v_ds);
	if (lower->v_ds == v_ds || !upper) {
		i_ds = lower->i_ds;
	} else {
		float perc_upper = (v_ds - lower->v_ds) / (upper->v_ds - lower->v_ds);
		i_ds = (1 - perc_upper) * lower->i_ds + perc_upper * upper->i_ds;
	}
	power_low = i_ds * power_ctx.tech->Vdd;

    if (over_range) {
        return power_low;
    } else {
		VTR_ASSERT(nmos_high != nullptr);
		power_find_nmos_leakage(nmos_high, &lower, &upper, v_ds);
		if (lower->v_ds == v_ds || !upper) {
			i_ds = lower->i_ds;
		} else {
			float perc_upper = (v_ds - lower->v_ds)
					/ (upper->v_ds - lower->v_ds);
			i_ds = (1 - perc_upper) * lower->i_ds + perc_upper * upper->i_ds;
		}
		power_high = i_ds * power_ctx.tech->Vdd;

		float perc_upper = (size - nmos_low->nmos_size)
				/ (nmos_high->nmos_size - nmos_low->nmos_size);
		return power_high * perc_upper + power_low * (1 - perc_upper);
	}
}

/**
 * Calculates the power of a wire
 * - power_usage: (Return value) Power usage of the wire
 * - capacitance: Capacitance of the wire (F)
 * - density: Transition density of the wire
 */
void power_usage_wire(t_power_usage * power_usage, float capacitance,
		float density, float period) {
	power_usage->leakage = 0.;
	power_usage->dynamic = power_calc_node_switching(capacitance, density,
			period);
}

/**
 * Calculates the power of a 2-input multiplexer, comprised of transmission gates
 * - power_usage: (Return value) Power usage of the mux
 * - in_dens: Array of input transition densities
 * - in_prob: Array of input signal probabilities
 * - sel_desn: Transition density of select line
 * - sel_prob: Signal probability of select line
 * - out_dens: Transition density of the output
 */
void power_usage_MUX2_transmission(t_power_usage * power_usage, float size,
		float * in_dens, float * in_prob, float sel_dens, float out_dens,
		float period) {

    auto& power_ctx = g_vpr_ctx.power();

	power_zero_usage(power_usage);

	float leakage_n, leakage_p;
	leakage_n = power_calc_leakage_st(NMOS, size);
	leakage_p = power_calc_leakage_st(PMOS, size * power_ctx.tech->PN_ratio);

	float C_g_n, C_d_n, C_s_n;
	power_calc_transistor_capacitance(&C_d_n, &C_s_n, &C_g_n, NMOS, size);

	float C_g_p, C_d_p, C_s_p;
	power_calc_transistor_capacitance(&C_d_p, &C_s_p, &C_g_p, PMOS,
			size * power_ctx.tech->PN_ratio);

	/* A transmission gate leaks if the selected input != other input  */
	power_usage->leakage += (in_prob[0] * (1 - in_prob[1])
			+ (1 - in_prob[0]) * in_prob[1]) * (leakage_n + leakage_p);

	/* Gate switching */
	power_usage->dynamic += 2
			* power_calc_node_switching(C_g_n + C_g_p, sel_dens, period);

	/* Input switching */
	power_usage->dynamic += power_calc_node_switching(C_d_n + C_s_p, in_dens[0],
			period);
	power_usage->dynamic += power_calc_node_switching(C_d_n + C_s_p, in_dens[1],
			period);

	/* Output switching */
	power_usage->dynamic += power_calc_node_switching(2 * (C_s_n + C_d_p),
			out_dens, period);
}

/**
 * Calucates the power of a static, single-level multiplexer
 * - power_usage: (Return value) power usage of the mux
 * - out_prob: (Return value) Signal probability of the output
 * - out_dens: (Return value) Transition density of the output
 * - num_inputs: Number of inputs of the mux
 * - selected_idx: The input index that is selected by the select lines
 * - in_prob: Array of input signal probabilities
 * - in_dens: Array of input tranistion densities
 * - v_in: Array of input max voltages
 * - transistor_size: Size of the NMOS transistors (must be 1.0)
 * - v_out_restored: Whether the output will be level restored to Vdd
 */
void power_usage_mux_singlelevel_static(t_power_usage * power_usage,
		float * out_prob, float * out_dens, float * v_out, int num_inputs,
		int selected_idx, float * in_prob, float * in_dens, float * v_in,
		float transistor_size, bool v_out_restored, float period) {
	int input_idx;
	float v_in_selected;
	float in_prob_avg;

	power_zero_usage(power_usage);

	VTR_ASSERT(transistor_size >= 1.0);

	if (selected_idx < num_inputs) {
		*out_prob = in_prob[selected_idx];
		*out_dens = in_dens[selected_idx];
		v_in_selected = v_in[selected_idx];

	} else {
		/* In this case, the multiplexer is not symetrical.  The
		 * other branch of the mux has more inputs than this one,
		 * and the selected input index is not a valid index for
		 * this portion of the mux.  If the mux was actually built
		 * this way, there would likely be a weak pull-up to ensure
		 * that the node does not float.
		 */
		*out_prob = 1.0;
		*out_dens = 0.0;

		v_in_selected = 0.;
		for (input_idx = 0; input_idx < num_inputs; input_idx++) {
			v_in_selected += v_in[input_idx];
		}
		v_in_selected /= num_inputs;
	}

	in_prob_avg = 0.;

	float C_d, C_g, C_s;
	power_calc_transistor_capacitance(&C_d, &C_s, &C_g, NMOS, transistor_size);

	for (input_idx = 0; input_idx < num_inputs; input_idx++) {
		/* Dynamic Power at Inputs */
		power_usage->dynamic += power_calc_node_switching_v(C_d,
				in_dens[input_idx], period, v_in[input_idx]);

		if (input_idx != selected_idx) {
			in_prob_avg += in_prob[input_idx];
		}
	}
	in_prob_avg /= (num_inputs - 1);

	if (v_out_restored) {
        auto& power_ctx = g_vpr_ctx.power();
		*v_out = power_ctx.tech->Vdd;
	} else {
		*v_out = power_calc_mux_v_out(num_inputs, transistor_size,
				v_in_selected, in_prob_avg);
	}

	for (input_idx = 0; input_idx < num_inputs; input_idx++) {
		/* Leakage */
		/* The selected input will never leak */
		if (input_idx == selected_idx) {
			continue;
		}

		/* Output is high and this input is low */
		power_usage->leakage += (*out_prob) * (1 - in_prob[input_idx])
				* power_calc_leakage_st_pass_transistor(transistor_size,
						*v_out);

		/* Output is low and this input is high */
		power_usage->leakage += (1 - *out_prob) * in_prob[input_idx]
				* power_calc_leakage_st_pass_transistor(transistor_size,
						v_in[input_idx]);
	}

	/* Dynamic Power at Output */
	power_usage->dynamic += power_calc_node_switching_v(C_s * num_inputs,
			*out_dens, period, *v_out);

}

/**
 * This function calcualtes the output voltage of a single-level multiplexer
 * - num_inputs: Number of inputs of the multiplexer
 * - transistor_size: The size of the NMOS transistors (must be 1.0)
 * - v_in: The input voltage of the selcted input
 * - in_prob_avg: The average signal probabilities of the non-selected inputs
 */
float power_calc_mux_v_out(int num_inputs, float transistor_size, float v_in,
		float in_prob_avg) {
	t_power_mux_volt_inf * mux_volt_inf_low;
	t_power_mux_volt_inf * mux_volt_inf_high;
	t_power_mux_volt_pair * lower;
	t_power_mux_volt_pair * upper;
	float v_out_min, v_out_max;
	float v_out_low;
	float v_out_high;
	bool over_range = false;

	VTR_ASSERT(transistor_size >= 1.0);

	t_power_nmos_mux_inf * mux_nmos_inf_lower = nullptr;
	t_power_nmos_mux_inf * mux_nmos_inf_upper = nullptr;

    auto& power_ctx = g_vpr_ctx.power();

// Check if nmos size is beyond range
	if (transistor_size
			>= power_ctx.tech->nmos_mux_info[power_ctx.tech->num_nmos_mux_info - 1].nmos_size) {
		mux_nmos_inf_lower =
				&power_ctx.tech->nmos_mux_info[power_ctx.tech->num_nmos_mux_info - 1];
		over_range = true;
	} else {
		for (int i = 1; i < power_ctx.tech->num_nmos_mux_info; i++) {
			if (transistor_size < power_ctx.tech->nmos_mux_info[i].nmos_size) {
				mux_nmos_inf_lower = &power_ctx.tech->nmos_mux_info[i - 1];
				mux_nmos_inf_upper = &power_ctx.tech->nmos_mux_info[i];
				break;
			}
		}
	}

    VTR_ASSERT(mux_nmos_inf_lower);

	if (transistor_size
			> power_ctx.tech->nmos_mux_info[power_ctx.tech->num_nmos_mux_info - 1].nmos_size) {
		power_log_msg(POWER_LOG_ERROR,
				"The architectures uses multiplexers with \
				transistors sizes larger than what is defined in the <multiplexers> \
				section of the technology file.");
	}

	if (num_inputs > mux_nmos_inf_lower->max_mux_sl_size
			|| (!over_range && mux_nmos_inf_upper && num_inputs > mux_nmos_inf_upper->max_mux_sl_size)) {
		power_log_msg(POWER_LOG_ERROR,
				"The circuit contains a single-level mux larger than \
				what is defined in the <multiplexers> section of the \
				technology file.");
	}

	mux_volt_inf_low = &mux_nmos_inf_lower->mux_voltage_inf[num_inputs];

	power_find_mux_volt_inf(&lower, &upper, mux_volt_inf_low, v_in);
	if (lower->v_in == v_in || !upper) {
		v_out_min = lower->v_out_min;
		v_out_max = lower->v_out_max;
	} else {
		float perc_upper = (v_in - lower->v_in) / (upper->v_in - lower->v_in);
		v_out_min = (1 - perc_upper) * lower->v_out_min
				+ perc_upper * upper->v_out_min;
		v_out_max = (1 - perc_upper) * lower->v_out_max
				+ perc_upper * upper->v_out_max;
	}
	v_out_low = in_prob_avg * v_out_max + (1 - in_prob_avg) * v_out_min;

    if (over_range) {
        return v_out_low;
    } else {
        VTR_ASSERT(mux_nmos_inf_upper);
		mux_volt_inf_high = &mux_nmos_inf_upper->mux_voltage_inf[num_inputs];
		power_find_mux_volt_inf(&lower, &upper, mux_volt_inf_high, v_in);
		if (lower->v_in == v_in || !upper) {
			v_out_min = lower->v_out_min;
			v_out_max = lower->v_out_max;
		} else {
			float perc_upper = (v_in - lower->v_in)
					/ (upper->v_in - lower->v_in);
			v_out_min = (1 - perc_upper) * lower->v_out_min
					+ perc_upper * upper->v_out_min;
			v_out_max = (1 - perc_upper) * lower->v_out_max
					+ perc_upper * upper->v_out_max;
		}
		v_out_high = in_prob_avg * v_out_max + (1 - in_prob_avg) * v_out_min;

		float perc_upper =
				(transistor_size - mux_nmos_inf_lower->nmos_size)
						/ (mux_nmos_inf_upper->nmos_size
								- mux_nmos_inf_lower->nmos_size);
		return v_out_high * perc_upper + (1 - perc_upper) * v_out_low;
	}
}

/** This function calculates the power of a single-level multiplexer, where the
 * select lines are dynamic
 * - power_usage: (Return value) The power usage of the mux
 * - num_inputs: Number of multiplexer inputs (must be 2)
 * - out_density: The transition density of the output
 * - out_prob: The signal probability of the output
 * - v_out: The output max voltage
 * - in_prob: Array of input signal probabilities
 * - in_dens: Array of input tranistion densities
 * - v_in: Array of input voltages
 * - sel_dens: Transition density of the select line
 * - sel_prob: Signal probability of the select line
 * - tranisistor_size: NMOS transistor sizes (must be 1.0)
 */
void power_usage_mux_singlelevel_dynamic(t_power_usage * power_usage,
		int num_inputs, float out_density, float v_out, float * in_prob,
		float * in_dens, float * v_in, float sel_dens, float sel_prob,
		float transistor_size, float period) {

	VTR_ASSERT(num_inputs == 2);

	power_zero_usage(power_usage);

	/* Leakage occurs when input1 != input2.
	 * If the selected input is low, the other transistor leaks input->output
	 * If the selected input is high, the other transistor leaks output->input*/

	/* 1st selected, 1st Low, 2nd High - Leakage from 2nd in->out */
	power_usage->leakage += (1 - sel_prob) * (1 - in_prob[0]) * in_prob[1]
			* power_calc_leakage_st_pass_transistor(transistor_size, v_in[1]);

	/* 1st selected, 1st High, 2nd Low - Leakage from 2nd out->in */
	/* 2nd selected, 1st Low, 2nd High - Leakage from 1st out->in */
	power_usage->leakage += ((1 - sel_prob) * in_prob[0] * (1 - in_prob[1])
			+ sel_prob * (1 - in_prob[0]) * in_prob[1])
			* power_calc_leakage_st_pass_transistor(transistor_size, v_out);

	/* 2nd selected, 1st High, 2nd Low - Leakage from 1st in->out */
	power_usage->leakage += sel_prob * in_prob[0] * (1 - in_prob[1])
			* power_calc_leakage_st_pass_transistor(transistor_size, v_in[0]);

	/* Gate switching */
	float C_d, C_s, C_g;
	power_calc_transistor_capacitance(&C_d, &C_s, &C_g, NMOS, transistor_size);
	power_usage->dynamic += 2
			* power_calc_node_switching(C_g, sel_dens, period);

	/* Input switching */
	power_usage->dynamic += power_calc_node_switching_v(C_d, in_dens[0], period,
			v_in[0]);
	power_usage->dynamic += power_calc_node_switching_v(C_d, in_dens[1], period,
			v_in[1]);

	/* Output switching */
	power_usage->dynamic += power_calc_node_switching_v(2 * C_s, out_density,
			period, v_out);
}

/**
 * This function calculates the power of a level restorer, which is a biased
 * inverter with a pull-up PMOS transistor in feedback.
 * - power_usage: (Return value) Power usage of the level restorer
 * - dyn_power_in: (Return value) Dynamic power at the input
 * - in_density: Transition density of the input
 * - in_prob: Signal probability of the input
 */
void power_usage_level_restorer(t_power_usage * power_usage,
		float * dyn_power_in, float in_dens, float in_prob, float period) {
	t_power_usage sub_power_usage;
	float C;
	float C_in;
	float input_dyn_power = 0.;

	power_zero_usage(power_usage);

	/* Inverter */
	power_usage_inverter_irregular(&sub_power_usage, &input_dyn_power, in_dens,
			in_prob, 1.0, 2.0, period);
	power_add_usage(power_usage, &sub_power_usage);

    auto& power_ctx = g_vpr_ctx.power();

	/* Pull-up PMOS */
	if (power_ctx.tech->PMOS_inf.long_trans_inf == nullptr) {
		power_log_msg(POWER_LOG_ERROR,
				"No long transistor information exists.  Cannot determine transistor properties.");
		return;
	}
	C = power_ctx.tech->PMOS_inf.long_trans_inf->C_d
			+ power_ctx.tech->PMOS_inf.long_trans_inf->C_g;
	C_in = power_ctx.tech->PMOS_inf.long_trans_inf->C_d;

	input_dyn_power += power_calc_node_switching(C_in, in_dens, period);
	power_usage->dynamic += power_calc_node_switching(C, in_dens, period);
	power_usage->leakage += (1 - in_prob)
			* power_ctx.tech->PMOS_inf.long_trans_inf->leakage_subthreshold;

	*dyn_power_in = input_dyn_power;
}

/**
 *  This function calculates the short-circuit factor for a buffer.  This factor
 *  represents the short-circuit power of a buffer, as a factor of switching power.
 *  - stages: Number of stages of the buffer
 *  - gain: The gain at each stage
 *  - level_restorer: Whether this buffer must level-restore the input to Vdd
 *  - input_mux_size: For level-restoring buffers, what is the size of the mux driving it
 */
// Not used anymore
#if 0
float power_calc_buffer_sc(int stages, float gain, bool level_restorer,
		int input_mux_size) {

	t_power_buffer_size_inf * size_inf;
	t_power_buffer_strength_inf * strength_lower;
	t_power_buffer_strength_inf * strength_upper;
	float sc;
    auto& power_ctx = g_vpr_ctx.power();

	/* Find information for given buffer size */
	size_inf = &power_ctx.tech->buffer_size_inf[stages];

	/* Find information for a given size/strength */
	power_find_buffer_strength_inf(&strength_lower, &strength_upper, size_inf,
			gain);

	if (!level_restorer) {
		if (strength_upper == NULL) {
			sc = strength_lower->sc_no_levr;
		} else {
			float percent_upper = (gain - strength_lower->stage_gain)
			/ (strength_upper->stage_gain - strength_lower->stage_gain);
			sc = (1 - percent_upper) * strength_lower->sc_no_levr
			+ percent_upper * strength_upper->sc_no_levr;
		}
	} else {
		/* Level Restored - Short Circuit depends on input mux size */

		if (strength_upper == NULL) {
			sc = power_calc_buffer_sc_levr(strength_lower, input_mux_size);
		} else {
			float sc_buf_low;
			float sc_buf_high;

			sc_buf_low = power_calc_buffer_sc_levr(strength_lower,
					input_mux_size);
			sc_buf_high = power_calc_buffer_sc_levr(strength_upper,
					input_mux_size);

			float percent_upper = (gain - strength_lower->stage_gain)
			/ (strength_upper->stage_gain - strength_lower->stage_gain);
			sc = (1 - percent_upper) * sc_buf_low + percent_upper * sc_buf_high;
		}
	}
	return sc;
}

/**
 * This function calculates the short-circuit factor for a level-restoring buffer,
 * used by power_calc_buffer_sc
 * - buffer_strength: The buffer information, for a given size/strength
 * - input_mux_size: The size of the mux driving this buffer
 */
static float power_calc_buffer_sc_levr(
		t_power_buffer_strength_inf * buffer_strength, int input_mux_size) {
	t_power_buffer_sc_levr_inf * mux_lower;
	t_power_buffer_sc_levr_inf * mux_upper;

	power_find_buffer_sc_levr(&mux_lower, &mux_upper, buffer_strength,
			input_mux_size);
	if (mux_upper == NULL) {
		return mux_lower->sc_levr;
	} else {
		float percent_upper = (input_mux_size - mux_lower->mux_size)
		/ (mux_upper->mux_size - mux_lower->mux_size);
		return (1 - percent_upper) * mux_lower->sc_levr
		+ percent_upper * mux_upper->sc_levr;
	}
}
#endif

float power_calc_buffer_size_from_Cout(float C_out) {
	int i;
	float C_found;
    auto& power_ctx = g_vpr_ctx.power();

	t_transistor_inf * nmos_info = &power_ctx.tech->NMOS_inf;
	t_transistor_inf * pmos_info = &power_ctx.tech->PMOS_inf;

	VTR_ASSERT(nmos_info->num_size_entries == pmos_info->num_size_entries);

	for (i = 0; i < nmos_info->num_size_entries; i++) {
		C_found = nmos_info->size_inf[i].C_d + pmos_info->size_inf[i].C_d;

		/* Not likely, since floating point */
		if (C_out == C_found) {
			return nmos_info->size_inf[i].size;
		}

		/* Gone past */
		if (C_found > C_out) {
			if (i == 0) {
				power_log_msg(POWER_LOG_WARNING,
						"Attempted to search for a transistor with a capacitance smaller than the smallest in the technology file.\n");
				return nmos_info->size_inf[i].size;
			} else {
				float C_prev = nmos_info->size_inf[i - 1].C_d
						+ pmos_info->size_inf[i - 1].C_d;
				float percent_upper = (C_out - C_prev) / (C_found - C_prev);
				return percent_upper * nmos_info->size_inf[i].size
						+ (1 - percent_upper) * nmos_info->size_inf[i - 1].size;
			}
		}

		/* Reached the End */
		if (i == nmos_info->num_size_entries - 1) {
			power_log_msg(POWER_LOG_WARNING,
					"Attempted to search for a transistor with a capacitance greater than the largest in the technology file.\n");
			return nmos_info->size_inf[i].size;
		}
	}

	return 0;
}
