From 69f2911e04ffb1b19eef1fafb8c040af271f656e Mon Sep 17 00:00:00 2001 From: Tor Aamodt Date: Thu, 15 Jul 2010 18:09:46 -0800 Subject: creating branch for adding support for CUDA 3.x and Fermi [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6829] --- src/intersim/buffer_state.cpp | 145 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src/intersim/buffer_state.cpp (limited to 'src/intersim/buffer_state.cpp') diff --git a/src/intersim/buffer_state.cpp b/src/intersim/buffer_state.cpp new file mode 100644 index 0000000..72a327d --- /dev/null +++ b/src/intersim/buffer_state.cpp @@ -0,0 +1,145 @@ +#include "booksim.hpp" +#include +#include +#include + +#include "buffer_state.hpp" +#include "random_utils.hpp" + +void BufferState::init( const Configuration& config ) +{ + _Init( config ); +} + +BufferState::BufferState( const Configuration& config, + Module *parent, const string& name ) : +Module( parent, name ) +{ + _Init( config ); +} + +void BufferState::_Init( const Configuration& config ) +{ + _buf_size = config.GetInt( "vc_buf_size" ); + _vcs = config.GetInt( "num_vcs" ); + + _wait_for_tail_credit = config.GetInt( "wait_for_tail_credit" ); + + _in_use = new bool [_vcs]; + _tail_sent = new bool [_vcs]; + _cur_occupied = new int [_vcs]; + + _last_avail = 0; + + for ( int v = 0; v < _vcs; ++v ) { + _in_use[v] = false; + _tail_sent[v] = false; + _cur_occupied[v] = 0; + } +} + +BufferState::~BufferState( ) +{ + delete [] _in_use; + delete [] _tail_sent; + delete [] _cur_occupied; +} + +void BufferState::ProcessCredit( Credit *c ) +{ + assert( c ); + + for ( int v = 0; v < c->vc_cnt; ++v ) { + assert( ( c->vc[v] >= 0 ) && ( c->vc[v] < _vcs ) ); + + if ( ( _wait_for_tail_credit ) && + ( !_in_use[c->vc[v]] ) ) { + Error( "Received credit for idle buffer" ); + } + + if ( _cur_occupied[c->vc[v]] > 0 ) { + --_cur_occupied[c->vc[v]]; + + if ( ( _cur_occupied[c->vc[v]] == 0 ) && + ( _tail_sent[c->vc[v]] ) ) { + _in_use[c->vc[v]] = false; + } + } else { + cout << "VC = " << c->vc[v] << endl; + Error( "Buffer occupancy fell below zero" ); + } + } +} + +void BufferState::SendingFlit( Flit *f ) +{ + assert( f && ( f->vc >= 0 ) && ( f->vc < _vcs ) ); + + if ( _cur_occupied[f->vc] < _buf_size ) { + ++_cur_occupied[f->vc]; + + if ( f->tail ) { + _tail_sent[f->vc] = true; + + if ( !_wait_for_tail_credit ) { + _in_use[f->vc] = false; + } + } + } else { + Error( "Flit sent to full buffer" ); + } +} + +void BufferState::TakeBuffer( int vc ) +{ + assert( ( vc >= 0 ) && ( vc < _vcs ) ); + + if ( _in_use[vc] ) { + Error( "Buffer taken while in use" ); + } + + _in_use[vc] = true; + _tail_sent[vc] = false; +} + +bool BufferState::IsFullFor( int vc ) const +{ + assert( ( vc >= 0 ) && ( vc < _vcs ) ); + return( _cur_occupied[vc] == _buf_size ) ? true : false; +} + +bool BufferState::IsAvailableFor( int vc ) const +{ + assert( ( vc >= 0 ) && ( vc < _vcs ) ); + return !_in_use[vc]; +} + +int BufferState::FindAvailable( ) +{ + int available_vc = -1; + int vc; + + _last_avail = RandomInt( _vcs - 1 ); + + for ( int v = 0; v < _vcs; ++v ) { + vc = ( v + _last_avail + 1 ) % _vcs; // Round-robin + + if ( IsAvailableFor( vc ) ) { + available_vc = vc; + _last_avail = vc; + break; + } + } + + return available_vc; +} + +void BufferState::Display( ) const +{ + cout << _fullname << " :" << endl; + for ( int v = 0; v < _vcs; ++v ) { + cout << " buffer class " << v << endl; + cout << " in_use = " << _in_use[v] << " tail_sent = " << _tail_sent[v] << endl; + cout << " occupied = " << _cur_occupied[v] << endl; + } +} -- cgit v1.3