Encapsulate all ruby-related files in a ruby namespace. Change-Id: If642c9751ecefc35b45c5dd69d85e67813cc5224 Issued-on: https://gem5.atlassian.net/browse/GEM5-984 Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/47307 Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu> Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
277 lines
10 KiB
C++
277 lines
10 KiB
C++
/*
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
* 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/logging.hh"
|
|
|
|
#define MAX(a,b) ((a > b) ? (a) : (b))
|
|
|
|
namespace gem5
|
|
{
|
|
|
|
namespace ruby
|
|
{
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::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)
|
|
{
|
|
std::cout << "--- PRINTING configurations ---\n";
|
|
for (int record = 0; record < configurations.size(); record++){
|
|
std::cout << "(" << record << ") ";
|
|
std::cout << "VCs=" << configurations[record].vcs << " ";
|
|
std::cout << "Buff/VC=" << configurations[record].buff_per_vc << " [";
|
|
for (int fault_type_num = 0;
|
|
fault_type_num < number_of_fault_types;
|
|
fault_type_num++){
|
|
std::cout <<
|
|
(100 * configurations[record].fault_type[fault_type_num]);
|
|
std::cout << "% ";
|
|
}
|
|
std::cout << "]\n";
|
|
}
|
|
std::cout << "--- PRINTING temperature weights ---\n";
|
|
for (int record = 0; record < temperature_weights.size(); record++){
|
|
std::cout << "temperature=" << record << " => ";
|
|
std::cout << "weight=" << temperature_weights[record];
|
|
std::cout << "\n";
|
|
}
|
|
}
|
|
|
|
} // namespace ruby
|
|
} // namespace gem5
|