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

    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 (size_t seg_idx = 0; seg_idx < (arch->Segments).size(); 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() {
    auto& device_ctx = g_vpr_ctx.device();

    for (const auto& type : device_ctx.logical_block_types) {
        if (type.pb_graph_head) {
            power_size_pb_rec(type.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->is_root_block_pin()) {
        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);
}
