interconnect_master_impl.hh

00001 
00002 #include <iostream>
00003 #include <vector>
00004 
00005 
00006 #include "interconnect.hh"
00007 #include "interconnect_master.hh"
00008 
00009 
00010 using namespace std;
00011 
00012 template<class MemType>
00013 InterconnectMaster<MemType>::InterconnectMaster(const string &name, 
00014                                                 Interconnect* interconnect,
00015                                                 MemType* cache,
00016                                                 HierParams *hier)
00017     : InterconnectInterface(interconnect, name, hier)
00018 {
00019     thisCache = cache;
00020 
00021     interfaceID = thisInterconnect->registerInterface(this,
00022                                                       false,
00023                                                       cache->getProcessorID());
00024     thisCache->setInterfaceID(interfaceID);
00025     
00026     currentAddr = 0;
00027     currentToCpuId = -1;
00028     currentValsValid = false;
00029     
00030     if(trace_on) cout << "InterconnectMaster with id "
00031                       << interfaceID << " created\n";
00032 }
00033 
00034 template<class MemType>
00035 MemAccessResult
00036 InterconnectMaster<MemType>::access(MemReqPtr &req){
00037 
00038     // NOTE: copied from MasterInterface
00039     int satisfied_before = req->flags & SATISFIED;
00040     // Cache Coherence call goes here
00041     //mem->snoop(req);
00042     if (satisfied_before != (req->flags & SATISFIED)) {
00043         return BA_SUCCESS;
00044     }
00045     
00046     return BA_NO_RESULT;
00047 }
00048 
00049 template<class MemType>
00050 void
00051 InterconnectMaster<MemType>::deliver(MemReqPtr &req){
00052     
00053     if(!req->cmd.isDirectoryMessage()){
00054         pair<Addr, Tick>* hitPair = NULL;
00055         int hitIndex = -1;
00056         for(int i=0;i<outstandingRequestAddrs.size();++i){
00057             pair<Addr, Tick>* tmpPair = outstandingRequestAddrs[i];
00058             if(req->paddr == tmpPair->first){
00059                 hitIndex = i;
00060                 hitPair = tmpPair;
00061             }
00062         }
00063         
00064         /* check if this actually was an answer to something we requested */
00065         assert(hitIndex >= 0);
00066         outstandingRequestAddrs.erase(outstandingRequestAddrs.begin()+hitIndex);
00067         delete hitPair;
00068     } 
00069     
00070     if(trace_on){
00071         cout << "Master "<< interfaceID <<" is waiting for: ";
00072         for(int i=0;i<outstandingRequestAddrs.size();++i){
00073             cout << "(" << outstandingRequestAddrs[i]->first 
00074                  << ", " << outstandingRequestAddrs[i]->second << ") ";
00075         }
00076         cout << "at tick " << curTick << "\n";
00077     }
00078     
00079     if(trace_on) cout << "TRACE: MASTER_RESPONSE id " << interfaceID 
00080                       << " addr " << req->paddr << " at " << curTick << "\n";
00081     thisCache->handleResponse(req);
00082 }
00083 
00084 template<class MemType>
00085 void
00086 InterconnectMaster<MemType>::request(Tick time){
00087 
00088     if(trace_on) cout << "TRACE: MASTER_REQUEST id " << interfaceID << " at " 
00089                       << curTick << "\n";
00090     
00091     thisInterconnect->request(time, interfaceID);
00092 }
00093 
00094 template<class MemType>
00095 bool
00096 InterconnectMaster<MemType>::grantData(){
00097     
00098     MemReqPtr req = thisCache->getMemReq();
00099     
00100     if(!req){
00101         thisInterconnect->incNullRequests();
00102         return false;
00103     }
00104     
00105     if(trace_on) cout << "TRACE: MASTER_SEND " << req->cmd.toString() 
00106                       << " from id " << interfaceID << " addr " << req->paddr 
00107                       << " at " << curTick << "\n";
00108     
00109     if(!req->cmd.isNoResponse()){
00110         if(!req->cmd.isDirectoryMessage()){
00111             outstandingRequestAddrs.push_back(
00112                     new pair<Addr, Tick>(req->paddr, curTick));
00113         }
00114     }
00115     
00116     req->fromInterfaceID = interfaceID;
00117     req->firstSendTime = curTick;
00118     req->readOnlyCache = thisCache->isInstructionCache();
00119     req->toInterfaceID = 
00120             thisInterconnect->getInterconnectID(req->toProcessorID);
00121     
00122     // make sure destination was set properly
00123     if(req->toProcessorID != -1) assert(req->toInterfaceID != -1);
00124 
00125     if(currentValsValid){
00126         assert(currentAddr == req->paddr);
00127         assert(currentToCpuId == req->toProcessorID);
00128         currentValsValid = false;
00129     }
00130     
00131     // Update send profile
00132     updateProfileValues(req);
00133     
00134     //Currently sends can't fail, so all reqs will be a success
00135     thisCache->sendResult(req, true);
00136     thisInterconnect->send(req, curTick, interfaceID);
00137     
00138     return thisCache->doMasterRequest();
00139 }
00140 
00141 template<class MemType>
00142 pair<Addr, int>
00143 InterconnectMaster<MemType>::getTargetAddr(){
00144     MemReqPtr currentRequest = thisCache->getMemReq();
00145     
00146     if(!currentRequest) return pair<Addr,int>(0,-2);
00147     assert(currentRequest->paddr != 0);
00148     
00149     int toInterface = 
00150             thisInterconnect->getInterconnectID(currentRequest->toProcessorID);
00151     if(currentRequest->toProcessorID != -1) assert(toInterface != -1);
00152     
00153     currentAddr = currentRequest->paddr;
00154     currentToCpuId = toInterface;
00155     currentValsValid = true;
00156     
00157     return pair<Addr,int>(currentRequest->paddr, toInterface);
00158 }
00159 
00160 // template<class MemType>
00161 // void
00162 // InterconnectMaster<MemType>::setCurrentRequestAddr(Addr address){
00163 //     /* not needed */
00164 // }
00165 

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