00001
00002 #include <iostream>
00003 #include <vector>
00004
00005 #include "interconnect.hh"
00006 #include "interconnect_slave.hh"
00007
00008 using namespace std;
00009
00010 template<class MemType>
00011 InterconnectSlave<MemType>::InterconnectSlave(const string &name,
00012 Interconnect* interconnect,
00013 MemType* cache,
00014 HierParams *hier)
00015 : InterconnectInterface(interconnect, name, hier)
00016 {
00017 thisCache = cache;
00018
00019 interfaceID = thisInterconnect->registerInterface(this,
00020 true,
00021 cache->getProcessorID());
00022 thisCache->setInterfaceID(interfaceID);
00023
00024 if(trace_on) cout << "InterconnectSlave with id " << interfaceID
00025 << " created\n";
00026
00027 }
00028
00029 template<class MemType>
00030 MemAccessResult
00031 InterconnectSlave<MemType>::access(MemReqPtr &req){
00032
00033 bool already_satisfied = req->isSatisfied();
00034 if (already_satisfied && !req->cmd.isDirectoryMessage()) {
00035 warn("Request is allready satisfied (InterconnectSlave: access())");
00036 return BA_NO_RESULT;
00037 }
00038
00039 if (this->inRange(req->paddr)) {
00040 assert(!blocked);
00041
00042 if(trace_on) cout << "TRACE: SLAVE_ACCESS from id "
00043 << req->fromInterfaceID << " addr " << req->paddr
00044 << " at " << curTick << "\n";
00045
00046 thisCache->access(req);
00047
00048 assert(!this->isBlocked() || thisCache->isBlocked());
00049
00050 if (this->isBlocked()) {
00051
00052 return BA_BLOCKED;
00053 } else {
00054
00055 return BA_SUCCESS;
00056 }
00057 }
00058
00059 return BA_NO_RESULT;
00060 }
00061
00062 template<class MemType>
00063 void
00064 InterconnectSlave<MemType>::respond(MemReqPtr &req, Tick time){
00065
00066 if (!req->cmd.isNoResponse()) {
00067 if(trace_on) cout << "TRACE: SLAVE_RESPONSE " << req->cmd.toString()
00068 << " from id " << req->fromInterfaceID
00069 << " addr " << req->paddr
00070 << " at " << curTick << "\n";
00071
00072
00073 if(req->toProcessorID != -1){
00074
00075 req->fromInterfaceID =
00076 thisInterconnect->getInterconnectID(req->toProcessorID);
00077 assert(req->fromInterfaceID != -1);
00078 }
00079
00080 responseQueue.push_back(new InterconnectResponse(req, time));
00081 thisInterconnect->request(time, interfaceID);
00082 }
00083 }
00084
00085
00086 template<class MemType>
00087 bool
00088 InterconnectSlave<MemType>::grantData(){
00089
00090 assert(responseQueue.size() > 0);
00091 InterconnectResponse* response = responseQueue.front();
00092 responseQueue.erase(responseQueue.begin());
00093
00094 MemReqPtr req = response->req;
00095
00096
00097 updateProfileValues(req);
00098
00099 thisInterconnect->send(req, curTick, interfaceID);
00100
00101 delete response;
00102
00103 return !responseQueue.empty();
00104
00105 }
00106
00107 template<class MemType>
00108 bool
00109 InterconnectSlave<MemType>::inRange(Addr addr)
00110 {
00111 assert(thisCache != NULL);
00112
00113 if(thisCache->isModuloAddressedBank()){
00114
00115 int bankID = thisCache->getBankID();
00116 int bankCount = thisCache->getBankCount();
00117
00118 int localBlkSize = thisCache->getBlockSize();
00119 int bitCnt = 1;
00120 assert(localBlkSize != 0);
00121 while((localBlkSize >>= 1) != 1) bitCnt++;
00122
00123 assert(bankID != -1);
00124 assert(bankCount != -1);
00125
00126 Addr effectiveAddr = addr >> bitCnt;
00127
00128 if((effectiveAddr % bankCount) == bankID) return true;
00129 return false;
00130 }
00131 else{
00132 for (int i = 0; i < ranges.size(); ++i) {
00133 if (addr == ranges[i]) {
00134 return true;
00135 }
00136 }
00137 return false;
00138 }
00139 }
00140