1/* Copyright (c) 2012 Massachusetts Institute of Technology 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 * copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 * THE SOFTWARE. 20 */ 21 22#include "model/electrical/MatrixArbiter.h" 23 24#include <cmath> 25#include <vector> 26 27#include "model/PortInfo.h" 28#include "model/EventInfo.h" 29#include "model/TransitionInfo.h" 30#include "model/ModelGen.h" 31#include "model/std_cells/StdCell.h" 32#include "model/std_cells/StdCellLib.h" 33 34namespace DSENT 35{ 36 using std::abs; 37 using std::vector; 38 39 MatrixArbiter::MatrixArbiter(const String& instance_name_, const TechModel* tech_model_) 40 : ElectricalModel(instance_name_, tech_model_) 41 { 42 initParameters(); 43 initProperties(); 44 } 45 46 MatrixArbiter::~MatrixArbiter() 47 {} 48 49 void MatrixArbiter::initParameters() 50 { 51 addParameterName("NumberRequests"); 52 return; 53 } 54 55 void MatrixArbiter::initProperties() 56 { 57 return; 58 } 59 60 MatrixArbiter* MatrixArbiter::clone() const 61 { 62 // TODO 63 return NULL; 64 } 65 66 void MatrixArbiter::constructModel() 67 { 68 // Get parameters 69 unsigned int number_requests = getParameter("NumberRequests").toUInt(); 70 71 ASSERT(number_requests > 0, "[Error] " + getInstanceName() + 72 " -> Number of requests must be > 0!"); 73 74 // Connect ports 75 createInputPort("CK"); 76 for(unsigned int i = 0; i < number_requests; ++i) 77 { 78 createInputPort("Request" + (String)i); 79 createOutputPort("Grant" + (String)i); 80 } 81 82 // Create area, power, event results 83 createElectricalResults(); 84 getEventInfo("Idle")->setStaticTransitionInfos(); 85 getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); 86// for(unsigned int i = 0; i <= number_requests; ++i) 87// { 88// // Create arbitrate event with i requests 89// createElectricalEventResult("Arbitrate" + (String)i); 90// EventInfo* event_info = getEventInfo("Arbitrate" + (String)i); 91// event_info->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); 92// 93// for(unsigned int j = 0; j < i; ++j) 94// { 95// event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(0.0, 0.0, 1.0)); 96// } 97// for(unsigned int j = i; j < number_requests; ++j) 98// { 99// event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(1.0, 0.0, 0.0)); 100// 101// } 102// //double P_0 = (double)(number_requests - i) / (double)(number_requests); 103// //double P_1 = (double)(i) / (double)(number_requests); 104// //TransitionInfo trans(P_0 * P_0, P_0 * P_1, P_1 * P_1); 105// 106// //for(unsigned int j = 0; j < number_requests; ++j) 107// //{ 108// // event_info->setTransitionInfo("Request" + (String)j, trans); 109// //} 110// } 111 createElectricalEventResult("Arbitrate"); 112 getEventInfo("Arbitrate")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); 113 for(unsigned int i = 0; i < number_requests; ++i) 114 { 115 getEventInfo("Arbitrate")->setTransitionInfo("Request" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); 116 } 117 118 if(number_requests == 1) 119 { 120 assign("Grant0", "Request0"); 121 } 122 else 123 { 124 // Init components 125 vector<String> g_inv_names(number_requests, ""); 126 vector<StdCell*> g_invs(number_requests, NULL); 127 vector<String> g_and2_names(number_requests, ""); 128 vector<StdCell*> g_and2s(number_requests, NULL); 129 for(unsigned int i = 0; i < number_requests; ++i) 130 { 131 g_inv_names[i] = "G_INV" + (String)i; 132 g_and2_names[i] = "G_AND2" + (String)i; 133 g_invs[i] = getTechModel()->getStdCellLib()->createStdCell("INV", g_inv_names[i]); 134 g_invs[i]->construct(); 135 g_and2s[i] = getTechModel()->getStdCellLib()->createStdCell("AND2", g_and2_names[i]); 136 g_and2s[i]->construct(); 137 } 138 139 unsigned int number_states = (number_requests - 1) * number_requests / 2; 140 141 vector<String> w_or2_names(number_states, ""); 142 vector<StdCell*> w_or2s(number_states, NULL); 143 vector<String> w_and2_names(number_states, ""); 144 vector<StdCell*> w_and2s(number_states, NULL); 145 vector<String> w_inv_names(number_states, ""); 146 vector<StdCell*> w_invs(number_states, NULL); 147 vector<String> w_dff_names(number_states, ""); 148 vector<StdCell*> w_dffs(number_states, NULL); 149 vector<String> dis_and2_names(number_states * 2, ""); 150 vector<StdCell*> dis_and2s(number_states * 2, NULL); 151 vector<String> dis_inv_names(number_states, ""); 152 vector<StdCell*> dis_invs(number_states, NULL); 153 unsigned int state_count = 0; 154 for(unsigned int i = 0; i < number_requests; ++i) 155 { 156 for(unsigned int j = i + 1; j < number_requests; ++j) 157 { 158 w_or2_names[state_count] = String::format("W_OR2_%d_%d", i, j); 159 w_and2_names[state_count] = String::format("W_AND2_%d_%d", i, j); 160 w_inv_names[state_count] = String::format("W_INV_%d_%d", i, j); 161 w_dff_names[state_count] = String::format("W_DFF_%d_%d", i, j); 162 w_or2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("OR2", w_or2_names[state_count]); 163 w_or2s[state_count]->construct(); 164 w_and2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("AND2", w_and2_names[state_count]); 165 w_and2s[state_count]->construct(); 166 w_invs[state_count] = getTechModel()->getStdCellLib()->createStdCell("INV", w_inv_names[state_count]); 167 w_invs[state_count]->construct(); 168 w_dffs[state_count] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", w_dff_names[state_count]); 169 w_dffs[state_count]->construct(); 170 171 dis_inv_names[state_count] = String::format("Dis_INV_%d_%d", i, j); 172 dis_and2_names[state_count] = String::format("Dis_AND2_%d_%d", i, j); 173 dis_and2_names[state_count + number_states] = String::format("Dis_AND2_%d_%d", j, i); 174 dis_invs[state_count] = getTechModel()->getStdCellLib()->createStdCell("INV", dis_inv_names[state_count]); 175 dis_invs[state_count]->construct(); 176 dis_and2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("AND2", dis_and2_names[state_count]); 177 dis_and2s[state_count]->construct(); 178 dis_and2s[state_count + number_states] = getTechModel()->getStdCellLib()->createStdCell("AND2", dis_and2_names[state_count + number_states]); 179 dis_and2s[state_count + number_states]->construct(); 180 state_count++; 181 } 182 } 183 184 vector<String> dis_or_names(number_requests, ""); 185 vector<ElectricalModel*> dis_ors(number_requests, NULL); 186 for(unsigned int i = 0; i < number_requests; ++i) 187 { 188 dis_or_names[i] = "Dis_OR" + (String)i; 189 dis_ors[i] = (ElectricalModel*)ModelGen::createModel("OR", dis_or_names[i], getTechModel()); 190 dis_ors[i]->setParameter("NumberInputs", number_requests-1); 191 dis_ors[i]->setParameter("NumberBits", 1); 192 dis_ors[i]->construct(); 193 } 194 195 state_count = 0; 196 for(unsigned int i = 0; i < number_requests; ++i) 197 { 198 createNet("Dis_OR_Out" + (String)i); 199 createNet("G_INV_Out" + (String)i); 200 portConnect(g_invs[i], "A", "Dis_OR_Out" + (String)i); 201 portConnect(g_invs[i], "Y", "G_INV_Out" + (String)i); 202 portConnect(g_and2s[i], "A", "Request" + (String)i); 203 portConnect(g_and2s[i], "B", "G_INV_Out" + (String)i); 204 portConnect(g_and2s[i], "Y", "Grant" + (String)i); 205 206 for(unsigned int j = i + 1; j < number_requests; ++j) 207 { 208 createNet(String::format("W_INV_Out_%d_%d", i, j)); 209 createNet(String::format("W_OR2_Out_%d_%d", i, j)); 210 createNet(String::format("W_AND2_Out_%d_%d", i, j)); 211 createNet(String::format("W_DFF_Out_%d_%d", i, j)); 212 portConnect(w_invs[state_count], "A", "Grant" + (String)i); 213 portConnect(w_invs[state_count], "Y", String::format("W_INV_Out_%d_%d", i, j)); 214 portConnect(w_or2s[state_count], "A", String::format("W_DFF_Out_%d_%d", i, j)); 215 portConnect(w_or2s[state_count], "B", "Grant" + (String)j); 216 portConnect(w_or2s[state_count], "Y", String::format("W_OR2_Out_%d_%d", i, j)); 217 portConnect(w_and2s[state_count], "A", String::format("W_OR2_Out_%d_%d", i, j)); 218 portConnect(w_and2s[state_count], "B", String::format("W_INV_Out_%d_%d", i, j)); 219 portConnect(w_and2s[state_count], "Y", String::format("W_AND2_Out_%d_%d", i, j)); 220 portConnect(w_dffs[state_count], "D", String::format("W_AND2_Out_%d_%d", i, j)); 221 portConnect(w_dffs[state_count], "CK", "CK"); 222 portConnect(w_dffs[state_count], "Q", String::format("W_DFF_Out_%d_%d", i, j)); 223 224 createNet(String::format("Dis_AND2_Out_%d_%d", i, j)); 225 createNet(String::format("Dis_AND2_Out_%d_%d", j, i)); 226 createNet(String::format("Dis_INV_Out_%d_%d", j, i)); 227 portConnect(dis_and2s[state_count], "A", "Request" + (String)i); 228 portConnect(dis_and2s[state_count], "B", String::format("W_DFF_Out_%d_%d", i, j)); 229 portConnect(dis_and2s[state_count], "Y", String::format("Dis_AND2_Out_%d_%d", i, j)); 230 231 portConnect(dis_invs[state_count], "A", String::format("W_DFF_Out_%d_%d", i, j)); 232 portConnect(dis_invs[state_count], "Y", String::format("Dis_INV_Out_%d_%d", j, i)); 233 portConnect(dis_and2s[state_count + number_states], "A", "Request" + (String)j); 234 portConnect(dis_and2s[state_count + number_states], "B", String::format("Dis_INV_Out_%d_%d", j, i)); 235 portConnect(dis_and2s[state_count + number_states], "Y", String::format("Dis_AND2_Out_%d_%d", j, i)); 236 237 state_count++; 238 } 239 } 240 for(unsigned int i = 0; i < number_requests; ++i) 241 { 242 unsigned int k = 0; 243 for(unsigned int j = 0; j < number_requests; ++j) 244 { 245 if(i != j) 246 { 247 portConnect(dis_ors[i], "In" + (String)k, String::format("Dis_AND2_Out_%d_%d", j, i)); 248 k++; 249 } 250 } 251 portConnect(dis_ors[i], "Out", "Dis_OR_Out" + (String)i); 252 } 253 254 // Add instances 255 for(unsigned int i = 0; i < number_requests; ++i) 256 { 257 addSubInstances(g_invs[i], 1.0); 258 addElectricalSubResults(g_invs[i], 1.0); 259 addSubInstances(g_and2s[i], 1.0); 260 addElectricalSubResults(g_and2s[i], 1.0); 261 addSubInstances(dis_ors[i], 1.0); 262 addElectricalSubResults(dis_ors[i], 1.0); 263 } 264 for(unsigned int i = 0; i < number_states; ++i) 265 { 266 addSubInstances(w_or2s[i], 1.0); 267 addElectricalSubResults(w_or2s[i], 1.0); 268 addSubInstances(w_and2s[i], 1.0); 269 addElectricalSubResults(w_and2s[i], 1.0); 270 addSubInstances(w_invs[i], 1.0); 271 addElectricalSubResults(w_invs[i], 1.0); 272 addSubInstances(w_dffs[i], 1.0); 273 addElectricalSubResults(w_dffs[i], 1.0); 274 addSubInstances(dis_and2s[i], 1.0); 275 addElectricalSubResults(dis_and2s[i], 1.0); 276 addSubInstances(dis_and2s[i + number_states], 1.0); 277 addElectricalSubResults(dis_and2s[i + number_states], 1.0); 278 addSubInstances(dis_invs[i], 1.0); 279 addElectricalSubResults(dis_invs[i], 1.0); 280 } 281 282 // Update event 283 //for(unsigned int i = 0; i <= number_requests; ++i) 284 //{ 285 //Result* arb_event = getEventResult("Arbitrate" + (String)i); 286 Result* arb_event = getEventResult("Arbitrate"); 287 for(unsigned int j = 0; j < number_requests; ++j) 288 { 289 arb_event->addSubResult(g_invs[j]->getEventResult("INV"), g_inv_names[j], 1.0); 290 arb_event->addSubResult(g_and2s[j]->getEventResult("AND2"), g_and2_names[j], 1.0); 291 arb_event->addSubResult(dis_ors[j]->getEventResult("OR"), dis_or_names[j], 1.0); 292 } 293 for(unsigned int j = 0; j < number_states; ++j) 294 { 295 arb_event->addSubResult(w_or2s[j]->getEventResult("OR2"), w_or2_names[j], 1.0); 296 arb_event->addSubResult(w_and2s[j]->getEventResult("AND2"), w_and2_names[j], 1.0); 297 arb_event->addSubResult(w_invs[j]->getEventResult("INV"), w_inv_names[j], 1.0); 298 arb_event->addSubResult(w_dffs[j]->getEventResult("DFFD"), w_dff_names[j], 1.0); 299 arb_event->addSubResult(w_dffs[j]->getEventResult("DFFQ"), w_dff_names[j], 1.0); 300 arb_event->addSubResult(w_dffs[j]->getEventResult("CK"), w_dff_names[j], 1.0); 301 arb_event->addSubResult(dis_and2s[j]->getEventResult("AND2"), dis_and2_names[j], 1.0); 302 arb_event->addSubResult(dis_and2s[j + number_states]->getEventResult("AND2"), dis_and2_names[j + number_states], 1.0); 303 arb_event->addSubResult(dis_invs[j]->getEventResult("INV"), dis_inv_names[j], 1.0); 304 } 305 //} 306 } 307 return; 308 } 309 310 void MatrixArbiter::propagateTransitionInfo() 311 { 312 // Get parameters 313 unsigned int number_requests = getParameter("NumberRequests").toUInt(); 314 315 if(number_requests == 1) 316 { 317 propagatePortTransitionInfo("Grant0", "Request0"); 318 } 319 else 320 { 321 unsigned int number_states = (number_requests - 1) * number_requests / 2; 322 323 vector<ElectricalModel*> g_and2s(number_requests, NULL); 324 vector<ElectricalModel*> g_invs(number_requests, NULL); 325 vector<ElectricalModel*> w_invs(number_states, NULL); 326 vector<ElectricalModel*> w_or2s(number_states, NULL); 327 vector<ElectricalModel*> w_and2s(number_states, NULL); 328 vector<ElectricalModel*> w_dffs(number_states, NULL); 329 vector<ElectricalModel*> dis_invs(number_states, NULL); 330 vector<ElectricalModel*> dis_and2s(number_requests * number_requests, NULL); 331 vector<ElectricalModel*> dis_ors(number_requests, NULL); 332 for(unsigned int i = 0; i < number_requests; ++i) 333 { 334 g_and2s[i] = (ElectricalModel*)getSubInstance("G_AND2" + (String)i); 335 g_invs[i] = (ElectricalModel*)getSubInstance("G_INV" + (String)i); 336 dis_ors[i] = (ElectricalModel*)getSubInstance("Dis_OR" + (String)i); 337 } 338 unsigned int state_count = 0; 339 for(unsigned int i = 0; i < number_requests; ++i) 340 { 341 for(unsigned int j = i + 1; j < number_requests; ++j) 342 { 343 w_invs[state_count] = (ElectricalModel*)getSubInstance(String::format("W_INV_%d_%d", i, j)); 344 w_or2s[state_count] = (ElectricalModel*)getSubInstance(String::format("W_OR2_%d_%d", i, j)); 345 w_and2s[state_count] = (ElectricalModel*)getSubInstance(String::format("W_AND2_%d_%d", i, j)); 346 w_dffs[state_count] = (ElectricalModel*)getSubInstance(String::format("W_DFF_%d_%d", i, j)); 347 dis_invs[state_count] = (ElectricalModel*)getSubInstance(String::format("Dis_INV_%d_%d", i, j)); 348 dis_and2s[i * number_requests + j] = (ElectricalModel*)getSubInstance(String::format("Dis_AND2_%d_%d", i, j)); 349 dis_and2s[j * number_requests + i] = (ElectricalModel*)getSubInstance(String::format("Dis_AND2_%d_%d", j, i)); 350 351 w_dffs[state_count]->getInputPort("D")->setTransitionInfo(TransitionInfo(0.5, 0.0, 0.5)); 352 propagatePortTransitionInfo(w_dffs[state_count], "CK", "CK"); 353 w_dffs[state_count]->use(); 354 355 state_count++; 356 } 357 } 358 359 unsigned int iteration = 1; 360 unsigned int max_number_iterations = 10; 361 //vector<TransitionInfo> trans_vector(number_states, TransitionInfo(0.0, 0.0, 1.0)); 362 //vector<double> total_P_vector(number_states, 0.0); 363 while(iteration < max_number_iterations) 364 { 365// for(unsigned int i = 0; i < number_states; ++i) 366// { 367// w_dffs[i]->getInputPort("D")->setTransitionInfo(trans_vector[i]); 368// propagatePortTransitionInfo(w_dffs[i], "CK", "CK"); 369// w_dffs[i]->use(); 370// } 371 state_count = 0; 372 for(unsigned int i = 0; i < number_requests; ++i) 373 { 374 for(unsigned int j = i + 1; j < number_requests; ++j) 375 { 376 propagatePortTransitionInfo(dis_and2s[i * number_requests + j], "A", "Request" + (String)i); 377 propagatePortTransitionInfo(dis_and2s[i * number_requests + j], "B", w_dffs[state_count], "Q"); 378 dis_and2s[i * number_requests + j]->use(); 379 propagatePortTransitionInfo(dis_invs[state_count], "A", w_dffs[state_count], "Q"); 380 dis_invs[state_count]->use(); 381 propagatePortTransitionInfo(dis_and2s[j * number_requests + i], "A", "Request" + (String)j); 382 propagatePortTransitionInfo(dis_and2s[j * number_requests + i], "B", dis_invs[state_count], "Y"); 383 dis_and2s[j * number_requests + i]->use(); 384 385 state_count++; 386 } 387 } 388 for(unsigned int i = 0; i < number_requests; ++i) 389 { 390 unsigned int k = 0; 391 for(unsigned int j = 0; j < number_requests; ++j) 392 { 393 if(i != j) 394 { 395 propagatePortTransitionInfo(dis_ors[i], "In" + (String)k, dis_and2s[j * number_requests + i], "Y"); 396 k++; 397 } 398 } 399 dis_ors[i]->use(); 400 } 401 for(unsigned int i = 0; i < number_requests; ++i) 402 { 403 propagatePortTransitionInfo(g_invs[i], "A", dis_ors[i], "Out"); 404 g_invs[i]->use(); 405 propagatePortTransitionInfo(g_and2s[i], "A", "Request" + (String)i); 406 propagatePortTransitionInfo(g_and2s[i], "B", g_invs[i], "Y"); 407 g_and2s[i]->use(); 408 } 409 state_count = 0; 410 for(unsigned int i = 0; i < number_requests; ++i) 411 { 412 for(unsigned int j = i + 1; j < number_requests; ++j) 413 { 414 propagatePortTransitionInfo(w_invs[state_count], "A", g_and2s[i], "Y"); 415 w_invs[state_count]->use(); 416 propagatePortTransitionInfo(w_or2s[state_count], "A", w_dffs[state_count], "Q"); 417 propagatePortTransitionInfo(w_or2s[state_count], "B", g_and2s[j], "Y"); 418 w_or2s[state_count]->use(); 419 propagatePortTransitionInfo(w_and2s[state_count], "A", w_or2s[state_count], "Y"); 420 propagatePortTransitionInfo(w_and2s[state_count], "B", w_invs[state_count], "Y"); 421 w_and2s[state_count]->use(); 422 propagatePortTransitionInfo(w_dffs[state_count], "D", w_and2s[state_count], "Y"); 423 propagatePortTransitionInfo(w_dffs[state_count], "CK", "CK"); 424 w_dffs[state_count]->use(); 425 state_count++; 426 } 427 } 428 429// for(unsigned int i = 0; i < number_states; ++i) 430// { 431// const TransitionInfo& new_trans = w_dffs[i]->getOutputPort("Q")->getTransitionInfo(); 432// total_P_vector[i] += new_trans.getProbability1(); 433// trans_vector[i] = TransitionInfo((1.0 - total_P_vector[i] / iteration) * (1.0 - total_P_vector[i] / iteration), 434// (1.0 - total_P_vector[i] / iteration) * (total_P_vector[i] / iteration), 435// (total_P_vector[i] / iteration) * (total_P_vector[i] / iteration)); 436// } 437// 438// for(unsigned int i = 0; i < number_requests; ++i) 439// { 440// g_and2s[i]->getOutputPort("Y")->getTransitionInfo().print(cout); 441// } 442// cout << endl; 443 iteration++; 444 } 445 446 for(unsigned int i = 0; i < number_requests; ++i) 447 { 448 propagatePortTransitionInfo("Grant" + (String)i, g_and2s[i], "Y"); 449 } 450 } 451 452 return; 453 } 454} // namespace DSENT 455 456