00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef ED_RTRIF_H
00025 #define ED_RTRIF_H
00026
00027 #include <sstream>
00028
00029 #include <deque>
00030
00031 #include <sst/core/sst_types.h>
00032 #include <sst/core/event.h>
00033 #include <sst/core/component.h>
00034 #include <sst/core/link.h>
00035 #include <sst/core/log.h>
00036 #include <sst/elements/include/paramUtil.h>
00037 #include "SS_network.h"
00038
00039 #define RTRIF_DBG 1
00040 #ifndef RTRIF_DBG
00041 #define RTRIF_DBG 0
00042 #endif
00043
00044 #define db_RtrIF(fmt,args...) \
00045 m_dbg.write( "%s():%d: "fmt, __FUNCTION__, __LINE__, ##args)
00046
00047 namespace SST {
00048
00049 class RtrIF : public Component {
00050 public:
00051 RtrIF( ComponentId_t id, Params_t& params ) :
00052 Component(id),
00053 rtrCountP(0),
00054 num_vcP(2),
00055 m_dbg( *new Log< RTRIF_DBG >( "RtrIF::", false ) ),
00056 m_dummyDbg( *new Log< RTRIF_DBG >( "Dummy::RtrIF::", false ) ),
00057 m_log( *new Log<>( "INFO RtrIF: ", false ) )
00058 {
00059 int num_tokens = 512;
00060
00061 if ( params.find( "info" ) != params.end() ) {
00062 if ( params[ "info" ].compare( "yes" ) == 0 ) {
00063 m_log.enable();
00064 }
00065 }
00066
00067 if ( params.find( "debug" ) != params.end() ) {
00068 if ( params[ "debug" ].compare( "yes" ) == 0 ) {
00069 m_dbg.enable();
00070 }
00071 }
00072
00073 if ( params.find( "dummyDebug" ) != params.end() ) {
00074 if ( params[ "dummyDebug" ].compare( "yes" ) == 0 ) {
00075 m_dummyDbg.enable();
00076 }
00077 }
00078
00079 if ( params.find( "id" ) == params.end() ) {
00080 _abort(RtrIF,"couldn't find routerID\n" );
00081 }
00082 m_id = str2long( params[ "id" ] );
00083
00084 if ( params.find("clock") != params.end() ) {
00085 frequency = params["clock"];
00086 }
00087
00088 if ( params.find( "num_vc" ) != params.end() ) {
00089 num_vcP = str2long( params["num_vc"] );
00090 }
00091
00092 if ( params.find( "Node2RouterQSize_flits" ) != params.end() ) {
00093 num_tokens = str2long( params["Node2RouterQSize_flits"] );
00094 }
00095
00096 std::ostringstream idStr;
00097 idStr << m_id << ":";
00098 m_dbg.prepend( idStr.str() );
00099 m_dummyDbg.prepend( idStr.str() );
00100 m_log.prepend( idStr.str() );
00101
00102 m_log.write("num_vc=%d num_tokens=%d\n",num_vcP,num_tokens);
00103 m_log.write("nic id=%d frequency=%s\n", m_id, frequency.c_str());
00104
00105 m_rtrLink = configureLink( "rtr", frequency, new Event::Handler<RtrIF>(this,&RtrIF::processEvent) );
00106
00107
00108
00109
00110
00111
00112
00113 registerClock( frequency, new Clock::Handler<RtrIF>(this, &RtrIF::clock), false );
00114
00115 db_RtrIF("Done registering clock\n");
00116
00117 for ( unsigned int i=0; i < num_vcP; i++ ) {
00118 toNicMapP[i] = new ToNic();
00119 toRtrMapP[i] = new ToRtr(num_tokens,toRtrQP);
00120 }
00121 }
00122
00123 bool toNicQ_empty(unsigned int vc)
00124 {
00125 if ( vc >= num_vcP ) _abort(RtrIF,"vc=%d\n",vc);
00126 return toNicMapP[vc]->empty();
00127 }
00128
00129 RtrEvent *toNicQ_front(unsigned int vc)
00130 {
00131 if ( vc >= num_vcP ) _abort(RtrIF,"vc=%d\n",vc);
00132 db_RtrIF("vc=%d\n",vc);
00133 return toNicMapP[vc]->front();
00134 }
00135
00136 void toNicQ_pop(unsigned int vc)
00137 {
00138 if ( vc >= num_vcP ) _abort(RtrIF,"vc=%d\n",vc);
00139 db_RtrIF("vc=%d\n",vc);
00140 returnTokens2Rtr( vc, toNicMapP[vc]->front()->packet.sizeInFlits() );
00141 toNicMapP[vc]->pop_front();
00142 }
00143
00144 bool send2Rtr( RtrEvent *event)
00145 {
00146 networkPacket* pkt = &event->packet;
00147 if ( pkt->vc() >= (int) num_vcP ) _abort(RtrIF,"vc=%d\n",pkt->vc());
00148
00149 bool retval = toRtrMapP[pkt->vc()]->push( event );
00150 if ( retval )
00151 db_RtrIF("vc=%d src=%d dest=%d pkt=%p\n",
00152 pkt->vc(),pkt->srcNum(),pkt->destNum(),pkt);
00153 if ( retval ) {
00154 sendPktToRtr( toRtrQP.front() );
00155 toRtrQP.pop_front();
00156 }
00157 return retval;
00158 }
00159
00160 int Finish() { return 0; }
00161
00162 private:
00163 bool rtrWillTake( int vc, int numFlits )
00164 {
00165 if ( vc >= (int) num_vcP ) _abort(RtrIF,"\n");
00166 db_RtrIF("vc=%d numFlits=%d\n",vc,numFlits);
00167 return toRtrMapP[vc]->willTake( numFlits );
00168 }
00169
00170 void processEvent( Event* e)
00171 {
00172 RtrEvent* event = static_cast<RtrEvent*>(e);
00173
00174
00175 db_RtrIF("type=%ld\n",event->type);
00176
00177 switch ( event->type ) {
00178 case RtrEvent::Credit:
00179 returnTokens2Nic( event->credit.vc, event->credit.num );
00180 delete event;
00181 break;
00182
00183 case RtrEvent::Packet:
00184 send2Nic( event );
00185 break;
00186
00187 default:
00188 _abort(RtrIF,"unknown type %d\n",event->type);
00189 }
00190 }
00191
00192 bool clock( Cycle_t cycle)
00193 {
00194 rtrCountP = (rtrCountP >= 0) ? 0 : rtrCountP + 1;
00195
00196 if ( ! toRtrQP.empty() ) {
00197 sendPktToRtr( toRtrQP.front());
00198 toRtrQP.pop_front();
00199 }
00200 return false;
00201 }
00202
00203 void send2Nic( RtrEvent* event )
00204 {
00205 networkPacket *pkt = &event->packet;
00206
00207 pkt->vc() = RTR_2_NIC_VC(pkt->vc());
00208
00209 if ( pkt->vc() >= (int) num_vcP ) {
00210 _abort(RtrIF,"vc=%d pkt=%p\n",pkt->vc(),pkt);
00211 }
00212
00213 db_RtrIF("vc=%d src=%d dest=%d pkt=%p\n",
00214 pkt->vc(),pkt->srcNum(),pkt->destNum(),pkt);
00215 toNicMapP[pkt->vc()]->push_back( event );
00216 }
00217
00218 void returnTokens2Nic( int vc, uint32_t num )
00219 {
00220 if ( vc >= (int) num_vcP ) _abort(RtrIF,"\n");
00221 db_RtrIF("vc=%d numFlits=%d\n", vc, num );
00222 toRtrMapP[vc]->returnTokens( num );
00223 }
00224
00225 void returnTokens2Rtr( int vc, uint numFlits )
00226 {
00227 RtrEvent* event = new RtrEvent;
00228
00229 db_RtrIF("vc=%d numFlits=%d\n", vc, numFlits );
00230
00231 event->type = RtrEvent::Credit;
00232 event->credit.num = numFlits;
00233 event->credit.vc = vc;
00234 m_rtrLink->Send( event );
00235 }
00236
00237 void sendPktToRtr( RtrEvent* event )
00238 {
00239 networkPacket* pkt = &event->packet;
00240
00241 db_RtrIF("vc=%d src=%d dest=%d pkt=%p\n",
00242 pkt->vc(),pkt->srcNum(),pkt->destNum(),pkt);
00243
00244 event->type = RtrEvent::Packet;
00245 event->packet = *pkt;
00246 int lat = reserveRtrLine(pkt->sizeInFlits());
00247 m_rtrLink->Send( lat, event );
00248 }
00249
00250 int reserveRtrLine (int cyc)
00251 {
00252 db_RtrIF("cyc=%d\n",cyc);
00253 int ret = (rtrCountP <= 0) ? -rtrCountP : 0;
00254 rtrCountP -= cyc;
00255 return ret;
00256 }
00257
00258 typedef std::deque<RtrEvent*> ToNic;
00259
00260 class ToRtr {
00261 public:
00262 ToRtr( int num_tokens, deque<RtrEvent*> &eventQ ) :
00263 tokensP(num_tokens), eventQP(eventQ) {}
00264
00265 bool push( RtrEvent* event) {
00266 networkPacket* pkt = &event->packet;
00267 if ( pkt->sizeInFlits() > (unsigned int) tokensP ) return false;
00268 tokensP -= pkt->sizeInFlits();
00269 eventQP.push_back(event);
00270 return true;
00271 }
00272
00273 int size() {
00274 return eventQP.size();
00275 }
00276
00277 bool willTake( int numFlits ) {
00278 return (numFlits <= tokensP );
00279 }
00280
00281 void returnTokens( int num ) {
00282 tokensP += num;
00283 }
00284
00285 private:
00286 int tokensP;
00287 deque<RtrEvent*> &eventQP;
00288 };
00289
00290 int rtrCountP;
00291 map<int,ToNic*> toNicMapP;
00292 map<int,ToRtr*> toRtrMapP;
00293
00294 uint num_vcP;
00295
00296 deque<RtrEvent*> toRtrQP;
00297
00298 Link* m_rtrLink;
00299 Log< RTRIF_DBG >& m_dbg;
00300 Log< RTRIF_DBG >& m_dummyDbg;
00301 Log<>& m_log;
00302
00303 protected:
00304 int m_id;
00305 std::string frequency;
00306 };
00307
00308 }
00309 #endif