/*********************************************************************
 *  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;
            case INTRA_CLUSTER_EDGE:
                VTR_ASSERT(0);
                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;
    }
}
