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/arbiter.cpp | 143 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/intersim/arbiter.cpp (limited to 'src/intersim/arbiter.cpp') diff --git a/src/intersim/arbiter.cpp b/src/intersim/arbiter.cpp new file mode 100644 index 0000000..7225b9b --- /dev/null +++ b/src/intersim/arbiter.cpp @@ -0,0 +1,143 @@ +#include "booksim.hpp" +#include + +#include "arbiter.hpp" + + +Arbiter::Arbiter( const Configuration &, + Module *parent, const string& name, + int inputs ) +: Module( parent, name ), _inputs( inputs ) +{ +} + +Arbiter::~Arbiter( ) +{ +} + +void Arbiter::Clear( ) +{ + _requests.clear( ); +} + +void Arbiter::AddRequest( int in, int label, int pri ) +{ + sRequest r; + list::iterator insert_point; + + r.in = in; r.label = label; r.pri = pri; + + insert_point = _requests.begin( ); + while ( ( insert_point != _requests.end( ) ) && + ( insert_point->in < in ) ) { + insert_point++; + } + + bool del = false; + bool add = true; + + // For consistant behavior, delete the existing request + // if it is for the same input and has a higher + // priority + + if ( ( insert_point != _requests.end( ) ) && + ( insert_point->in == in ) ) { + if ( insert_point->pri < pri ) { + del = true; + } else { + add = false; + } + } + + if ( add ) { + _requests.insert( insert_point, r ); + } + + if ( del ) { + _requests.erase( insert_point ); + } +} + +void Arbiter::RemoveRequest( int in, int label ) +{ + list::iterator erase_point; + + erase_point = _requests.begin( ); + while ( ( erase_point != _requests.end( ) ) && + ( erase_point->in < in ) ) { + erase_point++; + } + + assert( erase_point != _requests.end( ) ); + _requests.erase( erase_point ); +} + +int Arbiter::Match( ) const +{ + return _match; +} + +//================================================== +// PriorityArbiter +//================================================== + +PriorityArbiter::PriorityArbiter( const Configuration &config, + Module *parent, const string& name, + int inputs ) +: Arbiter( config, parent, name, inputs ) +{ + _rr_ptr = 0; +} + +PriorityArbiter::~PriorityArbiter( ) +{ +} + +void PriorityArbiter::Arbitrate( ) +{ + list::iterator p; + + int max_index, max_pri; + bool wrapped; + + if ( _requests.begin( ) != _requests.end( ) ) { + // A round-robin arbiter between input requests + p = _requests.begin( ); + while ( ( p != _requests.end( ) ) && + ( p->in < _rr_ptr ) ) { + p++; + } + + max_index = -1; + max_pri = 0; + + wrapped = false; + while ( (!wrapped) || ( p->in < _rr_ptr ) ) { + if ( p == _requests.end( ) ) { + if ( wrapped ) { + break; + } + // p is valid here because empty lists + // are skipped (above) + p = _requests.begin( ); + wrapped = true; + } + + // check if request is the highest priority so far + if ( ( p->pri > max_pri ) || ( max_index == -1 ) ) { + max_pri = p->pri; + max_index = p->in; + } + + p++; + } + + _match = max_index; // -1 for no match + if ( _match != -1 ) { + _rr_ptr = ( _match + 1 ) % _inputs; + } + + } else { + _match = -1; + } +} -- cgit v1.3