/*
 * Copyright (c) 2011 Massachusetts Institute of Technology
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Konstantinos Aisopos
 */

/*
 * Official Tool Website: www.mit.edu/~kaisopos/FaultModel
 *
 * If you use our tool for academic research, we request that you cite: 
 * Konstantinos Aisopos, Chia-Hsin Owen Chen, and Li-Shiuan Peh. Enabling
 * System-Level Modeling of Variation-Induced Faults in Networks-on-Chip.
 * Proceedings of the 48th Design Automation Conference (DAC'11)
 */

// C++ includes
#include <cassert>
#include <fstream>
#include <iostream>
#include <vector>

// GEM5 includes
#include "FaultModel.hh"
#include "base/misc.hh" 

using namespace std;

#define MAX(a,b) ((a > b) ? (a) : (b))


FaultModel::FaultModel(const Params *p) : SimObject(p)
{
    // read configurations into "configurations" vector
    // format: <buff/vc> <vcs> <10 fault types> 
    bool more_records = true;
    for (int i = 0; more_records; i += (fields_per_conf_record)){
        system_conf configuration;
        configuration.buff_per_vc = 
            p->baseline_fault_vector_database[i + conf_record_buff_per_vc];
        configuration.vcs = 
            p->baseline_fault_vector_database[i + conf_record_vcs];
        for (int fault_index = 0; fault_index < number_of_fault_types; 
            fault_index++){
            configuration.fault_type[fault_index] = 
                p->baseline_fault_vector_database[i + 
                   conf_record_first_fault_type + fault_index] / 100;
        }
        configurations.push_back(configuration);
        if (p->baseline_fault_vector_database[i+fields_per_conf_record] < 0){
            more_records = false;
        }
    }

    // read temperature weights into "temperature_weights" vector
    // format: <temperature> <weight>
    more_records = true;
    for (int i = 0; more_records; i += (fields_per_temperature_record)){
        int record_temperature = 
               p->temperature_weights_database[i + temperature_record_temp];
        int record_weight =
               p->temperature_weights_database[i + temperature_record_weight];
        static int first_record = true;
        if (first_record){
            for (int temperature = 0; temperature < record_temperature; 
                 temperature++){
                 temperature_weights.push_back(0);
            }
            first_record = false;
        }
        assert(record_temperature == temperature_weights.size());
        temperature_weights.push_back(record_weight);
        if (p->temperature_weights_database[i + 
               fields_per_temperature_record] < 0){
            more_records = false;
        }
    }
}

string
FaultModel::fault_type_to_string(int ft)
{
   if (ft == data_corruption__few_bits){
       return "data_corruption__few_bits";
   } else if (ft == data_corruption__all_bits){
      return "data_corruption__all_bits";
   } else if (ft == flit_conservation__flit_duplication){
      return "flit_conservation__flit_duplication";
   } else if (ft == flit_conservation__flit_loss_or_split){
      return "flit_conservation__flit_loss_or_split";
   } else if (ft == misrouting){
      return "misrouting";
   } else if (ft == credit_conservation__credit_generation){
      return "credit_conservation__credit_generation";
   } else if (ft == credit_conservation__credit_loss){
      return "credit_conservation__credit_loss";
   } else if (ft == erroneous_allocation__VC){
      return "erroneous_allocation__VC";
   } else if (ft == erroneous_allocation__switch){
      return "erroneous_allocation__switch";
   } else if (ft == unfair_arbitration){
      return "unfair_arbitration";
   } else if (ft == number_of_fault_types){
      return "none";
   } else {
      return "none";
   }
}


int 
FaultModel::declare_router(int number_of_inputs, 
                           int number_of_outputs, 
                           int number_of_vcs_per_input, 
                           int number_of_buff_per_data_vc, 
                           int number_of_buff_per_ctrl_vc)
{
    // check inputs (are they legal?)
    if (number_of_inputs <= 0 || number_of_outputs <= 0 ||
        number_of_vcs_per_input <= 0 || number_of_buff_per_data_vc <= 0 || 
        number_of_buff_per_ctrl_vc <= 0){
        fatal("Fault Model: ERROR in argument of FaultModel_declare_router!");
    }
    int number_of_buffers_per_vc = MAX(number_of_buff_per_data_vc,
                                       number_of_buff_per_ctrl_vc);
    int total_vcs = number_of_inputs * number_of_vcs_per_input;
    if (total_vcs > MAX_VCs){
        fatal("Fault Model: ERROR! Number inputs*VCs (MAX_VCs) unsupported");
    }
    if (number_of_buffers_per_vc > MAX_BUFFERS_per_VC){
        fatal("Fault Model: ERROR! buffers/VC (MAX_BUFFERS_per_VC) too high");
    }

    // link the router to a DB record
    int record_hit = -1;
    for (int record = 0; record < configurations.size(); record++){    
        if ((configurations[record].buff_per_vc == number_of_buffers_per_vc)&&
            (configurations[record].vcs == total_vcs)){
            record_hit = record;
        }
    }
    if (record_hit == -1){
        panic("Fault Model: ERROR! configuration not found in DB. BUG?");
    }

    // remember the router and return its ID
    routers.push_back(configurations[record_hit]);
    static int router_index = 0;
    return router_index++;
}

bool 
FaultModel::fault_vector(int routerID, 
                         int temperature_input,
                         float fault_vector[])
{
    bool ok = true;

    // is the routerID recorded?
    if (routerID < 0 || routerID >= ((int) routers.size())){
         warn("Fault Model: ERROR! unknown router ID argument.");
        fatal("Fault Model: Did you enable the fault model flag)?");     
    }

    // is the temperature too high/too low?
    int temperature = temperature_input;
    if (temperature_input >= ((int) temperature_weights.size())){
        ok = false;
        warn_once("Fault Model: Temperature exceeded simulated upper bound.");
        warn_once("Fault Model: The fault model is not accurate any more.");
        temperature = (temperature_weights.size() - 1);
    } else if (temperature_input < 0){
        ok = false;
        warn_once("Fault Model: Temperature exceeded simulated lower bound.");
        warn_once("Fault Model: The fault model is not accurate any more.");
        temperature = 0;
    }

    // recover the router record and return its fault vector
    for (int i = 0; i < number_of_fault_types; i++){
        fault_vector[i] = routers[routerID].fault_type[i] * 
                          ((float)temperature_weights[temperature]);
    }
    return ok;
}

bool 
FaultModel::fault_prob(int routerID, 
                       int temperature_input,
                       float *aggregate_fault_prob)
{
    *aggregate_fault_prob = 1.0;
    bool ok = true;

    // is the routerID recorded?
    if (routerID < 0 || routerID >= ((int) routers.size())){
         warn("Fault Model: ERROR! unknown router ID argument.");
        fatal("Fault Model: Did you enable the fault model flag)?");     
    }

    // is the temperature too high/too low?
    int temperature = temperature_input;
    if (temperature_input >= ((int) temperature_weights.size()) ){
        ok = false;
        warn_once("Fault Model: Temperature exceeded simulated upper bound.");
        warn_once("Fault Model: The fault model is not accurate any more.");
        temperature = (temperature_weights.size()-1);
    } else if (temperature_input < 0){
        ok = false;
        warn_once("Fault Model: Temperature exceeded simulated lower bound.");
        warn_once("Fault Model: The fault model is not accurate any more.");
        temperature = 0;
    }

    // recover the router record and return its aggregate fault probability
    for (int i = 0; i < number_of_fault_types; i++){
        *aggregate_fault_prob=  *aggregate_fault_prob * 
                               ( 1.0 - (routers[routerID].fault_type[i] * 
                                 ((float)temperature_weights[temperature])) );
    }
    *aggregate_fault_prob = 1.0 - *aggregate_fault_prob;
    return ok;
}

// this function is used only for debugging purposes
void 
FaultModel::print(void)
{
    cout << "--- PRINTING configurations ---\n";
    for (int record = 0; record < configurations.size(); record++){
        cout << "(" << record << ") ";
        cout << "VCs=" << configurations[record].vcs << " ";
        cout << "Buff/VC=" << configurations[record].buff_per_vc << " [";
        for (int fault_type_num = 0; 
             fault_type_num < number_of_fault_types; 
             fault_type_num++){
            cout << (100 * configurations[record].fault_type[fault_type_num]); 
            cout << "% ";
        }
        cout << "]\n";
    }
    cout << "--- PRINTING temperature weights ---\n";
    for (int record = 0; record < temperature_weights.size(); record++){
        cout << "temperature=" << record << " => ";
        cout << "weight=" << temperature_weights[record];
        cout << "\n";
    }
}

FaultModel *
FaultModelParams::create()
{
    return new FaultModel(this);
}
