diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 0264d2b0..4818e017 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -37,53 +37,6 @@ BankMachine::BankMachine(SchedulerIF *scheduler, CheckerIF *checker, Bank bank) : scheduler(scheduler), checker(checker), bank(bank) {} -sc_time BankMachine::startBankMachine() -{ - if (currentPayload == nullptr) - { - currentPayload = scheduler->getNextRequest(bank, 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(); - timeToSchedule = sc_time_stamp() + delay; - } - else if (currentState == BmState::Activated) - { - if (extension.getRow() == currentRow) // row hit - { - if (currentPayload->get_command() == TLM_READ_COMMAND) - { - delay = checker->delayToSatisfyConstraints(Command::RD, bank); - nextCommand = Command::RD; - timeToSchedule = sc_time_stamp() + delay; - } - else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - { - delay = checker->delayToSatisfyConstraints(Command::WR, bank); - nextCommand = Command::WR; - timeToSchedule = sc_time_stamp() + delay; - } - 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; -} - std::pair BankMachine::getNextCommand() { if (sc_time_stamp() == timeToSchedule) @@ -103,6 +56,11 @@ void BankMachine::updateState(Command command) currentState = BmState::Precharged; else if (command == Command::RD || command == Command::WR) currentPayload = nullptr; + else if (command == Command::RDA || command == Command::WRA) + { + currentState = BmState::Precharged; + currentPayload = nullptr; + } else SC_REPORT_FATAL("BankMachine", "Unknown phase"); } @@ -127,3 +85,97 @@ BmState BankMachine::getState() { return currentState; } + +BankMachineOpen::BankMachineOpen(SchedulerIF *scheduler, CheckerIF *checker, Bank bank) + : BankMachine(scheduler, checker, bank) {} + +sc_time BankMachineOpen::startBankMachine() +{ + if (currentPayload == nullptr) + { + currentPayload = scheduler->getNextRequest(bank, 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 (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; +} + +BankMachineClosed::BankMachineClosed(SchedulerIF *scheduler, CheckerIF *checker, Bank bank) + : BankMachine(scheduler, checker, bank) {} + +sc_time BankMachineClosed::startBankMachine() +{ + if (currentPayload == nullptr) + { + currentPayload = scheduler->getNextRequest(bank, 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 (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 + { + delay = checker->delayToSatisfyConstraints(Command::PRE, bank); + nextCommand = Command::PRE; + nextRow = extension.getRow(); + } + } + timeToSchedule = sc_time_stamp() + delay; + return delay; +} diff --git a/DRAMSys/library/src/controller/BankMachine.h b/DRAMSys/library/src/controller/BankMachine.h index 87c26072..6ee71ff1 100644 --- a/DRAMSys/library/src/controller/BankMachine.h +++ b/DRAMSys/library/src/controller/BankMachine.h @@ -58,8 +58,8 @@ enum class BmState class BankMachine { public: - BankMachine(SchedulerIF *, CheckerIF*, Bank); - sc_time startBankMachine(); + virtual ~BankMachine() {} + virtual sc_time startBankMachine() = 0; std::pair getNextCommand(); void updateState(Command); bool forcePrecharge(); @@ -67,16 +67,31 @@ public: Row getOpenRow(); BmState getState(); -private: +protected: + BankMachine(SchedulerIF *, CheckerIF *, Bank); tlm_generic_payload *currentPayload = nullptr; - BmState currentState = BmState::Precharged; - Bank bank; - Row currentRow; - Row nextRow; - Command nextCommand; - sc_time timeToSchedule = SC_ZERO_TIME; SchedulerIF *scheduler; CheckerIF *checker; + Command nextCommand; + Row nextRow; + BmState currentState = BmState::Precharged; + Row currentRow; + sc_time timeToSchedule = SC_ZERO_TIME; + Bank bank; +}; + +class BankMachineOpen final : public BankMachine +{ +public: + BankMachineOpen(SchedulerIF *, CheckerIF *, Bank); + sc_time startBankMachine(); +}; + +class BankMachineClosed final : public BankMachine +{ +public: + BankMachineClosed(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 56749619..59e56a7b 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -91,8 +91,16 @@ Controller::Controller(sc_module_name name) : else SC_REPORT_FATAL("Controller", "Selected scheduler not supported"); - for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++) - bankMachines[Bank(bankID)] = new BankMachine(scheduler, checker, Bank(bankID)); + if (config.OpenPagePolicy) + { + 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)); + } startBandwidthIdleCollector(); } @@ -211,7 +219,7 @@ tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &trans, PRINTDEBUGMESSAGE(name(), "[bw] " + phaseNameToString(phase) + " notification in " + delay.to_string()); - if (phase == END_RD || phase == END_WR) + if (phase == END_RD || phase == END_RDA || phase == END_WR || phase == END_WRA) { std::pair element((sc_time_stamp() + delay), &trans); responseQueue.push(element); @@ -276,8 +284,12 @@ void Controller::sendToDram(Command command, tlm_generic_payload *payload) phase = BEGIN_PRE; else if (command == Command::RD) phase = BEGIN_RD; + else if (command == Command::RDA) + phase = BEGIN_RDA; else if (command == Command::WR) phase = BEGIN_WR; + else if (command == Command::WRA) + phase = BEGIN_WRA; else if (command == Command::PREA) phase = BEGIN_PREA; else if (command == Command::REFA) diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 73c651d3..8e3ed98e 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -60,7 +60,7 @@ void ControllerRecordable::sendToFrontend(tlm_generic_payload *payload, tlm_phas void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payload) { - if (command == Command::RD || command == Command::WR) + if (commandIsIn(command, {Command::RD, Command::RDA, Command::WR, Command::WRA})) { sc_time execTime = Configuration::getInstance().memSpec->getExecutionTime(command); ScheduledCommand scheduledCommand(command, sc_time_stamp(), execTime, *payload); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp index ec859bde..61b04ff0 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp @@ -103,10 +103,18 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Bank bank) if (lastCommand.isValidCommand()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tCCD); + lastCommand = lastScheduledByCommand[Command::RDA]; + if (lastCommand.isValidCommand()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tCCD); + lastCommand = lastScheduledByCommand[Command::WR]; if (lastCommand.isValidCommand()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWTR); + lastCommand = lastScheduledByCommand[Command::WRA]; + if (lastCommand.isValidCommand()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWTR); + refreshChecker->delayToSatisfyRD(bank, earliestTimeToStart); } else if (command == Command::WR || command == Command::WRA) @@ -118,10 +126,18 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Bank bank) if (lastCommand.isValidCommand()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL); + lastCommand = lastScheduledByCommand[Command::RDA]; + if (lastCommand.isValidCommand()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL); + lastCommand = lastScheduledByCommand[Command::WR]; if (lastCommand.isValidCommand()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tCCD); + lastCommand = lastScheduledByCommand[Command::WRA]; + if (lastCommand.isValidCommand()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommand.getStart() + memSpec->tCCD); + refreshChecker->delayToSatisfyWR(bank, earliestTimeToStart); } else if (command == Command::PRE) diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp index 024beaf3..c640bd64 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp @@ -46,7 +46,7 @@ CmdMuxStrict::selectCommand(std::vector