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