diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_rp.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_rp.xml index caa9ff67..68b2799c 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_rp.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_rp.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h index 3b2450de..ece2b5b4 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h @@ -57,9 +57,9 @@ public: protected: std::map> buffer; + std::deque::iterator FindRowHit(Bank bank); private: - std::deque::iterator FindRowHit(Bank bank); }; diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_read_priority.cpp b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_read_priority.cpp index 750bfc92..57f17426 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_read_priority.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_read_priority.cpp @@ -40,72 +40,100 @@ std::pair FR_FCFS_RP::getNextRequest(Bank bank) { - // If the bank is empty like Bank0 in the example we do nothing + // If the bank is empty like Bank0 in the example we do nothing: if(buffer[bank].empty()) { return pair(Command::NOP, NULL); } - // In FR_FCFS row hits have always the highest priority, therefore we search - // for row hits. If we find a row hit, we remove the transaction from the - // queue and send it to the DRAM. - deque::iterator it = FindRowHit_RP(bank); - if(it != buffer[bank].end()) + // Order of Priority: + // 1. Read Hits (Hazard Check) + // 2. Write Hits + // 3. Read Miss (Hazard Check) TODO + // 4. Write Miss TODO + + if(DebugManager::getInstance().writeToConsole == true) { - gp* payload = *it; - buffer[bank].erase(it); - return pair(getReadWriteCommand(*payload), payload); + for(unsigned long i=0; i < buffer[bank].size(); i++) + { + gp* trans = buffer[bank].at(i); + cout << ((trans->get_command() == tlm::TLM_READ_COMMAND)?"R":"W"); + } + cout << endl; + cout.flush(); } - // If there is no row hit, the FR_FCFS takes always the oldest transaction - // in the buffer, i.e. the transaction in the front. + // 1. Seach for read hit: + for(unsigned long i=0; i < buffer[bank].size(); i++) + { + gp* read = buffer[bank].at(i); + + if(read->get_command() == tlm::TLM_READ_COMMAND) + { + // If there is a row hit: + if(DramExtension::getRow(read) + == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) + { + if(hazardDetection(bank, i) == false) + { + buffer[bank].erase(buffer[bank].begin() + i); + return pair(getReadWriteCommand(*read), + read); + } + } + } + } + + // 2. Search for write hit: + for(unsigned long i=0; i < buffer[bank].size(); i++) + { + gp* write = buffer[bank].at(i); + + if(write->get_command() == tlm::TLM_WRITE_COMMAND) + { + // If there is a row hit: + if(DramExtension::getRow(write) + == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) + { + buffer[bank].erase(buffer[bank].begin() + i); + return pair(getReadWriteCommand(*write), + write); + } + } + } + + // For now return the oldest request. TODO: do read first! return pair(getNextCommand(buffer[bank].front()), buffer[bank].front()); + + reportFatal("FR_FCFS_RP", "Never should go here ..."); } -// This function searches for a row hit in the scheduling queue of the specific -// bank like FindRowHit in FR_FCFS. However, it will search for reads first and -// it will take a write only if there is no read row hit. -// If no row hit is found the end of the queue is returned. -// -// Note: end() Returns an iterator referring to the past-the-end element in the -// deque container. The past-the-end element is the theoretical element that -// would follow the last element in the deque container. It does not point to -// any element, and thus shall not be dereferenced. -deque::iterator FR_FCFS_RP::FindRowHit_RP(Bank bank) +// There is a hazard if a read is found which will be scheduled before a write +// to the same column and the same row of the same bank: +bool FR_FCFS_RP::hazardDetection(Bank bank, unsigned long id) { - deque &queue = buffer[bank]; + gp* read = buffer[bank].at(id); - if(!controllerCore.getRowBufferStates().rowBufferIsOpen(bank)) - return queue.end(); - - // Traverse the scheduling queue of the specific - // bank and serach for read hits: - for(auto it = queue.begin(); it!=queue.end(); it++) + for(unsigned long i=0; i < id; i++) { - gp* payload = *it; - //Found read row-hit and return the according iterator - if(DramExtension::getRow(payload) - == controllerCore.getRowBufferStates().getRowInRowBuffer(bank) - && payload->get_command() == tlm::TLM_READ_COMMAND) + gp* write = buffer[bank].at(i); + if(write->get_command() == tlm::TLM_WRITE_COMMAND) { - return it; + if((DramExtension::getExtension(read).getColumn() + == DramExtension::getExtension(write).getColumn()) + && (DramExtension::getExtension(read).getRow() + == DramExtension::getExtension(write).getRow())) + { + printDebugMessage("Hazard Detected"); + return true; + } } } - // Traverse the scheduling queue of the specific - // bank and serach for write hits in case no read was found: - for(auto it = queue.begin(); it!=queue.end(); it++) - { - gp* payload = *it; - //Found read row-hit and return the according iterator - if(DramExtension::getRow(payload) - == controllerCore.getRowBufferStates().getRowInRowBuffer(bank) - && payload->get_command() == tlm::TLM_WRITE_COMMAND) - { - return it; - } - } - - // If neither read or write hit was found we return the end: - return queue.end(); + return false; +} + +void FR_FCFS_RP::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage("FR_FCFS_RP", message); } diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_read_priority.h b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_read_priority.h index d0cab41c..1593a517 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_read_priority.h +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_read_priority.h @@ -48,7 +48,8 @@ public: private: - std::deque::iterator FindRowHit_RP(Bank bank); + bool hazardDetection(Bank bank, unsigned long id); + void printDebugMessage(std::string message); }; #endif // FR_FCFS_READ_PRIORITY_H