18612Stushar@csail.mit.edu/*
28612Stushar@csail.mit.edu * Copyright (c) 2011 Massachusetts Institute of Technology
38612Stushar@csail.mit.edu * All rights reserved.
48612Stushar@csail.mit.edu *
58612Stushar@csail.mit.edu * Redistribution and use in source and binary forms, with or without
68612Stushar@csail.mit.edu * modification, are permitted provided that the following conditions are
78612Stushar@csail.mit.edu * met: redistributions of source code must retain the above copyright
88612Stushar@csail.mit.edu * notice, this list of conditions and the following disclaimer;
98612Stushar@csail.mit.edu * redistributions in binary form must reproduce the above copyright
108612Stushar@csail.mit.edu * notice, this list of conditions and the following disclaimer in the
118612Stushar@csail.mit.edu * documentation and/or other materials provided with the distribution;
128612Stushar@csail.mit.edu * neither the name of the copyright holders nor the names of its
138612Stushar@csail.mit.edu * contributors may be used to endorse or promote products derived from
148612Stushar@csail.mit.edu * this software without specific prior written permission.
158612Stushar@csail.mit.edu *
168612Stushar@csail.mit.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178612Stushar@csail.mit.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188612Stushar@csail.mit.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198612Stushar@csail.mit.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208612Stushar@csail.mit.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218612Stushar@csail.mit.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228612Stushar@csail.mit.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238612Stushar@csail.mit.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248612Stushar@csail.mit.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258612Stushar@csail.mit.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
268612Stushar@csail.mit.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278612Stushar@csail.mit.edu *
288612Stushar@csail.mit.edu * Authors: Konstantinos Aisopos
298612Stushar@csail.mit.edu */
308612Stushar@csail.mit.edu
318612Stushar@csail.mit.edu/*
328612Stushar@csail.mit.edu * Official Tool Website: www.mit.edu/~kaisopos/FaultModel
338612Stushar@csail.mit.edu *
3411320Ssteve.reinhardt@amd.com * If you use our tool for academic research, we request that you cite:
358612Stushar@csail.mit.edu * Konstantinos Aisopos, Chia-Hsin Owen Chen, and Li-Shiuan Peh. Enabling
368612Stushar@csail.mit.edu * System-Level Modeling of Variation-Induced Faults in Networks-on-Chip.
378612Stushar@csail.mit.edu * Proceedings of the 48th Design Automation Conference (DAC'11)
388612Stushar@csail.mit.edu */
398612Stushar@csail.mit.edu
408612Stushar@csail.mit.edu// C++ includes
418946Sandreas.hansson@arm.com#include <cassert>
428612Stushar@csail.mit.edu#include <fstream>
438612Stushar@csail.mit.edu#include <iostream>
448612Stushar@csail.mit.edu#include <vector>
458612Stushar@csail.mit.edu
468612Stushar@csail.mit.edu// GEM5 includes
478612Stushar@csail.mit.edu#include "FaultModel.hh"
4812334Sgabeblack@google.com#include "base/logging.hh"
498612Stushar@csail.mit.edu
508946Sandreas.hansson@arm.comusing namespace std;
518946Sandreas.hansson@arm.com
528612Stushar@csail.mit.edu#define MAX(a,b) ((a > b) ? (a) : (b))
538612Stushar@csail.mit.edu
548612Stushar@csail.mit.edu
558612Stushar@csail.mit.eduFaultModel::FaultModel(const Params *p) : SimObject(p)
568612Stushar@csail.mit.edu{
578612Stushar@csail.mit.edu    // read configurations into "configurations" vector
5811320Ssteve.reinhardt@amd.com    // format: <buff/vc> <vcs> <10 fault types>
598612Stushar@csail.mit.edu    bool more_records = true;
608612Stushar@csail.mit.edu    for (int i = 0; more_records; i += (fields_per_conf_record)){
618612Stushar@csail.mit.edu        system_conf configuration;
6211320Ssteve.reinhardt@amd.com        configuration.buff_per_vc =
638612Stushar@csail.mit.edu            p->baseline_fault_vector_database[i + conf_record_buff_per_vc];
6411320Ssteve.reinhardt@amd.com        configuration.vcs =
658612Stushar@csail.mit.edu            p->baseline_fault_vector_database[i + conf_record_vcs];
6611320Ssteve.reinhardt@amd.com        for (int fault_index = 0; fault_index < number_of_fault_types;
678612Stushar@csail.mit.edu            fault_index++){
6811320Ssteve.reinhardt@amd.com            configuration.fault_type[fault_index] =
6911320Ssteve.reinhardt@amd.com                p->baseline_fault_vector_database[i +
708612Stushar@csail.mit.edu                   conf_record_first_fault_type + fault_index] / 100;
718612Stushar@csail.mit.edu        }
728612Stushar@csail.mit.edu        configurations.push_back(configuration);
738612Stushar@csail.mit.edu        if (p->baseline_fault_vector_database[i+fields_per_conf_record] < 0){
748612Stushar@csail.mit.edu            more_records = false;
758612Stushar@csail.mit.edu        }
768612Stushar@csail.mit.edu    }
778612Stushar@csail.mit.edu
788612Stushar@csail.mit.edu    // read temperature weights into "temperature_weights" vector
798612Stushar@csail.mit.edu    // format: <temperature> <weight>
808612Stushar@csail.mit.edu    more_records = true;
818612Stushar@csail.mit.edu    for (int i = 0; more_records; i += (fields_per_temperature_record)){
8211320Ssteve.reinhardt@amd.com        int record_temperature =
838612Stushar@csail.mit.edu               p->temperature_weights_database[i + temperature_record_temp];
848612Stushar@csail.mit.edu        int record_weight =
858612Stushar@csail.mit.edu               p->temperature_weights_database[i + temperature_record_weight];
868612Stushar@csail.mit.edu        static int first_record = true;
878612Stushar@csail.mit.edu        if (first_record){
8811320Ssteve.reinhardt@amd.com            for (int temperature = 0; temperature < record_temperature;
898612Stushar@csail.mit.edu                 temperature++){
908612Stushar@csail.mit.edu                 temperature_weights.push_back(0);
918612Stushar@csail.mit.edu            }
928612Stushar@csail.mit.edu            first_record = false;
938612Stushar@csail.mit.edu        }
948612Stushar@csail.mit.edu        assert(record_temperature == temperature_weights.size());
958612Stushar@csail.mit.edu        temperature_weights.push_back(record_weight);
9611320Ssteve.reinhardt@amd.com        if (p->temperature_weights_database[i +
978612Stushar@csail.mit.edu               fields_per_temperature_record] < 0){
988612Stushar@csail.mit.edu            more_records = false;
998612Stushar@csail.mit.edu        }
1008612Stushar@csail.mit.edu    }
1018612Stushar@csail.mit.edu}
1028612Stushar@csail.mit.edu
1038612Stushar@csail.mit.edustring
1048612Stushar@csail.mit.eduFaultModel::fault_type_to_string(int ft)
1058612Stushar@csail.mit.edu{
1068612Stushar@csail.mit.edu   if (ft == data_corruption__few_bits){
1078612Stushar@csail.mit.edu       return "data_corruption__few_bits";
1088612Stushar@csail.mit.edu   } else if (ft == data_corruption__all_bits){
1098612Stushar@csail.mit.edu      return "data_corruption__all_bits";
1108612Stushar@csail.mit.edu   } else if (ft == flit_conservation__flit_duplication){
1118612Stushar@csail.mit.edu      return "flit_conservation__flit_duplication";
1128612Stushar@csail.mit.edu   } else if (ft == flit_conservation__flit_loss_or_split){
1138612Stushar@csail.mit.edu      return "flit_conservation__flit_loss_or_split";
1148612Stushar@csail.mit.edu   } else if (ft == misrouting){
1158612Stushar@csail.mit.edu      return "misrouting";
1168612Stushar@csail.mit.edu   } else if (ft == credit_conservation__credit_generation){
1178612Stushar@csail.mit.edu      return "credit_conservation__credit_generation";
1188612Stushar@csail.mit.edu   } else if (ft == credit_conservation__credit_loss){
1198612Stushar@csail.mit.edu      return "credit_conservation__credit_loss";
1208612Stushar@csail.mit.edu   } else if (ft == erroneous_allocation__VC){
1218612Stushar@csail.mit.edu      return "erroneous_allocation__VC";
1228612Stushar@csail.mit.edu   } else if (ft == erroneous_allocation__switch){
1238612Stushar@csail.mit.edu      return "erroneous_allocation__switch";
1248612Stushar@csail.mit.edu   } else if (ft == unfair_arbitration){
1258612Stushar@csail.mit.edu      return "unfair_arbitration";
1268612Stushar@csail.mit.edu   } else if (ft == number_of_fault_types){
1278612Stushar@csail.mit.edu      return "none";
1288612Stushar@csail.mit.edu   } else {
1298612Stushar@csail.mit.edu      return "none";
1308612Stushar@csail.mit.edu   }
1318612Stushar@csail.mit.edu}
1328612Stushar@csail.mit.edu
1338612Stushar@csail.mit.edu
13411320Ssteve.reinhardt@amd.comint
13511320Ssteve.reinhardt@amd.comFaultModel::declare_router(int number_of_inputs,
13611320Ssteve.reinhardt@amd.com                           int number_of_outputs,
13711320Ssteve.reinhardt@amd.com                           int number_of_vcs_per_input,
13811320Ssteve.reinhardt@amd.com                           int number_of_buff_per_data_vc,
1398612Stushar@csail.mit.edu                           int number_of_buff_per_ctrl_vc)
1408612Stushar@csail.mit.edu{
1418612Stushar@csail.mit.edu    // check inputs (are they legal?)
1428612Stushar@csail.mit.edu    if (number_of_inputs <= 0 || number_of_outputs <= 0 ||
14311320Ssteve.reinhardt@amd.com        number_of_vcs_per_input <= 0 || number_of_buff_per_data_vc <= 0 ||
1448612Stushar@csail.mit.edu        number_of_buff_per_ctrl_vc <= 0){
1458612Stushar@csail.mit.edu        fatal("Fault Model: ERROR in argument of FaultModel_declare_router!");
1468612Stushar@csail.mit.edu    }
1478612Stushar@csail.mit.edu    int number_of_buffers_per_vc = MAX(number_of_buff_per_data_vc,
1488612Stushar@csail.mit.edu                                       number_of_buff_per_ctrl_vc);
1498612Stushar@csail.mit.edu    int total_vcs = number_of_inputs * number_of_vcs_per_input;
1508612Stushar@csail.mit.edu    if (total_vcs > MAX_VCs){
1518612Stushar@csail.mit.edu        fatal("Fault Model: ERROR! Number inputs*VCs (MAX_VCs) unsupported");
1528612Stushar@csail.mit.edu    }
1538612Stushar@csail.mit.edu    if (number_of_buffers_per_vc > MAX_BUFFERS_per_VC){
1548612Stushar@csail.mit.edu        fatal("Fault Model: ERROR! buffers/VC (MAX_BUFFERS_per_VC) too high");
1558612Stushar@csail.mit.edu    }
1568612Stushar@csail.mit.edu
1578612Stushar@csail.mit.edu    // link the router to a DB record
1588612Stushar@csail.mit.edu    int record_hit = -1;
15911320Ssteve.reinhardt@amd.com    for (int record = 0; record < configurations.size(); record++){
1608612Stushar@csail.mit.edu        if ((configurations[record].buff_per_vc == number_of_buffers_per_vc)&&
1618612Stushar@csail.mit.edu            (configurations[record].vcs == total_vcs)){
1628612Stushar@csail.mit.edu            record_hit = record;
1638612Stushar@csail.mit.edu        }
1648612Stushar@csail.mit.edu    }
1658612Stushar@csail.mit.edu    if (record_hit == -1){
1668612Stushar@csail.mit.edu        panic("Fault Model: ERROR! configuration not found in DB. BUG?");
1678612Stushar@csail.mit.edu    }
1688612Stushar@csail.mit.edu
1698612Stushar@csail.mit.edu    // remember the router and return its ID
1708612Stushar@csail.mit.edu    routers.push_back(configurations[record_hit]);
1718612Stushar@csail.mit.edu    static int router_index = 0;
1728612Stushar@csail.mit.edu    return router_index++;
1738612Stushar@csail.mit.edu}
1748612Stushar@csail.mit.edu
17511320Ssteve.reinhardt@amd.combool
17611320Ssteve.reinhardt@amd.comFaultModel::fault_vector(int routerID,
1778612Stushar@csail.mit.edu                         int temperature_input,
1788612Stushar@csail.mit.edu                         float fault_vector[])
1798612Stushar@csail.mit.edu{
1808612Stushar@csail.mit.edu    bool ok = true;
1818612Stushar@csail.mit.edu
1828612Stushar@csail.mit.edu    // is the routerID recorded?
1838612Stushar@csail.mit.edu    if (routerID < 0 || routerID >= ((int) routers.size())){
1848612Stushar@csail.mit.edu         warn("Fault Model: ERROR! unknown router ID argument.");
18511320Ssteve.reinhardt@amd.com        fatal("Fault Model: Did you enable the fault model flag)?");
1868612Stushar@csail.mit.edu    }
1878612Stushar@csail.mit.edu
1888612Stushar@csail.mit.edu    // is the temperature too high/too low?
1898612Stushar@csail.mit.edu    int temperature = temperature_input;
1908612Stushar@csail.mit.edu    if (temperature_input >= ((int) temperature_weights.size())){
1918612Stushar@csail.mit.edu        ok = false;
1928612Stushar@csail.mit.edu        warn_once("Fault Model: Temperature exceeded simulated upper bound.");
1938612Stushar@csail.mit.edu        warn_once("Fault Model: The fault model is not accurate any more.");
1948612Stushar@csail.mit.edu        temperature = (temperature_weights.size() - 1);
1958612Stushar@csail.mit.edu    } else if (temperature_input < 0){
1968612Stushar@csail.mit.edu        ok = false;
1978612Stushar@csail.mit.edu        warn_once("Fault Model: Temperature exceeded simulated lower bound.");
1988612Stushar@csail.mit.edu        warn_once("Fault Model: The fault model is not accurate any more.");
1998612Stushar@csail.mit.edu        temperature = 0;
2008612Stushar@csail.mit.edu    }
2018612Stushar@csail.mit.edu
2028612Stushar@csail.mit.edu    // recover the router record and return its fault vector
2038612Stushar@csail.mit.edu    for (int i = 0; i < number_of_fault_types; i++){
20411320Ssteve.reinhardt@amd.com        fault_vector[i] = routers[routerID].fault_type[i] *
2058612Stushar@csail.mit.edu                          ((float)temperature_weights[temperature]);
2068612Stushar@csail.mit.edu    }
2078612Stushar@csail.mit.edu    return ok;
2088612Stushar@csail.mit.edu}
2098612Stushar@csail.mit.edu
21011320Ssteve.reinhardt@amd.combool
21111320Ssteve.reinhardt@amd.comFaultModel::fault_prob(int routerID,
2128612Stushar@csail.mit.edu                       int temperature_input,
2138612Stushar@csail.mit.edu                       float *aggregate_fault_prob)
2148612Stushar@csail.mit.edu{
2158612Stushar@csail.mit.edu    *aggregate_fault_prob = 1.0;
2168612Stushar@csail.mit.edu    bool ok = true;
2178612Stushar@csail.mit.edu
2188612Stushar@csail.mit.edu    // is the routerID recorded?
2198612Stushar@csail.mit.edu    if (routerID < 0 || routerID >= ((int) routers.size())){
2208612Stushar@csail.mit.edu         warn("Fault Model: ERROR! unknown router ID argument.");
22111320Ssteve.reinhardt@amd.com        fatal("Fault Model: Did you enable the fault model flag)?");
2228612Stushar@csail.mit.edu    }
2238612Stushar@csail.mit.edu
2248612Stushar@csail.mit.edu    // is the temperature too high/too low?
2258612Stushar@csail.mit.edu    int temperature = temperature_input;
2268612Stushar@csail.mit.edu    if (temperature_input >= ((int) temperature_weights.size()) ){
2278612Stushar@csail.mit.edu        ok = false;
2288612Stushar@csail.mit.edu        warn_once("Fault Model: Temperature exceeded simulated upper bound.");
2298612Stushar@csail.mit.edu        warn_once("Fault Model: The fault model is not accurate any more.");
2308612Stushar@csail.mit.edu        temperature = (temperature_weights.size()-1);
2318612Stushar@csail.mit.edu    } else if (temperature_input < 0){
2328612Stushar@csail.mit.edu        ok = false;
2338612Stushar@csail.mit.edu        warn_once("Fault Model: Temperature exceeded simulated lower bound.");
2348612Stushar@csail.mit.edu        warn_once("Fault Model: The fault model is not accurate any more.");
2358612Stushar@csail.mit.edu        temperature = 0;
2368612Stushar@csail.mit.edu    }
2378612Stushar@csail.mit.edu
2388612Stushar@csail.mit.edu    // recover the router record and return its aggregate fault probability
2398612Stushar@csail.mit.edu    for (int i = 0; i < number_of_fault_types; i++){
24011320Ssteve.reinhardt@amd.com        *aggregate_fault_prob=  *aggregate_fault_prob *
24111320Ssteve.reinhardt@amd.com                               ( 1.0 - (routers[routerID].fault_type[i] *
2428612Stushar@csail.mit.edu                                 ((float)temperature_weights[temperature])) );
2438612Stushar@csail.mit.edu    }
2448612Stushar@csail.mit.edu    *aggregate_fault_prob = 1.0 - *aggregate_fault_prob;
2458612Stushar@csail.mit.edu    return ok;
2468612Stushar@csail.mit.edu}
2478612Stushar@csail.mit.edu
2488612Stushar@csail.mit.edu// this function is used only for debugging purposes
24911320Ssteve.reinhardt@amd.comvoid
2508612Stushar@csail.mit.eduFaultModel::print(void)
2518612Stushar@csail.mit.edu{
2528612Stushar@csail.mit.edu    cout << "--- PRINTING configurations ---\n";
2538612Stushar@csail.mit.edu    for (int record = 0; record < configurations.size(); record++){
2548612Stushar@csail.mit.edu        cout << "(" << record << ") ";
2558612Stushar@csail.mit.edu        cout << "VCs=" << configurations[record].vcs << " ";
2568612Stushar@csail.mit.edu        cout << "Buff/VC=" << configurations[record].buff_per_vc << " [";
25711320Ssteve.reinhardt@amd.com        for (int fault_type_num = 0;
25811320Ssteve.reinhardt@amd.com             fault_type_num < number_of_fault_types;
2598612Stushar@csail.mit.edu             fault_type_num++){
26011320Ssteve.reinhardt@amd.com            cout << (100 * configurations[record].fault_type[fault_type_num]);
2618612Stushar@csail.mit.edu            cout << "% ";
2628612Stushar@csail.mit.edu        }
2638612Stushar@csail.mit.edu        cout << "]\n";
2648612Stushar@csail.mit.edu    }
2658612Stushar@csail.mit.edu    cout << "--- PRINTING temperature weights ---\n";
2668612Stushar@csail.mit.edu    for (int record = 0; record < temperature_weights.size(); record++){
2678612Stushar@csail.mit.edu        cout << "temperature=" << record << " => ";
2688612Stushar@csail.mit.edu        cout << "weight=" << temperature_weights[record];
2698612Stushar@csail.mit.edu        cout << "\n";
2708612Stushar@csail.mit.edu    }
2718612Stushar@csail.mit.edu}
2728612Stushar@csail.mit.edu
2738612Stushar@csail.mit.eduFaultModel *
2748612Stushar@csail.mit.eduFaultModelParams::create()
2758612Stushar@csail.mit.edu{
2768612Stushar@csail.mit.edu    return new FaultModel(this);
2778612Stushar@csail.mit.edu}
278