Ejemplo n.º 1
0
void TrafficManager::_ClassInject()
{
	Flit *f, *nf;
	Credit *cred;
	int psize;

	// Receive credits and inject new traffic
	for (int input = 0; input < _net->NumSources(); ++input)
	{

		cred = _net->ReadCredit(input);
		if (cred)
		{
			_buf_states[input]->ProcessCredit(cred);
			delete cred;
		}

		bool write_flit = false;
		int highest_class = 0;
		bool generated;

		for (int c = 0; c < _classes; ++c)
		{
			// Potentially generate packets for any (input,class)
			// that is currently empty
			if (_partial_packets[input][c].empty())
			{
				generated = false;

				if (!_empty_network)
				{

					// Lagging injection process
					while (!generated && (_qtime[input][c] <= _time))
					{
						psize = _IssuePacket(input, c);

						if (psize)
						{
							_GeneratePacket(input, psize, c,
									_include_queuing ? _qtime[input][c] : _time);
							generated = true;
						}
						++_qtime[input][c];
					}

					if ((_sim_state == draining) && (_qtime[input][c]
							> _drain_time))
					{
						_qdrained[input][c] = true;
					}
				}

				if (generated)
				{
					highest_class = c;
				}
			}
			else
			{
				highest_class = c;
			}
		}

		// Now, check partially issued packet to
		// see if it can be issued
		if (!_partial_packets[input][highest_class].empty())
		{
			f = _partial_packets[input][highest_class].front();

			if (f->head && (f->vc == -1))
			{ // Find first available VC
				f->vc = _buf_states[input]->FindAvailable();

				if (f->vc != -1)
				{
					_buf_states[input]->TakeBuffer(f->vc);
				}
			}

			if (f->vc != -1)
			{
				if (!_buf_states[input]->IsFullFor(f->vc))
				{

					_partial_packets[input][highest_class].pop_front();
					_buf_states[input]->SendingFlit(f);
					write_flit = true;

					// Pass VC "back"
					if (!_partial_packets[input][highest_class].empty()
							&& !f->tail)
					{
						nf = _partial_packets[input][highest_class].front();
						nf->vc = f->vc;
					}
				}
				if (f->watch)
				{
					cout << "Flit " << f->id
							<< " written into injection port at time " << _time
							<< endl;
				}
			}
			else
			{
				if (f->watch)
				{
					cout << "Flit " << f->id
							<< " stalled at injection waiting for available VC at time "
							<< _time << endl;
				}
			}
		}

		_net->WriteFlit(write_flit ? f : 0, input);
	}
}
Ejemplo n.º 2
0
void TrafficManager::_VOQInject()
{
	Flit *f;
	Credit *cred;

	int vc;
	int dest;
	int psize;

	for (int input = 0; input < _net->NumSources(); ++input)
	{

		// Receive credits
		cred = _net->ReadCredit(input);
		if (cred)
		{
			_buf_states[input]->ProcessCredit(cred);

			for (int i = 0; i < cred->vc_cnt; i++)
			{
				vc = cred->vc[i];

				// If this credit enables a VC that has packets waiting,
				// set the VC to active (append it to the active list)

				if (!_voq[input][vc].empty() && !_active_vc[input][vc])
				{
					f = _voq[input][vc].front();

					if ((f->head && _buf_states[input]->IsAvailableFor(vc))
							|| (!f->head && !_buf_states[input]->IsFullFor(vc)))
					{
						_active_list[input].push_back(vc);
						_active_vc[input][vc] = true;
					}
				}
			}

			delete cred;
		}

		if (!_empty_network)
		{
			// Inject packets
			psize = _IssuePacket(input, 0);
		}
		else
		{
			psize = 0;
		}

		if (psize)
		{
			_GeneratePacket(input, psize, 0, _time);
			dest = -1;

			bool wasempty = false;

			// Move a generated packet to the appropriate VOQ
			while (!_partial_packets[input][0].empty())
			{
				f = _partial_packets[input][0].front();
				_partial_packets[input][0].pop_front();

				if (f->head)
				{
					dest = f->dest;
					wasempty = _voq[input][dest].empty();
				}

				if (dest == -1)
				{
					Error("Didn't see head flit in VOQ injection");
				}

				f->dest = dest;
				f->vc = dest;

				_voq[input][dest].push_back(f);
			}

			// If this packet enables a VC,
			// set the VC to active (append it to the active list)
			if (wasempty && (!_active_vc[input][dest])
					&& (_buf_states[input]->IsAvailableFor(dest)))
			{
				_active_list[input].push_back(dest);
				_active_vc[input][dest] = true;
			}
		}

		// Write packets to the network
		if (!_active_list[input].empty())
		{

			dest = _active_list[input].front();
			_active_list[input].pop_front();

			if (_voq[input][dest].empty())
			{
				Error("VOQ marked as active, but empty");
			}

			f = _voq[input][dest].front();
			_voq[input][dest].pop_front();

			if (f->head)
			{
				_buf_states[input]->TakeBuffer(dest);
			}

			_buf_states[input]->SendingFlit(f);
			_net->WriteFlit(f, input);

			// Inactivate VC if it can't accept any more flits or
			// no more flits are available to be sent
			if ((f->tail && _buf_states[input]->IsAvailableFor(dest))
					|| (!f->tail && !_buf_states[input]->IsFullFor(dest)))
			{
				_active_list[input].push_back(dest);
			}
			else
			{
				_active_vc[input][dest] = false;
			}

		}
		else
		{
			_net->WriteFlit(0, input);
		}
	}
}
Ejemplo n.º 3
0
void PTrafficManager::_NormalInjectP(int tid){

  short ** class_array;
  class_array = new short* [duplicate_networks];
  for (int i=0; i < duplicate_networks; ++i) {
    class_array[i] = new short [_classes];
    memset(class_array[i], 0, sizeof(short)*_classes);
  }
  Flit   *f, *nf;
  Credit *cred;
  int    psize;
  // Receive credits and inject new traffic
  for ( int input_pos = 0; input_pos < node_count[tid]; ++input_pos ) {
    int input = node_list[tid][input_pos];
    for (int i = 0; i < duplicate_networks; ++i) {
      cred = _net[i]->ReadCredit( input );
      if ( cred ) {
        _buf_states[input][i]->ProcessCredit( cred );
        delete cred;
      }
    }
    
    bool write_flit    = false;
    int  highest_class = 0;
    bool generated;

    for ( int c = 0; c < _classes; ++c ) {
      // Potentially generate packets for any (input,class)
      // that is currently empty
      if ( (duplicate_networks > 1) || _partial_packets[input][c][0].empty() ) {
      // For multiple networks, always flip coin because now you have multiple send buffers so you can't choose one only to check.
	generated = false;
	  
	if ( !_empty_network ) {
	  while( !generated && ( _qtime[input][c] <= thread_time[tid] ) ) {
	    psize = _IssuePacket( input, c );

	    if ( psize ) { //generate a packet
	      _GeneratePacketP( input, psize, c, 
			       _include_queuing==1 ? 
			       _qtime[input][c] : thread_time[tid], tid );
	      generated = true;
	    }
	    //this is not a request packet
	    //don't advance time
	    if(_use_read_write && psize>0){
	      
	      assert(false);
	    } else {
	      ++_qtime[input][c];
	    }
	  }
	  
	  if ( ( _sim_state == draining ) && 
	       ( _qtime[input][c] > _drain_time ) ) {
	    _qdrained[input][c] = true;
	  }
	}
	if ( generated ) {
	  //highest_class = c;
	  class_array[sub_network][c]++; // One more packet for this class.
	}
      } //else {
	//highest_class = c;
      //} This is not necessary with class_array because it stays.
    }

    // Now, check partially issued packets to
    // see if they can be issued
    for (int i = 0; i < duplicate_networks; ++i) {
      write_flit = false;
      highest_class = 0;
//       // Now just find which is the highest_class.
//       for (short a = _classes - 1; a >= 0; --a) {
// 	if (class_array[i][a]) {
// 	  highest_class = a;
// 	  break;
// 	}
//       }
      if ( !_partial_packets[input][highest_class][i].empty( ) ) {
        f = _partial_packets[input][highest_class][i].front( );
        if ( f->head && f->vc == -1) { // Find first available VC

	  if ( _voqing ) {
	    if ( _buf_states[input][i]->IsAvailableFor( f->dest ) ) {
	      f->vc = f->dest;
  	    }
	  } else {
	    f->vc = _buf_states[input][i]->FindAvailable( );
	  }
	  
	  if ( f->vc != -1 ) {
	    _buf_states[input][i]->TakeBuffer( f->vc );
	  }
        }

        if ( ( f->vc != -1 ) &&
	     ( !_buf_states[input][i]->IsFullFor( f->vc ) ) ) {

	  _partial_packets[input][highest_class][i].pop_front( );
	  _buf_states[input][i]->SendingFlit( f );
	  write_flit = true;

	  // Pass VC "back"
	  if ( !_partial_packets[input][highest_class][i].empty( ) && !f->tail ) {
	    nf = _partial_packets[input][highest_class][i].front( );
	    nf->vc = f->vc;
	  }
        }
      }
      _net[i]->WriteFlit( write_flit ? f : 0, input );
      if (write_flit && f->tail) // If a tail flit, reduce the number of packets of this class.
	class_array[i][highest_class]--;
    }
  }
  for (int i=0; i < duplicate_networks; ++i) {
    delete [] class_array[i];
  }
  delete [] class_array;
}