/*********************************************************************
 *  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.
 *
 ********************************************************************/

/**
 * The functions in this file are used to count the transistors in the
 * FPGA, for physical size estimations
 */

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

#include "vtr_util.h"
#include "vtr_assert.h"
#include "vtr_memory.h"

#include "power_sizing.h"
#include "power.h"
#include "globals.h"
#include "power_util.h"
#include "vpr_utils.h"
/************************ FILE SCOPE *********************************/
static double f_MTA_area;

/************************* FUNCTION DECLARATIONS ********************/
static double power_count_transistors_connectionbox();
static double power_count_transistors_mux(t_mux_arch * mux_arch);
static double power_count_transistors_mux_node(t_mux_node * mux_node,
		float transistor_size);
static void power_mux_node_max_inputs(t_mux_node * mux_node,
		float * max_inputs);
static double power_count_transistors_interc(t_interconnect * interc);
static double power_count_transistors_pb_node(t_pb_graph_node * pb_node);
static double power_count_transistors_switchbox(const t_arch * arch);
static double power_count_transistors_primitive(t_pb_type * pb_type);
static double power_count_transistors_LUT(int LUT_inputs,
		float transistor_size);
static double power_count_transistors_FF(float size);
static double power_count_transistor_SRAM_bit();
static double power_count_transistors_inv(float size);
static double power_count_transistors_trans_gate(float size);
static double power_count_transistors_levr();
static void power_size_pin_buffers_and_wires(t_pb_graph_pin * pin,
		bool pin_is_an_input);
static double power_transistors_for_pb_node(t_pb_graph_node * pb_node);
static double power_transistors_per_tile(const t_arch * arch);
static void power_size_pb();
static void power_size_pb_rec(t_pb_graph_node * pb_node);
static void power_size_pin_to_interconnect(t_interconnect * interc,
		int * fanout, float * wirelength);
static double power_MTAs(float W_size);
static double power_MTAs_L(float L_size);
/************************* FUNCTION DEFINITIONS *********************/

/**
 *  Counts the number of transistors in the largest connection box
 */
static double power_count_transistors_connectionbox() {
	double transistor_cnt = 0.;
	int inputs;
	float buffer_size;

    auto& device_ctx = g_vpr_ctx.device();
    auto& power_ctx = g_vpr_ctx.power();

    auto type = find_most_common_block_type(device_ctx.grid);
	VTR_ASSERT(type->pb_graph_head->num_input_ports == 1);
	inputs = type->pb_graph_head->num_input_pins[0];

	/* Buffers from Tracks */
	buffer_size = power_ctx.commonly_used->max_seg_to_IPIN_fanout
			* (power_ctx.commonly_used->NMOS_1X_C_d
					/ power_ctx.commonly_used->INV_1X_C_in)
			/ power_ctx.arch->logical_effort_factor;
	buffer_size = max(1.0F, buffer_size);
	transistor_cnt += power_ctx.solution_inf.channel_width
			* power_count_transistors_buffer(buffer_size);

	/* Muxes to IPINs */
	transistor_cnt += inputs
			* power_count_transistors_mux(
					power_get_mux_arch(power_ctx.commonly_used->max_IPIN_fanin,
							power_ctx.arch->mux_transistor_size));

	return transistor_cnt;
}

/**
 * Counts the number of transistors in a buffer.
 * - buffer_size: The final stage size of the buffer, relative to a minimum sized inverter
 */
double power_count_transistors_buffer(float buffer_size) {
	int stages;
	float effort;
	float stage_size;
	int stage_idx;
	double transistor_cnt = 0.;

    auto& power_ctx = g_vpr_ctx.power();

	stages = power_calc_buffer_num_stages(buffer_size,
			power_ctx.arch->logical_effort_factor);
	effort = calc_buffer_stage_effort(stages, buffer_size);

	stage_size = 1;
	for (stage_idx = 0; stage_idx < stages; stage_idx++) {
		transistor_cnt += power_count_transistors_inv(stage_size);
		stage_size *= effort;
	}

	return transistor_cnt;
}

/**
 * Counts the number of transistors in a multiplexer
 * - mux_arch: The architecture of the multiplexer
 */
static double power_count_transistors_mux(t_mux_arch * mux_arch) {
	double transistor_cnt = 0.;
	int lvl_idx;
	float * max_inputs;

	/* SRAM bits */
	max_inputs = (float*) vtr::calloc(mux_arch->levels, sizeof(float));
	for (lvl_idx = 0; lvl_idx < mux_arch->levels; lvl_idx++) {
		max_inputs[lvl_idx] = 0.;
	}
	power_mux_node_max_inputs(mux_arch->mux_graph_head, max_inputs);

	for (lvl_idx = 0; lvl_idx < mux_arch->levels; lvl_idx++) {
		/* Assume there is decoder logic */
		transistor_cnt += ceil(log(max_inputs[lvl_idx]) / log((double) 2.0))
				* power_count_transistor_SRAM_bit();

		/*
		 if (mux_arch->encoding_types[lvl_idx] == ENCODING_DECODER) {
		 transistor_cnt += ceil(log2((float)max_inputs[lvl_idx]))
		 * power_cnt_transistor_SRAM_bit();
		 // TODO - Size of decoder
		 } else if (mux_arch->encoding_types[lvl_idx] == ENCODING_ONE_HOT) {
		 transistor_cnt += max_inputs[lvl_idx]
		 * power_cnt_transistor_SRAM_bit();
		 } else {
		 VTR_ASSERT(0);
		 }
		 */
	}

	transistor_cnt += power_count_transistors_mux_node(mux_arch->mux_graph_head,
			mux_arch->transistor_size);
	free(max_inputs);
	return transistor_cnt;
}

/**
 *  This function is used recursively to determine the largest single-level
 *  multiplexer at each level of a multi-level multiplexer
 */
static void power_mux_node_max_inputs(t_mux_node * mux_node,
		float * max_inputs) {

	max_inputs[mux_node->level] = max(max_inputs[mux_node->level],
			static_cast<float>(mux_node->num_inputs));

	if (mux_node->level != 0) {
		int child_idx;

		for (child_idx = 0; child_idx < mux_node->num_inputs; child_idx++) {
			power_mux_node_max_inputs(&mux_node->children[child_idx],
					max_inputs);
		}
	}
}

/**
 * This function is used recursively to count the number of transistors in a multiplexer
 */
static double power_count_transistors_mux_node(t_mux_node * mux_node,
		float transistor_size) {
	int input_idx;
	double transistor_cnt = 0.;

	if (mux_node->num_inputs != 1) {
		for (input_idx = 0; input_idx < mux_node->num_inputs; input_idx++) {
			/* Single Pass transistor */
			transistor_cnt += power_MTAs(transistor_size);

			/* Child MUX */
			if (mux_node->level != 0) {
				transistor_cnt += power_count_transistors_mux_node(
						&mux_node->children[input_idx], transistor_size);
			}
		}
	}

	return transistor_cnt;
}

/**
 * This function returns the number of transistors in an interconnect structure
 */
static double power_count_transistors_interc(t_interconnect * interc) {
	double transistor_cnt = 0.;

	switch (interc->type) {
	case DIRECT_INTERC:
		/* No transistors */
		break;
	case MUX_INTERC:
	case COMPLETE_INTERC: {
		/* Bus based interconnect:
		 * - Each output port requires a (num_input_ports:1) bus-based multiplexor.
		 * - The number of muxes required for bus based multiplexors is equivalent to
		 * the width of the bus (num_pins_per_port).
		 */
        auto& power_ctx = g_vpr_ctx.power();
		transistor_cnt += interc->interconnect_power->num_output_ports
				* interc->interconnect_power->num_pins_per_port
				* power_count_transistors_mux(
						power_get_mux_arch(
								interc->interconnect_power->num_input_ports,
								power_ctx.arch->mux_transistor_size));
		break;
    } default:
		VTR_ASSERT(0);
	}

	interc->interconnect_power->transistor_cnt = transistor_cnt;
	return transistor_cnt;
}

void power_sizing_init(const t_arch * arch) {
	float transistors_per_tile;

    auto& power_ctx = g_vpr_ctx.power();

	// tech size = 2 lambda, so lambda^2/4.0 = tech^2
	f_MTA_area = ((POWER_MTA_L * POWER_MTA_W)/ 4.0)*pow(power_ctx.tech->tech_size,
			(float) 2.0);

	// Determines physical size of different PBs
	power_size_pb();

	/* Find # of transistors in each tile type */
	transistors_per_tile = power_transistors_per_tile(arch);

	/* Calculate CLB tile size
	 *  - Assume a square tile
	 *  - Assume min transistor size is Wx6L
	 *  - Assume an overhead to space transistors
	 */
	power_ctx.commonly_used->tile_length = sqrt(
			power_transistor_area(transistors_per_tile));
}

/**
 * This functions counts the number of transistors in all structures in the FPGA.
 * It returns the number of transistors in a grid of the FPGA (logic block,
 * switch box, 2 connection boxes)
 */
static double power_transistors_per_tile(const t_arch * arch) {
    auto& device_ctx = g_vpr_ctx.device();

	double transistor_cnt = 0.;

    auto type = find_most_common_block_type(device_ctx.grid);
	transistor_cnt += power_transistors_for_pb_node(type->pb_graph_head);

	transistor_cnt += 2 * power_count_transistors_switchbox(arch);

	transistor_cnt += 2 * power_count_transistors_connectionbox();

	return transistor_cnt;
}

static double power_transistors_for_pb_node(t_pb_graph_node * pb_node) {
	return pb_node->pb_node_power->transistor_cnt_interc
			+ pb_node->pb_node_power->transistor_cnt_pb_children
			+ pb_node->pb_node_power->transistor_cnt_buffers;
}

/**
 * This function counts the number of transistors for a given physical block type
 */
static double power_count_transistors_pb_node(t_pb_graph_node * pb_node) {
	int mode_idx;
	int interc;
	int child;
	int pb_idx;

	double tc_children_max = 0;
	double tc_interc_max = 0;
	bool ignore_interc = false;

	t_pb_type * pb_type = pb_node->pb_type;

	/* Check if this is a leaf node, or whether it has children */
	if (pb_type->num_modes == 0) {
		/* Leaf node */
		tc_interc_max = 0;
		tc_children_max = power_count_transistors_primitive(pb_type);
	} else {
		/* Find max transistor count between all modes */
		for (mode_idx = 0; mode_idx < pb_type->num_modes; mode_idx++) {

			double tc_children = 0;
			double tc_interc = 0;

			t_mode * mode = &pb_type->modes[mode_idx];

			if (pb_type->class_type == LUT_CLASS) {
				/* LUTs will have a child node that is used for routing purposes
				 * For the routing algorithms it is completely connected; however,
				 * this interconnect does not exist in FPGA hardware and should
				 * be ignored for power calculations. */
				ignore_interc = true;
			}

			/* Count Interconnect Transistors */
			if (!ignore_interc) {
				for (interc = 0; interc < mode->num_interconnect; interc++) {
					tc_interc += power_count_transistors_interc(
							&mode->interconnect[interc]);
				}
			}
			tc_interc_max = max(tc_interc_max, tc_interc);

			/* Count Child PB Types */
			for (child = 0; child < mode->num_pb_type_children; child++) {
				t_pb_type * child_type = &mode->pb_type_children[child];

				for (pb_idx = 0; pb_idx < child_type->num_pb; pb_idx++) {
					tc_children +=
							power_transistors_for_pb_node(
									&pb_node->child_pb_graph_nodes[mode_idx][child][pb_idx]);
				}
			}

			tc_children_max = max(tc_children_max, tc_children);
		}
	}

	pb_node->pb_node_power->transistor_cnt_interc = tc_interc_max;
	pb_node->pb_node_power->transistor_cnt_pb_children = tc_children_max;

	return (tc_interc_max + tc_children_max);
}

/**
 * This function counts the maximum number of transistors in a switch box
 */
static double power_count_transistors_switchbox(const t_arch * arch) {
	double transistor_cnt = 0.;
	double transistors_per_buf_mux = 0.;
	int seg_idx;

    auto& power_ctx = g_vpr_ctx.power();

	/* Buffer */
	transistors_per_buf_mux += power_count_transistors_buffer(
			(float) power_ctx.commonly_used->max_seg_fanout
					/ power_ctx.arch->logical_effort_factor);

	/* Multiplexor */
	transistors_per_buf_mux += power_count_transistors_mux(
			power_get_mux_arch(power_ctx.commonly_used->max_routing_mux_size,
					power_ctx.arch->mux_transistor_size));

	for (seg_idx = 0; seg_idx < arch->num_segments; seg_idx++) {
		/* In each switchbox, the different types of segments occur with relative freqencies.
		 * Thus the total number of wires of each segment type is (#tracks * freq * 2).
		 * The (x2) factor accounts for vertical and horizontal tracks.
		 * Of the wires of each segment type only (1/seglength) will have a mux&buffer.
		 */
		float freq_frac = (float) arch->Segments[seg_idx].frequency
				/ (float) MAX_CHANNEL_WIDTH;

		transistor_cnt += transistors_per_buf_mux * 2 * freq_frac
				* power_ctx.solution_inf.channel_width
				* (1 / (float) arch->Segments[seg_idx].length);
	}

	return transistor_cnt;
}

/**
 * This function calculates the number of transistors for a primitive physical block
 */
static double power_count_transistors_primitive(t_pb_type * pb_type) {
	double transistor_cnt;

    auto& power_ctx = g_vpr_ctx.power();

	if (strcmp(pb_type->blif_model, MODEL_NAMES) == 0) {
		/* LUT */
		transistor_cnt = power_count_transistors_LUT(pb_type->num_input_pins,
				power_ctx.arch->LUT_transistor_size);
	} else if (strcmp(pb_type->blif_model, MODEL_LATCH) == 0) {
		/* Latch */
		transistor_cnt = power_count_transistors_FF(power_ctx.arch->FF_size);
	} else {
		/* Other */
		char msg[vtr::bufsize];

		sprintf(msg, "No transistor counter function for BLIF model: %s",
				pb_type->blif_model);
		power_log_msg(POWER_LOG_WARNING, msg);
		transistor_cnt = 0;
	}

	return transistor_cnt;
}

/**
 * Returns the transistor count of an SRAM cell
 */
static double power_count_transistor_SRAM_bit() {
    auto& power_ctx = g_vpr_ctx.power();
	return power_ctx.arch->transistors_per_SRAM_bit;
}

static double power_count_transistors_levr() {
	double transistor_cnt = 0.;

	/* Each level restorer has a P/N=1/2 inverter and a W/L=1/2 PMOS */

	/* Inverter */
	transistor_cnt += power_MTAs(2); // NMOS
	transistor_cnt += 1.0; // PMOS

	/* Pull-up */
	transistor_cnt += power_MTAs_L(2.0); // Double length

	return transistor_cnt;
}

/**
 * Returns the transistor count for a LUT
 */
static double power_count_transistors_LUT(int LUT_inputs,
		float transistor_size) {
	double transistor_cnt = 0.;
	int level_idx;

	/* Each input driver has 1-1X and 2-2X inverters */
	transistor_cnt += (double) LUT_inputs
			* (power_count_transistors_inv(1.0)
					+ 2 * power_count_transistors_inv(2.0));

	/* SRAM bits */
	transistor_cnt += power_count_transistor_SRAM_bit() * (1 << LUT_inputs);

	for (level_idx = 0; level_idx < LUT_inputs; level_idx++) {

		/* Pass transistors */
		transistor_cnt += (1 << (LUT_inputs - level_idx))
				* power_MTAs(transistor_size);

		/* 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_inputs - 2))
				|| (level_idx == LUT_inputs - 1)) {
			transistor_cnt += power_count_transistors_levr();
		}
	}

	return transistor_cnt;
}

static double power_count_transistors_trans_gate(float size) {
	double transistor_cnt = 0.;
    auto& power_ctx = g_vpr_ctx.power();

	transistor_cnt += power_MTAs(size);
	transistor_cnt += power_MTAs(size * power_ctx.tech->PN_ratio);

	return transistor_cnt;
}

static double power_count_transistors_inv(float size) {
	double transistor_cnt = 0.;
    auto& power_ctx = g_vpr_ctx.power();

	/* NMOS */
	transistor_cnt += power_MTAs(size);

	/* PMOS */
	transistor_cnt += power_MTAs(power_ctx.tech->PN_ratio * size);

	return transistor_cnt;
}

/**
 * Returns the transistor count for a flip-flop
 */
static double power_count_transistors_FF(float size) {
	double transistor_cnt = 0.;

	/* 4 1X Inverters */
	transistor_cnt += 4 * power_count_transistors_inv(size);

	/* 2 Muxes = 4 transmission gates */
	transistor_cnt += 4 * power_count_transistors_trans_gate(size);

	return transistor_cnt;
}

double power_transistor_area(double num_MTAs) {
	return num_MTAs * f_MTA_area;
}

static double power_MTAs(float W_size) {
	return 1 + (W_size - 1) * (POWER_DRC_MIN_W / POWER_MTA_W);
}

static double power_MTAs_L(float L_size) {
	return 1 + (L_size - 1) * (POWER_DRC_MIN_L / POWER_MTA_L);
}

static void power_size_pb() {
	int type_idx;

    auto& device_ctx = g_vpr_ctx.device();

	for (type_idx = 0; type_idx < device_ctx.num_block_types; type_idx++) {
		if (device_ctx.block_types[type_idx].pb_graph_head) {
			power_size_pb_rec(device_ctx.block_types[type_idx].pb_graph_head);
		}
	}
}

static void power_size_pb_rec(t_pb_graph_node * pb_node) {
	int port_idx, pin_idx;
	int mode_idx, type_idx, pb_idx;
	bool size_buffers_and_wires = true;

    auto& device_ctx = g_vpr_ctx.device();

    auto type = find_most_common_block_type(device_ctx.grid);

	if (!power_method_is_transistor_level(
			pb_node->pb_type->pb_type_power->estimation_method)
			&& pb_node != type->pb_graph_head) {
		/* Area information is only needed for:
		 *  1. Transistor-level estimation methods
		 *  2. the most common block type for tile size calculations
		 */
		return;
	}

	/* Recursive call for all child pb nodes */
	for (mode_idx = 0; mode_idx < pb_node->pb_type->num_modes; mode_idx++) {
		t_mode * mode = &pb_node->pb_type->modes[mode_idx];

		for (type_idx = 0; type_idx < mode->num_pb_type_children; type_idx++) {
			int num_pb = mode->pb_type_children[type_idx].num_pb;

			for (pb_idx = 0; pb_idx < num_pb; pb_idx++) {

				power_size_pb_rec(
						&pb_node->child_pb_graph_nodes[mode_idx][type_idx][pb_idx]);
			}
		}
	}

	/* Determine # of transistors for this node */
	power_count_transistors_pb_node(pb_node);

	if (pb_node->pb_type->class_type == LUT_CLASS) {
		/* LUTs will have a child node that is used for routing purposes
		 * For the routing algorithms it is completely connected; however,
		 * this interconnect does not exist in FPGA hardware and should
		 * be ignored for power calculations. */
		size_buffers_and_wires = false;
	}

	if (!power_method_is_transistor_level(
			pb_node->pb_type->pb_type_power->estimation_method)) {
		size_buffers_and_wires = false;
	}

	/* Size all local buffers and wires */
	if (size_buffers_and_wires) {
		for (port_idx = 0; port_idx < pb_node->num_input_ports; port_idx++) {
			for (pin_idx = 0; pin_idx < pb_node->num_input_pins[port_idx];
					pin_idx++) {
				power_size_pin_buffers_and_wires(
						&pb_node->input_pins[port_idx][pin_idx], true);
			}
		}

		for (port_idx = 0; port_idx < pb_node->num_output_ports; port_idx++) {
			for (pin_idx = 0; pin_idx < pb_node->num_output_pins[port_idx];
					pin_idx++) {
				power_size_pin_buffers_and_wires(
						&pb_node->output_pins[port_idx][pin_idx], false);
			}
		}

		for (port_idx = 0; port_idx < pb_node->num_clock_ports; port_idx++) {
			for (pin_idx = 0; pin_idx < pb_node->num_clock_pins[port_idx];
					pin_idx++) {
				power_size_pin_buffers_and_wires(
						&pb_node->clock_pins[port_idx][pin_idx], true);
			}
		}
	}

}

/* Provides statistics about the connection between the pin and interconnect */
static void power_size_pin_to_interconnect(t_interconnect * interc,
		int * fanout, float * wirelength) {

	float this_interc_sidelength;

	/* Pin to interconnect wirelength */
	switch (interc->type) {
	case DIRECT_INTERC:
		*wirelength = 0;
		*fanout = 1;
		break;
	case MUX_INTERC:

	case COMPLETE_INTERC:
		/* The sidelength of this crossbar */
		this_interc_sidelength = sqrt(
				power_transistor_area(
						interc->interconnect_power->transistor_cnt));

		/* Assume that inputs to the crossbar have a structure like this:
		 *
		 * A   B|-----
		 * -----|---C-
		 *      |-----
		 *
		 * A - wire from pin to point of fanout (grows pb interconnect area)
		 * B - fanout wire (sidelength of this crossbar)
		 * C - fanouts to crossbar muxes (grows with pb interconnect area)
		 */

		*fanout = interc->interconnect_power->num_output_ports;
		*wirelength = this_interc_sidelength;
		//*wirelength = ((1 + *fanout) / 2.0) * power_ctx.arch->local_interc_factor
		//		* pb_interc_sidelength + this_interc_sidelength;
		break;
	default:
		VTR_ASSERT(0);
		break;
	}

}

static void power_size_pin_buffers_and_wires(t_pb_graph_pin * pin,
		bool pin_is_an_input) {
	int edge_idx;
	int list_cnt;
	t_interconnect ** list;
	bool found;
	int i;

	float C_load;
	float this_pb_length;

	int fanout;
	float wirelength_out = 0;
	float wirelength_in = 0;

	int fanout_tmp = 0;
	float wirelength_tmp = 0;

	float this_pb_interc_sidelength = 0;
	float parent_pb_interc_sidelength = 0;
	bool top_level_pb;

	t_pb_type * this_pb_type = pin->parent_node->pb_type;

    auto& power_ctx = g_vpr_ctx.power();

	/*
	 if (strcmp(pin->parent_node->pb_type->name, "clb") == 0) {
	 //VTR_LOG("here\n");
	 }*/

	this_pb_interc_sidelength = sqrt(
			power_transistor_area(
					pin->parent_node->pb_node_power->transistor_cnt_interc));
	if (pin->parent_node->parent_pb_graph_node == nullptr) {
		top_level_pb = true;
		parent_pb_interc_sidelength = 0.;
	} else {
		top_level_pb = false;
		parent_pb_interc_sidelength =
				sqrt(
						power_transistor_area(
								pin->parent_node->parent_pb_graph_node->pb_node_power->transistor_cnt_interc));
	}

	/* Pins are connected to a wire that is connected to:
	 * 1. Interconnect structures belonging its pb_node, and/or
	 * 		- The pb_node may have one or more modes, each with a set of
	 * 		interconnect.  The capacitance is the worst-case capacitance
	 * 		between the different modes.
	 *
	 * 2. Interconnect structures belonging to its parent pb_node
	 */

	/* We want to estimate the physical pin fan-out, unfortunately it is not defined in the architecture file.
	 * Instead, we know the modes of operation, and the fanout may differ depending on the mode.  We assume
	 * that the physical fanout is the max of the connections to the various modes (although in reality it could
	 * be higher)*/

	/* Loop through all edges, building a list of interconnect that this pin drives */
	list = nullptr;
	list_cnt = 0;
	for (edge_idx = 0; edge_idx < pin->num_output_edges; edge_idx++) {
		/* Check if its already in the list */
		found = false;
		for (i = 0; i < list_cnt; i++) {
			if (list[i] == pin->output_edges[edge_idx]->interconnect) {
				found = true;
				break;
			}
		}

		if (!found) {
			list_cnt++;
			list = (t_interconnect**) vtr::realloc(list,
					list_cnt * sizeof(t_interconnect*));
			list[list_cnt - 1] = pin->output_edges[edge_idx]->interconnect;
		}
	}

	/* Determine the:
	 * 1. Wirelength connected to the pin
	 * 2. Fanout of the pin
	 */
	if (pin_is_an_input) {
		/* Pin is an input to the PB.
		 * Thus, all interconnect it drives belong to the modes of the PB.
		 */
		int * fanout_per_mode;
		float * wirelength_out_per_mode;

		fanout_per_mode = (int*) vtr::calloc(this_pb_type->num_modes,
				sizeof(int));
		wirelength_out_per_mode = (float *) vtr::calloc(this_pb_type->num_modes,
				sizeof(float));

		for (i = 0; i < list_cnt; i++) {
			int mode_idx = list[i]->parent_mode_index;

			power_size_pin_to_interconnect(list[i], &fanout_tmp,
					&wirelength_tmp);

			fanout_per_mode[mode_idx] += fanout_tmp;
			wirelength_out_per_mode[mode_idx] += wirelength_tmp;
		}

		fanout = 0;
		wirelength_out = 0.;

		/* Find worst-case between modes*/
		for (i = 0; i < this_pb_type->num_modes; i++) {
			fanout = max(fanout, fanout_per_mode[i]);
			wirelength_out = max(wirelength_out, wirelength_out_per_mode[i]);
		}
		if (wirelength_out != 0) {
			wirelength_out += power_ctx.arch->local_interc_factor
					* this_pb_interc_sidelength;
		}

		free(fanout_per_mode);
		free(wirelength_out_per_mode);

		/* Input wirelength - from parent PB */
		if (!top_level_pb) {
			wirelength_in = power_ctx.arch->local_interc_factor
					* parent_pb_interc_sidelength;
		}

	} else {
		/* Pin is an output of the PB.
		 * Thus, all interconnect it drives belong to the parent PB.
		 */
		fanout = 0;
		wirelength_out = 0.;

		if (top_level_pb) {
			/* Outputs of top-level pb should not drive interconnect */
			VTR_ASSERT(list_cnt == 0);
		}

		/* Loop through all interconnect that this pin drives */

		for (i = 0; i < list_cnt; i++) {
			power_size_pin_to_interconnect(list[i], &fanout_tmp,
					&wirelength_tmp);
			fanout += fanout_tmp;
			wirelength_out += wirelength_tmp;
		}
		if (wirelength_out != 0) {
			wirelength_out += power_ctx.arch->local_interc_factor
					* parent_pb_interc_sidelength;
		}

		/* Input wirelength - from this PB */
		wirelength_in = power_ctx.arch->local_interc_factor
				* this_pb_interc_sidelength;

	}
	free(list);

	/* Wirelength */
	switch (pin->port->port_power->wire_type) {
	case POWER_WIRE_TYPE_IGNORED:
		/* User is ignoring this wirelength */
		pin->pin_power->C_wire = 0.;
		break;
	case POWER_WIRE_TYPE_C:
		pin->pin_power->C_wire = pin->port->port_power->wire.C;
		break;
	case POWER_WIRE_TYPE_ABSOLUTE_LENGTH:
		pin->pin_power->C_wire = pin->port->port_power->wire.absolute_length
				* power_ctx.arch->C_wire_local;
		break;
	case POWER_WIRE_TYPE_RELATIVE_LENGTH:
		this_pb_length = sqrt(
				power_transistor_area(
						power_transistors_for_pb_node(pin->parent_node)));
		pin->pin_power->C_wire = pin->port->port_power->wire.relative_length
				* this_pb_length * power_ctx.arch->C_wire_local;
		break;

	case POWER_WIRE_TYPE_AUTO:
		pin->pin_power->C_wire += power_ctx.arch->C_wire_local
				* (wirelength_in + wirelength_out);
		break;
	case POWER_WIRE_TYPE_UNDEFINED:
	default:
		VTR_ASSERT(0);
		break;
	}

	/* Buffer */
	switch (pin->port->port_power->buffer_type) {
	case POWER_BUFFER_TYPE_NONE:
		/* User assumes no buffer */
		pin->pin_power->buffer_size = 0.;
		break;
	case POWER_BUFFER_TYPE_ABSOLUTE_SIZE:
		pin->pin_power->buffer_size = pin->port->port_power->buffer_size;
		break;
	case POWER_BUFFER_TYPE_AUTO:
		/* Asume the buffer drives the wire & fanout muxes */
		C_load = pin->pin_power->C_wire
				+ (fanout) * power_ctx.commonly_used->INV_1X_C_in; //power_ctx.commonly_used->NMOS_1X_C_d;
		if (C_load > power_ctx.commonly_used->INV_1X_C_in) {
			pin->pin_power->buffer_size = power_buffer_size_from_logical_effort(
					C_load);
		} else {
			pin->pin_power->buffer_size = 0.;
		}
		break;
	case POWER_BUFFER_TYPE_UNDEFINED:
	default:
		VTR_ASSERT(0);
	}

	pin->parent_node->pb_node_power->transistor_cnt_buffers +=
			power_count_transistors_buffer(pin->pin_power->buffer_size);
}
