void xyyx_flatfly( const Router *r, const Flit *f, int in_channel, OutputSet *outputs, bool inject ) { // ( Traffic Class , Routing Order ) -> Virtual Channel Range int vcBegin = 0, vcEnd = gNumVCs-1; if ( f->type == Flit::READ_REQUEST ) { vcBegin = gReadReqBeginVC; vcEnd = gReadReqEndVC; } else if ( f->type == Flit::WRITE_REQUEST ) { vcBegin = gWriteReqBeginVC; vcEnd = gWriteReqEndVC; } else if ( f->type == Flit::READ_REPLY ) { vcBegin = gReadReplyBeginVC; vcEnd = gReadReplyEndVC; } else if ( f->type == Flit::WRITE_REPLY ) { vcBegin = gWriteReplyBeginVC; vcEnd = gWriteReplyEndVC; } assert(((f->vc >= vcBegin) && (f->vc <= vcEnd)) || (inject && (f->vc < 0))); int out_port; if(inject) { out_port = 0; } else { int dest = flatfly_transformation(f->dest); int targetr = (int)(dest/gC); if(targetr==r->GetID()){ //if we are at the final router, yay, output to client out_port = dest - targetr*gC; } else { //each class must have at least 2 vcs assigned or else xy_yx will deadlock int const available_vcs = (vcEnd - vcBegin + 1) / 2; assert(available_vcs > 0); // randomly select dimension order at first hop bool x_then_y = ((in_channel < gC) ? (RandomInt(1) > 0) : (f->vc < (vcBegin + available_vcs))); if(x_then_y) { out_port = flatfly_outport(dest, r->GetID()); vcEnd -= available_vcs; } else { out_port = flatfly_outport_yx(dest, r->GetID()); vcBegin += available_vcs; } } } outputs->Clear( ); outputs->AddRange( out_port , vcBegin, vcEnd ); }
void xyyx_flatfly( const Router *r, const Flit *f, int in_channel, OutputSet *outputs, bool inject ) { outputs->Clear( ); int dest = flatfly_transformation(f->dest); int targetr= (int)(dest/gC); int out_port = -1; if(in_channel<gC){ if(RandomInt(1)){ f->x_then_y = true; } else { f->x_then_y = false; } } if(targetr==r->GetID()){ //if we are at the final router, yay, output to client out_port = dest - targetr*gC; } else{ if(f->x_then_y){ out_port = flatfly_outport(dest, r->GetID()); } else { out_port = flatfly_outport_yx(dest, r->GetID()); } } int vcBegin = 0, vcEnd = gNumVCS-1; int available_vcs = 0; //each class must have ast east 2 vcs assigned or else xy_yx will deadlock if ( f->type == Flit::READ_REQUEST ) { available_vcs = (gReadReqEndVC-gReadReqBeginVC)+1; vcBegin = gReadReqBeginVC; } else if ( f->type == Flit::WRITE_REQUEST ) { available_vcs = (gWriteReqEndVC-gWriteReqBeginVC)+1; vcBegin = gWriteReqBeginVC; } else if ( f->type == Flit::READ_REPLY ) { available_vcs = (gReadReplyEndVC-gReadReplyBeginVC)+1; vcBegin = gReadReplyBeginVC; } else if ( f->type == Flit::WRITE_REPLY ) { available_vcs = (gWriteReplyEndVC-gWriteReplyBeginVC)+1; vcBegin = gWriteReplyBeginVC; } else if ( f->type == Flit::ANY_TYPE ) { available_vcs = gNumVCS; vcBegin = 0; } assert( available_vcs>=2); if(f->x_then_y){ vcEnd =vcBegin +(available_vcs>>1)-1; }else{
void min_flatfly( const Router *r, const Flit *f, int in_channel, OutputSet *outputs, bool inject ) { // ( Traffic Class , Routing Order ) -> Virtual Channel Range int vcBegin = 0, vcEnd = gNumVCs-1; if ( f->type == Flit::READ_REQUEST ) { vcBegin = gReadReqBeginVC; vcEnd = gReadReqEndVC; } else if ( f->type == Flit::WRITE_REQUEST ) { vcBegin = gWriteReqBeginVC; vcEnd = gWriteReqEndVC; } else if ( f->type == Flit::READ_REPLY ) { vcBegin = gReadReplyBeginVC; vcEnd = gReadReplyEndVC; } else if ( f->type == Flit::WRITE_REPLY ) { vcBegin = gWriteReplyBeginVC; vcEnd = gWriteReplyEndVC; } assert(((f->vc >= vcBegin) && (f->vc <= vcEnd)) || (inject && (f->vc < 0))); int out_port; if(inject) { out_port = 0; } else { int dest = flatfly_transformation(f->dest); int targetr= (int)(dest/gC); //int xdest = ((int)(dest/gC)) % gK; //int xcurr = ((r->GetID())) % gK; //int ydest = ((int)(dest/gC)) / gK; //int ycurr = ((r->GetID())) / gK; if(targetr==r->GetID()){ //if we are at the final router, yay, output to client out_port = dest - targetr*gC; } else{ //else select a dimension at random out_port = flatfly_outport(dest, r->GetID()); } } outputs->Clear( ); outputs->AddRange( out_port , vcBegin, vcEnd ); }
//ugal now uses modified comparison, modefied getcredit void ugal_flatfly_onchip( const Router *r, const Flit *f, int in_channel, OutputSet *outputs, bool inject ) { // ( Traffic Class , Routing Order ) -> Virtual Channel Range int vcBegin = 0, vcEnd = gNumVCs-1; if ( f->type == Flit::READ_REQUEST ) { vcBegin = gReadReqBeginVC; vcEnd = gReadReqEndVC; } else if ( f->type == Flit::WRITE_REQUEST ) { vcBegin = gWriteReqBeginVC; vcEnd = gWriteReqEndVC; } else if ( f->type == Flit::READ_REPLY ) { vcBegin = gReadReplyBeginVC; vcEnd = gReadReplyEndVC; } else if ( f->type == Flit::WRITE_REPLY ) { vcBegin = gWriteReplyBeginVC; vcEnd = gWriteReplyEndVC; } assert(((f->vc >= vcBegin) && (f->vc <= vcEnd)) || (inject && (f->vc < 0))); int out_port; if(inject) { out_port = 0; } else { int dest = flatfly_transformation(f->dest); int rID = r->GetID(); int _concentration = gC; int found; int debug = 0; int tmp_out_port, _ran_intm; int _min_hop, _nonmin_hop, _min_queucnt, _nonmin_queucnt; int threshold = 2; if ( in_channel < gC ){ if(gTrace){ cout<<"New Flit "<<f->src<<endl; } f->ph = 0; } if(gTrace){ int load = 0; cout<<"Router "<<rID<<endl; cout<<"Input Channel "<<in_channel<<endl; //need to modify router to report the buffere depth load +=r->GetBuffer(in_channel); cout<<"Rload "<<load<<endl; } if (debug){ cout << " FLIT ID: " << f->id << " Router: " << rID << " routing from src : " << f->src << " to dest : " << dest << " f->ph: " <<f->ph << " intm: " << f->intm << endl; } // f->ph == 0 ==> make initial global adaptive decision // f->ph == 1 ==> route nonminimaly to random intermediate node // f->ph == 2 ==> route minimally to destination found = 0; if (f->ph == 1){ dest = f->intm; } if (dest >= rID*_concentration && dest < (rID+1)*_concentration) { if (f->ph == 1) { f->ph = 2; dest = flatfly_transformation(f->dest); if (debug) cout << " done routing to intermediate "; } else { found = 1; out_port = dest % gC; if (debug) cout << " final routing to destination "; } } if (!found) { if (f->ph == 0) { _min_hop = find_distance(flatfly_transformation(f->src),dest); _ran_intm = find_ran_intm(flatfly_transformation(f->src), dest); tmp_out_port = flatfly_outport(dest, rID); if (f->watch){ *gWatchOut << GetSimTime() << " | " << r->FullName() << " | " << " MIN tmp_out_port: " << tmp_out_port; } _min_queucnt = r->GetCredit(tmp_out_port, -1, -1); _nonmin_hop = find_distance(flatfly_transformation(f->src),_ran_intm) + find_distance(_ran_intm, dest); tmp_out_port = flatfly_outport(_ran_intm, rID); if (f->watch){ *gWatchOut << GetSimTime() << " | " << r->FullName() << " | " << " NONMIN tmp_out_port: " << tmp_out_port << endl; } if (_ran_intm >= rID*_concentration && _ran_intm < (rID+1)*_concentration) { _nonmin_queucnt = numeric_limits<int>::max(); } else { _nonmin_queucnt = r->GetCredit(tmp_out_port, -1, -1); } if (debug){ cout << " _min_hop " << _min_hop << " _min_queucnt: " <<_min_queucnt << " _nonmin_hop: " << _nonmin_hop << " _nonmin_queucnt :" << _nonmin_queucnt << endl; } if (_min_hop * _min_queucnt <= _nonmin_hop * _nonmin_queucnt +threshold) { if (debug) cout << " Route MINIMALLY " << endl; f->ph = 2; } else { // route non-minimally f->minimal = 0; if (debug) { cout << " Route NONMINIMALLY int node: " <<_ran_intm << endl; } f->ph = 1; f->intm = _ran_intm; dest = f->intm; if (dest >= rID*_concentration && dest < (rID+1)*_concentration) { f->ph = 2; dest = flatfly_transformation(f->dest); } } } // find minimal correct dimension to route through out_port = flatfly_outport(dest, rID); // if we haven't reached our destination, restrict VCs appropriately to avoid routing deadlock if(out_port >= gC) { int const available_vcs = (vcEnd - vcBegin + 1) / 2; assert(available_vcs > 0); if(f->ph == 1) { vcEnd -= available_vcs; } else { assert(f->ph == 2); vcBegin += available_vcs; } } found = 1; } if (!found) { cout << " ERROR: output not found in routing. " << endl; cout << *f; exit (-1); } if (out_port >= gN*(gK-1) + gC) { cout << " ERROR: output port too big! " << endl; cout << " OUTPUT select: " << out_port << endl; cout << " router radix: " << gN*(gK-1) + gK << endl; exit (-1); } if (debug) cout << " through output port : " << out_port << endl; if(gTrace){cout<<"Outport "<<out_port<<endl;cout<<"Stop Mark"<<endl;} } outputs->Clear( ); outputs->AddRange( out_port , vcBegin, vcEnd ); }
void valiant_flatfly( const Router *r, const Flit *f, int in_channel, OutputSet *outputs, bool inject ) { // ( Traffic Class , Routing Order ) -> Virtual Channel Range int vcBegin = 0, vcEnd = gNumVCs-1; if ( f->type == Flit::READ_REQUEST ) { vcBegin = gReadReqBeginVC; vcEnd = gReadReqEndVC; } else if ( f->type == Flit::WRITE_REQUEST ) { vcBegin = gWriteReqBeginVC; vcEnd = gWriteReqEndVC; } else if ( f->type == Flit::READ_REPLY ) { vcBegin = gReadReplyBeginVC; vcEnd = gReadReplyEndVC; } else if ( f->type == Flit::WRITE_REPLY ) { vcBegin = gWriteReplyBeginVC; vcEnd = gWriteReplyEndVC; } assert(((f->vc >= vcBegin) && (f->vc <= vcEnd)) || (inject && (f->vc < 0))); int out_port; if(inject) { out_port = 0; } else { if ( in_channel < gC ){ f->ph = 0; f->intm = RandomInt( powi( gK, gN )*gC-1); } int intm = flatfly_transformation(f->intm); int dest = flatfly_transformation(f->dest); if((int)(intm/gC) == r->GetID() || (int)(dest/gC)== r->GetID()){ f->ph = 1; } if(f->ph == 0) { out_port = flatfly_outport(intm, r->GetID()); } else { assert(f->ph == 1); out_port = flatfly_outport(dest, r->GetID()); } if((int)(dest/gC) != r->GetID()) { //each class must have at least 2 vcs assigned or else valiant valiant will deadlock int const available_vcs = (vcEnd - vcBegin + 1) / 2; assert(available_vcs > 0); if(f->ph == 0) { vcEnd -= available_vcs; } else { // If routing to final destination use the second half of the VCs. assert(f->ph == 1); vcBegin += available_vcs; } } } outputs->Clear( ); outputs->AddRange( out_port , vcBegin, vcEnd ); }
//The initial XY or YX minimal routing direction is chosen adaptively void adaptive_xyyx_flatfly( const Router *r, const Flit *f, int in_channel, OutputSet *outputs, bool inject ) { // ( Traffic Class , Routing Order ) -> Virtual Channel Range int vcBegin = 0, vcEnd = gNumVCs-1; if ( f->type == Flit::READ_REQUEST ) { vcBegin = gReadReqBeginVC; vcEnd = gReadReqEndVC; } else if ( f->type == Flit::WRITE_REQUEST ) { vcBegin = gWriteReqBeginVC; vcEnd = gWriteReqEndVC; } else if ( f->type == Flit::READ_REPLY ) { vcBegin = gReadReplyBeginVC; vcEnd = gReadReplyEndVC; } else if ( f->type == Flit::WRITE_REPLY ) { vcBegin = gWriteReplyBeginVC; vcEnd = gWriteReplyEndVC; } assert(((f->vc >= vcBegin) && (f->vc <= vcEnd)) || (inject && (f->vc < 0))); int out_port; if(inject) { out_port = -1; } else { int dest = flatfly_transformation(f->dest); int targetr = (int)(dest/gC); if(targetr==r->GetID()){ //if we are at the final router, yay, output to client out_port = dest % gC; } else { //each class must have at least 2 vcs assigned or else xy_yx will deadlock int const available_vcs = (vcEnd - vcBegin + 1) / 2; assert(available_vcs > 0); int out_port_xy = flatfly_outport(dest, r->GetID()); int out_port_yx = flatfly_outport_yx(dest, r->GetID()); // Route order (XY or YX) determined when packet is injected // into the network, adaptively bool x_then_y; if(in_channel < gC){ int credit_xy = r->GetUsedCredit(out_port_xy); int credit_yx = r->GetUsedCredit(out_port_yx); if(credit_xy > credit_yx) { x_then_y = false; } else if(credit_xy < credit_yx) { x_then_y = true; } else { x_then_y = (RandomInt(1) > 0); } } else { x_then_y = (f->vc < (vcBegin + available_vcs)); } if(x_then_y) { out_port = out_port_xy; vcEnd -= available_vcs; } else { out_port = out_port_yx; vcBegin += available_vcs; } } } outputs->Clear( ); outputs->AddRange( out_port , vcBegin, vcEnd ); }