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