gem5/src/mem/ruby/network/booksim2/routefunc.cc
void fattree_nca( const BSRouter *r, const Flit *f,
               int in_channel, OutputSet* outputs, bool inject)
{
  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 = f->dest;
    int router_id = r->GetID(); //routers are numbered with smallest at the top level
    int routers_per_level = powi(gK, gN-1);
    int pos = router_id%routers_per_level;
    int router_depth  = router_id/ routers_per_level; //which level
    int routers_per_neighborhood = powi(gK,gN-router_depth-1);
    int router_neighborhood = pos/routers_per_neighborhood; //coverage of this tree
    int router_coverage = powi(gK, gN-router_depth);  //span of the tree from this router


    //NCA reached going down
    if(dest <(router_neighborhood+1)* router_coverage &&
       dest >=router_neighborhood* router_coverage){
      //down ports are numbered first

      //ejection
      if(router_depth == gN-1){
	out_port = dest%gK;
      } else {
	//find the down port for the destination
	int router_branch_coverage = powi(gK, gN-(router_depth+1));
	out_port = (dest-router_neighborhood* router_coverage)/router_branch_coverage;
      }
    } else {
      //up ports are numbered last
      assert(in_channel<gK);//came from a up channel
      out_port = gK+RandomInt(gK-1);
    }
  }
  outputs->Clear( );

  outputs->AddRange( out_port, vcBegin, vcEnd );
}
// ============================================================
//  FATTREE: Nearest Common Ancestor w/ Random  Routing Up
// ===
Nearest Common Ancestor w/ Random  Routing Up
Nearest Common Ancestor w / Random Routing Up
void fattree_nca( const BSRouter *r, const Flit *f,
               int in_channel, OutputSet* outputs, bool inject)
{
  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 = f->dest;
    int router_id = r->GetID(); 
    int routers_per_level = powi(gK, gN-1);
    int pos = router_id%routers_per_level;
    int router_depth  = router_id/ routers_per_level; 
    int routers_per_neighborhood = powi(gK,gN-router_depth-1);
    int router_neighborhood = pos/routers_per_neighborhood; 
    int router_coverage = powi(gK, gN-router_depth);  
    if(dest <(router_neighborhood+1)* router_coverage &&
       dest >=router_neighborhood* router_coverage){
      if(router_depth == gN-1){
	out_port = dest%gK;
      } else {
	int router_branch_coverage = powi(gK, gN-(router_depth+1));
	out_port = (dest-router_neighborhood* router_coverage)/router_branch_coverage;
      }
    } else {
      assert(in_channel<gK);
      out_port = gK+RandomInt(gK-1);
    }
  }
  outputs->Clear( );
  outputs->AddRange( out_port, vcBegin, vcEnd );
}
void fattree_nca ( const BSRouter * r , const Flit * f , int in_channel , OutputSet * outputs , bool inject ) { 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 = f -> dest ; int router_id = r -> GetID ( ) ; int routers_per_level = powi ( gK , gN - 1 ) ; int pos = router_id % routers_per_level ; int router_depth = router_id / routers_per_level ; int routers_per_neighborhood = powi ( gK , gN - router_depth - 1 ) ; int router_neighborhood = pos / routers_per_neighborhood ; int router_coverage = powi ( gK , gN - router_depth ) ; if ( dest < ( router_neighborhood + 1 ) * router_coverage && dest >= router_neighborhood * router_coverage ) { if ( router_depth == gN - 1 ) { out_port = dest % gK ; } else { int router_branch_coverage = powi ( gK , gN - ( router_depth + 1 ) ) ; out_port = ( dest - router_neighborhood * router_coverage ) / router_branch_coverage ; } } else { assert ( in_channel < gK ) ; out_port = gK + RandomInt ( gK - 1 ) ; } } outputs -> Clear ( ) ; outputs -> AddRange ( out_port , vcBegin , vcEnd ) ; }
FATTREE: Nearest Common Ancestor w/ Random  Routing Up
FATTREE : Nearest Common Ancestor w / Random Routing Up
//routers are numbered with smallest at the top level //which level //coverage of this tree //span of the tree from this router //NCA reached going down //down ports are numbered first //ejection //find the down port for the destination //up ports are numbered last //came from a up channel