Ignore:
Timestamp:
May 24, 2015, 6:37:08 PM (10 years ago)
Author:
cfuguet
Message:

reconf: modify the broadcast routing function to support holes in the
mesh.

  • Add a test platform in dspin_router directory that validates the introduced modifications.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/reconfiguration/modules/dspin_router/caba/source/src/dspin_router.cpp

    r947 r994  
    6060                             const size_t   in_fifo_depth,
    6161                             const size_t   out_fifo_depth,
    62                              const bool     broadcast_supported)
     62                             const bool     broadcast_supported,
     63                             const bool     configuration_supported)
    6364    : soclib::caba::BaseModule(name),
    6465
     
    6768      p_in( alloc_elems<DspinInput<flit_width> >("p_in", 5) ),
    6869      p_out( alloc_elems<DspinOutput<flit_width> >("p_out", 5) ),
     70      p_recovery_cfg(NULL),
    6971
    7072      r_alloc_out( alloc_elems<sc_signal<bool> >("r_alloc_out", 5)),
     
    116118        }
    117119
    118         p_recovery_cfg = NULL;
     120        if (configuration_supported) {
     121            p_recovery_cfg = new sc_core::sc_in<uint32_t> ("p_recovery_cfg");
     122        }
    119123    } //  end constructor
    120124
     
    122126    tmpl(/**/)::~DspinRouter()
    123127    {
    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);
    125150    }
    126151
     
    135160
    136161    ///////////////////////////////////////////////////
    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     ///////////////////////////////////////////////////
    146162    tmpl(bool)::is_destination_blackhole( size_t xdest, size_t ydest, int bhpos )
    147163    {
    148164        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;
    183200        }
    184201
     
    300317        size_t xdest = (size_t)(data >> m_x_shift) & m_x_mask;
    301318        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()) )
    305324            {
    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();
    311326
    312327#if SOCLIB_MODULE_DEBUG
    313                     std::cout << "<" << name() << "> migration: "
    314                               << "route request to DIR = " << dir << std::endl;
     328                std::cout << "<" << name() << "> migration: "
     329                          << "route request to DIR = " << dir << std::endl;
    315330#endif
    316                     return dir;
    317                 }
    318 
    319                 if (is_network_recovery_enable())
    320                 {
    321                     int dir = recovery_route(xdest, ydest);
     331                return dir;
     332            }
     333
     334            if (is_network_recovery_enable())
     335            {
     336                int dir = recovery_route(xdest, ydest);
    322337
    323338#if SOCLIB_MODULE_DEBUG
    324                     std::cout << "<" << name() << "> network recovery: "
    325                               << "route request to DIR = " << dir << std::endl;
     339                std::cout << "<" << name() << "> network recovery: "
     340                          << "route request to DIR = " << dir << std::endl;
    326341#endif
    327                     return dir;
    328                 }
     342                return dir;
    329343            }
    330344        }
     
    332346    }
    333347
    334     //////////////////////////////////////////////////////////////////////////
     348    ///////////////////////////////////////////////////
    335349    tmpl(int)::broadcast_route(int step, int source, sc_uint<flit_width> data)
    336350    {
    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);
    342360
    343361        switch(source) {
    344362        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            }
    349379        break;
    350380        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            }
    355397        break;
    356398        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;
    361413        break;
    362414        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;
    367425        break;
    368426        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;
    373441        break;
    374442        }
    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
    379459
    380460        return sel;
     
    382462
    383463    /////////////////////////////////////////////////////////
    384     tmpl(inline bool)::is_broadcast(sc_uint<flit_width> data)
     464    tmpl(bool)::is_broadcast(sc_uint<flit_width> data)
    385465    {
    386466        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;
    387508    }
    388509
     
    414535        };
    415536
     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
    416550        std::cout << "DSPIN_ROUTER " << name();
     551        std::cout << " / bh = " << bh_str[blackhole_position()];
    417552
    418553        for( size_t i = 0 ; i < 5 ; i++)  // loop on input ports
     
    517652                             m_broadcast_supported )          // broadcast
    518653                        {
     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
    519665                            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;
    522668                            r_index_in[i]   = req_in[i];
    523669                            if( req_in[i] == REQ_NOP ) r_fsm_in[i] = INFSM_REQ_SECOND;
Note: See TracChangeset for help on using the changeset viewer.