00001
00002
00003
00004
00005
00006
00007
00008 #ifndef ROUTER_H_
00009 #define ROUTER_H_
00010
00011 #include "systemc.h"
00012 #include <queue>
00013 #include <map>
00014 #include <set>
00015 #include "Technology.h"
00016
00017 using namespace std ;
00018
00019 template< int Nin , int Nout , int FlitWidth >
00020 class Router : public sc_module
00021 {
00022
00023 public:
00024
00025 sc_in< bool > Clock ;
00026
00027
00028 sc_in < sc_bv< FlitWidth > > DataIn[Nin] ;
00029 sc_in < bool > ValidIn[Nin] ;
00030 sc_out< bool > AckOut[Nin] ;
00031 sc_out< bool > FullOut[Nin] ;
00032
00033
00034 sc_out< sc_bv< FlitWidth > > DataOut[Nout] ;
00035 sc_out< bool > ValidOut[Nout] ;
00036 sc_in< bool > AckIn[Nout] ;
00037 sc_in< bool > FullIn[Nout] ;
00038
00039 SC_HAS_PROCESS( Router ) ;
00040
00041 void Fsm( ) ;
00042 void InputFsm( ) ;
00043 void SwitchFsm( ) ;
00044 void OutputFsm( ) ;
00045 void PrintState( ) ;
00046
00047 Router( sc_module_name n ,
00048 int T ,
00049 int Size ,
00050 map< pair<int,int> , int > RoutingTable ,
00051 vector< double > ChannelWeights ,
00052 TechnologyNode Tech) : sc_module( n ) {
00053
00054 mTech = Tech ;
00055 mRoutingTable = RoutingTable ;
00056 mSize = Size ;
00057 mT = T ;
00058 mChannelWeights = ChannelWeights ;
00059
00060 mLastGranted = 0 ;
00061
00062 for( int i = 0 ; i < Nin ; i++ ) {
00063 mRstate[i] = RIDLE ;
00064 mState[i] = IDLE ;
00065 }
00066
00067 for( int i = 0 ; i < Nout ; i++ ) {
00068 mWstate[i] = WIDLE ;
00069 }
00070
00071 mInputGranted.resize( Nin , false ) ;
00072 mOutput.resize( Nin , -1 ) ;
00073 mOutputBusy.resize( Nout , false ) ;
00074 mFlitCount.resize( Nin , 0 ) ;
00075
00076 mFIFO.resize( Nin ) ;
00077 mCurrentFlow.resize( Nin ) ;
00078 mSentFlits.resize( Nin , 0 ) ;
00079 mTotalFlitSent = 1 ;
00080 mOutputBuffer.resize( Nout ) ;
00081 mInput.resize( Nout , -1 ) ;
00082
00083
00084 SC_THREAD( Fsm ) ;
00085 sensitive_pos << Clock ;
00086
00087 mDynamicEnergy = 0 ;
00088
00089 cout << "Router " << name( ) << " initialized " << endl ;
00090
00091 }
00092
00093 double GetDynamicPower( ) {
00094 return ( mDynamicEnergy/ ( sc_simulation_time( ) * 10e-9) ) ;
00095 }
00096
00097 TechnologyNode mTech ;
00098 map< pair<int,int> , int > mRoutingTable ;
00099 vector< double > mChannelWeights ;
00100 int mSize ;
00101 int mT ;
00102
00103 vector< queue< sc_bv< FlitWidth > > > mFIFO ;
00104
00105 vector< queue< sc_bv< FlitWidth > > > mOutputBuffer ;
00106
00107
00108
00109 enum{ RIDLE , RX } mRstate[Nin] ;
00110
00111 enum{ WIDLE , TX } mWstate[Nout] ;
00112
00113 vector< bool > mInputGranted ;
00114
00115 vector< int > mOutput ;
00116
00117 vector< int > mInput ;
00118
00119 vector< bool > mOutputBusy ;
00120
00121 vector< int > mFlitCount ;
00122
00123 vector<int> mSentFlits ;
00124
00125 vector< pair<int,int> > mCurrentFlow ;
00126
00127 int mTotalFlitSent ;
00128
00129
00130 enum{ IDLE , FLIT} mState[Nin] ;
00131
00132 int mLastGranted ;
00133
00134 double mDynamicEnergy ;
00135
00136
00137 } ;
00138
00139
00140 template< int Nin , int Nout , int FlitWidth >
00141 void Router< Nin , Nout , FlitWidth >::PrintState( ) {
00142
00143 cout << name( ) << endl ;
00144 cout << "Input queues " << endl ;
00145 for( int Input = 0 ; Input < Nin ; Input++ ) {
00146 cout << "Input " << Input << " size = " << mFIFO[Input].size( ) ;
00147 if ( !mState[Input] == FLIT ) {
00148 cout << " Header " ;
00149 sc_bv< FlitWidth > Header ;
00150 Header = mFIFO[Input].front( ) ;
00151 pair<int,int> Sd ;
00152 Sd.first = ( Header.range( 7 , 0 )).to_int( ) ;
00153 Sd.second = (Header.range( 15 , 8 )).to_int( ) ;
00154
00155 cout << "Flow (" << Sd.first << "," << Sd.second << ") to output " << mRoutingTable[Sd] ;
00156 }
00157 else {
00158 cout << " Flit" << " Flow (" << mCurrentFlow[Input].first << "," << mCurrentFlow[Input].second ;
00159 }
00160 if ( mInputGranted[Input] ) {
00161 cout << " Assigned to " << mOutput[Input] ;
00162 cout << " need to send " << mFlitCount[Input] << endl ;
00163 } else {
00164 cout << " Not assigned " << endl ;
00165 }
00166 }
00167
00168 cout << "Output queues " << endl ;
00169 for( int Output = 0 ; Output < Nout ; Output++ ) {
00170 cout << "Output " << Output << " size = " << mOutputBuffer[Output].size( ) << " " ;
00171 if( mOutputBusy[Output] )
00172 cout << "Busy " << endl ;
00173 else
00174 cout << "Available" << endl ;
00175 }
00176
00177 }
00178
00179
00180
00181 template< int Nin , int Nout , int FlitWidth >
00182 void Router< Nin , Nout , FlitWidth >::Fsm( ) {
00183
00184 cout << "Router " << name( ) << " running " << endl ;
00185
00186 while( true ) {
00187
00188
00189 for( int i = 0 ; i < Nin ; i++ ) {
00190 if ( mFIFO[i].size( ) == mSize ) {
00191 FullOut[i] = true ;
00192 } else {
00193 FullOut[i] = false ;
00194 }
00195 }
00196
00197 wait( ) ;
00198
00199 InputFsm( ) ;
00200 SwitchFsm( ) ;
00201 OutputFsm( ) ;
00202 }
00203
00204 }
00205
00206 template< int Nin , int Nout , int FlitWidth >
00207 void Router< Nin , Nout , FlitWidth >::InputFsm( ) {
00208 for( int Input = 0 ; Input < Nin ; Input++ ) {
00209
00210 switch( mRstate[Input] ) {
00211 case RIDLE :
00212 if ( ValidIn[Input] ) {
00213 mFIFO[Input].push( DataIn[Input] ) ;
00214 mRstate[Input] = RX ;
00215 AckOut[Input] = true ;
00216 }
00217 break ;
00218 case RX :
00219 AckOut[Input] = false ;
00220 mRstate[Input] = RIDLE ;
00221 break ;
00222 }
00223 }
00224 }
00225
00226
00227 template< int Nin , int Nout , int FlitWidth >
00228 void Router< Nin , Nout , FlitWidth >::OutputFsm( ) {
00229
00230 for( int Output = 0 ; Output < Nout ; Output++ ) {
00231 if ( ! mOutputBuffer[Output].empty( ) ) {
00232 switch( mWstate[Output] ) {
00233 case WIDLE:
00234 if ( ! FullIn[Output] ) {
00235 DataOut[Output] = mOutputBuffer[Output].front( ) ;
00236 ValidOut[Output] = true ;
00237 mWstate[Output] = TX ;
00238 }
00239 break;
00240 case TX:
00241 if ( AckIn[Output] ) {
00242 ValidOut[Output] =false ;
00243 mOutputBuffer[Output].pop( ) ;
00244 mFlitCount[mInput[Output]]-- ;
00245 mSentFlits[mInput[Output]]++ ;
00246 mTotalFlitSent++ ;
00247
00248
00249 mDynamicEnergy += mTech.Erouter[Nin][Nout] ;
00250
00251 if ( mFlitCount[mInput[Output]] == 0 ) {
00252 mInputGranted[ mInput[Output] ] = false ;
00253 mOutputBusy[ Output ] = false ;
00254 mState[mInput[Output]] = IDLE ;
00255 }
00256 mWstate[Output] = WIDLE ;
00257 }
00258 break;
00259 }
00260 }
00261 }
00262 }
00263
00264 template< int Nin , int Nout , int FlitWidth >
00265 void Router< Nin , Nout , FlitWidth >::SwitchFsm( ) {
00266
00268
00270
00271
00272 vector< double > Slack( Nin , 0 ) ;
00273 for( int i = 0 ; i < Nin ; i++ ) {
00274 Slack[i] = ( (double)mSentFlits[i])/((double)mTotalFlitSent) - mChannelWeights[i] ;
00275
00276 }
00277
00278
00279 vector< set< int > > CompetingInputs( Nout ) ;
00280 sc_bv< FlitWidth > Header ;
00281 pair<int,int> Sd ;
00282 for( int i = 0 ; i < Nin ; i++ ) {
00283
00284
00285
00286
00287 if ( ( ! mInputGranted[i] ) && ( ! mFIFO[i].empty( ) ) ) {
00288 Header = mFIFO[i].front( ) ;
00289 Sd.first = ( Header.range( 7 , 0 )).to_int( ) ;
00290 Sd.second = (Header.range( 15 , 8 )).to_int( ) ;
00291 mCurrentFlow[i] = Sd ;
00292
00293 CompetingInputs[mRoutingTable[Sd]].insert( i ) ;
00294 }
00295
00296 }
00297
00298
00299
00300 for( int i = 0 ; i < Nout ; i++ ) {
00301
00302 if ( ! mOutputBusy[i] && ! CompetingInputs[i].empty( ) ) {
00303
00304
00305 set<int>::iterator It ;
00306 double MinSlack = DBL_MAX ; int MinIn = 0 ;
00307 for( It = CompetingInputs[i].begin( ) ; It != CompetingInputs[i].end( ) ; It++ ) {
00308 if ( Slack[*It] < MinSlack ) {
00309 MinSlack = Slack[*It] ;
00310 MinIn = *It ;
00311 }
00312 }
00313
00314
00315 mInputGranted[ MinIn ] = true ;
00316 mOutput[ MinIn ] = i ;
00317 mInput[ i ] = MinIn ;
00318 mOutputBusy[ i ] = true ;
00319 }
00320 }
00321
00323
00325 int Input ;
00326 for( Input = 0 ; Input < Nin ; Input++ ) {
00327
00328 if ( mInputGranted[Input] ) {
00329
00330 switch( mState[Input] ) {
00331 case IDLE :
00332 if ( mOutputBuffer[ mOutput[ Input ] ].size( ) == 0 && ! mFIFO[Input].empty( ) ) {
00333
00334 Header = mFIFO[Input].front( ) ;
00335 mFlitCount[Input] = ( Header.range( 23 , 16 )).to_int( ) ;
00336
00337
00338 mOutputBuffer[ mOutput[ Input ] ].push( Header ) ;
00339 mFIFO[Input].pop( ) ;
00340 mState[Input] = FLIT ;
00341 }
00342 break ;
00343 case FLIT :
00344 if ( mOutputBuffer[ mOutput[ Input ] ].size( ) == 0 && ! mFIFO[Input].empty( ) ) {
00345
00346
00347 mOutputBuffer[ mOutput[ Input ] ].push( mFIFO[Input].front( ) ) ;
00348
00349 mFIFO[Input].pop( ) ;
00350
00351 }
00352 break ;
00353 }
00354 }
00355 }
00356 }
00357
00358 #endif