⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trouter.cpp

📁 noxim系统的软件实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************  TRouter.cpp -- Router implementation*****************************************************************************//* Copyright 2005-2007      Fabrizio Fazzino <fabrizio.fazzino@diit.unict.it>    Maurizio Palesi <mpalesi@diit.unict.it>    Davide Patti <dpatti@diit.unict.it> *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "TRouter.h"//---------------------------------------------------------------------------//---------------------------------------------------------------------------void TRouter::rxProcess(){  if(reset.read())    {      // Clear outputs and indexes of receiving protocol      for(int i=0; i<DIRECTIONS+1; i++)	{	  ack_rx[i].write(0);	  current_level_rx[i] = 0;	}      reservation_table.clear();      routed_flits = 0;      local_drained = 0;    }  else    {      // For each channel decide if a new flit can be accepted      //      // This process simply sees a flow of incoming flits. All arbitration      // and wormhole related issues are addressed in the txProcess()       for(int i=0; i<DIRECTIONS+1; i++)	{	  // To accept a new flit, the following conditions must match:	  //	  // 1) there is an incoming request	  // 2) there is a free slot in the input buffer of direction i	  if ( (req_rx[i].read()==1-current_level_rx[i]) && !buffer[i].IsFull() )	    {	      TFlit received_flit = flit_rx[i].read();	      if(TGlobalParams::verbose_mode > VERBOSE_OFF)		{		  cout << sc_time_stamp().to_double()/1000 << ": Router[" << local_id <<"], Input[" << i << "], Received flit: " << received_flit << endl;		}	      // Store the incoming flit in the circular buffer	      buffer[i].Push(received_flit);            	      // Negate the old value for Alternating Bit Protocol (ABP)	      current_level_rx[i] = 1-current_level_rx[i];	      // Incoming flit	      stats.power.Incoming();	    }	  ack_rx[i].write(current_level_rx[i]);	}    }  stats.power.Standby();}//---------------------------------------------------------------------------void TRouter::txProcess(){  if (reset.read())    {      // Clear outputs and indexes of transmitting protocol      for(int i=0; i<DIRECTIONS+1; i++)	{	  req_tx[i].write(0);	  current_level_tx[i] = 0;	}    }  else    {      // 1st phase: Reservation      for(int j=0; j<DIRECTIONS+1; j++)	{	  int i = (start_from_port + j) % (DIRECTIONS + 1);	  if ( !buffer[i].IsEmpty() )	    {	      TFlit flit = buffer[i].Front();	      if (flit.flit_type==FLIT_TYPE_HEAD) 		{		  // prepare data for routing		  TRouteData route_data;		  route_data.current_id = local_id;		  route_data.src_id = flit.src_id;		  route_data.dst_id = flit.dst_id;		  route_data.dir_in = i;		  int o = route(route_data);		  if (reservation_table.isAvailable(o))		    {		      reservation_table.reserve(i, o);		      if(TGlobalParams::verbose_mode > VERBOSE_OFF)			{			  cout << sc_time_stamp().to_double()/1000 			       << ": Router[" << local_id 			       << "], Input[" << i << "] (" << buffer[i].Size() << " flits)" 			       << ", reserved Output[" << o << "], flit: " << flit << endl;			}		      		    }		}	    }	}      start_from_port++;      // 2nd phase: Forwarding      for(int i=0; i<DIRECTIONS+1; i++)	{	  if ( !buffer[i].IsEmpty() )	    {	      TFlit flit = buffer[i].Front();	      int o = reservation_table.getOutputPort(i);	      if (o != NOT_RESERVED)		{		  if ( current_level_tx[o] == ack_tx[o].read() )		    {                      if(TGlobalParams::verbose_mode > VERBOSE_OFF)			{			  cout << sc_time_stamp().to_double()/1000 			       << ": Router[" << local_id 			       << "], Input[" << i << "] forward to Output[" << o << "], flit: " << flit << endl;			}		      flit_tx[o].write(flit);		      current_level_tx[o] = 1 - current_level_tx[o];		      req_tx[o].write(current_level_tx[o]);		      buffer[i].Pop();		      stats.power.Forward();		      if (flit.flit_type == FLIT_TYPE_TAIL) 			reservation_table.release(o);					      // Update stats		      if (o == DIRECTION_LOCAL)			{			  stats.receivedFlit(sc_time_stamp().to_double()/1000, flit);			  if (TGlobalParams::max_volume_to_be_drained)			    {			      if (drained_volume >= TGlobalParams::max_volume_to_be_drained)				sc_stop();			      else			      {				drained_volume++;				local_drained++;			      }			    }			}		      else if (i != DIRECTION_LOCAL)			{			  // Increment routed flits counter			  routed_flits++;			}		    }		}	    }	}    } // else  stats.power.Standby();}//---------------------------------------------------------------------------TNoP_data TRouter::getCurrentNoPData() const {    TNoP_data NoP_data;    for (int j=0; j<DIRECTIONS; j++)    {	NoP_data.channel_status_neighbor[j].free_slots = free_slots_neighbor[j].read();	NoP_data.channel_status_neighbor[j].available = (reservation_table.isAvailable(j));    }    NoP_data.sender_id = local_id;    return NoP_data;}//---------------------------------------------------------------------------void TRouter::bufferMonitor(){  if (reset.read())  {    for (int i=0; i<DIRECTIONS+1; i++) free_slots[i].write(buffer[i].GetMaxBufferSize());  }  else  {    if (TGlobalParams::selection_strategy==SEL_BUFFER_LEVEL ||	TGlobalParams::selection_strategy==SEL_NOP)    {      // update current input buffers level to neighbors      for (int i=0; i<DIRECTIONS+1; i++)	free_slots[i].write(buffer[i].getCurrentFreeSlots());      // NoP selection: send neighbor info to each direction 'i'      TNoP_data current_NoP_data = getCurrentNoPData();      for (int i=0; i<DIRECTIONS; i++)	NoP_data_out[i].write(current_NoP_data);      if (TGlobalParams::verbose_mode == -57) 	  NoP_report();    }  }}//---------------------------------------------------------------------------vector<int> TRouter::routingFunction(const TRouteData& route_data) {  TCoord position  = id2Coord(route_data.current_id);  TCoord src_coord = id2Coord(route_data.src_id);  TCoord dst_coord = id2Coord(route_data.dst_id);  int dir_in = route_data.dir_in;  switch (TGlobalParams::routing_algorithm)    {    case ROUTING_XY:      return routingXY(position, dst_coord);    case ROUTING_WEST_FIRST:      return routingWestFirst(position, dst_coord);    case ROUTING_NORTH_LAST:      return routingNorthLast(position, dst_coord);    case ROUTING_NEGATIVE_FIRST:      return routingNegativeFirst(position, dst_coord);    case ROUTING_ODD_EVEN:      return routingOddEven(position, src_coord, dst_coord);    case ROUTING_DYAD:      return routingDyAD(position, src_coord, dst_coord);    case ROUTING_FULLY_ADAPTIVE:      return routingFullyAdaptive(position, dst_coord);    case ROUTING_TABLE_BASED:      return routingTableBased(dir_in, position, dst_coord);    default:      assert(false);    }  // something weird happened, you shouldn't be here  return (vector<int>)(0);}//---------------------------------------------------------------------------int TRouter::route(const TRouteData& route_data){  stats.power.Routing();  if (route_data.dst_id == local_id)    return DIRECTION_LOCAL;  vector<int> candidate_channels = routingFunction(route_data);  return selectionFunction(candidate_channels,route_data);}//---------------------------------------------------------------------------void TRouter::NoP_report() const{    TNoP_data NoP_tmp;      cout << sc_time_stamp().to_double()/1000 << ": Router[" << local_id << "] NoP report: " << endl;      for (int i=0;i<DIRECTIONS; i++)       {	  NoP_tmp = NoP_data_in[i].read();	  if (NoP_tmp.sender_id!=NOT_VALID)	    cout << NoP_tmp;      }}//---------------------------------------------------------------------------int TRouter::NoPScore(const TNoP_data& nop_data, const vector<int>& nop_channels) const{    int score = 0;    if (TGlobalParams::verbose_mode==-58)    {	cout << nop_data;	cout << "      On-Path channels: " << endl;    }    for (unsigned int i=0;i<nop_channels.size();i++)    {	int available;	if (nop_data.channel_status_neighbor[nop_channels[i]].available)	    available = 1; 	else available = 0;	int free_slots = nop_data.channel_status_neighbor[nop_channels[i]].free_slots;	if (TGlobalParams::verbose_mode==-58)	{	    cout << "       channel " << nop_channels[i] << " -> score: ";	    cout << " + " << available << " * (" << free_slots << ")" << endl;	}	score += available*free_slots;    }    return score;}//---------------------------------------------------------------------------int TRouter::selectionNoP(const vector<int>& directions, const TRouteData& route_data){  vector<int> neighbors_on_path;  vector<int> score;  int direction_selected = NOT_VALID;  int current_id = route_data.current_id;  if (TGlobalParams::verbose_mode==-58)  {    cout << endl;    cout << sc_time_stamp().to_double()/1000 << ": Router[" << local_id << "] NoP SELECTION ----------------" << endl;    cout << "      Packet: " << route_data.src_id << " --> " << route_data.dst_id << endl;  }  for (uint i=0; i<directions.size(); i++)  {    // get id of adjacent candidate    int candidate_id = getNeighborId(current_id,directions[i]);  // apply routing function to the adjacent candidate node    TRouteData tmp_route_data;    tmp_route_data.current_id = candidate_id;    tmp_route_data.src_id = route_data.src_id;    tmp_route_data.dst_id = route_data.dst_id;    tmp_route_data.dir_in = reflexDirection(directions[i]);    if (TGlobalParams::verbose_mode==-58)    {	cout << "\n    -> Adjacent candidate: " << candidate_id << " (direction " << directions[i] << ")" << endl;    }    vector<int> next_candidate_channels = routingFunction(tmp_route_data);    // select useful data from Neighbor-on-Path input     TNoP_data nop_tmp = NoP_data_in[directions[i]].read();    // store the score of node in the direction[i]    score.push_back(NoPScore(nop_tmp,next_candidate_channels));  }  // check for direction with higher score  int max_direction = directions[0];  int max = score[0];  for (unsigned int i = 0;i<directions.size();i++)  {      if (score[i]>max)      {	  max_direction = directions[i];	  max = score[i];      }  }  // if multiple direction have the same score = max, choose randomly.    vector<int> equivalent_directions;  for (unsigned int i = 0;i<directions.size();i++)      if (score[i]==max)	  equivalent_directions.push_back(directions[i]);  direction_selected =  equivalent_directions[rand() % equivalent_directions.size()];   if (TGlobalParams::verbose_mode==-58)  {      if (equivalent_directions.size()>1)      {	  cout << "\n    equivalent directions found! : ";	  for (unsigned int i =0;i<equivalent_directions.size();i++)	      cout  << " " << equivalent_directions[i];      }      cout << "\n CHOICE: node " << getNeighborId(current_id,direction_selected) << " (direction " << direction_selected << ")" << endl;  }  return direction_selected; }//---------------------------------------------------------------------------int TRouter::selectionBufferLevel(const vector<int>& directions){  vector<int>  best_dirs;  int          max_free_slots = 0;  for (unsigned int i=0; i<directions.size(); i++)    {      int free_slots = free_slots_neighbor[directions[i]].read();      bool available = reservation_table.isAvailable(directions[i]);      if (available)	{	  if (free_slots > max_free_slots) 	    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -