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