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"
00017 #include "cpu/base.hh"
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
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
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(){ }
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
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__