interconnect.cc

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     /* Arbitration */
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     /* Transfer */
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     /* Other statistics */
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 //     duplicateRequests
00118 //             .name(name() + ".duplicate_requests")
00119 //             .desc("total number of duplicate requests")
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     /* seems like function is not needed as measurements only are taken in the 
00137      * second phase when using fast forwarding. Consequently, it is not 
00138      * implemented.
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         // This is a slave interface (i.e. interface to a L2 bank)
00154         ++slaveInterfaceCount;
00155         slaveInterfaces.push_back(interface);
00156         assert(slaveInterfaceCount == (slaveInterfaces.size()-1));
00157     }
00158     else{
00159         // This is a master interface (i.e. interface to a L1 cache)
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 // void
00195 // Interconnect::incDuplicateRequests(){
00196 //     duplicateRequests++;
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     // make sure at least one result is returned
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         

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