2 * Copyright (c) 2011 Massachusetts Institute of Technology
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * Official Tool Website: www.mit.edu/~kaisopos/FaultModel
32 * If you use our tool for academic research, we request that you cite:
33 * Konstantinos Aisopos, Chia-Hsin Owen Chen, and Li-Shiuan Peh. Enabling
34 * System-Level Modeling of Variation-Induced Faults in Networks-on-Chip.
35 * Proceedings of the 48th Design Automation Conference (DAC'11)
45 #include "FaultModel.hh"
46 #include "base/logging.hh"
50 #define MAX(a,b) ((a > b) ? (a) : (b))
53 FaultModel::FaultModel(const Params
&p
) : SimObject(p
)
55 // read configurations into "configurations" vector
56 // format: <buff/vc> <vcs> <10 fault types>
57 bool more_records
= true;
58 for (int i
= 0; more_records
; i
+= (fields_per_conf_record
)){
59 system_conf configuration
;
60 configuration
.buff_per_vc
=
61 p
.baseline_fault_vector_database
[i
+ conf_record_buff_per_vc
];
63 p
.baseline_fault_vector_database
[i
+ conf_record_vcs
];
64 for (int fault_index
= 0; fault_index
< number_of_fault_types
;
66 configuration
.fault_type
[fault_index
] =
67 p
.baseline_fault_vector_database
[i
+
68 conf_record_first_fault_type
+ fault_index
] / 100;
70 configurations
.push_back(configuration
);
71 if (p
.baseline_fault_vector_database
[i
+fields_per_conf_record
] < 0){
76 // read temperature weights into "temperature_weights" vector
77 // format: <temperature> <weight>
79 for (int i
= 0; more_records
; i
+= (fields_per_temperature_record
)){
80 int record_temperature
=
81 p
.temperature_weights_database
[i
+ temperature_record_temp
];
83 p
.temperature_weights_database
[i
+ temperature_record_weight
];
84 static int first_record
= true;
86 for (int temperature
= 0; temperature
< record_temperature
;
88 temperature_weights
.push_back(0);
92 assert(record_temperature
== temperature_weights
.size());
93 temperature_weights
.push_back(record_weight
);
94 if (p
.temperature_weights_database
[i
+
95 fields_per_temperature_record
] < 0){
102 FaultModel::fault_type_to_string(int ft
)
104 if (ft
== data_corruption__few_bits
){
105 return "data_corruption__few_bits";
106 } else if (ft
== data_corruption__all_bits
){
107 return "data_corruption__all_bits";
108 } else if (ft
== flit_conservation__flit_duplication
){
109 return "flit_conservation__flit_duplication";
110 } else if (ft
== flit_conservation__flit_loss_or_split
){
111 return "flit_conservation__flit_loss_or_split";
112 } else if (ft
== misrouting
){
114 } else if (ft
== credit_conservation__credit_generation
){
115 return "credit_conservation__credit_generation";
116 } else if (ft
== credit_conservation__credit_loss
){
117 return "credit_conservation__credit_loss";
118 } else if (ft
== erroneous_allocation__VC
){
119 return "erroneous_allocation__VC";
120 } else if (ft
== erroneous_allocation__switch
){
121 return "erroneous_allocation__switch";
122 } else if (ft
== unfair_arbitration
){
123 return "unfair_arbitration";
124 } else if (ft
== number_of_fault_types
){
133 FaultModel::declare_router(int number_of_inputs
,
134 int number_of_outputs
,
135 int number_of_vcs_per_input
,
136 int number_of_buff_per_data_vc
,
137 int number_of_buff_per_ctrl_vc
)
139 // check inputs (are they legal?)
140 if (number_of_inputs
<= 0 || number_of_outputs
<= 0 ||
141 number_of_vcs_per_input
<= 0 || number_of_buff_per_data_vc
<= 0 ||
142 number_of_buff_per_ctrl_vc
<= 0){
143 fatal("Fault Model: ERROR in argument of FaultModel_declare_router!");
145 int number_of_buffers_per_vc
= MAX(number_of_buff_per_data_vc
,
146 number_of_buff_per_ctrl_vc
);
147 int total_vcs
= number_of_inputs
* number_of_vcs_per_input
;
148 if (total_vcs
> MAX_VCs
){
149 fatal("Fault Model: ERROR! Number inputs*VCs (MAX_VCs) unsupported");
151 if (number_of_buffers_per_vc
> MAX_BUFFERS_per_VC
){
152 fatal("Fault Model: ERROR! buffers/VC (MAX_BUFFERS_per_VC) too high");
155 // link the router to a DB record
157 for (int record
= 0; record
< configurations
.size(); record
++){
158 if ((configurations
[record
].buff_per_vc
== number_of_buffers_per_vc
)&&
159 (configurations
[record
].vcs
== total_vcs
)){
163 if (record_hit
== -1){
164 panic("Fault Model: ERROR! configuration not found in DB. BUG?");
167 // remember the router and return its ID
168 routers
.push_back(configurations
[record_hit
]);
169 static int router_index
= 0;
170 return router_index
++;
174 FaultModel::fault_vector(int routerID
,
175 int temperature_input
,
176 float fault_vector
[])
180 // is the routerID recorded?
181 if (routerID
< 0 || routerID
>= ((int) routers
.size())){
182 warn("Fault Model: ERROR! unknown router ID argument.");
183 fatal("Fault Model: Did you enable the fault model flag)?");
186 // is the temperature too high/too low?
187 int temperature
= temperature_input
;
188 if (temperature_input
>= ((int) temperature_weights
.size())){
190 warn_once("Fault Model: Temperature exceeded simulated upper bound.");
191 warn_once("Fault Model: The fault model is not accurate any more.");
192 temperature
= (temperature_weights
.size() - 1);
193 } else if (temperature_input
< 0){
195 warn_once("Fault Model: Temperature exceeded simulated lower bound.");
196 warn_once("Fault Model: The fault model is not accurate any more.");
200 // recover the router record and return its fault vector
201 for (int i
= 0; i
< number_of_fault_types
; i
++){
202 fault_vector
[i
] = routers
[routerID
].fault_type
[i
] *
203 ((float)temperature_weights
[temperature
]);
209 FaultModel::fault_prob(int routerID
,
210 int temperature_input
,
211 float *aggregate_fault_prob
)
213 *aggregate_fault_prob
= 1.0;
216 // is the routerID recorded?
217 if (routerID
< 0 || routerID
>= ((int) routers
.size())){
218 warn("Fault Model: ERROR! unknown router ID argument.");
219 fatal("Fault Model: Did you enable the fault model flag)?");
222 // is the temperature too high/too low?
223 int temperature
= temperature_input
;
224 if (temperature_input
>= ((int) temperature_weights
.size()) ){
226 warn_once("Fault Model: Temperature exceeded simulated upper bound.");
227 warn_once("Fault Model: The fault model is not accurate any more.");
228 temperature
= (temperature_weights
.size()-1);
229 } else if (temperature_input
< 0){
231 warn_once("Fault Model: Temperature exceeded simulated lower bound.");
232 warn_once("Fault Model: The fault model is not accurate any more.");
236 // recover the router record and return its aggregate fault probability
237 for (int i
= 0; i
< number_of_fault_types
; i
++){
238 *aggregate_fault_prob
= *aggregate_fault_prob
*
239 ( 1.0 - (routers
[routerID
].fault_type
[i
] *
240 ((float)temperature_weights
[temperature
])) );
242 *aggregate_fault_prob
= 1.0 - *aggregate_fault_prob
;
246 // this function is used only for debugging purposes
248 FaultModel::print(void)
250 cout
<< "--- PRINTING configurations ---\n";
251 for (int record
= 0; record
< configurations
.size(); record
++){
252 cout
<< "(" << record
<< ") ";
253 cout
<< "VCs=" << configurations
[record
].vcs
<< " ";
254 cout
<< "Buff/VC=" << configurations
[record
].buff_per_vc
<< " [";
255 for (int fault_type_num
= 0;
256 fault_type_num
< number_of_fault_types
;
258 cout
<< (100 * configurations
[record
].fault_type
[fault_type_num
]);
263 cout
<< "--- PRINTING temperature weights ---\n";
264 for (int record
= 0; record
< temperature_weights
.size(); record
++){
265 cout
<< "temperature=" << record
<< " => ";
266 cout
<< "weight=" << temperature_weights
[record
];