00001
00002 #include "interconnect.hh"
00003 #include "sim/builder.hh"
00004 #include "mem/base_hier.hh"
00005
00006 using namespace std;
00007
00008
00009 void
00010 Interconnect::regStats(){
00011
00012 using namespace Stats;
00013
00014
00015
00016 totalArbitrationCycles
00017 .name(name() + ".total_arbitration_cycles")
00018 .desc("total number of arbitration cycles for all requests")
00019 ;
00020
00021 avgArbCyclesPerRequest
00022 .name(name() + ".avg_arbitration_cycles_per_req")
00023 .desc("average number of arbitration cycles per requests")
00024 ;
00025 avgArbCyclesPerRequest = totalArbitrationCycles / arbitratedRequests;
00026
00027 totalArbQueueCycles
00028 .name(name() + ".total_arbitration_queue_cycles")
00029 .desc("total number of cycles in the arbitration queue "
00030 "for all requests")
00031 ;
00032
00033 avgArbQueueCyclesPerRequest
00034 .name(name() + ".avg_arbitration_queue_cycles_per_req")
00035 .desc("average number of arbitration queue cycles per requests")
00036 ;
00037 avgArbQueueCyclesPerRequest = totalArbQueueCycles / arbitratedRequests;
00038
00039
00040
00041 totalTransferCycles
00042 .name(name() + ".total_transfer_cycles")
00043 .desc("total number of transfer cycles for all requests")
00044 ;
00045
00046 avgTransCyclesPerRequest
00047 .name(name() + ".avg_transfer_cycles_per_request")
00048 .desc("average number of transfer cycles per requests")
00049 ;
00050
00051 avgTransCyclesPerRequest = totalTransferCycles / sentRequests;
00052
00053 totalTransQueueCycles
00054 .name(name() + ".total_transfer_queue_cycles")
00055 .desc("total number of transfer queue cycles for all requests")
00056 ;
00057
00058 avgTransQueueCyclesPerRequest
00059 .name(name() + ".avg_transfer_queue_cycles_per_request")
00060 .desc("average number of transfer queue cycles per request")
00061 ;
00062
00063 avgTransQueueCyclesPerRequest = totalTransQueueCycles / sentRequests;
00064
00065 perCpuTotalTransferCycles
00066 .init(cpu_count)
00067 .name(name() + ".per_cpu_total_transfer_cycles")
00068 .desc("total number of transfer cycles per cpu for all requests")
00069 .flags(total)
00070 ;
00071
00072 perCpuTotalTransQueueCycles
00073 .init(cpu_count)
00074 .name(name() + ".per_cpu_total_transfer_queue_cycles")
00075 .desc("total number of cycles in the transfer queue per cpu "
00076 "for all requests")
00077 .flags(total)
00078 ;
00079
00080
00081
00082 avgTotalDelayCyclesPerRequest
00083 .name(name() + ".avg_total_delay_cycles_per_request")
00084 .desc("average number of delay cycles per request")
00085 ;
00086
00087 avgTotalDelayCyclesPerRequest = avgArbCyclesPerRequest
00088 + avgArbQueueCyclesPerRequest
00089 + avgTransCyclesPerRequest
00090 + avgTransQueueCyclesPerRequest;
00091
00092 requests
00093 .name(name() + ".requests")
00094 .desc("total number of requests")
00095 ;
00096
00097 arbitratedRequests
00098 .name(name() + ".arbitrated_requests")
00099 .desc("total number of requests that reached arbitration")
00100 ;
00101
00102 sentRequests
00103 .name(name() + ".sent_requests")
00104 .desc("total number of requests that are actually sent")
00105 ;
00106
00107 nullRequests
00108 .name(name() + ".null_requests")
00109 .desc("total number of null requests")
00110 ;
00111
00112 nullRequests
00113 .name(name() + ".null_requests")
00114 .desc("total number of null requests")
00115 ;
00116
00117
00118
00119
00120
00121
00122 numSetBlocked
00123 .name(name() + ".num_set_blocked")
00124 .desc("the number of times the interconnect has been blocked")
00125 ;
00126
00127 numClearBlocked
00128 .name(name() + ".num_clear_blocked")
00129 .desc("the number of times the interconnect has been cleared")
00130 ;
00131
00132 }
00133
00134 void
00135 Interconnect::resetStats(){
00136
00137
00138
00139
00140 }
00141
00142 int
00143 Interconnect::registerInterface(InterconnectInterface* interface,
00144 bool isL2,
00145 int processorID){
00146
00147
00148 ++totalInterfaceCount;
00149 allInterfaces.push_back(interface);
00150 assert(totalInterfaceCount == (allInterfaces.size()-1));
00151
00152 if(isL2){
00153
00154 ++slaveInterfaceCount;
00155 slaveInterfaces.push_back(interface);
00156 assert(slaveInterfaceCount == (slaveInterfaces.size()-1));
00157 }
00158 else{
00159
00160 ++masterInterfaceCount;
00161 masterInterfaces.push_back(interface);
00162 assert(masterInterfaceCount == (masterInterfaces.size()-1));
00163 }
00164
00165 if(processorID != -1){
00166 assert(processorID >= 0);
00167 processorIDToInterconnectIDMap.insert(
00168 make_pair(processorID, totalInterfaceCount));
00169 interconnectIDToProcessorIDMap.insert(
00170 make_pair(totalInterfaceCount, processorID));
00171 }
00172 else{
00173 assert(isL2);
00174 interconnectIDToL2IDMap.insert(
00175 make_pair(totalInterfaceCount, slaveInterfaceCount));
00176 }
00177
00178 return totalInterfaceCount;
00179 }
00180
00181 void
00182 Interconnect::rangeChange(){
00183 for(int i=0;i<allInterfaces.size();++i){
00184 list<Range<Addr> > range_list;
00185 allInterfaces[i]->getRange(range_list);
00186 }
00187 }
00188
00189 void
00190 Interconnect::incNullRequests(){
00191 nullRequests++;
00192 }
00193
00194
00195
00196
00197
00198
00199 int
00200 Interconnect::getInterconnectID(int processorID){
00201 if(processorID == -1) return -1;
00202
00203 map<int,int>::iterator tmp =
00204 processorIDToInterconnectIDMap.find(processorID);
00205
00206
00207 assert(tmp != processorIDToInterconnectIDMap.end());
00208
00209 return tmp->second;
00210 }
00211
00212 void
00213 Interconnect::getSendSample(int* dataSends,
00214 int* instSends,
00215 int* coherenceSends,
00216 int* totalSends){
00217
00218 assert(*dataSends == 0);
00219 assert(*instSends == 0);
00220 assert(*coherenceSends == 0);
00221 assert(*totalSends == 0);
00222
00223 int tmpSends, tmpInsts, tmpCoh, tmpTotal;
00224
00225 for(int i=0;i<allInterfaces.size();i++){
00226 allInterfaces[i]->getSendSample(&tmpSends,
00227 &tmpInsts,
00228 &tmpCoh,
00229 &tmpTotal);
00230 *dataSends += tmpSends;
00231 *instSends += tmpInsts;
00232 *coherenceSends += tmpCoh;
00233 *totalSends += tmpTotal;
00234 }
00235 }
00236
00237 int
00238 Interconnect::getTarget(Addr address){
00239 int toID = -1;
00240 int hitCount = 0;
00241
00242 for(int i=0;i<allInterfaces.size();i++){
00243
00244 if(allInterfaces[i]->isMaster()) continue;
00245
00246 if(allInterfaces[i]->inRange(address)){
00247 toID = i;
00248 hitCount++;
00249 }
00250 }
00251 if(hitCount == 0) fatal("No supplier for address in interconnect");
00252 if(hitCount > 1) fatal("More than one supplier for address in interconnect");
00253
00254 return toID;
00255 }
00256
00257 bool
00258 Interconnect::isSorted(list<InterconnectDelivery*>* inList){
00259 InterconnectDelivery* prev = NULL;
00260 bool first = true;
00261 bool nonSeqDataExists = false;
00262 for(list<InterconnectDelivery*>::iterator i=inList->begin();
00263 i!=inList->end();
00264 i++){
00265 if(first){
00266 first = false;
00267 prev = *i;
00268 continue;
00269 }
00270
00271 if(prev->grantTime > (*i)->grantTime) nonSeqDataExists = true;
00272 prev = *i;
00273 }
00274 return !nonSeqDataExists;
00275 }
00276
00277 bool
00278 Interconnect::isSorted(list<InterconnectRequest*>* inList){
00279 InterconnectRequest* prev = NULL;
00280 bool first = true;
00281 bool nonSeqDataExists = false;
00282 for(list<InterconnectRequest*>::iterator i=inList->begin();
00283 i!=inList->end();
00284 i++){
00285 if(first){
00286 first = false;
00287 prev = *i;
00288 continue;
00289 }
00290
00291 if(prev->time > (*i)->time) nonSeqDataExists = true;
00292 prev = *i;
00293 }
00294 return !nonSeqDataExists;
00295 }
00296
00297 void
00298 InterconnectArbitrationEvent::process(){
00299
00300 int foundIndex = -1;
00301 int eventHitCount = 0;
00302 for(int i=0;i<interconnect->arbitrationEvents.size();++i){
00303 if(interconnect->arbitrationEvents[i] == this){
00304 foundIndex = i;
00305 eventHitCount++;
00306 }
00307 }
00308 assert(foundIndex >= 0);
00309 assert(eventHitCount == 1);
00310 interconnect->arbitrationEvents.erase(
00311 interconnect->arbitrationEvents.begin()+foundIndex);
00312
00313 interconnect->arbitrate(this->when());
00314 delete this;
00315 }
00316
00317 const char*
00318 InterconnectArbitrationEvent::description(){
00319 return "Interconnect arbitration event";
00320 }
00321
00322 void
00323 InterconnectDeliverEvent::process(){
00324 interconnect->deliver(this->req, this->when(), this->toID, this->fromID);
00325 delete this;
00326 }
00327
00328 const char*
00329 InterconnectDeliverEvent::description(){
00330 return "Interconnect deliver event";
00331 }
00332
00333
00334 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00335
00336 DEFINE_SIM_OBJECT_CLASS_NAME("Interconnect", Interconnect);
00337
00338 #endif
00339