/*
 * 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)
 */

#ifndef __MEM_RUBY_NETWORK_FAULT_MODEL_HH__
#define __MEM_RUBY_NETWORK_FAULT_MODEL_HH__

// tool limitations and fixed inputs
#define MAX_VCs 40
#define MAX_BUFFERS_per_VC 5
#define BASELINE_TEMPERATURE_CELCIUS 71

// C++ includes
#include <string>

// GEM5 includes
#include "params/FaultModel.hh"
#include "sim/sim_object.hh"

class FaultModel : public SimObject
{
  public:
    typedef FaultModelParams Params;
    FaultModel(const Params *p);
    const Params *params() const { return (const Params *)_params; }

    /************************************************************************/
    /**********  THE FAULT TYPES SUPPORTED BY THE FAULT MODEL ***************/
    /************************************************************************/

    enum fault_type
    {
        data_corruption__few_bits,
        data_corruption__all_bits,
        flit_conservation__flit_duplication,
        flit_conservation__flit_loss_or_split,
        misrouting,
        credit_conservation__credit_generation,
        credit_conservation__credit_loss,
        erroneous_allocation__VC,
        erroneous_allocation__switch,
        unfair_arbitration,
        number_of_fault_types
    };

    /************************************************************************/
    /********************  INTERFACE OF THE FAULT MODEL *********************/
    /************************************************************************/

    enum conf_record_format
    {
        conf_record_buff_per_vc,
        conf_record_vcs,
        conf_record_first_fault_type,
        conf_record_last_fault_type = conf_record_first_fault_type + number_of_fault_types - 1,
        fields_per_conf_record
    };

    enum temperature_record_format
    {
        temperature_record_temp,
        temperature_record_weight,
        fields_per_temperature_record
    };

    struct system_conf
    {
        int vcs;
        int buff_per_vc;
        float fault_type[number_of_fault_types];
    };

    int declare_router(int number_of_inputs,
                       int number_of_outputs,
                       int number_of_vcs_per_vnet,
                       int number_of_buff_per_data_vc,
                       int number_of_buff_per_ctrl_vc);

    std::string fault_type_to_string(int fault_type_index);

    // the following 2 functions are called at runtime, to get the probability
    // of each fault type (fault_vector) or the aggregate fault probability
    // (fault_prob). Note: the probability values are provided by reference
    // (in the variables fault_vector[] & aggregate_fault_prob respectively).
    // Both functions also return a success flag (which is always true if
    // temperature ranges from 0C to 125C)

    bool fault_vector(int routerID,
                      int temperature,
                      float fault_vector[]);

    bool fault_prob(int routerID,
                    int temperature,
                    float *aggregate_fault_prob);

    // for debugging purposes

    void print(void);

  private:
    std::vector <system_conf> configurations;
    std::vector <system_conf> routers;
    std::vector <int> temperature_weights;
};

#endif //  __MEM_RUBY_NETWORK_FAULT_MODEL_HH__
