From ef011ad52cf6740122ba0a0dceec87fa6cb55dbd Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 22 Jul 2019 00:23:12 +0200 Subject: [PATCH] Ready for debugging. --- .../resources/configs/simulator/ddr3.xml | 2 +- .../library/src/controller/BankMachine.cpp | 84 +++- DRAMSys/library/src/controller/BankMachine.h | 21 +- DRAMSys/library/src/controller/CommandMux.cpp | 49 +- DRAMSys/library/src/controller/CommandMux.h | 18 +- .../library/src/controller/ControllerNew.cpp | 163 ++++++- .../library/src/controller/ControllerNew.h | 32 +- .../src/controller/core/ControllerCore.cpp | 4 +- .../src/controller/core/ControllerCore.h | 2 +- .../scheduling/checker/CheckerDDR3New.cpp | 443 +++++------------- .../core/scheduling/checker/CheckerDDR3New.h | 6 +- 11 files changed, 437 insertions(+), 387 deletions(-) diff --git a/DRAMSys/library/resources/configs/simulator/ddr3.xml b/DRAMSys/library/resources/configs/simulator/ddr3.xml index 1613737f..f43e4b8c 100644 --- a/DRAMSys/library/resources/configs/simulator/ddr3.xml +++ b/DRAMSys/library/resources/configs/simulator/ddr3.xml @@ -1,6 +1,6 @@ - + diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index dda0cd81..d372b4e1 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -1,12 +1,88 @@ #include "BankMachine.h" #include "Command.h" +#include "core/scheduling/checker/CheckerDDR3New.h" -BankMachine::BankMachine(ControllerNew *controller) : controller(controller) +BankMachine::BankMachine(ControllerNew *controller, SchedulerNew *scheduler, CheckerDDR3New *checker, Bank bank) + : controller(controller), scheduler(scheduler), checker(checker), bank(bank) {} + +void BankMachine::setCommandFinishedTime(sc_time time) { - + commandFinishedTime = time; } -void BankMachine::setResultReady(sc_time time) +tlm_generic_payload *BankMachine::getNextStateAndResult() { - resultReady = time; + tlm_generic_payload *payloadToReturn = nullptr; + + if (commandFinishedTime == sc_time_stamp()) + { + if (currentState == BmState::Activating) + currentState = BmState::Activated; + else if (currentState == BmState::Precharging) + currentState = BmState::Precharged; + else if (currentState == BmState::Reading || currentState == BmState::Writing) + { + currentState = BmState::Activated; + payloadToReturn = currentPayload; + currentPayload = nullptr; + } + else + SC_REPORT_FATAL("BankMachine", "Wrong command!"); + } + return payloadToReturn; +} + +void BankMachine::startBankMachine(sc_time minDelay) +{ + if (currentPayload == nullptr) + { + currentPayload = scheduler->getNextRequest(bank); + if (currentPayload == nullptr) + return; + } + if (currentState == BmState::Precharged) + { + sc_time delay = max(minDelay, checker->delayToSatisfyConstraints(Command::ACT, bank)); + controller->triggerEventAfterDelay(delay); + nextCommand = Command::ACT; + timeToSchedule = sc_time_stamp() + delay; + } + else if (currentState == BmState::Activated) + { + DramExtension extension = DramExtension::getExtension(currentPayload); + if (extension.getRow() == currentRow) + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + { + sc_time delay = max(minDelay, checker->delayToSatisfyConstraints(Command::RD, bank)); + controller->triggerEventAfterDelay(delay); + nextCommand = Command::RD; + timeToSchedule = sc_time_stamp() + delay; + } + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + { + sc_time delay = max(minDelay, checker->delayToSatisfyConstraints(Command::WR, bank)); + controller->triggerEventAfterDelay(delay); + nextCommand = Command::WR; + timeToSchedule = sc_time_stamp() + delay; + } + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + else + { + sc_time delay = max(minDelay, checker->delayToSatisfyConstraints(Command::PRE, bank)); + controller->triggerEventAfterDelay(delay); + nextCommand = Command::PRE; + timeToSchedule = sc_time_stamp() + delay; + } + } +} + +std::pair BankMachine::getNextCommand() +{ + if (timeToSchedule == sc_time_stamp()) + return std::pair(nextCommand, currentPayload); + else + return std::pair(Command::NOP, nullptr); } diff --git a/DRAMSys/library/src/controller/BankMachine.h b/DRAMSys/library/src/controller/BankMachine.h index 130bb0d7..c583d455 100644 --- a/DRAMSys/library/src/controller/BankMachine.h +++ b/DRAMSys/library/src/controller/BankMachine.h @@ -5,30 +5,43 @@ #include #include "../common/dramExtensions.h" #include "Command.h" +#include "SchedulerNew.h" using namespace tlm; class ControllerNew; +class SchedulerNew; +class CheckerDDR3New; enum class BmState { Precharged, - Activated + Activated, + Precharging, + Activating, + Reading, + Writing }; class BankMachine { public: - BankMachine(ControllerNew *); - void setResultReady(sc_time); + BankMachine(ControllerNew *, SchedulerNew *, CheckerDDR3New*, Bank); + void setCommandFinishedTime(sc_time); + tlm_generic_payload *getNextStateAndResult(); + void startBankMachine(sc_time minDelay); + std::pair getNextCommand(); private: tlm_generic_payload *currentPayload = nullptr; BmState currentState = BmState::Precharged; + Bank bank; Row currentRow = Row(0); Command nextCommand = Command::NOP; sc_time timeToSchedule = SC_ZERO_TIME; - sc_time resultReady = SC_ZERO_TIME; + sc_time commandFinishedTime = SC_ZERO_TIME; ControllerNew *controller; + SchedulerNew *scheduler; + CheckerDDR3New *checker; }; #endif // BANKMACHINE_H diff --git a/DRAMSys/library/src/controller/CommandMux.cpp b/DRAMSys/library/src/controller/CommandMux.cpp index 0f5db035..65d290a5 100644 --- a/DRAMSys/library/src/controller/CommandMux.cpp +++ b/DRAMSys/library/src/controller/CommandMux.cpp @@ -1,19 +1,42 @@ #include "CommandMux.h" #include "core/configuration/Configuration.h" -CommandMux::CommandMux(ControllerNew *controller) : - controller(controller), - state("CommandMux", &Configuration::getInstance()), - checker(Configuration::getInstance(), state) {} +CommandMux::CommandMux(ControllerNew *controller, ControllerState *state, std::map &bankMachines) : + controller(controller), state(state), bankMachines(bankMachines) {} -/* -void CommandMux::compute() +void CommandMux::insertPayload(tlm_generic_payload *payload) { - // Handling of backpressure from / to arbiter!!! - - /* END_RESP from arbiter: check for successful transaction, remove payload from response queue, numberOfPayloads-- - * END_RD / END_WR from DRAM: check for successful transaction, move payload from BM to response queue, send result to arbiter (delay??) - * BEGIN_REQ from arbiter: check for transaction, move to scheduler map - * Trigger by BM: get transactions from all BM, choose one, send one, change state on BM, postpone all BM to next point in time + payloadOrder.push(payload); +} + +void CommandMux::selectCommand() +{ + for (auto it : bankMachines) + { + std::pair result = it.second->getNextCommand(); + if (result.first != Command::NOP) + readyCommands.push_back(result); + } + for (auto it : readyCommands) + { + if (it.first == Command::ACT || it.first == Command::PRE) + { + controller->sendToDram(it.first, it.second); + readyCommands.clear(); + return; + } + } + for (auto it : readyCommands) + { + if (it.first == Command::RD || it.first == Command::WR) + { + if (it.second == payloadOrder.front()) + { + payloadOrder.pop(); + controller->sendToDram(it.first, it.second); + readyCommands.clear(); + return; + } + } + } } -*/ diff --git a/DRAMSys/library/src/controller/CommandMux.h b/DRAMSys/library/src/controller/CommandMux.h index 9312e57b..ba74115c 100644 --- a/DRAMSys/library/src/controller/CommandMux.h +++ b/DRAMSys/library/src/controller/CommandMux.h @@ -1,26 +1,30 @@ #ifndef COMMANDMUX_H #define COMMANDMUX_H +#include #include #include #include "ControllerState.h" -#include "core/scheduling/checker/CheckerDDR3New.h" +#include "BankMachine.h" +#include "ControllerNew.h" using namespace tlm; class ControllerNew; +class BankMachine; class CommandMux { public: - CommandMux(ControllerNew *); - SC_HAS_PROCESS(CommandMux); - void triggerEventAtTime(sc_time triggerTime); - void triggerEventQueueAtTime(sc_time triggerTime); + CommandMux(ControllerNew *, ControllerState*, std::map &); + void insertPayload(tlm_generic_payload *); + void selectCommand(); private: - ControllerState state; - CheckerDDR3New checker; + ControllerState *state; ControllerNew *controller; + std::queue payloadOrder; + std::map &bankMachines; + std::vector> readyCommands; }; #endif // COMMANDMUX_H diff --git a/DRAMSys/library/src/controller/ControllerNew.cpp b/DRAMSys/library/src/controller/ControllerNew.cpp index 4c41219c..8fff7670 100644 --- a/DRAMSys/library/src/controller/ControllerNew.cpp +++ b/DRAMSys/library/src/controller/ControllerNew.cpp @@ -3,26 +3,32 @@ #include "scheduler/FifoStrict.h" #include "../common/dramExtensions.h" #include "../common/protocol.h" +#include "core/scheduling/ScheduledCommand.h" ControllerNew::ControllerNew(sc_module_name name, TlmRecorder *tlmRecorder) : sc_module(name), tlmRecorder(tlmRecorder), debugManager(&DebugManager::getInstance()) { - SC_METHOD(control); + SC_METHOD(controllerMethod); sensitive << triggerEvent << triggerEventQueue; + dont_initialize(); tSocket.register_nb_transport_fw(this, &ControllerNew::nb_transport_fw); tSocket.register_transport_dbg(this, &ControllerNew::transport_dbg); iSocket.register_nb_transport_bw(this, &ControllerNew::nb_transport_bw); - for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++) - bankMachines[Bank(bankID)] = new BankMachine(this); - commandMux = new CommandMux(this); + state = new ControllerState("Controller", &Configuration::getInstance()); + checker = new CheckerDDR3New(Configuration::getInstance(), *state); scheduler = new SchedulerNew(); + for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++) + bankMachines[Bank(bankID)] = new BankMachine(this, scheduler, checker, Bank(bankID)); + commandMux = new CommandMux(this, state, bankMachines); } ControllerNew::~ControllerNew() { tlmRecorder->closeConnection(); + delete state; + delete checker; for (auto it : bankMachines) delete it.second; delete commandMux; @@ -32,18 +38,20 @@ ControllerNew::~ControllerNew() tlm_sync_enum ControllerNew::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) { + recordPhase(trans, phase, delay); sc_time notDelay = delay; if (phase == BEGIN_REQ) { notDelay += Configuration::getInstance().memSpec->clk; payloadToAcquire = &trans; + timeToAcquire = sc_time_stamp() + notDelay; } else if (phase = END_RESP) { // FIXME: synchronization! notDelay += Configuration::getInstance().memSpec->clk; - payloadToRelease = &trans; + timeToRelease = sc_time_stamp() + notDelay; } else { @@ -67,16 +75,12 @@ unsigned int ControllerNew::transport_dbg(tlm_generic_payload &trans) tlm_sync_enum ControllerNew::nb_transport_bw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) { - // only for END_RD and END_WR - if (phase == END_RD || phase == END_WR) - { - printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " + - delay.to_string()); - Bank bank = DramExtension::getExtension(trans).getBank(); - sc_time triggerTime = sc_time_stamp() + delay; - bankMachines[bank]->setResultReady(triggerTime); - triggerEventQueueAtTime(triggerTime); - } + recordPhase(trans, phase, delay); + printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " + + delay.to_string()); + Bank bank = DramExtension::getExtension(trans).getBank(); + bankMachines[bank]->setCommandFinishedTime(sc_time_stamp() + delay); + triggerEventQueue.notify(delay); return TLM_ACCEPTED; } @@ -104,17 +108,136 @@ void ControllerNew::recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_ tlmRecorder->recordPhase(trans, phase, recTime); } -void ControllerNew::triggerEventAtTime(sc_time triggerTime) +void ControllerNew::triggerEventAfterDelay(sc_time delay) { - triggerEvent.notify(triggerTime); + triggerEvent.notify(delay); } -void ControllerNew::triggerEventQueueAtTime(sc_time triggerTime) +void ControllerNew::triggerEventQueueAfterDelay(sc_time delay) { - triggerEventQueue.notify(triggerTime); + triggerEventQueue.notify(delay); } -void ControllerNew::control() +void ControllerNew::controllerMethod() { + std::cout << sc_time_stamp() << std::endl; + releasePayload(); + acquirePayload(); + getNextBmStates(); + sendToFrontend(); + startBankMachines(); + commandMux->selectCommand(); + restartBankMachines(); +} + +void ControllerNew::releasePayload() +{ + if (sc_time_stamp() == timeToRelease /*&& payloadToRelease != nullptr*/) + { + responseQueue.pop(); + payloadToRelease->release(); + payloadToRelease = nullptr; + numberOfPayloads--; + // TODO: insert payload ID + printDebugMessage("Payload ID left system."); + } +} + +void ControllerNew::acquirePayload() +{ + if (sc_time_stamp() >= timeToAcquire && payloadToAcquire != nullptr) + { + if (numberOfPayloads < Configuration::getInstance().MaxNrOfTransactions) + { + payloadToAcquire->acquire(); + scheduler->storeRequest(payloadToAcquire); + commandMux->insertPayload(payloadToAcquire); + payloadToAcquire = nullptr; + numberOfPayloads++; + // TODO: insert payload ID + printDebugMessage("Payload ID entered system."); + payloadToAcquire->set_response_status(TLM_OK_RESPONSE); + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + recordPhase(*payloadToAcquire, tPhase, tDelay); + tSocket->nb_transport_bw(*payloadToAcquire, tPhase, tDelay); + } + else + printDebugMessage("Total number of payloads exceeded, backpressure!"); + } +} + +void ControllerNew::sendToFrontend() +{ + if (payloadToRelease == nullptr) + { + if (!responseQueue.empty()) + { + payloadToRelease = responseQueue.front(); + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + tSocket->nb_transport_bw(*payloadToRelease, tPhase, tDelay); + } + } +} + +void ControllerNew::getNextBmStates() +{ + for (auto it : bankMachines) + { + tlm_generic_payload *result = it.second->getNextStateAndResult(); + if (result != nullptr) + { + responseQueue.push(result); + } + } } + +void ControllerNew::startBankMachines() +{ + for (auto it : bankMachines) + it.second->startBankMachine(SC_ZERO_TIME); +} + +void ControllerNew::restartBankMachines() +{ + sc_time minDelay = Configuration::getInstance().memSpec->clk; + for (auto it : bankMachines) + it.second->startBankMachine(minDelay); +} + +void ControllerNew::sendToDram(Command command, tlm_generic_payload *payload) +{ + sc_time execTime = Configuration::getInstance().memSpec->getExecutionTime(command, *payload); + ScheduledCommand scheduledCommand(command, sc_time_stamp(), execTime, *payload); + state->cleanUp(sc_time_stamp()); + state->change(scheduledCommand); + + sc_time delay = SC_ZERO_TIME; + tlm_phase phase; + if (command == Command::ACT) + phase = BEGIN_ACT; + else if (command == Command::PRE) + phase = BEGIN_PRE; + else if (command == Command::RD) + phase = BEGIN_RD; + else if (command == Command::WR) + phase = BEGIN_WR; + else + SC_REPORT_FATAL("ControllerNew", "Unknown phase"); + iSocket->nb_transport_fw(*payload, phase, delay); +} + + +//void CommandMux::compute() +//{ +// // Handling of backpressure from / to arbiter!!! + +// /* END_RESP from arbiter: check for successful transaction, remove payload from response queue, numberOfPayloads-- +// * END_RD / END_WR from DRAM: check for successful transaction, move payload from BM to response queue, send result to arbiter (delay??) +// * BEGIN_REQ from arbiter: check for transaction, move to scheduler map +// * Trigger by BM: get transactions from all BM, choose one, send one, change state on BM, postpone all BM to next point in time +// */ +//} + diff --git a/DRAMSys/library/src/controller/ControllerNew.h b/DRAMSys/library/src/controller/ControllerNew.h index 5210a2d2..0e161c6a 100644 --- a/DRAMSys/library/src/controller/ControllerNew.h +++ b/DRAMSys/library/src/controller/ControllerNew.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -13,10 +14,14 @@ #include "SchedulerNew.h" #include "../common/TlmRecorder.h" #include "../common/DebugManager.h" +#include "core/scheduling/checker/CheckerDDR3New.h" +#include "ControllerState.h" using namespace tlm; class SchedulerNew; +class BankMachine; +class CommandMux; class ControllerNew : public sc_module { @@ -28,8 +33,16 @@ public: tlm_utils::simple_target_socket tSocket; tlm_utils::simple_initiator_socket iSocket; - void triggerEventAtTime(sc_time triggerTime); - void triggerEventQueueAtTime(sc_time triggerTime); + void triggerEventAfterDelay(sc_time); + void triggerEventQueueAfterDelay(sc_time); + + ControllerState *state; + std::map bankMachines; + CommandMux *commandMux; + SchedulerNew *scheduler; + CheckerDDR3New *checker; + + void sendToDram(Command, tlm_generic_payload *); private: tlm_sync_enum nb_transport_fw(tlm_generic_payload &trans, @@ -40,19 +53,24 @@ private: void printDebugMessage(string message); void recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_time delay); + void releasePayload(); + void acquirePayload(); + void getNextBmStates(); + void sendToFrontend(); + void startBankMachines(); + void restartBankMachines(); + unsigned numberOfPayloads = 0; tlm_generic_payload *payloadToAcquire = nullptr; + sc_time timeToAcquire = SC_ZERO_TIME; tlm_generic_payload *payloadToRelease = nullptr; + sc_time timeToRelease = SC_ZERO_TIME; std::queue responseQueue; - std::map bankMachines; - CommandMux *commandMux; - SchedulerNew *scheduler; - TlmRecorder *tlmRecorder; DebugManager *debugManager; - void control(); + void controllerMethod(); sc_event triggerEvent; sc_event_queue triggerEventQueue; }; diff --git a/DRAMSys/library/src/controller/core/ControllerCore.cpp b/DRAMSys/library/src/controller/core/ControllerCore.cpp index 4ec38ff6..8b5c87ab 100644 --- a/DRAMSys/library/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/library/src/controller/core/ControllerCore.cpp @@ -87,7 +87,7 @@ ControllerCore::ControllerCore(sc_module_name /*name*/, commandChecker[Command::PDXP] = commandChecker[Command::PDEA]; commandChecker[Command::SREFEX] = commandChecker[Command::PDEA]; - timingChecker = new CheckerDDR3New(config, *state); + //timingChecker = new CheckerDDR3New(config, *state); // if (config.RowGranularRef) { // refreshManager = new RGR("RGR", *this); @@ -127,7 +127,7 @@ ControllerCore::~ControllerCore() delete commandChecker[Command::WR]; delete commandChecker[Command::REFA]; delete commandChecker[Command::PDEA]; - delete timingChecker; + //delete timingChecker; //delete refreshManager; //delete powerDownManager; delete state; diff --git a/DRAMSys/library/src/controller/core/ControllerCore.h b/DRAMSys/library/src/controller/core/ControllerCore.h index 291ba905..424998f3 100644 --- a/DRAMSys/library/src/controller/core/ControllerCore.h +++ b/DRAMSys/library/src/controller/core/ControllerCore.h @@ -85,7 +85,7 @@ private: ScheduledCommand schedule(Command command, sc_time start, tlm::tlm_generic_payload &payload); std::map commandChecker; - ICommandChecker *timingChecker; + //ICommandChecker *timingChecker; void printDebugMessage(string message); }; diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/CheckerDDR3New.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/CheckerDDR3New.cpp index 451158cf..696f7b02 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/CheckerDDR3New.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/CheckerDDR3New.cpp @@ -11,365 +11,158 @@ using namespace std; -void CheckerDDR3New::delayToSatisfyConstraints(ScheduledCommand &command) const +sc_time CheckerDDR3New::delayToSatisfyConstraints(Command command, Bank bank) { - ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank()); - Command LastCmd = lastCommandOnBank.getCommand(); - Command nextCmd = command.getCommand(); ScheduledCommand lastCommand; - if (nextCmd == Command::ACT) + sc_time minTimeToWait = sc_time_stamp(); + + if (command == Command::ACT) { - // TODO: WRA_bank0 -> PREA -> ACT_bank0: WRA_bank0 and ACT_bank0 have TD, - // but we only consider PREA -> ACT_bank0 TD - // REFA -> PDEP -> PDXP -> ACT - lastCommand = state.getLastCommand(Command::RDA, command.getBank()); + lastCommand = state.getLastCommand(Command::RDA, bank); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP + memSpec->tRP); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRTP + memSpec->tRP); - lastCommand = state.getLastCommand(Command::WRA, command.getBank()); + lastCommand = state.getLastCommand(Command::WRA, bank); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP); - lastCommand = state.getLastCommand(Command::PRE, command.getBank()); + lastCommand = state.getLastCommand(Command::PRE, bank); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRP); - lastCommand = state.getLastCommand(Command::PREA, command.getBank()); + lastCommand = state.getLastCommand(Command::PREA, bank); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRP); - lastCommand = state.getLastCommand(Command::PDXA, command.getBank()); + lastCommand = state.getLastCommand(Command::PDXA, bank); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); - lastCommand = state.getLastCommand(Command::PDXP, command.getBank()); + lastCommand = state.getLastCommand(Command::PDXP, bank); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); - lastCommand = state.getLastCommand(Command::REFA, command.getBank()); + lastCommand = state.getLastCommand(Command::REFA, bank); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRFC); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRFC); - lastCommand = state.getLastCommand(Command::SREFEX, command.getBank()); + lastCommand = state.getLastCommand(Command::SREFEX, bank); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXS); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXS); - lastCommand = state.getLastCommand(Command::ACT, command.getBank()); + lastCommand = state.getLastCommand(Command::ACT, bank); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRC); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRC); - while (!(state.bus.isFree(command.getStart()) && satsfiesACTtoACTdifferentBank(command) && satisfiesNActivateWindow(command))) - command.delayStart(memSpec->clk); - } - else if (nextCmd == Command::RD || nextCmd == Command::RDA) - { - lastCommand = state.getLastCommand(Command::ACT, command.getBank()); - //if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRCD); - - lastCommand = state.getLastCommand(Command::RD, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCCD); - - lastCommand = state.getLastCommand(Command::WR, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWTR); - - lastCommand = state.getLastCommand(Command::PDXA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP); - - lastCommand = state.getLastCommand(Command::SREFEX, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXSDLL); - - while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe_RD(command)) - command.delayStart(memSpec->clk); - } - else if (nextCmd == Command::WR || nextCmd == Command::WRA) - { - lastCommand = state.getLastCommand(Command::ACT, command.getBank()); - //if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRCD); - - lastCommand = state.getLastCommand(Command::RD, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL); - - lastCommand = state.getLastCommand(Command::WR, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCCD); - - lastCommand = state.getLastCommand(Command::PDXA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP); - - lastCommand = state.getLastCommand(Command::SREFEX, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXSDLL); - - while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe_WR(command)) - command.delayStart(memSpec->clk); - } - else if (nextCmd == Command::PRE) - { - lastCommand = state.getLastCommand(Command::ACT, command.getBank()); - //if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRAS); - - lastCommand = state.getLastCommand(Command::RD, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP); - - lastCommand = state.getLastCommand(Command::WR, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR); - - lastCommand = state.getLastCommand(Command::PDXA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP); - - state.bus.moveCommandToNextFreeSlot(command); - } - else if (nextCmd == Command::PREA) - { - lastCommand = state.getLastCommand(Command::ACT); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRAS); - - lastCommand = state.getLastCommand(Command::RD); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP); - - lastCommand = state.getLastCommand(Command::RDA); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP); - - lastCommand = state.getLastCommand(Command::WR); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR); - - lastCommand = state.getLastCommand(Command::WRA); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR); - - lastCommand = state.getLastCommand(Command::PDXA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP); - - lastCommand = state.getLastCommand(Command::REFA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRFC); - - state.bus.moveCommandToNextFreeSlot(command); - } - else if (nextCmd == Command::PDEA) - { - // TODO: Remove? - lastCommand = state.getLastCommand(Command::ACT); - //if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk); - - lastCommand = state.getLastCommand(Command::RD); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk); - - lastCommand = state.getLastCommand(Command::RDA); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk); - - lastCommand = state.getLastCommand(Command::WR); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + 4 * memSpec->clk + memSpec->tWR); - - lastCommand = state.getLastCommand(Command::WRA); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + 5 * memSpec->clk + memSpec->tWR); - - // TODO: Remove? - lastCommand = state.getLastCommand(Command::PRE); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk); - - lastCommand = state.getLastCommand(Command::PDXA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKE); - - state.bus.moveCommandToNextFreeSlot(command); - } - else if (nextCmd == Command::PDEP) - { - lastCommand = state.getLastCommand(Command::RD); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk); - - lastCommand = state.getLastCommand(Command::RDA); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk); - - lastCommand = state.getLastCommand(Command::WRA); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + 5 * memSpec->clk + memSpec->tWR); - - // TODO: Remove? - lastCommand = state.getLastCommand(Command::PRE); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk); - - // TODO: Remove? - lastCommand = state.getLastCommand(Command::PREA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk); - - lastCommand = state.getLastCommand(Command::PDXP, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKE); - - // TODO: Remove? - lastCommand = state.getLastCommand(Command::REFA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk); - - lastCommand = state.getLastCommand(Command::SREFEX, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXS); - - state.bus.moveCommandToNextFreeSlot(command); - } - else if (nextCmd == Command::SREFEN) - { - lastCommand = state.getLastCommand(Command::RDA); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk); - - lastCommand = state.getLastCommand(Command::WRA); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + 5 * memSpec->clk + memSpec->tWR); - - lastCommand = state.getLastCommand(Command::PRE); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP); - - lastCommand = state.getLastCommand(Command::PREA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP); - - lastCommand = state.getLastCommand(Command::PDXP, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP); - - lastCommand = state.getLastCommand(Command::SREFEX, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXS); - - state.bus.moveCommandToNextFreeSlot(command); - } - else if (nextCmd == Command::PDXA) - { - lastCommand = state.getLastScheduledCommand(command.getBank()); - if (lastCommand.getCommand() != Command::PDEA) - reportFatal("CheckerDDR3New", "PDXA can not follow " + commandToString(lastCommand.getCommand())); - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKE); - - state.bus.moveCommandToNextFreeSlot(command); - } - else if (nextCmd == Command::PDXP) - { - lastCommand = state.getLastScheduledCommand(command.getBank()); - if (lastCommand.getCommand() != Command::PDEP) - reportFatal("CheckerDDR3New", "PDXP can not follow " + commandToString(lastCommand.getCommand())); - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKE); - - state.bus.moveCommandToNextFreeSlot(command); - } - else if (nextCmd == Command::SREFEX) - { - lastCommand = state.getLastScheduledCommand(command.getBank()); - if (lastCommand.getCommand() != Command::SREFEN) - reportFatal("CheckerDDR3New", "SREFEX can not follow " + commandToString(lastCommand.getCommand())); - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKESR); - - state.bus.moveCommandToNextFreeSlot(command); - } - else if (nextCmd == Command::REFA) - { - // TODO: Bankwise logic - if (config.BankwiseLogic) + for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++) { - if (lastCommandOnBank.isValidCommand()) - { - switch (LastCmd) - { - case Command::PRE: - case Command::PREA: - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - memSpec->tRP_old); - break; - case Command::RDA: - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - memSpec->tRTP + memSpec->tRP_old); - break; - case Command::WRA: - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - memSpec->tWL + memSpec->getWriteAccessTime() - + memSpec->tWR + memSpec->tRP_old); - break; - case Command::REFA: - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - memSpec->tRFC_old); - break; - case Command::PDXP: - case Command::PDXA: - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - memSpec->tXP); - break; - case Command::SREFEX: - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - memSpec->tXS); - break; - default: - reportFatal("CheckerDDR3New", - "Refresh can not follow " + commandToString(LastCmd)); - } - } + lastCommand = state.getLastCommand(Command::ACT, Bank(bankID)); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRRD); } - else + + if (!state.bus.isFree(sc_time_stamp())) + minTimeToWait = max(minTimeToWait, sc_time_stamp() + memSpec->clk); + } + else if (command == Command::RD || command == Command::RDA) + { + lastCommand = state.getLastCommand(Command::ACT, bank); + //if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRCD); + +// lastCommand = state.getLastCommand(Command::RD, bank); +// if (lastCommand.isValidCommand()) +// minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD); + +// lastCommand = state.getLastCommand(Command::WR, bank); +// if (lastCommand.isValidCommand()) +// minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWTR); + + lastCommand = state.getLastCommand(Command::PDXA, bank); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); + + lastCommand = state.getLastCommand(Command::SREFEX, bank); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXSDLL); + + if (!state.bus.isFree(sc_time_stamp())) + minTimeToWait = max(minTimeToWait, sc_time_stamp() + memSpec->clk); + + for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++) { - lastCommand = state.getLastCommand(Command::RDA); + lastCommand = state.getLastCommand(Command::RD, Bank(bankID)); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP + memSpec->tRP); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD); - lastCommand = state.getLastCommand(Command::WRA); + lastCommand = state.getLastCommand(Command::WR, Bank(bankID)); if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP); - - lastCommand = state.getLastCommand(Command::PRE); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP); - - lastCommand = state.getLastCommand(Command::PREA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP); - - lastCommand = state.getLastCommand(Command::PDXP, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP); - - lastCommand = state.getLastCommand(Command::REFA, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRFC); - - lastCommand = state.getLastCommand(Command::SREFEX, command.getBank()); - if (lastCommand.isValidCommand()) - command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXS); + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWTR); } - state.bus.moveCommandToNextFreeSlot(command); + } + else if (command == Command::WR || command == Command::WRA) + { + lastCommand = state.getLastCommand(Command::ACT, bank); + //if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRCD); + +// lastCommand = state.getLastCommand(Command::RD, bank); +// if (lastCommand.isValidCommand()) +// minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL); + +// lastCommand = state.getLastCommand(Command::WR, bank); +// if (lastCommand.isValidCommand()) +// minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD); + + lastCommand = state.getLastCommand(Command::PDXA, bank); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); + + lastCommand = state.getLastCommand(Command::SREFEX, bank); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXSDLL); + + if (!state.bus.isFree(sc_time_stamp())) + minTimeToWait = max(minTimeToWait, sc_time_stamp() + memSpec->clk); + + for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++) + { + lastCommand = state.getLastCommand(Command::RD, Bank(bankID)); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL); + + lastCommand = state.getLastCommand(Command::WR, Bank(bankID)); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD); + } + } + else if (command == Command::PRE) + { + lastCommand = state.getLastCommand(Command::ACT, bank); + //if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRAS); + + lastCommand = state.getLastCommand(Command::RD, bank); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRTP); + + lastCommand = state.getLastCommand(Command::WR, bank); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWR); + + lastCommand = state.getLastCommand(Command::PDXA, bank); + if (lastCommand.isValidCommand()) + minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP); + + if (!state.bus.isFree(sc_time_stamp())) + minTimeToWait = max(minTimeToWait, sc_time_stamp() + memSpec->clk); } else { reportFatal("CheckerDDR3New", "Unknown command!"); } + return (minTimeToWait - sc_time_stamp()); } /* diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/CheckerDDR3New.h b/DRAMSys/library/src/controller/core/scheduling/checker/CheckerDDR3New.h index 6daff0dc..349b250d 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/CheckerDDR3New.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/CheckerDDR3New.h @@ -6,7 +6,7 @@ #include "../../../ControllerState.h" //Activate -class CheckerDDR3New : public ICommandChecker +class CheckerDDR3New { public: CheckerDDR3New(const Configuration &config, @@ -16,9 +16,9 @@ public: if (memSpec == nullptr) SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen"); } - virtual ~CheckerDDR3New() {} + ~CheckerDDR3New() {} - virtual void delayToSatisfyConstraints(ScheduledCommand &command) const override; + sc_time delayToSatisfyConstraints(Command command, Bank bank); private: MemSpecDDR3 *memSpec;