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.h>
00032 #include <sst/core/eventFunctor.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 EventHandler_t* handler = new EventHandler<
00106 RtrIF, bool, Event* >
00107 ( this, &RtrIF::processEvent );
00108
00109 m_rtrLink = LinkAdd( "rtr", handler );
00110
00111 ClockHandler_t* clockHandler = new EventHandler< RtrIF, bool, Cycle_t >
00112 ( this, &RtrIF::clock );
00113
00114 if ( ! registerClock( frequency, clockHandler ) ) {
00115 _abort(XbarV2,"couldn't register clock handler");
00116 }
00117
00118 db_RtrIF("Done registering clock\n");
00119
00120 for ( unsigned int i=0; i < num_vcP; i++ ) {
00121 toNicMapP[i] = new ToNic();
00122 toRtrMapP[i] = new ToRtr(num_tokens,toRtrQP);
00123 }
00124 }
00125
00126 bool toNicQ_empty(unsigned int vc)
00127 {
00128 if ( vc >= num_vcP ) _abort(RtrIF,"vc=%d\n",vc);
00129 return toNicMapP[vc]->empty();
00130 }
00131
00132 RtrEvent *toNicQ_front(unsigned int vc)
00133 {
00134 if ( vc >= num_vcP ) _abort(RtrIF,"vc=%d\n",vc);
00135 db_RtrIF("vc=%d\n",vc);
00136 return toNicMapP[vc]->front();
00137 }
00138
00139 void toNicQ_pop(unsigned int vc)
00140 {
00141 if ( vc >= num_vcP ) _abort(RtrIF,"vc=%d\n",vc);
00142 db_RtrIF("vc=%d\n",vc);
00143 returnTokens2Rtr( vc, toNicMapP[vc]->front()->u.packet.sizeInFlits() );
00144 toNicMapP[vc]->pop_front();
00145 }
00146
00147 bool send2Rtr( RtrEvent *event)
00148 {
00149 networkPacket* pkt = &event->u.packet;
00150 if ( pkt->vc() >= (int) num_vcP ) _abort(RtrIF,"vc=%d\n",pkt->vc());
00151 bool retval = toRtrMapP[pkt->vc()]->push( event );
00152 if ( retval )
00153 db_RtrIF("vc=%d src=%d dest=%d pkt=%p\n",
00154 pkt->vc(),pkt->srcNum(),pkt->destNum(),pkt);
00155 if ( retval ) {
00156 sendPktToRtr( toRtrQP.front() );
00157 toRtrQP.pop_front();
00158 }
00159 return retval;
00160 }
00161
00162 int Finish() { return 0; }
00163
00164 private:
00165 bool rtrWillTake( int vc, int numFlits )
00166 {
00167 if ( vc >= (int) num_vcP ) _abort(RtrIF,"\n");
00168 db_RtrIF("vc=%d numFlits=%d\n",vc,numFlits);
00169 return toRtrMapP[vc]->willTake( numFlits );
00170 }
00171
00172 bool processEvent( Event* e)
00173 {
00174 RtrEvent* event = static_cast<RtrEvent*>(e);
00175
00176 db_RtrIF("type=%ld\n",event->type);
00177
00178 switch ( event->type ) {
00179 case RtrEvent::Credit:
00180 returnTokens2Nic( event->u.credit.vc, event->u.credit.num );
00181 delete event;
00182 break;
00183
00184 case RtrEvent::Packet:
00185 send2Nic( event );
00186 break;
00187
00188 default:
00189 _abort(RtrIF,"unknown type %d\n",event->type);
00190 }
00191 return false;
00192 }
00193
00194 bool clock( Cycle_t cycle)
00195 {
00196 rtrCountP = (rtrCountP >= 0) ? 0 : rtrCountP + 1;
00197
00198 if ( ! toRtrQP.empty() ) {
00199 sendPktToRtr( toRtrQP.front());
00200 toRtrQP.pop_front();
00201 }
00202 return false;
00203 }
00204
00205 void send2Nic( RtrEvent* event )
00206 {
00207 networkPacket *pkt = &event->u.packet;
00208
00209 pkt->vc() = RTR_2_NIC_VC(pkt->vc());
00210
00211 if ( pkt->vc() >= (int) num_vcP ) {
00212 _abort(RtrIF,"vc=%d pkt=%p\n",pkt->vc(),pkt);
00213 }
00214
00215 db_RtrIF("vc=%d src=%d dest=%d pkt=%p\n",
00216 pkt->vc(),pkt->srcNum(),pkt->destNum(),pkt);
00217 toNicMapP[pkt->vc()]->push_back( event );
00218 }
00219
00220 void returnTokens2Nic( int vc, uint32_t num )
00221 {
00222 if ( vc >= (int) num_vcP ) _abort(RtrIF,"\n");
00223 db_RtrIF("vc=%d numFlits=%d\n", vc, num );
00224 toRtrMapP[vc]->returnTokens( num );
00225 }
00226
00227 void returnTokens2Rtr( int vc, uint numFlits )
00228 {
00229 RtrEvent* event = new RtrEvent;
00230
00231 db_RtrIF("vc=%d numFlits=%d\n", vc, numFlits );
00232
00233 event->type = RtrEvent::Credit;
00234 event->u.credit.num = numFlits;
00235 event->u.credit.vc = vc;
00236 m_rtrLink->Send( event );
00237 }
00238
00239 void sendPktToRtr( RtrEvent* event )
00240 {
00241 networkPacket* pkt = &event->u.packet;
00242
00243 db_RtrIF("vc=%d src=%d dest=%d pkt=%p\n",
00244 pkt->vc(),pkt->srcNum(),pkt->destNum(),pkt);
00245
00246 event->type = RtrEvent::Packet;
00247 event->u.packet = *pkt;
00248 int lat = reserveRtrLine(pkt->sizeInFlits());
00249 m_rtrLink->Send( lat, event );
00250 }
00251
00252 int reserveRtrLine (int cyc)
00253 {
00254 db_RtrIF("cyc=%d\n",cyc);
00255 int ret = (rtrCountP <= 0) ? -rtrCountP : 0;
00256 rtrCountP -= cyc;
00257 return ret;
00258 }
00259
00260 typedef std::deque<RtrEvent*> ToNic;
00261
00262 class ToRtr {
00263 public:
00264 ToRtr( int num_tokens, deque<RtrEvent*> &eventQ ) :
00265 tokensP(num_tokens), eventQP(eventQ) {}
00266
00267 bool push( RtrEvent* event) {
00268 networkPacket* pkt = &event->u.packet;
00269 if ( pkt->sizeInFlits() > (unsigned int) tokensP ) return false;
00270 tokensP -= pkt->sizeInFlits();
00271 eventQP.push_back(event);
00272 return true;
00273 }
00274
00275 int size() {
00276 return eventQP.size();
00277 }
00278
00279 bool willTake( int numFlits ) {
00280 return (numFlits <= tokensP );
00281 }
00282
00283 void returnTokens( int num ) {
00284 tokensP += num;
00285 }
00286
00287 private:
00288 int tokensP;
00289 deque<RtrEvent*> &eventQP;
00290 };
00291
00292 int rtrCountP;
00293 map<int,ToNic*> toNicMapP;
00294 map<int,ToRtr*> toRtrMapP;
00295
00296 uint num_vcP;
00297
00298 deque<RtrEvent*> toRtrQP;
00299
00300 Link* m_rtrLink;
00301 Log< RTRIF_DBG >& m_dbg;
00302 Log< RTRIF_DBG >& m_dummyDbg;
00303 Log<>& m_log;
00304
00305 protected:
00306 int m_id;
00307 std::string frequency;
00308 };
00309
00310 }
00311 #endif