• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/SS_router/SS_router/RtrIF.h

00001 // Copyright 2009-2010 Sandia Corporation. Under the terms
00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
00003 // Government retains certain rights in this software.
00004 // 
00005 // Copyright (c) 2009-2010, Sandia Corporation
00006 // All rights reserved.
00007 // 
00008 // This file is part of the SST software package. For license
00009 // information, see the LICENSE file in the top level directory of the
00010 // distribution.
00011 
00012 
00013 // Copyright 2007 Sandia Corporation. Under the terms
00014 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
00015 // Government retains certain rights in this software.
00016 //
00017 // Copyright (c) 2007, Sandia Corporation
00018 // All rights reserved.
00019 //
00020 // This file is part of the SST software package. For license
00021 // information, see the LICENSE file in the top level directory of the
00022 // distribution.
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 //         ClockHandler_t* clockHandler = new EventHandler< RtrIF, bool, Cycle_t >
00108 //                                                 ( this, &RtrIF::clock );
00109 
00110 //         if ( ! registerClock( frequency, clockHandler, false ) ) {
00111 //             _abort(XbarV2,"couldn't register clock handler");
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 /*      printf("%5d: Sending to %d @ %lu\n",m_id,pkt->destNum(),getCurrentSimTimeNano()); */
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 /*      printf("%5d:  got an event from %d @ %lu\n",m_id,event->packet.srcNum(),getCurrentSimTimeNano()); */
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

Generated on Fri Oct 22 2010 11:02:28 for SST by  doxygen 1.7.1