diff --git a/DRAMSys/library/resources/configs/mcconfigs/fifoStrict.xml b/DRAMSys/library/resources/configs/mcconfigs/fifoStrict.xml index bc54f607..64b06284 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fifoStrict.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/fifoStrict.xml @@ -1,5 +1,6 @@ + diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.xml b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.xml index bcaf76dd..35e118dc 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.xml @@ -1,5 +1,6 @@ + diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 4818e017..daeb6cc9 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -76,6 +76,11 @@ bool BankMachine::forcePrecharge() return false; } +Bank BankMachine::getBank() +{ + return bank; +} + Row BankMachine::getOpenRow() { return currentRow; @@ -93,7 +98,7 @@ sc_time BankMachineOpen::startBankMachine() { if (currentPayload == nullptr) { - currentPayload = scheduler->getNextRequest(bank, this); + currentPayload = scheduler->getNextRequest(this); if (currentPayload == nullptr) return SC_ZERO_TIME; } @@ -140,7 +145,7 @@ sc_time BankMachineClosed::startBankMachine() { if (currentPayload == nullptr) { - currentPayload = scheduler->getNextRequest(bank, this); + currentPayload = scheduler->getNextRequest(this); if (currentPayload == nullptr) return SC_ZERO_TIME; } @@ -179,3 +184,134 @@ sc_time BankMachineClosed::startBankMachine() timeToSchedule = sc_time_stamp() + delay; return delay; } + +BankMachineOpenAdaptive::BankMachineOpenAdaptive(SchedulerIF *scheduler, CheckerIF *checker, Bank bank) + : BankMachine(scheduler, checker, bank) {} + +sc_time BankMachineOpenAdaptive::startBankMachine() +{ + if (currentPayload == nullptr) + { + currentPayload = scheduler->getNextRequest(this); + if (currentPayload == nullptr) + return SC_ZERO_TIME; + } + sc_time delay; + DramExtension extension = DramExtension::getExtension(currentPayload); + if (currentState == BmState::Precharged) // row miss + { + delay = checker->delayToSatisfyConstraints(Command::ACT, bank); + nextCommand = Command::ACT; + nextRow = extension.getRow(); + } + else if (currentState == BmState::Activated) + { + if (extension.getRow() == currentRow) // row hit + { + if (scheduler->hasRequest(bank) && !scheduler->hasRowHit(bank, currentRow)) + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + { + delay = checker->delayToSatisfyConstraints(Command::RDA, bank); + nextCommand = Command::RDA; + } + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + { + delay = checker->delayToSatisfyConstraints(Command::WRA, bank); + nextCommand = Command::WRA; + } + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + else + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + { + delay = checker->delayToSatisfyConstraints(Command::RD, bank); + nextCommand = Command::RD; + } + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + { + delay = checker->delayToSatisfyConstraints(Command::WR, bank); + nextCommand = Command::WR; + } + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + } + else // row miss + { + delay = checker->delayToSatisfyConstraints(Command::PRE, bank); + nextCommand = Command::PRE; + nextRow = extension.getRow(); + } + } + timeToSchedule = sc_time_stamp() + delay; + return delay; +} + +BankMachineClosedAdaptive::BankMachineClosedAdaptive(SchedulerIF *scheduler, CheckerIF *checker, Bank bank) + : BankMachine(scheduler, checker, bank) {} + +sc_time BankMachineClosedAdaptive::startBankMachine() +{ + if (currentPayload == nullptr) + { + currentPayload = scheduler->getNextRequest(this); + if (currentPayload == nullptr) + return SC_ZERO_TIME; + } + sc_time delay; + DramExtension extension = DramExtension::getExtension(currentPayload); + if (currentState == BmState::Precharged) // row miss + { + delay = checker->delayToSatisfyConstraints(Command::ACT, bank); + nextCommand = Command::ACT; + nextRow = extension.getRow(); + } + else if (currentState == BmState::Activated) + { + if (extension.getRow() == currentRow) // row hit + { + if (scheduler->hasRowHit(bank, currentRow)) + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + { + delay = checker->delayToSatisfyConstraints(Command::RD, bank); + nextCommand = Command::RD; + } + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + { + delay = checker->delayToSatisfyConstraints(Command::WR, bank); + nextCommand = Command::WR; + } + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + else + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + { + delay = checker->delayToSatisfyConstraints(Command::RDA, bank); + nextCommand = Command::RDA; + } + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + { + delay = checker->delayToSatisfyConstraints(Command::WRA, bank); + nextCommand = Command::WRA; + } + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + } + else // row miss TODO: remove this, can never happen + { + delay = checker->delayToSatisfyConstraints(Command::PRE, bank); + nextCommand = Command::PRE; + nextRow = extension.getRow(); + SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy"); + } + } + timeToSchedule = sc_time_stamp() + delay; + return delay; +} diff --git a/DRAMSys/library/src/controller/BankMachine.h b/DRAMSys/library/src/controller/BankMachine.h index 6ee71ff1..882059e3 100644 --- a/DRAMSys/library/src/controller/BankMachine.h +++ b/DRAMSys/library/src/controller/BankMachine.h @@ -64,6 +64,7 @@ public: void updateState(Command); bool forcePrecharge(); + Bank getBank(); Row getOpenRow(); BmState getState(); @@ -94,4 +95,18 @@ public: sc_time startBankMachine(); }; +class BankMachineOpenAdaptive final : public BankMachine +{ +public: + BankMachineOpenAdaptive(SchedulerIF *, CheckerIF *, Bank); + sc_time startBankMachine(); +}; + +class BankMachineClosedAdaptive final : public BankMachine +{ +public: + BankMachineClosedAdaptive(SchedulerIF *, CheckerIF *, Bank); + sc_time startBankMachine(); +}; + #endif // BANKMACHINE_H diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 59e56a7b..09f69eaf 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -93,13 +93,29 @@ Controller::Controller(sc_module_name name) : if (config.OpenPagePolicy) { - for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++) - bankMachines[Bank(bankID)] = new BankMachineOpen(scheduler, checker, Bank(bankID)); + if (config.AdaptivePagePolicy) + { + for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++) + bankMachines[Bank(bankID)] = new BankMachineOpenAdaptive(scheduler, checker, Bank(bankID)); + } + else + { + for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++) + bankMachines[Bank(bankID)] = new BankMachineOpen(scheduler, checker, Bank(bankID)); + } } else { - for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++) - bankMachines[Bank(bankID)] = new BankMachineClosed(scheduler, checker, Bank(bankID)); + if (config.AdaptivePagePolicy) + { + for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++) + bankMachines[Bank(bankID)] = new BankMachineClosedAdaptive(scheduler, checker, Bank(bankID)); + } + else + { + for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++) + bankMachines[Bank(bankID)] = new BankMachineClosed(scheduler, checker, Bank(bankID)); + } } startBandwidthIdleCollector(); diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp index 03210066..db52486c 100644 --- a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp @@ -138,6 +138,8 @@ void Configuration::setParameter(std::string name, std::string value) BankwiseLogic = string2bool(value); else if (name == "OpenPagePolicy") OpenPagePolicy = string2bool(value); + else if (name == "AdaptivePagePolicy") + AdaptivePagePolicy = string2bool(value); else if (name == "MaxNrOfTransactions") MaxNrOfTransactions = string2int(value); else if (name == "Scheduler") diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.h b/DRAMSys/library/src/controller/core/configuration/Configuration.h index d17c2a95..efab5eeb 100644 --- a/DRAMSys/library/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/library/src/controller/core/configuration/Configuration.h @@ -65,6 +65,7 @@ struct Configuration // MCConfig: bool BankwiseLogic = false; bool OpenPagePolicy = true; + bool AdaptivePagePolicy = false; unsigned int MaxNrOfTransactions = 8; std::string Scheduler; unsigned int SJFProbability; diff --git a/DRAMSys/library/src/controller/core/configuration/TemperatureSimConfig.h b/DRAMSys/library/src/controller/core/configuration/TemperatureSimConfig.h index 11c0e32d..f8344541 100644 --- a/DRAMSys/library/src/controller/core/configuration/TemperatureSimConfig.h +++ b/DRAMSys/library/src/controller/core/configuration/TemperatureSimConfig.h @@ -76,7 +76,7 @@ struct TemperatureSimConfig void parsePowerInfoFile() { - PRINTDEBUGMESSAGE("TemperatureSimConfig", "Power Info File: " + powerInfoFile) + PRINTDEBUGMESSAGE("TemperatureSimConfig", "Power Info File: " + powerInfoFile); powerInfoFile = pathToResources + "/configs/thermalsim/" diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index 626a3541..a3b1ef70 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -40,14 +40,34 @@ void SchedulerFifo::storeRequest(tlm_generic_payload *payload) buffer[bank].push(payload); } -tlm_generic_payload *SchedulerFifo::getNextRequest(Bank bank, BankMachine *) +tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) { + Bank bank = bankMachine->getBank(); if (!buffer[bank].empty()) { - tlm_generic_payload *result = buffer[bank].front(); + tlm_generic_payload *front = buffer[bank].front(); buffer[bank].pop(); - return result; + return front; } else return nullptr; } + +bool SchedulerFifo::hasRowHit(Bank bank, Row row) +{ + if (!buffer[bank].empty()) + { + tlm_generic_payload *front = buffer[bank].front(); + if (DramExtension::getRow(front) == row) + return true; + } + return false; +} + +bool SchedulerFifo::hasRequest(Bank bank) +{ + if (buffer[bank].empty()) + return false; + else + return true; +} diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index f6640d74..74783a87 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -48,7 +48,9 @@ class SchedulerFifo : public SchedulerIF { public: void storeRequest(tlm_generic_payload *); - tlm_generic_payload *getNextRequest(Bank, BankMachine *); + tlm_generic_payload *getNextRequest(BankMachine *); + bool hasRowHit(Bank, Row); + bool hasRequest(Bank); private: std::map> buffer; }; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index c6cb27ae..405e389c 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -42,8 +42,9 @@ void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload) buffer[bank].push_back(payload); } -tlm_generic_payload *SchedulerFrFcfs::getNextRequest(Bank bank, BankMachine *bankMachine) +tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) { + Bank bank = bankMachine->getBank(); if (!buffer[bank].empty()) { BmState currentState = bankMachine->getState(); @@ -76,3 +77,21 @@ tlm_generic_payload *SchedulerFrFcfs::getNextRequest(Bank bank, BankMachine *ban } return nullptr; } + +bool SchedulerFrFcfs::hasRowHit(Bank bank, Row row) +{ + for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++) + { + if (DramExtension::getRow(*it) == row) + return true; + } + return false; +} + +bool SchedulerFrFcfs::hasRequest(Bank bank) +{ + if (buffer[bank].empty()) + return false; + else + return true; +} diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index 819d7b50..ffc75edc 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -48,7 +48,9 @@ class SchedulerFrFcfs : public SchedulerIF { public: void storeRequest(tlm_generic_payload *); - tlm_generic_payload *getNextRequest(Bank, BankMachine *); + tlm_generic_payload *getNextRequest(BankMachine *); + bool hasRowHit(Bank, Row); + bool hasRequest(Bank); private: std::map> buffer; }; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index e07f3d03..8568773b 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -50,7 +50,9 @@ class SchedulerIF public: virtual ~SchedulerIF() {} virtual void storeRequest(tlm_generic_payload *) = 0; - virtual tlm_generic_payload *getNextRequest(Bank, BankMachine *) = 0; + virtual tlm_generic_payload *getNextRequest(BankMachine *) = 0; + virtual bool hasRowHit(Bank, Row) = 0; + virtual bool hasRequest(Bank) = 0; }; #endif // SCHEDULERIF_H