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
00039 int satisfied_before = req->flags & SATISFIED;
00040
00041
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
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
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
00132 updateProfileValues(req);
00133
00134
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
00161
00162
00163
00164
00165