interconnect.hh

00001 
00002 #ifndef __INTERCONNECT_HH__
00003 #define __INTERCONNECT_HH__
00004 
00005 #include <iostream>
00006 #include <vector>
00007 #include <queue>
00008 #include <fstream>
00009         
00010 #include "mem/base_hier.hh"
00011 #include "interconnect_interface.hh"
00012 #include "interconnect_profile.hh"
00013 #include "sim/eventq.hh"
00014 #include "sim/stats.hh"
00015         
00016 #include "cpu/exec_context.hh" // for ExecContext, needed for cpu_id
00017 #include "cpu/base.hh" // for BaseCPU, needed for cpu_id
00018 
00019 
00021 #define TICK_T_MAX ULL(0x3FFFFFFFFFFFFF)
00022 
00023 class InterconnectInterface;
00024 class InterconnectArbitrationEvent;
00025 class InterconnectDeliverQueueEvent;
00026 class InterconnectProfile;
00027 
00043 class Interconnect : public BaseHier
00044 {
00045     private:
00046         
00047         int masterInterfaceCount;
00048         int slaveInterfaceCount;
00049         int totalInterfaceCount;
00050         
00051     protected:
00052         
00053         bool blocked;
00054         int waitingFor;
00055         Tick blockedAt;
00056         
00057         int cpu_count;
00058         
00059         InterconnectProfile* profiler;
00060         
00061         std::map<int, int> processorIDToInterconnectIDMap;
00062         std::map<int, int> interconnectIDToProcessorIDMap;
00063         std::map<int, int> interconnectIDToL2IDMap;
00064         
00065         std::vector<InterconnectInterface* > masterInterfaces;
00066         std::vector<InterconnectInterface* > slaveInterfaces;
00067         std::vector<InterconnectInterface* > allInterfaces;
00068   
00069         /* Statistics variables */
00070         Stats::Scalar<> totalArbitrationCycles;
00071         Stats::Scalar<> totalArbQueueCycles;
00072         Stats::Formula avgArbCyclesPerRequest;
00073         Stats::Formula avgArbQueueCyclesPerRequest;
00074         
00075         Stats::Scalar<> totalTransferCycles;
00076         Stats::Scalar<> totalTransQueueCycles;
00077         Stats::Formula avgTransCyclesPerRequest;
00078         Stats::Formula avgTransQueueCyclesPerRequest;
00079         
00080         Stats::Vector<> perCpuTotalTransferCycles;
00081         Stats::Vector<> perCpuTotalTransQueueCycles;
00082         
00083         Stats::Formula avgTotalDelayCyclesPerRequest;
00084         
00085         Stats::Scalar<> requests;
00086         Stats::Scalar<> arbitratedRequests;
00087         Stats::Scalar<> sentRequests;
00088         Stats::Scalar<> nullRequests;
00089 //         Stats::Scalar<> duplicateRequests;
00090         Stats::Scalar<> numClearBlocked;
00091         Stats::Scalar<> numSetBlocked;
00092         
00096         class InterconnectRequest{
00097             public:
00098                 Tick time;
00099                 int fromID;
00100             
00107                 InterconnectRequest(Tick _time, int _fromID){
00108                     time = _time;
00109                     fromID = _fromID;
00110                 }
00111         };
00112         
00117         class InterconnectDelivery{
00118             public:
00119                 Tick grantTime;
00120                 int fromID;
00121                 int toID;
00122                 MemReqPtr req;
00123             
00124                 
00134                 InterconnectDelivery(Tick _grantTime,
00135                                      int _fromID,
00136                                      int _toID,
00137                                      MemReqPtr& _req)
00138                 {
00139                     grantTime = _grantTime;
00140                     fromID = _fromID;
00141                     toID = _toID;
00142                     req = _req;
00143                 }
00144         };
00145 
00146     public:
00147         int clock;
00148         int width;
00149         int transferDelay;
00150         int arbitrationDelay;
00151         
00152         std::vector<InterconnectArbitrationEvent *> arbitrationEvents;
00153         std::vector<InterconnectDeliverQueueEvent* > deliverEvents;
00154         
00155     protected:
00156         
00169         bool isSorted(std::list<InterconnectRequest*>* inList);
00170         
00183         bool isSorted(std::list<InterconnectDelivery*>* inList);
00184         
00185         
00186     public:
00187         
00209         Interconnect(const std::string &_name, 
00210                  int _width, 
00211                  int _clock,
00212                  int _transDelay,
00213                  int _arbDelay,
00214                  int _cpu_count,
00215                  HierParams *_hier)
00216             : BaseHier(_name, _hier){
00217 
00218             width = _width;
00219             clock = _clock;
00220             transferDelay = _transDelay;
00221             arbitrationDelay = _arbDelay;
00222             cpu_count = _cpu_count;
00223     
00224             if(clock != 1){
00225                 fatal("The interconnects are only implemented to run "
00226                       "at the same frequency as the CPU core");
00227             }
00228             
00229             if(cpu_count < 1){
00230                 fatal("There must be at least one CPU in the system");
00231             }
00232             
00233             masterInterfaceCount = -1;
00234             slaveInterfaceCount = -1;
00235             totalInterfaceCount = -1;
00236             
00237             blocked = false;
00238             blockedAt = -1;
00239             waitingFor = -1;
00240             
00241         }
00242         
00243         ~Interconnect(){ /* does nothing */ }
00244         
00251         void registerProfiler(InterconnectProfile* _profiler){
00252             profiler = _profiler;
00253         }
00254         
00259         void regStats();
00260 
00265         void resetStats();
00266         
00281         int registerInterface(InterconnectInterface* interface,
00282                               bool isL2,
00283                               int processorID);
00284         
00289         void rangeChange();
00290         
00301         void incNullRequests();
00302         
00303 //         void incDuplicateRequests();
00304         
00316         int getInterconnectID(int processorID);
00317         
00334         void getSendSample(int* dataSends,
00335                            int* instSends,
00336                            int* coherenceSends,
00337                            int* totalSends);
00338         
00347         int getTarget(Addr address);
00348         
00352         virtual void request(Tick time, int fromID) = 0;
00353 
00357         virtual void send(MemReqPtr& req, Tick time, int fromID) = 0;
00358         
00362         virtual void arbitrate(Tick cycle) = 0;
00363         
00367         virtual void deliver(MemReqPtr& req, 
00368                              Tick cycle, 
00369                              int toID, 
00370                              int fromID) = 0;
00371         
00375         virtual void setBlocked(int fromInterface) = 0;
00376         
00380         virtual void clearBlocked(int fromInterface) = 0;
00381         
00385         virtual int getChannelCount() = 0;
00386         
00390         virtual std::vector<int> getChannelSample() = 0;
00391         
00395         virtual void writeChannelDecriptor(std::ofstream &stream) = 0;
00396 };
00397 
00411 class InterconnectArbitrationEvent : public Event
00412 {
00413 
00414     public:
00415         Interconnect *interconnect;
00416         
00422         InterconnectArbitrationEvent(Interconnect *_interconnect)
00423             : Event(&mainEventQueue), interconnect(_interconnect)
00424         {
00425         }
00426         
00435         void process();
00436 
00440         virtual const char *description();
00441 };
00442 
00460 class InterconnectDeliverEvent : public Event
00461 {
00462     
00463     public:
00464         
00465         Interconnect *interconnect;
00466         MemReqPtr req;
00467         int toID;
00468         int fromID;
00469         
00480         InterconnectDeliverEvent(Interconnect *_interconnect,
00481                                  MemReqPtr& _req,
00482                                  int _toID,
00483                                  int _fromID)
00484             : Event(&mainEventQueue)
00485         {
00486             interconnect = _interconnect;
00487             req = _req;
00488             toID = _toID;
00489             fromID = _fromID;
00490         }
00491 
00499         void process();
00500 
00504         virtual const char *description();
00505 };
00506 
00507 
00525 class InterconnectDeliverQueueEvent : public Event
00526 {
00527     
00528     public:
00529         
00530         Interconnect *interconnect;
00531         
00539         InterconnectDeliverQueueEvent(Interconnect* _interconnect)
00540             : Event(&mainEventQueue) {
00541             interconnect = _interconnect;
00542     }
00543 
00555     void process(){
00556         bool found = false;
00557         int foundIndex = -1;
00558         for(int i=0;i<interconnect->deliverEvents.size();i++){
00559             if((InterconnectDeliverQueueEvent*) interconnect->deliverEvents[i] 
00560                 == this){
00561                 foundIndex = i;
00562                 found = true;
00563             }
00564         }
00565         assert(found);
00566         interconnect->deliverEvents.erase(
00567                 interconnect->deliverEvents.begin()+foundIndex);
00568             
00569         MemReqPtr noReq = NULL;
00570         interconnect->deliver(noReq, this->when(), -1, -1);
00571         delete this;
00572     }
00573     
00577     virtual const char *description(){
00578         return "InterconnectDeliverQueueEvent";
00579     }
00580 };
00581 
00582 #endif // __INTERCONNECT_HH__

Generated on Tue Jun 5 12:55:20 2007 for M5InterconnectExtensions by  doxygen 1.4.7