/*********************************************************************
 *  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 is the top-level file for power estimation in VTR
 */

/************************* INCLUDES *********************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <csignal>
#include <ctime>
#include <cmath>
#include <ctype.h>

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

#include "power.h"
#include "power_components.h"
#include "power_util.h"
#include "power_lowlevel.h"
#include "power_sizing.h"
#include "power_callibrate.h"
#include "power_cmos_tech.h"

#include "physical_types.h"
#include "globals.h"
#include "rr_graph.h"
#include "vpr_utils.h"

/************************* DEFINES **********************************/
#define CONVERT_NM_PER_M 1000000000
#define CONVERT_UM_PER_M 1000000

/************************* ENUMS ************************************/
typedef enum {
    POWER_BREAKDOWN_ENTRY_TYPE_TITLE = 0,
    POWER_BREAKDOWN_ENTRY_TYPE_MODE,
    POWER_BREAKDOWN_ENTRY_TYPE_COMPONENT,
    POWER_BREAKDOWN_ENTRY_TYPE_PB,
    POWER_BREAKDOWN_ENTRY_TYPE_INTERC,
    POWER_BREAKDOWN_ENTRY_TYPE_BUFS_WIRES
} e_power_breakdown_entry_type;

/************************* File Scope **********************************/
static t_rr_node_power* rr_node_power;

/************************* Function Declarations ********************/
/* Routing */
static void power_usage_routing(t_power_usage* power_usage,
                                const t_det_routing_arch* routing_arch,
                                const std::vector<t_segment_inf>& segment_inf);

/* Tiles */
static void power_usage_blocks(t_power_usage* power_usage);
static void power_usage_pb(t_power_usage* power_usage, t_pb* pb, t_pb_graph_node* pb_node, ClusterBlockId iblk);
static void power_usage_primitive(t_power_usage* power_usage, t_pb* pb, t_pb_graph_node* pb_graph_node, ClusterBlockId iblk);
static void power_reset_tile_usage();
static void power_reset_pb_type(t_pb_type* pb_type);
static void power_usage_local_buffers_and_wires(t_power_usage* power_usage,
                                                t_pb* pb,
                                                t_pb_graph_node* pb_node,
                                                ClusterBlockId iblk);

/* Clock */
static void power_usage_clock(t_power_usage* power_usage,
                              t_clock_arch* clock_arch);
static void power_usage_clock_single(t_power_usage* power_usage,
                                     t_clock_network* clock_inf);

/* Init/Uninit */
static void dealloc_mux_graph(t_mux_node* node);
static void dealloc_mux_graph_rec(t_mux_node* node);

/* Printing */
static void power_print_breakdown_pb_rec(FILE* fp, t_pb_type* pb_type, int indent);
static void power_print_summary(FILE* fp, const t_vpr_setup& vpr_setup);
//static void power_print_stats(FILE * fp);
static void power_print_breakdown_summary(FILE* fp);
static void power_print_breakdown_entry(FILE* fp, int indent, e_power_breakdown_entry_type type, const char* name, float power, float total_power, float perc_dyn, const char* method);
static void power_print_breakdown_component(FILE* fp, const char* name, e_power_component_type type, int indent_level);
static void power_print_breakdown_pb(FILE* fp);

static const char* power_estimation_method_name(e_power_estimation_method power_method);

void power_usage_local_pin_toggle(t_power_usage* power_usage, t_pb* pb, t_pb_graph_pin* pin, ClusterBlockId iblk);
void power_usage_local_pin_buffer_and_wire(t_power_usage* power_usage,
                                           t_pb* pb,
                                           t_pb_graph_pin* pin,
                                           ClusterBlockId iblk);
void power_alloc_and_init_pb_pin(t_pb_graph_pin* pin);
void power_uninit_pb_pin(t_pb_graph_pin* pin);
void power_init_pb_pins_rec(t_pb_graph_node* pb_node);
void power_uninit_pb_pins_rec(t_pb_graph_node* pb_node);
void power_pb_pins_init();
void power_pb_pins_uninit();
void power_routing_init(const t_det_routing_arch* routing_arch);

/************************* FUNCTION DEFINITIONS *********************/
/**
 *  This function calculates the power of primitives (ff, lut, etc),
 *  by calling the appropriate primitive function.
 *  - power_usage: (Return value)
 *  - pb: The pysical block
 *  - pb_graph_node: The physical block graph node
 *  - calc_dynamic: Calculate dynamic power? Otherwise ignore
 *  - calc_static: Calculate static power? Otherwise ignore
 */
static void power_usage_primitive(t_power_usage* power_usage, t_pb* pb, t_pb_graph_node* pb_graph_node, ClusterBlockId iblk) {
    t_power_usage sub_power_usage;

    power_zero_usage(power_usage);
    power_zero_usage(&sub_power_usage);

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

    if (strcmp(pb_graph_node->pb_type->blif_model, MODEL_NAMES) == 0) {
        /* LUT */

        char* SRAM_values;
        float* input_probabilities;
        float* input_densities;
        int LUT_size;
        int pin_idx;

        VTR_ASSERT(pb_graph_node->num_input_ports == 1);

        LUT_size = pb_graph_node->num_input_pins[0];

        input_probabilities = (float*)vtr::calloc(LUT_size, sizeof(float));
        input_densities = (float*)vtr::calloc(LUT_size, sizeof(float));

        for (pin_idx = 0; pin_idx < LUT_size; pin_idx++) {
            t_pb_graph_pin* pin = &pb_graph_node->input_pins[0][pin_idx];

            input_probabilities[pin_idx] = pin_prob(pb, pin, iblk);
            input_densities[pin_idx] = pin_dens(pb, pin, iblk);
        }

        if (pb) {
            AtomBlockId blk_id = atom_ctx.lookup.pb_atom(pb);
            SRAM_values = alloc_SRAM_values_from_truth_table(LUT_size,
                                                             atom_ctx.nlist.block_truth_table(blk_id));
        } else {
            SRAM_values = alloc_SRAM_values_from_truth_table(LUT_size, AtomNetlist::TruthTable());
        }
        power_usage_lut(&sub_power_usage, LUT_size,
                        power_ctx.arch->LUT_transistor_size, SRAM_values,
                        input_probabilities, input_densities, power_ctx.solution_inf.T_crit);
        power_add_usage(power_usage, &sub_power_usage);
        free(SRAM_values);
        free(input_probabilities);
        free(input_densities);
    } else if (strcmp(pb_graph_node->pb_type->blif_model, MODEL_LATCH) == 0) {
        /* Flip-Flop */

        t_pb_graph_pin* D_pin = &pb_graph_node->input_pins[0][0];
        t_pb_graph_pin* Q_pin = &pb_graph_node->output_pins[0][0];

        float D_dens = 0.;
        float D_prob = 0.;
        float Q_prob = 0.;
        float Q_dens = 0.;
        float clk_dens = 0.;
        float clk_prob = 0.;

        D_dens = pin_dens(pb, D_pin, iblk);
        D_prob = pin_prob(pb, D_pin, iblk);
        Q_dens = pin_dens(pb, Q_pin, iblk);
        Q_prob = pin_prob(pb, Q_pin, iblk);

        clk_prob = device_ctx.clock_arch->clock_inf[0].prob;
        clk_dens = device_ctx.clock_arch->clock_inf[0].dens;

        power_usage_ff(&sub_power_usage, power_ctx.arch->FF_size, D_prob, D_dens,
                       Q_prob, Q_dens, clk_prob, clk_dens, power_ctx.solution_inf.T_crit);
        power_add_usage(power_usage, &sub_power_usage);

    } else {
        char msg[vtr::bufsize];
        sprintf(msg, "No dynamic power defined for BLIF model: %s",
                pb_graph_node->pb_type->blif_model);
        power_log_msg(POWER_LOG_WARNING, msg);

        sprintf(msg, "No leakage power defined for BLIF model: %s",
                pb_graph_node->pb_type->blif_model);
        power_log_msg(POWER_LOG_WARNING, msg);
    }
}

void power_usage_local_pin_toggle(t_power_usage* power_usage, t_pb* pb, t_pb_graph_pin* pin, ClusterBlockId iblk) {
    float scale_factor;
    auto& power_ctx = g_vpr_ctx.power();

    power_zero_usage(power_usage);

    if (pin->pin_power->scaled_by_pin) {
        scale_factor = pin_prob(pb, pin->pin_power->scaled_by_pin, iblk);
        if (pin->port->port_power->reverse_scaled) {
            scale_factor = 1 - scale_factor;
        }
    } else {
        scale_factor = 1.0;
    }

    /* Divide by 2 because density is switches/cycle, but a toggle is 2 switches */
    power_usage->dynamic += scale_factor
                            * pin->port->port_power->energy_per_toggle * pin_dens(pb, pin, iblk) / 2.0
                            / power_ctx.solution_inf.T_crit;
}

void power_usage_local_pin_buffer_and_wire(t_power_usage* power_usage,
                                           t_pb* pb,
                                           t_pb_graph_pin* pin,
                                           ClusterBlockId iblk) {
    t_power_usage sub_power_usage;
    float buffer_size = 0.;
    double C_wire;
    auto& power_ctx = g_vpr_ctx.power();

    power_zero_usage(power_usage);

    /* Wire switching */
    C_wire = pin->pin_power->C_wire;
    power_usage_wire(&sub_power_usage, C_wire, pin_dens(pb, pin, iblk),
                     power_ctx.solution_inf.T_crit);
    power_add_usage(power_usage, &sub_power_usage);

    /* Buffer power */
    buffer_size = pin->pin_power->buffer_size;
    if (buffer_size) {
        power_usage_buffer(&sub_power_usage, buffer_size, pin_prob(pb, pin, iblk),
                           pin_dens(pb, pin, iblk), false, power_ctx.solution_inf.T_crit);
        power_add_usage(power_usage, &sub_power_usage);
    }
}

static void power_usage_local_buffers_and_wires(t_power_usage* power_usage,
                                                t_pb* pb,
                                                t_pb_graph_node* pb_node,
                                                ClusterBlockId iblk) {
    int port_idx;
    int pin_idx;
    t_power_usage pin_power;

    power_zero_usage(power_usage);

    /* Input pins */
    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_usage_local_pin_buffer_and_wire(&pin_power, pb,
                                                  &pb_node->input_pins[port_idx][pin_idx], iblk);
            power_add_usage(power_usage, &pin_power);
        }
    }

    /* Output pins */
    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_usage_local_pin_buffer_and_wire(&pin_power, pb,
                                                  &pb_node->output_pins[port_idx][pin_idx], iblk);
            power_add_usage(power_usage, &pin_power);
        }
    }

    /* Clock pins */
    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_usage_local_pin_buffer_and_wire(&pin_power, pb,
                                                  &pb_node->clock_pins[port_idx][pin_idx], iblk);
            power_add_usage(power_usage, &pin_power);
        }
    }
}

/** Calculates the power of a pb:
 * First checks if dynamic/static power is provided by user in arch file.  If not:
 * - Calculate power of all interconnect
 * - Call recursively for children
 * - If no children, must be a primitive.  Call primitive hander.
 */
static void power_usage_pb(t_power_usage* power_usage, t_pb* pb, t_pb_graph_node* pb_node, ClusterBlockId iblk) {
    t_power_usage power_usage_bufs_wires;
    t_power_usage power_usage_local_muxes;
    t_power_usage power_usage_children;
    t_power_usage power_usage_pin_toggle;
    t_power_usage power_usage_sub;

    int pb_type_idx;
    int pb_idx;
    int interc_idx;
    int pb_mode;
    int port_idx;
    int pin_idx;
    float dens_avg;
    int num_pins;

    auto& power_ctx = g_vpr_ctx.power();

    power_zero_usage(power_usage);

    t_pb_type* pb_type = pb_node->pb_type;
    t_pb_type_power* pb_power = pb_node->pb_type->pb_type_power;

    bool estimate_buffers_and_wire = false;
    bool estimate_multiplexers = false;
    bool estimate_primitives = false;
    bool recursive_children;

    /* Get mode */
    if (pb) {
        pb_mode = pb->mode;
    } else {
        /* Default mode if not initialized (will only affect leakage power) */
        pb_mode = pb_type->pb_type_power->leakage_default_mode;
    }

    recursive_children = power_method_is_recursive(pb_node->pb_type->pb_type_power->estimation_method);

    power_zero_usage(&power_usage_sub);

    switch (pb_node->pb_type->pb_type_power->estimation_method) {
        case POWER_METHOD_IGNORE:
        case POWER_METHOD_SUM_OF_CHILDREN:
            break;

        case POWER_METHOD_ABSOLUTE:
            power_add_usage(power_usage, &pb_power->absolute_power_per_instance);
            power_component_add_usage(&pb_power->absolute_power_per_instance,
                                      POWER_COMPONENT_PB_OTHER);
            break;

        case POWER_METHOD_C_INTERNAL:
            power_zero_usage(&power_usage_sub);

            /* Just take the average density of inputs pins and use
             * that with user-defined block capacitance and leakage */

            /* Average the activity of all pins */
            num_pins = 0;
            dens_avg = 0.;
            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++) {
                    dens_avg += pin_dens(pb,
                                         &pb_node->input_pins[port_idx][pin_idx], iblk);
                    num_pins++;
                }
            }
            if (num_pins != 0) {
                dens_avg = dens_avg / num_pins;
            }
            power_usage_sub.dynamic += power_calc_node_switching(pb_power->C_internal,
                                                                 dens_avg,
                                                                 power_ctx.solution_inf.T_crit);

            /* Leakage is an absolute */
            power_usage_sub.leakage += pb_power->absolute_power_per_instance.leakage;

            /* Add to power of this PB */
            power_add_usage(power_usage, &power_usage_sub);

            // Add to component type
            power_component_add_usage(&power_usage_sub, POWER_COMPONENT_PB_OTHER);
            break;

        case POWER_METHOD_TOGGLE_PINS:
            power_zero_usage(&power_usage_pin_toggle);

            /* Add toggle power of each input pin */
            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++) {
                    t_power_usage pin_power;
                    power_usage_local_pin_toggle(&pin_power, pb,
                                                 &pb_node->input_pins[port_idx][pin_idx], iblk);
                    power_add_usage(&power_usage_pin_toggle, &pin_power);
                }
            }

            /* Add toggle power of each output pin */
            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++) {
                    t_power_usage pin_power;
                    power_usage_local_pin_toggle(&pin_power, pb,
                                                 &pb_node->output_pins[port_idx][pin_idx], iblk);
                    power_add_usage(&power_usage_pin_toggle, &pin_power);
                }
            }

            /* Add toggle power of each clock pin */
            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++) {
                    t_power_usage pin_power;
                    power_usage_local_pin_toggle(&pin_power, pb,
                                                 &pb_node->clock_pins[port_idx][pin_idx], iblk);
                    power_add_usage(&power_usage_pin_toggle, &pin_power);
                }
            }

            /* Static is supplied as an absolute */
            power_usage_pin_toggle.leakage += pb_power->absolute_power_per_instance.leakage;

            // Add to this PB power
            power_add_usage(power_usage, &power_usage_pin_toggle);

            // Add to component type power
            power_component_add_usage(&power_usage_pin_toggle,
                                      POWER_COMPONENT_PB_OTHER);
            break;
        case POWER_METHOD_SPECIFY_SIZES:
            estimate_buffers_and_wire = true;
            estimate_multiplexers = true;
            estimate_primitives = true;
            break;
        case POWER_METHOD_AUTO_SIZES:
            estimate_buffers_and_wire = true;
            estimate_multiplexers = true;
            estimate_primitives = true;
            break;
        case POWER_METHOD_UNDEFINED:
        default:
            VTR_ASSERT(0);
            break;
    }

    if (pb_node->pb_type->class_type == LUT_CLASS) {
        /* LUTs will have a child node that is used to indicate pin
         * equivalence for routing purposes.
         * There is a crossbar to the child node; however,
         * this interconnect does not exist in FPGA hardware and should
         * be ignored for power calculations. */
        estimate_buffers_and_wire = false;
        estimate_multiplexers = false;
    }

    if (pb_node->is_primitive()) {
        /* This is a leaf node, which is a primitive (lut, ff, etc) */
        if (estimate_primitives) {
            VTR_ASSERT(pb_node->pb_type->blif_model);
            power_usage_primitive(&power_usage_sub, pb, pb_node, iblk);

            // Add to power of this PB
            power_add_usage(power_usage, &power_usage_sub);

            // Add to power of component type
            power_component_add_usage(&power_usage_sub,
                                      POWER_COMPONENT_PB_PRIMITIVES);
        }

    } else {
        /* This node had children.  The power of this node is the sum of:
         *  - Buffers/Wires in Interconnect from Parent to children
         *  - Multiplexers in Interconnect from Parent to children
         *  - Child nodes
         */

        if (estimate_buffers_and_wire) {
            /* Check pins of all interconnect */
            power_usage_local_buffers_and_wires(&power_usage_bufs_wires, pb,
                                                pb_node, iblk);
            power_component_add_usage(&power_usage_bufs_wires,
                                      POWER_COMPONENT_PB_BUFS_WIRE);
            power_add_usage(&pb_node->pb_type->pb_type_power->power_usage_bufs_wires,
                            &power_usage_bufs_wires);
            power_add_usage(power_usage, &power_usage_bufs_wires);
        }

        /* Interconnect Structures (multiplexers) */
        if (estimate_multiplexers) {
            power_zero_usage(&power_usage_local_muxes);
            for (interc_idx = 0;
                 interc_idx < pb_type->modes[pb_mode].num_interconnect;
                 interc_idx++) {
                power_usage_local_interc_mux(&power_usage_sub, pb,
                                             &pb_node->interconnect_pins[pb_mode][interc_idx], iblk);
                power_add_usage(&power_usage_local_muxes, &power_usage_sub);
            }
            // Add to power of this PB
            power_add_usage(power_usage, &power_usage_local_muxes);

            // Add to component type power
            power_component_add_usage(&power_usage_local_muxes,
                                      POWER_COMPONENT_PB_INTERC_MUXES);

            // Add to power of this mode
            power_add_usage(&pb_node->pb_type->modes[pb_mode].mode_power->power_usage,
                            &power_usage_local_muxes);
        }

        /* Add power for children */
        if (recursive_children) {
            power_zero_usage(&power_usage_children);
            for (pb_type_idx = 0;
                 pb_type_idx
                 < pb_node->pb_type->modes[pb_mode].num_pb_type_children;
                 pb_type_idx++) {
                for (pb_idx = 0;
                     pb_idx
                     < pb_node->pb_type->modes[pb_mode].pb_type_children[pb_type_idx].num_pb;
                     pb_idx++) {
                    t_pb* child_pb = nullptr;
                    t_pb_graph_node* child_pb_graph_node;

                    if (pb && pb->child_pbs[pb_type_idx][pb_idx].name) {
                        /* Child is initialized */
                        child_pb = &pb->child_pbs[pb_type_idx][pb_idx];
                    }
                    child_pb_graph_node = &pb_node->child_pb_graph_nodes[pb_mode][pb_type_idx][pb_idx];

                    power_usage_pb(&power_usage_sub, child_pb,
                                   child_pb_graph_node, iblk);
                    power_add_usage(&power_usage_children, &power_usage_sub);
                }
            }
            // Add to power of this PB
            power_add_usage(power_usage, &power_usage_children);

            // Add to power of this mode
            power_add_usage(&pb_node->pb_type->modes[pb_mode].mode_power->power_usage,
                            &power_usage_children);
        }
    }

    power_add_usage(&pb_node->pb_type->pb_type_power->power_usage, power_usage);
}

/* Resets the power stats for all physical blocks */
static void power_reset_pb_type(t_pb_type* pb_type) {
    int mode_idx;
    int child_idx;
    int interc_idx;

    power_zero_usage(&pb_type->pb_type_power->power_usage);
    power_zero_usage(&pb_type->pb_type_power->power_usage_bufs_wires);

    for (mode_idx = 0; mode_idx < pb_type->num_modes; mode_idx++) {
        power_zero_usage(&pb_type->modes[mode_idx].mode_power->power_usage);

        for (child_idx = 0;
             child_idx < pb_type->modes[mode_idx].num_pb_type_children;
             child_idx++) {
            power_reset_pb_type(&pb_type->modes[mode_idx].pb_type_children[child_idx]);
        }
        for (interc_idx = 0;
             interc_idx < pb_type->modes[mode_idx].num_interconnect;
             interc_idx++) {
            power_zero_usage(&pb_type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage);
        }
    }
}

/**
 * Resets the power usage for all tile types
 */
static void power_reset_tile_usage() {
    auto& device_ctx = g_vpr_ctx.device();

    for (const auto& type : device_ctx.logical_block_types) {
        if (type.pb_type) {
            power_reset_pb_type(type.pb_type);
        }
    }
}

/*
 * Calcultes the power usage of all tiles in the FPGA
 */
static void power_usage_blocks(t_power_usage* power_usage) {
    auto& device_ctx = g_vpr_ctx.device();
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& place_ctx = g_vpr_ctx.placement();

    power_zero_usage(power_usage);

    power_reset_tile_usage();

    /* Loop through all grid locations */
    for (size_t x = 0; x < device_ctx.grid.width(); x++) {
        for (size_t y = 0; y < device_ctx.grid.height(); y++) {
            if ((device_ctx.grid[x][y].width_offset != 0)
                || (device_ctx.grid[x][y].height_offset != 0)
                || (device_ctx.grid[x][y].type == device_ctx.EMPTY_TYPE)) {
                continue;
            }

            for (int z = 0; z < device_ctx.grid[x][y].type->capacity; z++) {
                t_pb* pb = nullptr;
                t_power_usage pb_power;

                ClusterBlockId iblk = place_ctx.grid_blocks[x][y].blocks[z];

                if (iblk != EMPTY_BLOCK_ID && iblk != INVALID_BLOCK_ID)
                    pb = cluster_ctx.clb_nlist.block_pb(iblk);

                /* Calculate power of this CLB */
                power_usage_pb(&pb_power, pb, logical_block_type(device_ctx.grid[x][y].type)->pb_graph_head, iblk);
                power_add_usage(power_usage, &pb_power);
            }
        }
    }
    return;
}

/**
 * Calculates the total power usage from the clock network
 */
static void power_usage_clock(t_power_usage* power_usage,
                              t_clock_arch* clock_arch) {
    int clock_idx;
    auto& power_ctx = g_vpr_ctx.power();

    /* Initialization */
    power_usage->dynamic = 0.;
    power_usage->leakage = 0.;

    /* if no global clock, then return */
    if (clock_arch->num_global_clocks == 0) {
        return;
    }

    for (clock_idx = 0; clock_idx < clock_arch->num_global_clocks;
         clock_idx++) {
        t_power_usage clock_power;

        /* Assume the global clock is active even for combinational circuits */
        if (clock_arch->num_global_clocks == 1) {
            if (clock_arch->clock_inf[clock_idx].dens == 0) {
                clock_arch->clock_inf[clock_idx].dens = 2;
                clock_arch->clock_inf[clock_idx].prob = 0.5;

                // This will need to change for multi-clock
                clock_arch->clock_inf[clock_idx].period = power_ctx.solution_inf.T_crit;
            }
        }
        /* find the power dissipated by each clock network */
        power_usage_clock_single(&clock_power,
                                 &clock_arch->clock_inf[clock_idx]);
        power_add_usage(power_usage, &clock_power);
    }

    return;
}

/**
 * Calculates the power from a single spine-and-rib global clock
 */
static void power_usage_clock_single(t_power_usage* power_usage,
                                     t_clock_network* single_clock) {
    /*
     *
     * The following code assumes a spine-and-rib clock network as shown below.
     * This is comprised of 3 main combonents:
     * 	1. A single wire from the io pad to the center of the chip
     * 	2. A H-structure which provides a 'spine' to all 4 quadrants
     * 	3. Ribs connect each spine with an entire column of blocks
     *
     * ___________________
     * |                 |
     * | |_|_|_2__|_|_|_ |
     * | | | |  | | | |  |
     * | |3| |  | | | |  |
     * |        |        |
     * | | | |  | | | |  |
     * | |_|_|__|_|_|_|_ |
     * | | | |  | | | |  |
     * |_______1|________|
     * It is assumed that there are a single-inverter buffers placed along each wire,
     * with spacing equal to the FPGA block size (1 buffer/block) */
    t_power_usage clock_buffer_power;
    int length;
    t_power_usage buffer_power;
    t_power_usage wire_power;
    float C_segment;
    float buffer_size;
    auto& power_ctx = g_vpr_ctx.power();
    auto& device_ctx = g_vpr_ctx.device();

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

    /* Check if this clock is active - this is used for calculating leakage */
    if (single_clock->dens) {
    } else {
        VTR_ASSERT(0);
    }

    C_segment = power_ctx.commonly_used->tile_length * single_clock->C_wire;
    if (single_clock->autosize_buffer) {
        buffer_size = 1 + C_segment / power_ctx.commonly_used->INV_1X_C_in;
    } else {
        buffer_size = single_clock->buffer_size;
    }

    /* Calculate the capacitance and leakage power for the clock buffer */
    power_usage_inverter(&clock_buffer_power, single_clock->dens,
                         single_clock->prob, buffer_size, single_clock->period);

    length = 0;

    /* 1. IO to chip center */
    length += device_ctx.grid.height() / 2;

    /* 2. H-Tree to 4 quadrants */
    length += device_ctx.grid.height() / 2; //Vertical component of H
    length += 2 * device_ctx.grid.width();  //Horizontal horizontal component of H (two rows)

    /* 3. Ribs - to */
    length += device_ctx.grid.width() / 2 * device_ctx.grid.height(); //Each rib spand 1/2 of width, two rows of ribs

    buffer_power.dynamic = length * clock_buffer_power.dynamic;
    buffer_power.leakage = length * clock_buffer_power.leakage;

    power_add_usage(power_usage, &buffer_power);
    power_component_add_usage(&buffer_power, POWER_COMPONENT_CLOCK_BUFFER);

    power_usage_wire(&wire_power, length * C_segment, single_clock->dens,
                     single_clock->period);
    power_add_usage(power_usage, &wire_power);
    power_component_add_usage(&wire_power, POWER_COMPONENT_CLOCK_WIRE);

    return;
}

/* Frees a multiplexer graph */
static void dealloc_mux_graph(t_mux_node* node) {
    dealloc_mux_graph_rec(node);
    free(node);
}

static void dealloc_mux_graph_rec(t_mux_node* node) {
    int child_idx;

    /* Dealloc Children */
    if (node->level != 0) {
        for (child_idx = 0; child_idx < node->num_inputs; child_idx++) {
            dealloc_mux_graph_rec(&node->children[child_idx]);
        }
        free(node->children);
    }
}

/**
 * Calculates the power of the entire routing fabric (not local routing
 */
static void power_usage_routing(t_power_usage* power_usage,
                                const t_det_routing_arch* routing_arch,
                                const std::vector<t_segment_inf>& segment_inf) {
    auto& power_ctx = g_vpr_ctx.power();
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& device_ctx = g_vpr_ctx.device();
    auto& route_ctx = g_vpr_ctx.routing();

    power_zero_usage(power_usage);

    /* Reset routing statistics */
    power_ctx.commonly_used->num_sb_buffers = 0;
    power_ctx.commonly_used->total_sb_buffer_size = 0.;
    power_ctx.commonly_used->num_cb_buffers = 0;
    power_ctx.commonly_used->total_cb_buffer_size = 0.;

    /* Reset rr graph net indices */
    for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
        rr_node_power[rr_node_idx].net_num = ClusterNetId::INVALID();
        rr_node_power[rr_node_idx].num_inputs = 0;
        rr_node_power[rr_node_idx].selected_input = 0;
    }

    /* Populate net indices into rr graph */
    for (auto net_id : cluster_ctx.clb_nlist.nets()) {
        t_trace* trace;

        for (trace = route_ctx.trace[net_id].head; trace != nullptr; trace = trace->next) {
            rr_node_power[trace->index].visited = false;
            rr_node_power[trace->index].net_num = net_id;
        }
    }

    /* Populate net indices into rr graph */
    for (auto net_id : cluster_ctx.clb_nlist.nets()) {
        t_trace* trace;

        for (trace = route_ctx.trace[net_id].head; trace != nullptr; trace = trace->next) {
            auto node = &device_ctx.rr_nodes[trace->index];
            t_rr_node_power* node_power = &rr_node_power[trace->index];

            if (node_power->visited) {
                continue;
            }

            for (t_edge_size edge_idx = 0; edge_idx < node->num_edges(); edge_idx++) {
                if (node->edge_sink_node(edge_idx) != OPEN) {
                    auto next_node = &device_ctx.rr_nodes[node->edge_sink_node(edge_idx)];
                    t_rr_node_power* next_node_power = &rr_node_power[node->edge_sink_node(edge_idx)];

                    switch (next_node->type()) {
                        case CHANX:
                        case CHANY:
                        case IPIN:
                            if (next_node_power->net_num == node_power->net_num) {
                                next_node_power->selected_input = next_node_power->num_inputs;
                            }
                            next_node_power->in_dens[next_node_power->num_inputs] = clb_net_density(node_power->net_num);
                            next_node_power->in_prob[next_node_power->num_inputs] = clb_net_prob(node_power->net_num);
                            next_node_power->num_inputs++;
                            if (next_node_power->num_inputs > next_node->fan_in()) {
                                VTR_LOG("%d %d\n", next_node_power->num_inputs,
                                        next_node->fan_in());
                                fflush(nullptr);
                                VTR_ASSERT(0);
                            }
                            break;
                        default:
                            /* Do nothing */
                            break;
                    }
                }
            }
            node_power->visited = true;
        }
    }

    /* Calculate power of all routing entities */
    for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
        t_power_usage sub_power_usage;
        auto node = &device_ctx.rr_nodes[rr_node_idx];
        t_rr_node_power* node_power = &rr_node_power[rr_node_idx];
        float C_wire;
        float buffer_size;
        int connectionbox_fanout;
        int switchbox_fanout;
        //float C_per_seg_split;
        int wire_length;

        switch (node->type()) {
            case SOURCE:
            case SINK:
            case OPIN:
                /* No power usage for these types */
                break;
            case IPIN:
                /* This is part of the connectionbox.  The connection box is comprised of:
                 *  - Driver (accounted for at end of CHANX/Y - see below)
                 *  - Multiplexor */

                if (node->fan_in()) {
                    VTR_ASSERT(node_power->in_dens);
                    VTR_ASSERT(node_power->in_prob);

                    /* Multiplexor */
                    power_usage_mux_multilevel(&sub_power_usage,
                                               power_get_mux_arch(node->fan_in(),
                                                                  power_ctx.arch->mux_transistor_size),
                                               node_power->in_prob, node_power->in_dens,
                                               node_power->selected_input, true,
                                               power_ctx.solution_inf.T_crit);
                    power_add_usage(power_usage, &sub_power_usage);
                    power_component_add_usage(&sub_power_usage,
                                              POWER_COMPONENT_ROUTE_CB);
                }
                break;
            case CHANX:
            case CHANY:
                /* This is a wire driven by a switchbox, which includes:
                 * 	- The Multiplexor at the beginning of the wire
                 * 	- A buffer, after the mux to drive the wire
                 * 	- The wire itself
                 * 	- A buffer at the end of the wire, going to switchbox/connectionbox */
                VTR_ASSERT(node_power->in_dens);
                VTR_ASSERT(node_power->in_prob);

                wire_length = 0;
                if (node->type() == CHANX) {
                    wire_length = node->xhigh() - node->xlow() + 1;
                } else if (node->type() == CHANY) {
                    wire_length = node->yhigh() - node->ylow() + 1;
                }
                C_wire = wire_length
                         * segment_inf[device_ctx.rr_indexed_data[node->cost_index()].seg_index].Cmetal;
                //(double)power_ctx.commonly_used->tile_length);
                VTR_ASSERT(node_power->selected_input < node->fan_in());

                /* Multiplexor */
                power_usage_mux_multilevel(&sub_power_usage,
                                           power_get_mux_arch(node->fan_in(),
                                                              power_ctx.arch->mux_transistor_size),
                                           node_power->in_prob, node_power->in_dens,
                                           node_power->selected_input, true, power_ctx.solution_inf.T_crit);
                power_add_usage(power_usage, &sub_power_usage);
                power_component_add_usage(&sub_power_usage,
                                          POWER_COMPONENT_ROUTE_SB);

                /* Buffer Size */
                switch (device_ctx.rr_switch_inf[node_power->driver_switch_type].power_buffer_type) {
                    case POWER_BUFFER_TYPE_AUTO:
                        /*
                         * C_per_seg_split = ((float) node->num_edges
                         * power_ctx.commonly_used->INV_1X_C_in + C_wire);
                         * // / (float) power_ctx.arch->seg_buffer_split;
                         * buffer_size = power_buffer_size_from_logical_effort(
                         * C_per_seg_split);
                         * buffer_size = std::max(buffer_size, 1.0F);
                         */
                        buffer_size = power_calc_buffer_size_from_Cout(device_ctx.rr_switch_inf[node_power->driver_switch_type].Cout);
                        break;
                    case POWER_BUFFER_TYPE_ABSOLUTE_SIZE:
                        buffer_size = device_ctx.rr_switch_inf[node_power->driver_switch_type].power_buffer_size;
                        buffer_size = std::max(buffer_size, 1.0F);
                        break;
                    case POWER_BUFFER_TYPE_NONE:
                        buffer_size = 0.;
                        break;
                    default:
                        buffer_size = 0.;
                        VTR_ASSERT(0);
                        break;
                }

                power_ctx.commonly_used->num_sb_buffers++;
                power_ctx.commonly_used->total_sb_buffer_size += buffer_size;

                /*
                 * power_ctx.commonly_used->num_sb_buffers +=
                 * power_ctx.arch->seg_buffer_split;
                 * power_ctx.commonly_used->total_sb_buffer_size += buffer_size
                 * power_ctx.arch->seg_buffer_split;
                 */

                /* Buffer */
                power_usage_buffer(&sub_power_usage, buffer_size,
                                   node_power->in_prob[node_power->selected_input],
                                   node_power->in_dens[node_power->selected_input], true,
                                   power_ctx.solution_inf.T_crit);
                power_add_usage(power_usage, &sub_power_usage);
                power_component_add_usage(&sub_power_usage,
                                          POWER_COMPONENT_ROUTE_SB);

                /* Wire Capacitance */
                power_usage_wire(&sub_power_usage, C_wire,
                                 clb_net_density(node_power->net_num), power_ctx.solution_inf.T_crit);
                power_add_usage(power_usage, &sub_power_usage);
                power_component_add_usage(&sub_power_usage,
                                          POWER_COMPONENT_ROUTE_GLB_WIRE);

                /* Determine types of switches that this wire drives */
                connectionbox_fanout = 0;
                switchbox_fanout = 0;
                for (t_edge_size iedge = 0; iedge < node->num_edges(); iedge++) {
                    if (node->edge_switch(iedge) == routing_arch->wire_to_rr_ipin_switch) {
                        connectionbox_fanout++;
                    } else if (node->edge_switch(iedge) == routing_arch->delayless_switch) {
                        /* Do nothing */
                    } else {
                        switchbox_fanout++;
                    }
                }

                /* Buffer to next Switchbox */
                if (switchbox_fanout) {
                    buffer_size = power_buffer_size_from_logical_effort(switchbox_fanout * power_ctx.commonly_used->NMOS_1X_C_d);
                    power_usage_buffer(&sub_power_usage, buffer_size,
                                       1 - node_power->in_prob[node_power->selected_input],
                                       node_power->in_dens[node_power->selected_input], false,
                                       power_ctx.solution_inf.T_crit);
                    power_add_usage(power_usage, &sub_power_usage);
                    power_component_add_usage(&sub_power_usage,
                                              POWER_COMPONENT_ROUTE_SB);
                }

                /* Driver for ConnectionBox */
                if (connectionbox_fanout) {
                    buffer_size = power_buffer_size_from_logical_effort(connectionbox_fanout * power_ctx.commonly_used->NMOS_1X_C_d);

                    power_usage_buffer(&sub_power_usage, buffer_size,
                                       1 - node_power->in_prob[node_power->selected_input],
                                       node_power->in_dens[node_power->selected_input],
                                       false, power_ctx.solution_inf.T_crit);
                    power_add_usage(power_usage, &sub_power_usage);
                    power_component_add_usage(&sub_power_usage,
                                              POWER_COMPONENT_ROUTE_CB);

                    power_ctx.commonly_used->num_cb_buffers++;
                    power_ctx.commonly_used->total_cb_buffer_size += buffer_size;
                }
                break;
            default:
                power_log_msg(POWER_LOG_WARNING,
                              "The global routing-resource graph contains an unknown node type.");
                break;
        }
    }
}

void power_alloc_and_init_pb_pin(t_pb_graph_pin* pin) {
    int port_idx;
    t_port* port_to_find;
    t_pb_graph_node* node = pin->parent_node;
    bool found;

    pin->pin_power = (t_pb_graph_pin_power*)vtr::malloc(sizeof(t_pb_graph_pin_power));
    pin->pin_power->C_wire = 0.;
    pin->pin_power->buffer_size = 0.;
    pin->pin_power->scaled_by_pin = nullptr;

    if (pin->port->port_power->scaled_by_port) {
        port_to_find = pin->port->port_power->scaled_by_port;

        /*pin->pin_power->scaled_by_pin =
         * get_pb_graph_node_pin_from_model_port_pin(
         * port_to_find->model_port,
         * pin->port->port_power->scaled_by_port_pin_idx,
         * pin->parent_node);*/
        /* Search input, output, clock ports */

        found = false;
        for (port_idx = 0; port_idx < node->num_input_ports; port_idx++) {
            if (node->input_pins[port_idx][0].port == port_to_find) {
                pin->pin_power->scaled_by_pin = &node->input_pins[port_idx][pin->port->port_power->scaled_by_port_pin_idx];
                found = true;
                break;
            }
        }
        if (!found) {
            for (port_idx = 0; port_idx < node->num_output_ports; port_idx++) {
                if (node->output_pins[port_idx][0].port == port_to_find) {
                    pin->pin_power->scaled_by_pin = &node->output_pins[port_idx][pin->port->port_power->scaled_by_port_pin_idx];
                    found = true;
                    break;
                }
            }
        }
        if (!found) {
            for (port_idx = 0; port_idx < node->num_clock_ports; port_idx++) {
                if (node->clock_pins[port_idx][0].port == port_to_find) {
                    pin->pin_power->scaled_by_pin = &node->clock_pins[port_idx][pin->port->port_power->scaled_by_port_pin_idx];
                    found = true;
                    break;
                }
            }
        }
        VTR_ASSERT(found);

        VTR_ASSERT(pin->pin_power->scaled_by_pin);
    }
}

void power_uninit_pb_pin(t_pb_graph_pin* pin) {
    vtr::free(pin->pin_power);
    pin->pin_power = nullptr;
}

void power_init_pb_pins_rec(t_pb_graph_node* pb_node) {
    int mode;
    int type;
    int pb;
    int port_idx;
    int pin_idx;

    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_alloc_and_init_pb_pin(&pb_node->input_pins[port_idx][pin_idx]);
        }
    }

    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_alloc_and_init_pb_pin(&pb_node->output_pins[port_idx][pin_idx]);
        }
    }

    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_alloc_and_init_pb_pin(&pb_node->clock_pins[port_idx][pin_idx]);
        }
    }

    for (mode = 0; mode < pb_node->pb_type->num_modes; mode++) {
        for (type = 0; type < pb_node->pb_type->modes[mode].num_pb_type_children; type++) {
            for (pb = 0; pb < pb_node->pb_type->modes[mode].pb_type_children[type].num_pb; pb++) {
                power_init_pb_pins_rec(&pb_node->child_pb_graph_nodes[mode][type][pb]);
            }
        }
    }
}

void power_uninit_pb_pins_rec(t_pb_graph_node* pb_node) {
    int mode;
    int type;
    int pb;
    int port_idx;
    int pin_idx;

    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_uninit_pb_pin(&pb_node->input_pins[port_idx][pin_idx]);
        }
    }

    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_uninit_pb_pin(&pb_node->output_pins[port_idx][pin_idx]);
        }
    }

    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_uninit_pb_pin(&pb_node->clock_pins[port_idx][pin_idx]);
        }
    }

    for (mode = 0; mode < pb_node->pb_type->num_modes; mode++) {
        for (type = 0; type < pb_node->pb_type->modes[mode].num_pb_type_children; type++) {
            for (pb = 0; pb < pb_node->pb_type->modes[mode].pb_type_children[type].num_pb; pb++) {
                power_uninit_pb_pins_rec(&pb_node->child_pb_graph_nodes[mode][type][pb]);
            }
        }
    }
}

void power_pb_pins_init() {
    auto& device_ctx = g_vpr_ctx.device();

    for (const auto& type : device_ctx.logical_block_types) {
        if (type.pb_graph_head) {
            power_init_pb_pins_rec(type.pb_graph_head);
        }
    }
}

void power_pb_pins_uninit() {
    auto& device_ctx = g_vpr_ctx.device();

    for (const auto& type : device_ctx.logical_block_types) {
        if (type.pb_graph_head) {
            power_uninit_pb_pins_rec(type.pb_graph_head);
        }
    }
}

void power_routing_init(const t_det_routing_arch* routing_arch) {
    int max_fanin;
    int max_IPIN_fanin;
    int max_seg_to_IPIN_fanout;
    int max_seg_to_seg_fanout;
    auto& power_ctx = g_vpr_ctx.mutable_power();
    auto& device_ctx = g_vpr_ctx.device();
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& atom_ctx = g_vpr_ctx.atom();

    /* Copy probability/density values to new netlist */
    if (power_ctx.clb_net_power.size() == 0) {
        power_ctx.clb_net_power.resize(cluster_ctx.clb_nlist.nets().size());
    }
    for (auto net_id : cluster_ctx.clb_nlist.nets()) {
        power_ctx.clb_net_power[net_id].probability = power_ctx.atom_net_power[atom_ctx.lookup.atom_net(net_id)].probability;
        power_ctx.clb_net_power[net_id].density = power_ctx.atom_net_power[atom_ctx.lookup.atom_net(net_id)].density;
    }

    /* Initialize RR Graph Structures */
    rr_node_power = (t_rr_node_power*)vtr::calloc(device_ctx.rr_nodes.size(),
                                                  sizeof(t_rr_node_power));
    for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
        rr_node_power[rr_node_idx].driver_switch_type = OPEN;
    }

    /* Initialize Mux Architectures */
    max_fanin = 0;
    max_IPIN_fanin = 0;
    max_seg_to_seg_fanout = 0;
    max_seg_to_IPIN_fanout = 0;
    for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
        int fanout_to_IPIN = 0;
        int fanout_to_seg = 0;
        auto node = &device_ctx.rr_nodes[rr_node_idx];
        t_rr_node_power* node_power = &rr_node_power[rr_node_idx];

        switch (node->type()) {
            case IPIN:
                max_IPIN_fanin = std::max(max_IPIN_fanin,
                                          static_cast<int>(node->fan_in()));
                max_fanin = std::max(max_fanin, static_cast<int>(node->fan_in()));

                node_power->in_dens = (float*)vtr::calloc(node->fan_in(),
                                                          sizeof(float));
                node_power->in_prob = (float*)vtr::calloc(node->fan_in(),
                                                          sizeof(float));
                break;
            case CHANX:
            case CHANY:
                for (t_edge_size iedge = 0; iedge < node->num_edges(); iedge++) {
                    if (node->edge_switch(iedge) == routing_arch->wire_to_rr_ipin_switch) {
                        fanout_to_IPIN++;
                    } else if (node->edge_switch(iedge) != routing_arch->delayless_switch) {
                        fanout_to_seg++;
                    }
                }
                max_seg_to_IPIN_fanout = std::max(max_seg_to_IPIN_fanout,
                                                  fanout_to_IPIN);
                max_seg_to_seg_fanout = std::max(max_seg_to_seg_fanout, fanout_to_seg);
                max_fanin = std::max(max_fanin, static_cast<int>(node->fan_in()));

                node_power->in_dens = (float*)vtr::calloc(node->fan_in(),
                                                          sizeof(float));
                node_power->in_prob = (float*)vtr::calloc(node->fan_in(),
                                                          sizeof(float));
                break;
            default:
                /* Do nothing */
                break;
        }
    }
    power_ctx.commonly_used->max_routing_mux_size = max_fanin;
    power_ctx.commonly_used->max_IPIN_fanin = max_IPIN_fanin;
    power_ctx.commonly_used->max_seg_to_seg_fanout = max_seg_to_seg_fanout;
    power_ctx.commonly_used->max_seg_to_IPIN_fanout = max_seg_to_IPIN_fanout;

#ifdef PRINT_SPICE_COMPARISON
    power_ctx.commonly_used->max_routing_mux_size = std::max(power_ctx.commonly_used->max_routing_mux_size, 26);
#endif

    /* Populate driver switch type */
    for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
        auto node = &device_ctx.rr_nodes[rr_node_idx];

        for (t_edge_size edge_idx = 0; edge_idx < node->num_edges(); edge_idx++) {
            if (node->edge_sink_node(edge_idx) != OPEN) {
                if (rr_node_power[node->edge_sink_node(edge_idx)].driver_switch_type == OPEN) {
                    rr_node_power[node->edge_sink_node(edge_idx)].driver_switch_type = node->edge_switch(edge_idx);
                } else {
                    VTR_ASSERT(rr_node_power[node->edge_sink_node(edge_idx)].driver_switch_type == node->edge_switch(edge_idx));
                }
            }
        }
    }

    /* Find Max Fanout of Routing Buffer	 */
    t_edge_size max_seg_fanout = 0;
    for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
        auto node = &device_ctx.rr_nodes[rr_node_idx];

        switch (node->type()) {
            case CHANX:
            case CHANY:
                if (node->num_edges() > max_seg_fanout) {
                    max_seg_fanout = node->num_edges();
                }
                break;
            default:
                /* Do nothing */
                break;
        }
    }
    power_ctx.commonly_used->max_seg_fanout = max_seg_fanout;
}

/**
 * Initialization for all power-related functions
 */
bool power_init(const char* power_out_filepath,
                const char* cmos_tech_behavior_filepath,
                const t_arch* arch,
                const t_det_routing_arch* routing_arch) {
    auto& power_ctx = g_vpr_ctx.mutable_power();
    bool error = false;

    /* Set global power architecture & options */
    power_ctx.arch = arch->power;
    power_ctx.commonly_used = new t_power_commonly_used;
    power_ctx.tech = (t_power_tech*)vtr::malloc(sizeof(t_power_tech));
    power_ctx.output = (t_power_output*)vtr::malloc(sizeof(t_power_output));

    /* Set up Logs */
    power_ctx.output->num_logs = POWER_LOG_NUM_TYPES;
    power_ctx.output->logs = (t_log*)vtr::calloc(power_ctx.output->num_logs,
                                                 sizeof(t_log));
    power_ctx.output->logs[POWER_LOG_ERROR].name = vtr::strdup("Errors");
    power_ctx.output->logs[POWER_LOG_WARNING].name = vtr::strdup("Warnings");

    /* Initialize output file */
    if (!error) {
        power_ctx.output->out = nullptr;
        power_ctx.output->out = vtr::fopen(power_out_filepath, "w");
        if (!power_ctx.output->out) {
            error = true;
        }
    }

    /* Load technology properties */
    power_tech_init(cmos_tech_behavior_filepath);

    /* Low-Level Initialization */
    power_lowlevel_init();

    /* Initialize sub-modules */
    power_components_init();

    /* Perform callibration */
    power_callibrate();

    /* Initialize routing information */
    power_routing_init(routing_arch);

    // Allocates power structures for each pb pin
    power_pb_pins_init();

    /* Size all components */
    power_sizing_init(arch);

    //power_print_spice_comparison();
    //	power_print_callibration();

    return error;
}

/**
 * Uninitialize power module
 */
bool power_uninit() {
    int mux_size;
    int log_idx;
    int msg_idx;
    auto& device_ctx = g_vpr_ctx.device();
    auto& power_ctx = g_vpr_ctx.power();
    bool error = false;

    for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
        auto node = &device_ctx.rr_nodes[rr_node_idx];
        t_rr_node_power* node_power = &rr_node_power[rr_node_idx];

        switch (node->type()) {
            case CHANX:
            case CHANY:
            case IPIN:
                if (node->fan_in()) {
                    free(node_power->in_dens);
                    free(node_power->in_prob);
                }
                break;
            default:
                /* Do nothing */
                break;
        }
    }
    free(rr_node_power);

    /* Free mux architectures */
    for (std::map<float, t_power_mux_info*>::iterator it = power_ctx.commonly_used->mux_info.begin();
         it != power_ctx.commonly_used->mux_info.end(); it++) {
        t_power_mux_info* mux_info = it->second;
        for (mux_size = 1; mux_size <= mux_info->mux_arch_max_size; mux_size++) {
            dealloc_mux_graph(mux_info->mux_arch[mux_size].mux_graph_head);
        }
        free(mux_info->mux_arch);
        delete mux_info;
    }
    /* Free components */
    for (int i = 0; i < POWER_CALLIB_COMPONENT_MAX; ++i) {
        delete power_ctx.commonly_used->component_callibration[i];
    }
    free(power_ctx.commonly_used->component_callibration);

    delete power_ctx.commonly_used;

    /* Free logs */
    if (power_ctx.output->out) {
        fclose(power_ctx.output->out);
    }
    for (log_idx = 0; log_idx < power_ctx.output->num_logs; log_idx++) {
        for (msg_idx = 0; msg_idx < power_ctx.output->logs[log_idx].num_messages;
             msg_idx++) {
            free(power_ctx.output->logs[log_idx].messages[msg_idx]);
        }
        free(power_ctx.output->logs[log_idx].messages);
        free(power_ctx.output->logs[log_idx].name);
    }
    free(power_ctx.output->logs);
    free(power_ctx.output);

    power_pb_pins_uninit();

    return error;
}

#if 0
/**
 * Prints the power of all pb structures, in an xml format that matches the archicture file
 */
static void power_print_pb_usage_recursive(FILE * fp, t_pb_type * type,
		int indent_level, float parent_power, float total_power) {
	int mode_idx;
	int mode_indent;
	int child_idx;
	int interc_idx;
	float pb_type_power;

	pb_type_power = type->pb_type_power->power_usage.dynamic
	+ type->pb_type_power->power_usage.leakage;

	print_tabs(fp, indent_level);
	fprintf(fp,
			"<pb_type name=\"%s\" P=\"%.4g\" P_parent=\"%.3g\" P_total=\"%.3g\" P_dyn=\"%.3g\" >\n",
			type->name, pb_type_power, pb_type_power / parent_power * 100,
			pb_type_power / total_power * 100,
			type->pb_type_power->power_usage.dynamic / pb_type_power);

	mode_indent = 0;
	if (type->num_modes > 1) {
		mode_indent = 1;
	}

	for (mode_idx = 0; mode_idx < type->num_modes; mode_idx++) {
		float mode_power;
		mode_power = type->modes[mode_idx].mode_power->power_usage.dynamic
		+ type->modes[mode_idx].mode_power->power_usage.leakage;

		if (type->num_modes > 1) {
			print_tabs(fp, indent_level + mode_indent);
			fprintf(fp,
					"<mode name=\"%s\" P=\"%.4g\" P_parent=\"%.3g\" P_total=\"%.3g\" P_dyn=\"%.3g\">\n",
					type->modes[mode_idx].name, mode_power,
					mode_power / pb_type_power * 100,
					mode_power / total_power * 100,
					type->modes[mode_idx].mode_power->power_usage.dynamic
					/ mode_power);
		}

		if (type->modes[mode_idx].num_interconnect) {
			/* Sum the interconnect power */
			t_power_usage interc_power_usage;
			float interc_total_power;

			power_zero_usage(&interc_power_usage);
			for (interc_idx = 0;
					interc_idx < type->modes[mode_idx].num_interconnect;
					interc_idx++) {
				power_add_usage(&interc_power_usage,
						&type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage);
			}
			interc_total_power = interc_power_usage.dynamic
			+ interc_power_usage.leakage;

			/* All interconnect */
			print_tabs(fp, indent_level + mode_indent + 1);
			fprintf(fp,
					"<interconnect P=\"%.4g\" P_parent=\"%.3g\" P_total=\"%.3g\" P_dyn=\"%.3g\">\n",
					interc_total_power, interc_total_power / mode_power * 100,
					interc_total_power / total_power * 100,
					interc_power_usage.dynamic / interc_total_power);
			for (interc_idx = 0;
					interc_idx < type->modes[mode_idx].num_interconnect;
					interc_idx++) {
				float interc_power =
				type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage.dynamic
				+ type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage.leakage;
				/* Each interconnect */
				print_tabs(fp, indent_level + mode_indent + 2);
				fprintf(fp,
						"<%s name=\"%s\" P=\"%.4g\" P_parent=\"%.3g\" P_total=\"%.3g\" P_dyn=\"%.3g\"/>\n",
						interconnect_type_name(
								type->modes[mode_idx].interconnect[interc_idx].type),
						type->modes[mode_idx].interconnect[interc_idx].name,
						interc_power, interc_power / interc_total_power * 100,
						interc_power / total_power * 100,
						type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage.dynamic
						/ interc_power);
			}
			print_tabs(fp, indent_level + mode_indent + 1);
			fprintf(fp, "</interconnect>\n");
		}

		for (child_idx = 0;
				child_idx < type->modes[mode_idx].num_pb_type_children;
				child_idx++) {
			power_print_pb_usage_recursive(fp,
					&type->modes[mode_idx].pb_type_children[child_idx],
					indent_level + mode_indent + 1,
					type->modes[mode_idx].mode_power->power_usage.dynamic
					+ type->modes[mode_idx].mode_power->power_usage.leakage,
					total_power);
		}

		if (type->num_modes > 1) {
			print_tabs(fp, indent_level + mode_indent);
			fprintf(fp, "</mode>\n");
		}
	}

	print_tabs(fp, indent_level);
	fprintf(fp, "</pb_type>\n");
}

static void power_print_clb_detailed(FILE * fp) {
	int type_idx;
    auto& device_ctx = g_vpr_ctx.device();

	float clb_power_total = power_component_get_usage_sum(
			POWER_COMPONENT_PB);
	for (type_idx = 0; type_idx < device_ctx.num_block_types; type_idx++) {
		if (!device_ctx.block_types[type_idx].pb_type) {
			continue;
		}

		power_print_pb_usage_recursive(fp, device_ctx.block_types[type_idx].pb_type,
				0, clb_power_total, clb_power_total);
	}
}
#endif

/*
 * static void power_print_stats(FILE * fp) {
 * auto& power_ctx = g_vpr_ctx.power();
 * fprintf(fp, "Max Segment Fanout: %d\n",
 * power_ctx.commonly_used->max_seg_fanout);
 * fprintf(fp, "Max Segment->Segment Fanout: %d\n",
 * power_ctx.commonly_used->max_seg_to_seg_fanout);
 * fprintf(fp, "Max Segment->IPIN Fanout: %d\n",
 * power_ctx.commonly_used->max_seg_to_IPIN_fanout);
 * fprintf(fp, "Max IPIN fanin: %d\n", power_ctx.commonly_used->max_IPIN_fanin);
 * fprintf(fp, "Average SB Buffer Size: %.1f\n",
 * power_ctx.commonly_used->total_sb_buffer_size
 * / (float) power_ctx.commonly_used->num_sb_buffers);
 * fprintf(fp, "SB Buffer Transistors: %g\n",
 * power_count_transistors_buffer(
 * power_ctx.commonly_used->total_sb_buffer_size
 * / (float) power_ctx.commonly_used->num_sb_buffers));
 * fprintf(fp, "Average CB Buffer Size: %.1f\n",
 * power_ctx.commonly_used->total_cb_buffer_size
 * / (float) power_ctx.commonly_used->num_cb_buffers);
 * fprintf(fp, "Tile length (um): %.2f\n",
 * power_ctx.commonly_used->tile_length * CONVERT_UM_PER_M);
 * fprintf(fp, "1X Inverter C_in: %g\n", power_ctx.commonly_used->INV_1X_C_in);
 * fprintf(fp, "\n");
 * }
 */

static const char* power_estimation_method_name(e_power_estimation_method power_method) {
    switch (power_method) {
        case POWER_METHOD_UNDEFINED:
            return "Undefined";
        case POWER_METHOD_IGNORE:
            return "Ignore";
        case POWER_METHOD_AUTO_SIZES:
            return "Transistor Auto-Size";
        case POWER_METHOD_SPECIFY_SIZES:
            return "Transistor Specify-Size";
        case POWER_METHOD_TOGGLE_PINS:
            return "Pin-Toggle";
        case POWER_METHOD_C_INTERNAL:
            return "C-Internal";
        case POWER_METHOD_ABSOLUTE:
            return "Absolute";
        case POWER_METHOD_SUM_OF_CHILDREN:
            return "Sum of Children";
        default:
            return "Unkown";
    }
}

static void power_print_breakdown_pb_rec(FILE* fp, t_pb_type* pb_type, int indent) {
    int mode_idx;
    int child_idx;
    int i;
    char buf[51];
    int child_indent;
    int interc_idx;
    t_mode* mode;
    t_power_usage interc_usage;
    e_power_estimation_method est_method = pb_type->pb_type_power->estimation_method;
    float total_power = power_component_get_usage_sum(POWER_COMPONENT_TOTAL);
    t_pb_type_power* pb_power = pb_type->pb_type_power;

    for (i = 0; i < indent; i++) {
        buf[i] = ' ';
    }
    strncpy(buf + indent, pb_type->name, 50 - indent);
    buf[50] = '\0';
    buf[strlen((pb_type->name)) + indent] = '\0';
    power_print_breakdown_entry(fp, indent, POWER_BREAKDOWN_ENTRY_TYPE_PB,
                                pb_type->name, power_sum_usage(&pb_power->power_usage), total_power,
                                power_perc_dynamic(&pb_power->power_usage),
                                power_estimation_method_name(pb_type->pb_type_power->estimation_method));

    if (power_method_is_transistor_level(pb_type->pb_type_power->estimation_method)) {
        /* Local bufs and wires */
        power_print_breakdown_entry(fp, indent + 1,
                                    POWER_BREAKDOWN_ENTRY_TYPE_BUFS_WIRES, "Bufs/Wires",
                                    power_sum_usage(&pb_power->power_usage_bufs_wires), total_power,
                                    power_perc_dynamic(&pb_power->power_usage_bufs_wires), nullptr);
    }

    if (power_method_is_recursive(est_method)) {
        if (pb_type->num_modes > 1) {
            child_indent = indent + 2;
        } else {
            child_indent = indent + 1;
        }

        for (mode_idx = 0; mode_idx < pb_type->num_modes; mode_idx++) {
            mode = &pb_type->modes[mode_idx];

            if (pb_type->num_modes > 1) {
                power_print_breakdown_entry(fp, indent + 1,
                                            POWER_BREAKDOWN_ENTRY_TYPE_MODE, mode->name,
                                            power_sum_usage(&mode->mode_power->power_usage),
                                            total_power,
                                            power_perc_dynamic(&mode->mode_power->power_usage),
                                            nullptr);
            }

            /* Interconnect Power */
            power_zero_usage(&interc_usage);

            /* Sum the interconnect */
            if (power_method_is_transistor_level(est_method)) {
                for (interc_idx = 0; interc_idx < mode->num_interconnect;
                     interc_idx++) {
                    power_add_usage(&interc_usage,
                                    &mode->interconnect[interc_idx].interconnect_power->power_usage);
                }
                if (mode->num_interconnect) {
                    power_print_breakdown_entry(fp, child_indent,
                                                POWER_BREAKDOWN_ENTRY_TYPE_INTERC, "Interc:",
                                                power_sum_usage(&interc_usage), total_power,
                                                power_perc_dynamic(&interc_usage), nullptr);
                }

                /* Print Interconnect Breakdown */
                for (interc_idx = 0; interc_idx < mode->num_interconnect;
                     interc_idx++) {
                    t_interconnect* interc = &mode->interconnect[interc_idx];
                    if (interc->type == DIRECT_INTERC) {
                        // no power - skip
                    } else {
                        power_print_breakdown_entry(fp, child_indent + 1,
                                                    POWER_BREAKDOWN_ENTRY_TYPE_INTERC, interc->name,
                                                    power_sum_usage(&interc->interconnect_power->power_usage),
                                                    total_power,
                                                    power_perc_dynamic(&interc->interconnect_power->power_usage),
                                                    nullptr);
                    }
                }
            }

            for (child_idx = 0;
                 child_idx < pb_type->modes[mode_idx].num_pb_type_children;
                 child_idx++) {
                power_print_breakdown_pb_rec(fp,
                                             &pb_type->modes[mode_idx].pb_type_children[child_idx],
                                             child_indent);
            }
        }
    }
}

static void power_print_summary(FILE* fp, const t_vpr_setup& vpr_setup) {
    auto& power_ctx = g_vpr_ctx.power();
    auto& device_ctx = g_vpr_ctx.device();

    fprintf(power_ctx.output->out, "Circuit: %s\n",
            vpr_setup.FileNameOpts.CircuitName.c_str());
    fprintf(power_ctx.output->out, "Architecture: %s\n", vtr::basename(vpr_setup.FileNameOpts.ArchFile).c_str());
    fprintf(fp, "Technology (nm): %.0f\n",
            power_ctx.tech->tech_size * CONVERT_NM_PER_M);
    fprintf(fp, "Voltage: %.2f\n", power_ctx.tech->Vdd);
    fprintf(fp, "Temperature: %g\n", power_ctx.tech->temperature);
    fprintf(fp, "Critical Path: %g\n", power_ctx.solution_inf.T_crit);
    fprintf(fp, "Size of FPGA: %zu x %zu\n", device_ctx.grid.width(), device_ctx.grid.height());
    fprintf(fp, "Channel Width: %d\n", power_ctx.solution_inf.channel_width);
    fprintf(fp, "\n");
}

/*
 * Top-level function for the power module.
 * Calculates the average power of the entire FPGA (watts),
 * and prints it to the output file
 * - run_time_s: (Return value) The total runtime in seconds (us accuracy)
 */
e_power_ret_code power_total(float* run_time_s, const t_vpr_setup& vpr_setup, const t_arch* arch, const t_det_routing_arch* routing_arch) {
    t_power_usage total_power;
    t_power_usage sub_power_usage;
    clock_t t_start;
    clock_t t_end;
    t_power_usage clb_power_usage;
    auto& power_ctx = g_vpr_ctx.power();

    t_start = clock();

    power_zero_usage(&total_power);

    if (routing_arch->directionality == BI_DIRECTIONAL) {
        power_log_msg(POWER_LOG_ERROR,
                      "Cannot calculate routing power for bi-directional architectures");
        return POWER_RET_CODE_ERRORS;
    }

    /* Calculate Power */
    /* Routing */
    power_usage_routing(&sub_power_usage, routing_arch, arch->Segments);
    power_add_usage(&total_power, &sub_power_usage);
    power_component_add_usage(&sub_power_usage, POWER_COMPONENT_ROUTING);

    /* Clock  */
    power_usage_clock(&sub_power_usage, arch->clocks);
    power_add_usage(&total_power, &sub_power_usage);
    power_component_add_usage(&sub_power_usage, POWER_COMPONENT_CLOCK);

    /* CLBs */
    power_usage_blocks(&clb_power_usage);
    power_add_usage(&total_power, &clb_power_usage);
    power_component_add_usage(&clb_power_usage, POWER_COMPONENT_PB);

    power_component_add_usage(&total_power, POWER_COMPONENT_TOTAL);

    power_print_title(power_ctx.output->out, "Summary");
    power_print_summary(power_ctx.output->out, vpr_setup);

    /* Print Error & Warning Logs */
    output_logs(power_ctx.output->out, power_ctx.output->logs,
                power_ctx.output->num_logs);

    //power_print_title(power_ctx.output->out, "Statistics");
    //power_print_stats(power_ctx.output->out);

    power_print_title(power_ctx.output->out, "Power Breakdown");
    power_print_breakdown_summary(power_ctx.output->out);

    power_print_title(power_ctx.output->out, "Power Breakdown by PB");
    power_print_breakdown_pb(power_ctx.output->out);

    //power_print_title(power_ctx.output->out, "Spice Comparison");
    //power_print_spice_comparison();

    t_end = clock();

    *run_time_s = (float)(t_end - t_start) / CLOCKS_PER_SEC;

    /* Return code */
    if (power_ctx.output->logs[POWER_LOG_ERROR].num_messages) {
        return POWER_RET_CODE_ERRORS;
    } else if (power_ctx.output->logs[POWER_LOG_WARNING].num_messages) {
        return POWER_RET_CODE_WARNINGS;
    } else {
        return POWER_RET_CODE_SUCCESS;
    }
}

/**
 * Prints the power usage for all components
 * - fp: File descripter to print out to
 */
static void power_print_breakdown_summary(FILE* fp) {
    power_print_breakdown_entry(fp, 0, POWER_BREAKDOWN_ENTRY_TYPE_TITLE, nullptr,
                                0., 0., 0., nullptr);
    power_print_breakdown_component(fp, "Total", POWER_COMPONENT_TOTAL, 0);
    fprintf(fp, "\n");
}

static void power_print_breakdown_pb(FILE* fp) {
    fprintf(fp,
            "This sections provides a detailed breakdown of power usage by PB (physical\n"
            "block). For each PB, the power is listed, which is the sum power of all\n"
            "instances of the block.  It also indicates its percentage of total power (entire\n"
            "FPGA), as well as the percentage of its power that is dynamic (vs. static).  It\n"
            "also indicates the method used for power estimation.\n\n"
            "The data includes:\n"
            "\tModes:\t\tWhen a pb contains multiple modes, each mode is "
            "listed, with\n\t\t\t\tits power statistics.\n"
            "\tBufs/Wires:\tPower of all local "
            "buffers and local wire switching\n"
            "\t\t\t\t(transistor-level estimation only).\n"
            "\tInterc:\t\tPower of local interconnect multiplexers (transistor-\n"
            "\t\t\t\tlevel estimation only)\n\n"
            "Description of Estimation Methods:\n"
            "\tTransistor Auto-Size: Transistor-level power estimation. Local buffers and\n"
            "\t\twire lengths are automatically sized. This is the default estimation\n"
            "\t\tmethod.\n"
            "\tTransistor Specify-Size: Transistor-level power estimation. Local buffers\n"
            "\t\tand wire lengths are only inserted where specified by the user in the\n"
            "\t\tarchitecture file.\n"
            "\tPin-Toggle: Dynamic power is calculated using enery-per-toggle of the PB\n"
            "\t\tinput pins. Static power is absolute.\n"
            "\tC-Internal: Dynamic power is calculated using an internal equivalent\n"
            "\t\tcapacitance for PB type. Static power is absolute.\n"
            "\tAbsolute: Dynamic and static power are absolutes from the architecture file.\n"
            "\tSum of Children: Power of PB is only the sum of all child PBs; interconnect\n"
            "\t\tbetween the PB and its children is ignored.\n"
            "\tIgnore: Power of PB is ignored.\n\n\n");

    power_print_breakdown_entry(fp, 0, POWER_BREAKDOWN_ENTRY_TYPE_TITLE, nullptr,
                                0., 0., 0., nullptr);

    auto& device_ctx = g_vpr_ctx.device();

    for (const auto& type : device_ctx.logical_block_types) {
        if (type.pb_type) {
            power_print_breakdown_pb_rec(fp, type.pb_type, 0);
        }
    }
    fprintf(fp, "\n");
}

/**
 * Internal recurseive function, used by power_component_print_usage
 */
static void power_print_breakdown_component(FILE* fp, const char* name, e_power_component_type type, int indent_level) {
    auto& power_ctx = g_vpr_ctx.power();
    power_print_breakdown_entry(fp, indent_level,
                                POWER_BREAKDOWN_ENTRY_TYPE_COMPONENT, name,
                                power_sum_usage(&power_ctx.by_component.components[type]),
                                power_sum_usage(&power_ctx.by_component.components[POWER_COMPONENT_TOTAL]),
                                power_perc_dynamic(&power_ctx.by_component.components[type]), nullptr);

    switch (type) {
        case (POWER_COMPONENT_TOTAL):
            power_print_breakdown_component(fp, "Routing", POWER_COMPONENT_ROUTING,
                                            indent_level + 1);
            power_print_breakdown_component(fp, "PB Types", POWER_COMPONENT_PB,
                                            indent_level + 1);
            power_print_breakdown_component(fp, "Clock", POWER_COMPONENT_CLOCK,
                                            indent_level + 1);
            break;
        case (POWER_COMPONENT_ROUTING):
            power_print_breakdown_component(fp, "Switch Box",
                                            POWER_COMPONENT_ROUTE_SB, indent_level + 1);
            power_print_breakdown_component(fp, "Connection Box",
                                            POWER_COMPONENT_ROUTE_CB, indent_level + 1);
            power_print_breakdown_component(fp, "Global Wires",
                                            POWER_COMPONENT_ROUTE_GLB_WIRE, indent_level + 1);
            break;
        case (POWER_COMPONENT_CLOCK):
            /*
             * power_print_breakdown_component(fp, "Clock Buffers",
             * POWER_COMPONENT_CLOCK_BUFFER, indent_level + 1);
             * power_print_breakdown_component(fp, "Clock Wires",
             * POWER_COMPONENT_CLOCK_WIRE, indent_level + 1);
             */
            break;
        case (POWER_COMPONENT_PB):
            power_print_breakdown_component(fp, "Primitives",
                                            POWER_COMPONENT_PB_PRIMITIVES, indent_level + 1);
            power_print_breakdown_component(fp, "Interc Structures",
                                            POWER_COMPONENT_PB_INTERC_MUXES, indent_level + 1);
            power_print_breakdown_component(fp, "Buffers and Wires",
                                            POWER_COMPONENT_PB_BUFS_WIRE, indent_level + 1);
            power_print_breakdown_component(fp, "Other Estimation Methods",
                                            POWER_COMPONENT_PB_OTHER, indent_level + 1);
            break;
        default:
            break;
    }
}

static void power_print_breakdown_entry(FILE* fp, int indent, e_power_breakdown_entry_type type, const char* name, float power, float total_power, float perc_dyn, const char* method) {
    const int buf_size = 32;
    char buf[buf_size];

    switch (type) {
        case POWER_BREAKDOWN_ENTRY_TYPE_TITLE:
            fprintf(fp, "%-*s%-12s%-12s%-12s%-12s\n\n", buf_size, "Component",
                    "Power (W)", "%-Total", "%-Dynamic", "Method");
            break;
        case POWER_BREAKDOWN_ENTRY_TYPE_MODE:
            for (int i = 0; i < indent; i++)
                buf[i] = ' ';
            strcpy(buf + indent, "Mode:");
            strncpy(buf + indent + 5, name, buf_size - indent - 6);
            fprintf(fp, "%-*s%-12.4g%-12.4g%-12.4g\n", buf_size, buf, power,
                    power / total_power, perc_dyn);
            break;
        case POWER_BREAKDOWN_ENTRY_TYPE_COMPONENT:
        case POWER_BREAKDOWN_ENTRY_TYPE_INTERC:
        case POWER_BREAKDOWN_ENTRY_TYPE_BUFS_WIRES:
            for (int i = 0; i < indent; i++)
                buf[i] = ' ';
            strncpy(buf + indent, name, buf_size - indent - 1);
            buf[buf_size - 1] = '\0';

            fprintf(fp, "%-*s%-12.4g%-12.4g%-12.4g\n", buf_size, buf, power,
                    power / total_power, perc_dyn);
            break;
        case POWER_BREAKDOWN_ENTRY_TYPE_PB:
            for (int i = 0; i < indent; i++)
                buf[i] = ' ';
            strncpy(buf + indent, name, buf_size - indent - 1);
            buf[buf_size - 1] = '\0';

            fprintf(fp, "%-*s%-12.4g%-12.4g%-12.4g%-12s\n", buf_size, buf, power,
                    power / total_power, perc_dyn, method);
            break;
        default:
            break;
    }
}
