- Timestamp:
- May 24, 2015, 6:37:08 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/reconfiguration/modules/dspin_router/caba/source/src/dspin_router.cpp
r947 r994 60 60 const size_t in_fifo_depth, 61 61 const size_t out_fifo_depth, 62 const bool broadcast_supported) 62 const bool broadcast_supported, 63 const bool configuration_supported) 63 64 : soclib::caba::BaseModule(name), 64 65 … … 67 68 p_in( alloc_elems<DspinInput<flit_width> >("p_in", 5) ), 68 69 p_out( alloc_elems<DspinOutput<flit_width> >("p_out", 5) ), 70 p_recovery_cfg(NULL), 69 71 70 72 r_alloc_out( alloc_elems<sc_signal<bool> >("r_alloc_out", 5)), … … 116 118 } 117 119 118 p_recovery_cfg = NULL; 120 if (configuration_supported) { 121 p_recovery_cfg = new sc_core::sc_in<uint32_t> ("p_recovery_cfg"); 122 } 119 123 } // end constructor 120 124 … … 122 126 tmpl(/**/)::~DspinRouter() 123 127 { 124 if ( p_recovery_cfg != NULL ) delete p_recovery_cfg; 128 if ( is_reconfigurable() ) delete p_recovery_cfg; 129 } 130 131 /////////////////////////////////////////////////// 132 tmpl(int)::blackhole_position() 133 { 134 if ( is_reconfigurable() ) { 135 return p_recovery_cfg->read() & 0xF; 136 } 137 return BH_NONE; 138 } 139 140 /////////////////////////////////////////////////// 141 tmpl(void)::bind_recovery_port(sc_signal<uint32_t> &s) 142 { 143 if (!is_reconfigurable()) { 144 std::cerr << "Error in " << name() 145 << ": router configuration not supported." << std::endl 146 << "Enable it during router instantiation." << std::endl; 147 exit(1); 148 } 149 (*p_recovery_cfg)(s); 125 150 } 126 151 … … 135 160 136 161 /////////////////////////////////////////////////// 137 tmpl(void)::bind_recovery_port( sc_core::sc_signal<uint32_t> &s )138 {139 if (p_recovery_cfg == NULL) {140 p_recovery_cfg = new sc_core::sc_in<uint32_t> ("p_recovery_cfg");141 }142 (*p_recovery_cfg)(s);143 }144 145 ///////////////////////////////////////////////////146 162 tmpl(bool)::is_destination_blackhole( size_t xdest, size_t ydest, int bhpos ) 147 163 { 148 164 size_t xhole, yhole; 149 if (bhpos == BH_N) { 150 xhole = m_local_x; 151 yhole = m_local_y - 1; 152 } 153 else if (bhpos == BH_NW) { 154 xhole = m_local_x + 1; 155 yhole = m_local_y - 1; 156 } 157 else if (bhpos == BH_W) { 158 xhole = m_local_x + 1; 159 yhole = m_local_y; 160 } 161 else if (bhpos == BH_SW) { 162 xhole = m_local_x + 1; 163 yhole = m_local_y + 1; 164 } 165 else if (bhpos == BH_S) { 166 xhole = m_local_x; 167 yhole = m_local_y + 1; 168 } 169 else if (bhpos == BH_SE) { 170 xhole = m_local_x - 1; 171 yhole = m_local_y + 1; 172 } 173 else if (bhpos == BH_E) { 174 xhole = m_local_x - 1; 175 yhole = m_local_y; 176 } 177 else if (bhpos == BH_NE) { 178 xhole = m_local_x - 1; 179 yhole = m_local_y - 1; 180 } 181 else { 182 return false; 165 switch (bhpos) { 166 case BH_N: 167 xhole = m_local_x; 168 yhole = m_local_y - 1; 169 break; 170 case BH_NW: 171 xhole = m_local_x + 1; 172 yhole = m_local_y - 1; 173 break; 174 case BH_W: 175 xhole = m_local_x + 1; 176 yhole = m_local_y; 177 break; 178 case BH_SW: 179 xhole = m_local_x + 1; 180 yhole = m_local_y + 1; 181 break; 182 case BH_S: 183 xhole = m_local_x; 184 yhole = m_local_y + 1; 185 break; 186 case BH_SE: 187 xhole = m_local_x - 1; 188 yhole = m_local_y + 1; 189 break; 190 case BH_E: 191 xhole = m_local_x - 1; 192 yhole = m_local_y; 193 break; 194 case BH_NE: 195 xhole = m_local_x - 1; 196 yhole = m_local_y - 1; 197 break; 198 default: 199 return false; 183 200 } 184 201 … … 300 317 size_t xdest = (size_t)(data >> m_x_shift) & m_x_mask; 301 318 size_t ydest = (size_t)(data >> m_y_shift) & m_y_mask; 302 if ( p_recovery_cfg != NULL ) 303 { 304 if (blackhole_position() != BH_NONE ) 319 if ( blackhole_position() != BH_NONE ) 320 { 321 // reroute the request if its destination is the blackhole (this 322 // is to implement the segment recovery mechanism) 323 if ( is_destination_blackhole(xdest, ydest, blackhole_position()) ) 305 324 { 306 // reroute the request if its destination is the blackhole (this 307 // is to implement the segment recovery mechanism) 308 if (is_destination_blackhole(xdest, ydest, blackhole_position())) 309 { 310 int dir = migration_route(); 325 int dir = migration_route(); 311 326 312 327 #if SOCLIB_MODULE_DEBUG 313 314 328 std::cout << "<" << name() << "> migration: " 329 << "route request to DIR = " << dir << std::endl; 315 330 #endif 316 317 318 319 320 321 331 return dir; 332 } 333 334 if (is_network_recovery_enable()) 335 { 336 int dir = recovery_route(xdest, ydest); 322 337 323 338 #if SOCLIB_MODULE_DEBUG 324 325 339 std::cout << "<" << name() << "> network recovery: " 340 << "route request to DIR = " << dir << std::endl; 326 341 #endif 327 return dir; 328 } 342 return dir; 329 343 } 330 344 } … … 332 346 } 333 347 334 /////////////////////////////////////////////////// ///////////////////////348 /////////////////////////////////////////////////// 335 349 tmpl(int)::broadcast_route(int step, int source, sc_uint<flit_width> data) 336 350 { 337 int sel = REQ_NOP; 338 size_t xmin = (data >> (flit_width - 5 )) & 0x1F; 339 size_t xmax = (data >> (flit_width - 10)) & 0x1F; 340 size_t ymin = (data >> (flit_width - 15)) & 0x1F; 341 size_t ymax = (data >> (flit_width - 20)) & 0x1F; 351 const size_t lx = m_local_x; 352 const size_t ly = m_local_y; 353 const size_t xmin = (data >> (flit_width - 5 )) & 0x1F; 354 const size_t xmax = (data >> (flit_width - 10)) & 0x1F; 355 const size_t ymin = (data >> (flit_width - 15)) & 0x1F; 356 const size_t ymax = (data >> (flit_width - 20)) & 0x1F; 357 const int bh = blackhole_position(); 358 int sel = REQ_NOP; 359 bool ew = ((data & 0x2) != 0); 342 360 343 361 switch(source) { 344 362 case REQ_LOCAL : 345 if ( step == 1 ) sel = REQ_NORTH; 346 else if ( step == 2 ) sel = REQ_SOUTH; 347 else if ( step == 3 ) sel = REQ_EAST; 348 else if ( step == 4 ) sel = REQ_WEST; 363 if ( step == 1 ) sel = REQ_NORTH; 364 else if ( step == 2 ) sel = REQ_SOUTH; 365 else if ( step == 3 ) { 366 if ( (bh == BH_N) && (lx != 0) && (ly != 1) ) { 367 sel = REQ_NOP; 368 break; 369 } 370 sel = REQ_EAST; 371 } 372 else if ( step == 4 ) { 373 if ( (bh == BH_NE) && (lx != 1) && (ly != 1) ) { 374 sel = REQ_NOP; 375 break; 376 } 377 sel = REQ_WEST; 378 } 349 379 break; 350 380 case REQ_NORTH : 351 if ( step == 1 ) sel = REQ_SOUTH; 352 else if ( step == 2 ) sel = REQ_LOCAL; 353 else if ( step == 3 ) sel = REQ_NOP; 354 else if ( step == 4 ) sel = REQ_NOP; 381 if ( step == 1 ) sel = REQ_SOUTH; 382 else if ( step == 2 ) sel = REQ_LOCAL; 383 else if ( step == 3 ) { 384 if ( bh == BH_SW ) { 385 sel = REQ_EAST; 386 break; 387 } 388 sel = REQ_NOP; 389 } 390 else if ( step == 4 ) { 391 if ( (bh == BH_SE) && (ew || (lx == 1)) ) { 392 sel = REQ_WEST; 393 break; 394 } 395 sel = REQ_NOP; 396 } 355 397 break; 356 398 case REQ_SOUTH : 357 if ( step == 1 ) sel = REQ_NORTH; 358 else if ( step == 2 ) sel = REQ_LOCAL; 359 else if ( step == 3 ) sel = REQ_NOP; 360 else if ( step == 4 ) sel = REQ_NOP; 399 if ( step == 1 ) sel = REQ_NORTH; 400 else if ( step == 2 ) sel = REQ_LOCAL; 401 else if ( step == 3 ) { 402 if ( bh == BH_NW ) { 403 sel = REQ_EAST; 404 break; 405 } 406 if ( (bh == BH_NE) && ((lx == 1) || (ly == 1)) ) { 407 sel = REQ_WEST; 408 break; 409 } 410 sel = REQ_NOP; 411 } 412 else if ( step == 4 ) sel = REQ_NOP; 361 413 break; 362 414 case REQ_EAST : 363 if ( step == 1 ) sel = REQ_WEST; 364 else if ( step == 2 ) sel = REQ_NORTH; 365 else if ( step == 3 ) sel = REQ_SOUTH; 366 else if ( step == 4 ) sel = REQ_LOCAL; 415 if ( step == 1 ) { 416 if ( (bh == BH_NE) && (lx != 1) && (ly != 1) ) { 417 sel = REQ_NOP; 418 break; 419 } 420 sel = REQ_WEST; 421 } 422 else if ( step == 2 ) sel = REQ_NORTH; 423 else if ( step == 3 ) sel = REQ_SOUTH; 424 else if ( step == 4 ) sel = REQ_LOCAL; 367 425 break; 368 426 case REQ_WEST : 369 if ( step == 1 ) sel = REQ_EAST; 370 else if ( step == 2 ) sel = REQ_NORTH; 371 else if ( step == 3 ) sel = REQ_SOUTH; 372 else if ( step == 4 ) sel = REQ_LOCAL; 427 if ( step == 1 ) { 428 if ( (bh == BH_N) && (ly != 1) ) { 429 sel = REQ_NOP; 430 break; 431 } 432 if ( (bh == BH_S) && !ew ) { 433 sel = REQ_NOP; 434 break; 435 } 436 sel = REQ_EAST; 437 } 438 else if ( step == 2 ) sel = REQ_NORTH; 439 else if ( step == 3 ) sel = REQ_SOUTH; 440 else if ( step == 4 ) sel = REQ_LOCAL; 373 441 break; 374 442 } 375 if ( (sel == REQ_NORTH) && !(m_local_y < ymax) ) sel = REQ_NOP; 376 else if ( (sel == REQ_SOUTH) && !(m_local_y > ymin) ) sel = REQ_NOP; 377 else if ( (sel == REQ_EAST ) && !(m_local_x < xmax) ) sel = REQ_NOP; 378 else if ( (sel == REQ_WEST ) && !(m_local_x > xmin) ) sel = REQ_NOP; 443 444 if ( (sel == REQ_NORTH) && !(ly < ymax) ) sel = REQ_NOP; 445 else if ( (sel == REQ_SOUTH) && !(ly > ymin) ) sel = REQ_NOP; 446 else if ( (sel == REQ_EAST ) && !(lx < xmax) ) sel = REQ_NOP; 447 else if ( (sel == REQ_WEST ) && !(lx > xmin) ) sel = REQ_NOP; 448 449 #if 0 450 /* This code can be used if we want to inhibit requests to the 451 * blackhole. However, it is not strictly necessary because the 452 * blackhole will consume the request and will do nothing with it */ 453 454 if ( (sel == REQ_NORTH) && (bh == BH_S) ) sel = REQ_NOP; 455 else if ( (sel == REQ_SOUTH) && (bh == BH_N) ) sel = REQ_NOP; 456 else if ( (sel == REQ_EAST ) && (bh == BH_W) ) sel = REQ_NOP; 457 else if ( (sel == REQ_WEST ) && (bh == BH_E) ) sel = REQ_NOP; 458 #endif 379 459 380 460 return sel; … … 382 462 383 463 ///////////////////////////////////////////////////////// 384 tmpl( inlinebool)::is_broadcast(sc_uint<flit_width> data)464 tmpl(bool)::is_broadcast(sc_uint<flit_width> data) 385 465 { 386 466 return ( (data & 0x1) != 0); 467 } 468 469 ///////////////////////////////////////////////////////// 470 tmpl(sc_uint<flit_width>)::compute_broadcast_header(int source) 471 { 472 const int bh = blackhole_position(); 473 sc_uint<flit_width> header = r_fifo_in[source].read().data; 474 sc_uint<flit_width> mask = 0x2; 475 switch (source) { 476 case REQ_LOCAL: 477 if ( bh != BH_NONE ) { 478 header |= mask; 479 } 480 break; 481 case REQ_EAST: 482 if ( (bh == BH_NE) || (bh == BH_E) ) { 483 header |= mask; 484 } 485 break; 486 case REQ_WEST: 487 if ( (bh == BH_NW) || (bh == BH_W) || (bh == BH_SW) ) { 488 header |= mask; 489 } 490 break; 491 492 /* Make sure that the EW bit is not set when it shouldn't. 493 * This can arrive if an initiator or a local interconnect uses 494 * the broadcast header reserved bits internally and don't reset 495 * them */ 496 case REQ_NORTH: 497 if ( (bh == BH_NW) || (bh == BH_N) || (bh == BH_NE) ) { 498 header &= ~mask; 499 } 500 break; 501 case REQ_SOUTH: 502 if ( (bh == BH_SW) || (bh == BH_S) || (bh == BH_SE) ) { 503 header &= ~mask; 504 } 505 break; 506 } 507 return header; 387 508 } 388 509 … … 414 535 }; 415 536 537 const char* bh_str[] = 538 { 539 "BH_NONE", 540 "BH_N", 541 "BH_NE", 542 "BH_E", 543 "BH_SE", 544 "BH_S", 545 "BH_SW", 546 "BH_W", 547 "BH_NW" 548 }; 549 416 550 std::cout << "DSPIN_ROUTER " << name(); 551 std::cout << " / bh = " << bh_str[blackhole_position()]; 417 552 418 553 for( size_t i = 0 ; i < 5 ; i++) // loop on input ports … … 517 652 m_broadcast_supported ) // broadcast 518 653 { 654 if ( r_fifo_in[i].read().eop ) 655 { 656 std::cout << "ERROR in DSPIN_ROUTER " << name() 657 << " : broadcast packet must be 2 flits" << std::endl; 658 exit(1); 659 } 660 661 internal_flit_t header; 662 header.eop = false; 663 header.data = compute_broadcast_header(i); 664 519 665 fifo_in_read[i] = true; 520 req_in[i] = broadcast_route(1, i, r_fifo_in[i].read().data);521 r_buf_in[i] = r_fifo_in[i].read();666 req_in[i] = broadcast_route(1, i, header.data); 667 r_buf_in[i] = header; 522 668 r_index_in[i] = req_in[i]; 523 669 if( req_in[i] == REQ_NOP ) r_fsm_in[i] = INFSM_REQ_SECOND;
Note: See TracChangeset
for help on using the changeset viewer.