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