/*********************************************************************
 *  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 file provides functions relating to the cmos technology.  It
 * includes functions to read the transistor characteristics from the
 * xml file into data structures, and functions to search within
 * these data structures.
 */

/************************* INCLUDES *********************************/
#include <cstring>
#include "vtr_assert.h"

#include "pugixml.hpp"
#include "pugixml_util.hpp"

#include "vtr_util.h"
#include "vtr_memory.h"
#include "vtr_math.h"

#include "vpr_error.h"

#include "globals.h"
#include "power_cmos_tech.h"
#include "power.h"
#include "power_util.h"
#include "read_xml_util.h"
#include "PowerSpicedComponent.h"
#include "power_callibrate.h"

/************************* FILE SCOPE **********************************/
static t_transistor_inf* f_transistor_last_searched;
static t_power_buffer_strength_inf* f_buffer_strength_last_searched;
static t_power_mux_volt_inf* f_mux_volt_last_searched;
static t_power_nmos_leakage_inf* f_power_searching_nmos_leakage_info;

/************************* FUNCTION DECLARATIONS ********************/

static void power_tech_load_xml_file(const char* cmos_tech_behavior_filepath);
static void process_tech_xml_load_transistor_info(pugi::xml_node parent, const pugiutil::loc_data& loc_data);
static void power_tech_xml_load_multiplexer_info(pugi::xml_node parent, const pugiutil::loc_data& loc_data);
static void power_tech_xml_load_nmos_st_leakages(pugi::xml_node parent, const pugiutil::loc_data& loc_data);
static int power_compare_transistor_size(const void* key_void, const void* elem_void);
static int power_compare_voltage_pair(const void* key_void, const void* elem_void);
static int power_compare_leakage_pair(const void* key_void, const void* elem_void);
//static void power_tech_xml_load_sc(pugi::xml_node parent, const pugiutil::loc_data& loc_data);
static int power_compare_buffer_strength(const void* key_void, const void* elem_void);
static int power_compare_buffer_sc_levr(const void* key_void, const void* elem_void);
static void power_tech_xml_load_components(pugi::xml_node parent, const pugiutil::loc_data& loc_data);
static void power_tech_xml_load_component(pugi::xml_node parent, const pugiutil::loc_data& loc_data, PowerSpicedComponent** component, const char* name, float (*usage_fn)(int num_inputs, float transistor_size));
/************************* FUNCTION DEFINITIONS *********************/

void power_tech_init(const char* cmos_tech_behavior_filepath) {
    power_tech_load_xml_file(cmos_tech_behavior_filepath);
}

/**
 * Reads the transistor properties from the .xml file
 */
void power_tech_load_xml_file(const char* cmos_tech_behavior_filepath) {
    pugi::xml_document doc;
    pugiutil::loc_data loc_data;
    try {
        loc_data = pugiutil::load_xml(doc, cmos_tech_behavior_filepath);
    } catch (const pugiutil::XmlError& e) {
        vpr_throw(VPR_ERROR_POWER, cmos_tech_behavior_filepath, 0,
                  "Failed to load CMOS Tech Properties file '%s' (%s).", cmos_tech_behavior_filepath, e.what());
    }

    auto technology = get_single_child(doc, "technology", loc_data);

    get_attribute(technology, "file", loc_data); //Check exists

    auto& power_ctx = g_vpr_ctx.power();

    auto tech_size = get_attribute(technology, "size", loc_data);
    power_ctx.tech->tech_size = tech_size.as_float();

    auto operating_point = get_single_child(technology, "operating_point", loc_data);
    power_ctx.tech->temperature = get_attribute(operating_point, "temperature", loc_data).as_float();
    power_ctx.tech->Vdd = get_attribute(operating_point, "Vdd", loc_data).as_float();

    auto p_to_n = get_single_child(technology, "p_to_n", loc_data);
    power_ctx.tech->PN_ratio = get_attribute(p_to_n, "ratio", loc_data).as_float();

    /* Transistor Information
     *  We expect two <transistor> sections for P and N types
     */
    auto child = get_first_child(technology, "transistor", loc_data);
    process_tech_xml_load_transistor_info(child, loc_data);

    child = child.next_sibling("transistor");

    process_tech_xml_load_transistor_info(child, loc_data);

    //Should be no more
    auto next = child.next_sibling("transistor");
    if (next) {
        vpr_throw(VPR_ERROR_POWER, loc_data.filename_c_str(), loc_data.line(next),
                  "Encountered extra <transitor> section (expect 2 only: pmos and nmos)\n");
    }

    /* Multiplexer Voltage Information */
    child = get_single_child(technology, "multiplexers", loc_data);
    power_tech_xml_load_multiplexer_info(child, loc_data);

    /* Vds Leakage Information */
    child = get_single_child(technology, "nmos_leakages", loc_data);
    power_tech_xml_load_nmos_st_leakages(child, loc_data);

    /* Buffer SC Info */
    /*
     * child = get_single_child(technology, "buffer_sc", loc_data);
     * power_tech_xml_load_sc(child);
     */

    /* Components */
    child = get_single_child(technology, "components", loc_data);
    power_tech_xml_load_components(child, loc_data);
}

static void power_tech_xml_load_component(pugi::xml_node parent, const pugiutil::loc_data& loc_data, PowerSpicedComponent** component, const char* name, float (*usage_fn)(int num_inputs, float transistor_size)) {
    std::string component_name(name);
    *component = new PowerSpicedComponent(component_name, usage_fn);

    auto cur = get_single_child(parent, name, loc_data);

    auto child = get_first_child(cur, "inputs", loc_data);
    while (child) {
        int num_inputs = get_attribute(child, "num_inputs", loc_data).as_int(0);

        auto gc = get_first_child(child, "size", loc_data);
        while (gc) {
            float transistor_size = get_attribute(gc, "transistor_size", loc_data).as_float(0.);
            float power = get_attribute(gc, "power", loc_data).as_float(0.);
            (*component)->add_data_point(num_inputs, transistor_size, power);

            gc = gc.next_sibling("size");
        }
        child = child.next_sibling("inputs");
    }
}

static void power_tech_xml_load_components(pugi::xml_node parent, const pugiutil::loc_data& loc_data) {
    auto& power_ctx = g_vpr_ctx.power();

    power_ctx.commonly_used->component_callibration = (PowerSpicedComponent**)vtr::calloc(POWER_CALLIB_COMPONENT_MAX,
                                                                                          sizeof(PowerSpicedComponent*));

    power_tech_xml_load_component(parent, loc_data,
                                  &power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_BUFFER],
                                  "buf", power_usage_buf_for_callibration);

    power_tech_xml_load_component(parent, loc_data,
                                  &power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_BUFFER_WITH_LEVR],
                                  "buf_levr", power_usage_buf_levr_for_callibration);

    power_tech_xml_load_component(parent, loc_data,
                                  &power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_FF],
                                  "dff", power_usage_ff_for_callibration);

    power_tech_xml_load_component(parent, loc_data,
                                  &power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_MUX],
                                  "mux", power_usage_mux_for_callibration);

    power_tech_xml_load_component(parent, loc_data,
                                  &power_ctx.commonly_used->component_callibration[POWER_CALLIB_COMPONENT_LUT],
                                  "lut", power_usage_lut_for_callibration);
}

/**
 *  Read NMOS subthreshold leakage currents from the .xml transistor characteristics
 *  This builds a table of (Vds,Ids) value pairs
 *  */
static void power_tech_xml_load_nmos_st_leakages(pugi::xml_node parent, const pugiutil::loc_data& loc_data) {
    int num_nmos_sizes;
    int num_leakage_pairs;
    int i;
    int nmos_idx;
    auto& power_ctx = g_vpr_ctx.power();

    num_nmos_sizes = count_children(parent, "nmos", loc_data);
    power_ctx.tech->num_nmos_leakage_info = num_nmos_sizes;
    power_ctx.tech->nmos_leakage_info = (t_power_nmos_leakage_inf*)vtr::calloc(num_nmos_sizes, sizeof(t_power_nmos_leakage_inf));

    auto me = get_first_child(parent, "nmos", loc_data);
    nmos_idx = 0;
    while (me) {
        t_power_nmos_leakage_inf* nmos_info = &power_ctx.tech->nmos_leakage_info[nmos_idx];
        nmos_info->nmos_size = get_attribute(me, "size", loc_data).as_float(0.);

        num_leakage_pairs = count_children(me, "nmos_leakage", loc_data);
        nmos_info->num_leakage_pairs = num_leakage_pairs;
        nmos_info->leakage_pairs = (t_power_nmos_leakage_pair*)vtr::calloc(num_leakage_pairs, sizeof(t_power_nmos_leakage_pair));

        auto child = get_first_child(me, "nmos_leakage", loc_data);
        i = 0;
        while (child) {
            nmos_info->leakage_pairs[i].v_ds = get_attribute(child, "Vds", loc_data).as_float(0.0);
            nmos_info->leakage_pairs[i].i_ds = get_attribute(child, "Ids", loc_data).as_float(0.0);

            child = child.next_sibling("nmos_leakage");
            i++;
        }

        me = me.next_sibling("nmos");
        nmos_idx++;
    }
}

/**
 *  Read multiplexer information from the .xml transistor characteristics.
 *  This contains the estimates of mux output voltages, depending on 1) Mux Size 2) Mux Vin
 *  */
static void power_tech_xml_load_multiplexer_info(pugi::xml_node parent, const pugiutil::loc_data& loc_data) {
    int num_nmos_sizes;
    int num_mux_sizes;
    int i, j, nmos_idx;
    auto& power_ctx = g_vpr_ctx.power();

    /* Process all nmos sizes */
    num_nmos_sizes = count_children(parent, "nmos", loc_data);
    VTR_ASSERT(num_nmos_sizes > 0);
    power_ctx.tech->num_nmos_mux_info = num_nmos_sizes;
    power_ctx.tech->nmos_mux_info = (t_power_nmos_mux_inf*)vtr::calloc(num_nmos_sizes, sizeof(t_power_nmos_mux_inf));

    auto me = get_first_child(parent, "nmos", loc_data);
    nmos_idx = 0;
    while (me) {
        t_power_nmos_mux_inf* nmos_inf = &power_ctx.tech->nmos_mux_info[nmos_idx];
        nmos_inf->nmos_size = get_attribute(me, "size", loc_data).as_float(0.0);

        /* Process all multiplexer sizes */
        num_mux_sizes = count_children(me, "multiplexer", loc_data);

        /* Add entries for 0 and 1, for convenience, although
         * they will never be used
         */
        nmos_inf->max_mux_sl_size = 1 + num_mux_sizes;
        nmos_inf->mux_voltage_inf = (t_power_mux_volt_inf*)vtr::calloc(nmos_inf->max_mux_sl_size + 1, sizeof(t_power_mux_volt_inf));

        auto child = get_first_child(me, "multiplexer", loc_data);
        i = 1;
        while (child) {
            int num_voltages;

            VTR_ASSERT(i == get_attribute(child, "size", loc_data).as_int(0));

            /* For each mux size, process all of the Vin levels */
            num_voltages = count_children(child, "voltages", loc_data);

            nmos_inf->mux_voltage_inf[i].num_voltage_pairs = num_voltages;
            nmos_inf->mux_voltage_inf[i].mux_voltage_pairs = (t_power_mux_volt_pair*)vtr::calloc(num_voltages,
                                                                                                 sizeof(t_power_mux_volt_pair));

            auto gc = get_first_child(child, "voltages", loc_data);
            j = 0;
            while (gc) {
                /* For each mux size, and Vin level, get the min/max V_out */
                nmos_inf->mux_voltage_inf[i].mux_voltage_pairs[j].v_in = get_attribute(gc, "in", loc_data).as_float(0.0);
                nmos_inf->mux_voltage_inf[i].mux_voltage_pairs[j].v_out_min = get_attribute(gc, "out_min", loc_data).as_float(0.0);
                nmos_inf->mux_voltage_inf[i].mux_voltage_pairs[j].v_out_max = get_attribute(gc, "out_max", loc_data).as_float(0.0);

                gc = gc.next_sibling("voltages");
                j++;
            }

            child = child.next_sibling("multiplexer");
            i++;
        }

        me = me.next_sibling("nmos");
        nmos_idx++;
    }
}

/**
 * Read the transistor information from the .xml transistor characteristics.
 * For each transistor size, it extracts the:
 * - transistor node capacitances
 * - subthreshold leakage
 * - gate leakage
 */
static void process_tech_xml_load_transistor_info(pugi::xml_node parent, const pugiutil::loc_data& loc_data) {
    t_transistor_inf* trans_inf;
    int i;
    auto& power_ctx = g_vpr_ctx.power();

    /* Get transistor type: NMOS or PMOS */
    auto prop = get_attribute(parent, "type", loc_data);
    trans_inf = nullptr;
    if (strcmp(prop.value(), "nmos") == 0) {
        trans_inf = &power_ctx.tech->NMOS_inf;
    } else if (strcmp(prop.value(), "pmos") == 0) {
        trans_inf = &power_ctx.tech->PMOS_inf;
    } else {
        vpr_throw(VPR_ERROR_POWER, loc_data.filename_c_str(), loc_data.line(parent),
                  "Unrecognized transistor type '%s', expected 'nmos' or 'pmos'\n", prop.value());
    }

    /* Get long transistor information (W=1,L=2) */
    trans_inf->long_trans_inf = (t_transistor_size_inf*)vtr::malloc(sizeof(t_transistor_size_inf));

    auto child = get_single_child(parent, "long_size", loc_data);
    VTR_ASSERT(get_attribute(child, "L", loc_data).as_int(0) == 2);
    trans_inf->long_trans_inf->size = get_attribute(child, "W", loc_data).as_float(0.);

    auto grandchild = get_single_child(child, "leakage_current", loc_data);
    trans_inf->long_trans_inf->leakage_subthreshold = get_attribute(grandchild, "subthreshold", loc_data).as_float(0.);

    grandchild = get_single_child(child, "capacitance", loc_data);
    trans_inf->long_trans_inf->C_g = get_attribute(grandchild, "C_g", loc_data).as_float(0);
    trans_inf->long_trans_inf->C_d = get_attribute(grandchild, "C_d", loc_data).as_float(0);
    trans_inf->long_trans_inf->C_s = get_attribute(grandchild, "C_s", loc_data).as_float(0);

    /* Process all transistor sizes */
    trans_inf->num_size_entries = count_children(parent, "size", loc_data);
    trans_inf->size_inf = (t_transistor_size_inf*)vtr::calloc(trans_inf->num_size_entries, sizeof(t_transistor_size_inf));

    child = get_first_child(parent, "size", loc_data);
    i = 0;
    while (child) {
        VTR_ASSERT(get_attribute(child, "L", loc_data).as_int(0) == 1);

        trans_inf->size_inf[i].size = get_attribute(child, "W", loc_data).as_float(0);

        /* Get leakage currents */
        grandchild = get_single_child(child, "leakage_current", loc_data);
        trans_inf->size_inf[i].leakage_subthreshold = get_attribute(grandchild, "subthreshold", loc_data).as_float(0);
        trans_inf->size_inf[i].leakage_gate = get_attribute(grandchild, "gate", loc_data).as_float(0);

        /* Get node capacitances */
        grandchild = get_single_child(child, "capacitance", loc_data);
        trans_inf->size_inf[i].C_g = get_attribute(grandchild, "C_g", loc_data).as_float(0);
        trans_inf->size_inf[i].C_s = get_attribute(grandchild, "C_s", loc_data).as_float(0);
        trans_inf->size_inf[i].C_d = get_attribute(grandchild, "C_d", loc_data).as_float(0);

        child = child.next_sibling("size");
        i++;
    }
}

/**
 * This function searches for a transistor by size
 * - lower: (Return value) The lower-bound matching transistor
 * - upper: (Return value) The upper-bound matching transistor
 * - type: The transistor type to search for
 * - size: The transistor size to search for (size = W/L)
 */
bool power_find_transistor_info(t_transistor_size_inf** lower,
                                t_transistor_size_inf** upper,
                                e_tx_type type,
                                float size) {
    char msg[1024];
    t_transistor_size_inf key;
    t_transistor_size_inf* found;
    t_transistor_inf* trans_info;
    float min_size, max_size;
    bool error = false;
    auto& power_ctx = g_vpr_ctx.power();

    key.size = size;

    /* Find the appropriate global transistor records */
    trans_info = nullptr;
    if (type == NMOS) {
        trans_info = &power_ctx.tech->NMOS_inf;
    } else if (type == PMOS) {
        trans_info = &power_ctx.tech->PMOS_inf;
    } else {
        VTR_ASSERT(0);
    }

    /* No transistor data exists */
    if (trans_info->size_inf == nullptr) {
        power_log_msg(POWER_LOG_ERROR,
                      "No transistor information exists.  Cannot determine transistor properties.");
        error = true;
        return error;
    }

    /* Make note of the transistor record we are searching in, and the bounds */
    f_transistor_last_searched = trans_info;
    min_size = trans_info->size_inf[0].size;
    max_size = trans_info->size_inf[trans_info->num_size_entries - 1].size;

    found = (t_transistor_size_inf*)bsearch(&key, trans_info->size_inf,
                                            trans_info->num_size_entries, sizeof(t_transistor_size_inf),
                                            &power_compare_transistor_size);
    VTR_ASSERT(found);

    if (size < min_size) {
        /* Too small */
        VTR_ASSERT(found == &trans_info->size_inf[0]);
        sprintf(msg,
                "Using %s transistor of size '%f', which is smaller than the smallest modeled transistor (%f) in the technology behavior file.",
                transistor_type_name(type), size, min_size);
        power_log_msg(POWER_LOG_WARNING, msg);
        *lower = nullptr;
        *upper = found;
    } else if (size > max_size) {
        /* Too large */
        VTR_ASSERT(found == &trans_info->size_inf[trans_info->num_size_entries - 1]);
        sprintf(msg,
                "Using %s transistor of size '%f', which is larger than the largest modeled transistor (%f) in the technology behavior file.",
                transistor_type_name(type), size, max_size);
        power_log_msg(POWER_LOG_WARNING, msg);
        *lower = found;
        *upper = nullptr;
    } else {
        *lower = found;
        *upper = found + 1;
    }

    return error;
}

/**
 * This function searches for the Ids leakage current, based on a given Vds.
 * This function is used for minimum-sized NMOS transistors (used in muxs).
 * - lower: (Return value) The lower-bound matching V/I pair
 * - upper: (Return value) The upper-bound matching V/I pair
 * - v_ds: The drain/source voltage to search for
 */
void power_find_nmos_leakage(t_power_nmos_leakage_inf* nmos_leakage_info,
                             t_power_nmos_leakage_pair** lower,
                             t_power_nmos_leakage_pair** upper,
                             float v_ds) {
    t_power_nmos_leakage_pair key;
    t_power_nmos_leakage_pair* found;

    key.v_ds = v_ds;

    f_power_searching_nmos_leakage_info = nmos_leakage_info;

    found = (t_power_nmos_leakage_pair*)bsearch(&key,
                                                nmos_leakage_info->leakage_pairs,
                                                nmos_leakage_info->num_leakage_pairs,
                                                sizeof(t_power_nmos_leakage_pair), power_compare_leakage_pair);
    VTR_ASSERT(found);

    if (found == &nmos_leakage_info->leakage_pairs[nmos_leakage_info->num_leakage_pairs - 1]) {
        /* The results equal to the max voltage (Vdd) */
        *lower = found;
        *upper = nullptr;
    } else {
        *lower = found;
        *upper = found + 1;
    }
}

/**
 * This function searches for the information for a given buffer strength.
 * - lower: (Return value) The lower-bound matching record
 * - upper: (Return value) The upper-bound matching record
 * - stage_gain: The buffer strength to search for
 */
void power_find_buffer_strength_inf(t_power_buffer_strength_inf** lower,
                                    t_power_buffer_strength_inf** upper,
                                    t_power_buffer_size_inf* size_inf,
                                    float stage_gain) {
    t_power_buffer_strength_inf key;
    t_power_buffer_strength_inf* found;

    float min_size;
    float max_size;

    min_size = size_inf->strength_inf[0].stage_gain;
    max_size = size_inf->strength_inf[size_inf->num_strengths - 1].stage_gain;

    VTR_ASSERT(stage_gain >= min_size && stage_gain <= max_size);

    key.stage_gain = stage_gain;

    found = (t_power_buffer_strength_inf*)bsearch(&key, size_inf->strength_inf,
                                                  size_inf->num_strengths, sizeof(t_power_buffer_strength_inf),
                                                  power_compare_buffer_strength);

    if (stage_gain == max_size) {
        *lower = found;
        *upper = nullptr;
    } else {
        *lower = found;
        *upper = found + 1;
    }
}

/**
 * This function searches for short-circuit current information for a level-restoring buffer,
 * based on the size of the multiplexer driving the input
 * - lower: (Return value) The lower-bound matching record
 * - upper: (Return value) The upper-bound matching record
 * - buffer_strength: The set of records to search withing, which are for a specific buffer size/strength
 * - input_mux_size: The input mux size to search for
 */
void power_find_buffer_sc_levr(t_power_buffer_sc_levr_inf** lower,
                               t_power_buffer_sc_levr_inf** upper,
                               t_power_buffer_strength_inf* buffer_strength,
                               int input_mux_size) {
    t_power_buffer_sc_levr_inf key;
    t_power_buffer_sc_levr_inf* found;
    char msg[1024];
    int max_size;

    VTR_ASSERT(input_mux_size >= 1);

    key.mux_size = input_mux_size;

    f_buffer_strength_last_searched = buffer_strength;
    found = (t_power_buffer_sc_levr_inf*)bsearch(&key,
                                                 buffer_strength->sc_levr_inf, buffer_strength->num_levr_entries,
                                                 sizeof(t_power_buffer_sc_levr_inf), power_compare_buffer_sc_levr);

    max_size = buffer_strength->sc_levr_inf[buffer_strength->num_levr_entries
                                            - 1]
                   .mux_size;
    if (input_mux_size > max_size) {
        /* Input mux too large */
        VTR_ASSERT(found == &buffer_strength->sc_levr_inf[buffer_strength->num_levr_entries - 1]);
        sprintf(msg,
                "Using buffer driven by mux of size '%d', which is larger than the largest modeled size (%d) in the technology behavior file.",
                input_mux_size, max_size);
        power_log_msg(POWER_LOG_WARNING, msg);
        *lower = found;
        *upper = nullptr;
    } else {
        *lower = found;
        *upper = found + 1;
    }
}

/**
 * Comparison function, used by power_find_nmos_leakage
 */
static int power_compare_leakage_pair(const void* key_void, const void* elem_void) {
    const t_power_nmos_leakage_pair* key = (const t_power_nmos_leakage_pair*)key_void;
    const t_power_nmos_leakage_pair* elem = (const t_power_nmos_leakage_pair*)elem_void;
    const t_power_nmos_leakage_pair* next = (const t_power_nmos_leakage_pair*)elem + 1;

    /* Compare against last? */
    if (elem == &f_power_searching_nmos_leakage_info->leakage_pairs[f_power_searching_nmos_leakage_info->num_leakage_pairs - 1]) {
        if (key->v_ds >= elem->v_ds) {
            return 0;
        } else {
            return -1;
        }
    }

    /* Check for exact match to Vdd (upper end) */
    if (key->v_ds == elem->v_ds) {
        return 0;
    } else if (key->v_ds < elem->v_ds) {
        return -1;
    } else if (key->v_ds > next->v_ds) {
        return 1;
    } else {
        return 0;
    }
}

/**
 * This function searches for multiplexer output voltage information, based on input voltage
 * - lower: (Return value) The lower-bound matching record
 * - upper: (Return value) The upper-bound matching record
 * - volt_inf: The set of records to search within, which are for a specific mux size
 * - v_in: The input voltage to search for
 */
void power_find_mux_volt_inf(t_power_mux_volt_pair** lower,
                             t_power_mux_volt_pair** upper,
                             t_power_mux_volt_inf* volt_inf,
                             float v_in) {
    t_power_mux_volt_pair key;
    t_power_mux_volt_pair* found;

    key.v_in = v_in;

    f_mux_volt_last_searched = volt_inf;
    found = (t_power_mux_volt_pair*)bsearch(&key, volt_inf->mux_voltage_pairs,
                                            volt_inf->num_voltage_pairs, sizeof(t_power_mux_volt_pair),
                                            power_compare_voltage_pair);
    VTR_ASSERT(found);

    if (found
        == &volt_inf->mux_voltage_pairs[volt_inf->num_voltage_pairs - 1]) {
        *lower = found;
        *upper = nullptr;
    } else {
        *lower = found;
        *upper = found + 1;
    }
}

/**
 * Comparison function, used by power_find_buffer_sc_levr
 */
static int power_compare_buffer_sc_levr(const void* key_void,
                                        const void* elem_void) {
    const t_power_buffer_sc_levr_inf* key = (const t_power_buffer_sc_levr_inf*)key_void;
    const t_power_buffer_sc_levr_inf* elem = (const t_power_buffer_sc_levr_inf*)elem_void;
    const t_power_buffer_sc_levr_inf* next;

    /* Compare against last? */
    if (elem
        == &f_buffer_strength_last_searched->sc_levr_inf[f_buffer_strength_last_searched->num_levr_entries
                                                         - 1]) {
        if (key->mux_size >= elem->mux_size) {
            return 0;
        } else {
            return -1;
        }
    }

    /* Compare against first? */
    if (elem == &f_buffer_strength_last_searched->sc_levr_inf[0]) {
        if (key->mux_size < elem->mux_size) {
            return 0;
        }
    }

    /* Check if the key is between elem and the next element */
    next = elem + 1;
    if (key->mux_size > next->mux_size) {
        return 1;
    } else if (key->mux_size < elem->mux_size) {
        return -1;
    } else {
        return 0;
    }
}

/**
 * Comparison function, used by power_find_buffer_strength_inf
 */
static int power_compare_buffer_strength(const void* key_void,
                                         const void* elem_void) {
    const t_power_buffer_strength_inf* key = (const t_power_buffer_strength_inf*)key_void;
    const t_power_buffer_strength_inf* elem = (const t_power_buffer_strength_inf*)elem_void;
    const t_power_buffer_strength_inf* next = (const t_power_buffer_strength_inf*)elem + 1;

    /* Check for exact match */
    if (key->stage_gain == elem->stage_gain) {
        return 0;
    } else if (key->stage_gain < elem->stage_gain) {
        return -1;
    } else if (key->stage_gain > next->stage_gain) {
        return 1;
    } else {
        return 0;
    }
}

/**
 * Comparison function, used by power_find_transistor_info
 */
static int power_compare_transistor_size(const void* key_void,
                                         const void* elem_void) {
    const t_transistor_size_inf* key = (const t_transistor_size_inf*)key_void;
    const t_transistor_size_inf* elem = (const t_transistor_size_inf*)elem_void;
    const t_transistor_size_inf* next;

    /* Check if we are comparing against the last element */
    if (elem
        == &f_transistor_last_searched->size_inf[f_transistor_last_searched->num_size_entries
                                                 - 1]) {
        /* Match if the desired value is larger than the largest item in the list */
        if (key->size >= elem->size) {
            return 0;
        } else {
            return -1;
        }
    }

    /* Check if we are comparing against the first element */
    if (elem == &f_transistor_last_searched->size_inf[0]) {
        /* Match the smallest if it is smaller than the smallest */
        if (key->size < elem->size) {
            return 0;
        }
    }

    /* Check if the key is between elem and the next element */
    next = elem + 1;
    if (key->size > next->size) {
        return 1;
    } else if (key->size < elem->size) {
        return -1;
    } else {
        return 0;
    }
}

/**
 * Comparison function, used by power_find_mux_volt_inf
 */
static int power_compare_voltage_pair(const void* key_void,
                                      const void* elem_void) {
    const t_power_mux_volt_pair* key = (const t_power_mux_volt_pair*)key_void;
    const t_power_mux_volt_pair* elem = (const t_power_mux_volt_pair*)elem_void;
    const t_power_mux_volt_pair* next = (const t_power_mux_volt_pair*)elem
                                        + 1;

    /* Check if we are comparing against the last element */
    if (elem
        == &f_mux_volt_last_searched->mux_voltage_pairs[f_mux_volt_last_searched->num_voltage_pairs
                                                        - 1]) {
        /* Match if the desired value is larger than the largest item in the list */
        if (key->v_in >= elem->v_in) {
            return 0;
        } else {
            return -1;
        }
    }

    /* Check for exact match to Vdd (upper end) */
    if (key->v_in == elem->v_in) {
        return 0;
    } else if (key->v_in < elem->v_in) {
        return -1;
    } else if (key->v_in > next->v_in) {
        return 1;
    } else {
        return 0;
    }
}
