diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.json b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.json index c31fc195..b38761e5 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.json +++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.json @@ -11,8 +11,11 @@ "RefreshMaxPulledin": 8, "PowerDownPolicy": "NoPowerDown", "PowerDownTimeout": 100, - "ArbitrationDelay": 0, - "ThinkDelay": 0, - "PhyDelay": 0 + "ArbitrationDelayFw": 0, + "ArbitrationDelayBw": 0, + "ThinkDelayFw": 0, + "ThinkDelayBw": 0, + "PhyDelayFw": 0, + "PhyDelayBw": 0 } } \ No newline at end of file diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 1cc1ae20..cdcee1af 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -181,12 +181,18 @@ void Configuration::setParameter(std::string name, nlohmann::json value) powerDownTimeout = value; else if (name == "MaxActiveTransactions") maxActiveTransactions = value; - else if (name == "ArbitrationDelay") - arbitrationDelay = memSpec->tCK * value; - else if (name == "ThinkDelay") - thinkDelay = memSpec->tCK * value; - else if (name == "PhyDelay") - phyDelay = memSpec->tCK * value; + else if (name == "ArbitrationDelayFw") + arbitrationDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; + else if (name == "ArbitrationDelayBw") + arbitrationDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; + else if (name == "ThinkDelayFw") + thinkDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; + else if (name == "ThinkDelayBw") + thinkDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; + else if (name == "PhyDelayFw") + phyDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; + else if (name == "PhyDelayBw") + phyDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; //SimConfig------------------------------------------------ else if (name == "SimulationName") simulationName = value; diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index 018a4ccf..7bcf88b7 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -82,9 +82,12 @@ public: enum class PowerDownPolicy {NoPowerDown, Staggered} powerDownPolicy; unsigned int powerDownTimeout = 3; unsigned int maxActiveTransactions = 64; - sc_time arbitrationDelay = SC_ZERO_TIME; - sc_time thinkDelay = SC_ZERO_TIME; - sc_time phyDelay = SC_ZERO_TIME; + sc_time arbitrationDelayFw = SC_ZERO_TIME; + sc_time arbitrationDelayBw = SC_ZERO_TIME; + sc_time thinkDelayFw = SC_ZERO_TIME; + sc_time thinkDelayBw = SC_ZERO_TIME; + sc_time phyDelayFw = SC_ZERO_TIME; + sc_time phyDelayBw = SC_ZERO_TIME; // SimConfig std::string simulationName = "default"; diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 5280a58d..5b729608 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -126,34 +126,27 @@ sc_time BankMachineOpen::start() timeToSchedule = sc_max_time(); nextCommand = Command::NOP; - if (sleeping) - return timeToSchedule; - - currentPayload = scheduler->getNextRequest(this); - if (currentPayload == nullptr) - return timeToSchedule; - - if (state == State::Precharged && !blocked) // row miss + if (!(sleeping || blocked)) { - nextCommand = Command::ACT; - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); - } - else if (state == State::Activated) - { - if (DramExtension::getRow(currentPayload) == openRow) // row hit + currentPayload = scheduler->getNextRequest(this); + if (currentPayload != nullptr) { - if (currentPayload->get_command() == TLM_READ_COMMAND) - nextCommand = Command::RD; - else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - nextCommand = Command::WR; - else - SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); - - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); - } - else if (!blocked) // row miss - { - nextCommand = Command::PRE; + if (state == State::Precharged) // bank precharged + nextCommand = Command::ACT; + else if (state == State::Activated) + { + if (DramExtension::getRow(currentPayload) == openRow) // row hit + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + nextCommand = Command::RD; + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + nextCommand = Command::WR; + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + else // row miss + nextCommand = Command::PRE; + } timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } } @@ -168,28 +161,24 @@ sc_time BankMachineClosed::start() timeToSchedule = sc_max_time(); nextCommand = Command::NOP; - if (sleeping) - return timeToSchedule; - - currentPayload = scheduler->getNextRequest(this); - if (currentPayload == nullptr) - return timeToSchedule; - - if (state == State::Precharged && !blocked) // row miss + if (!(sleeping || blocked)) { - nextCommand = Command::ACT; - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); - } - else if (state == State::Activated) - { - if (currentPayload->get_command() == TLM_READ_COMMAND) - nextCommand = Command::RDA; - else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - nextCommand = Command::WRA; - else - SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); - - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); + currentPayload = scheduler->getNextRequest(this); + if (currentPayload != nullptr) + { + if (state == State::Precharged) // bank precharged + nextCommand = Command::ACT; + else if (state == State::Activated) + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + nextCommand = Command::RDA; + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + nextCommand = Command::WRA; + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); + } } return timeToSchedule; } @@ -202,45 +191,39 @@ sc_time BankMachineOpenAdaptive::start() timeToSchedule = sc_max_time(); nextCommand = Command::NOP; - if (sleeping) - return timeToSchedule; - - currentPayload = scheduler->getNextRequest(this); - if (currentPayload == nullptr) - return timeToSchedule; - - if (state == State::Precharged && !blocked) // row miss + if (!(sleeping || blocked)) { - nextCommand = Command::ACT; - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); - } - else if (state == State::Activated) - { - if (DramExtension::getRow(currentPayload) == openRow) // row hit + currentPayload = scheduler->getNextRequest(this); + if (currentPayload != nullptr) { - if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, openRow)) + if (state == State::Precharged) // bank precharged + nextCommand = Command::ACT; + else if (state == State::Activated) { - if (currentPayload->get_command() == TLM_READ_COMMAND) - nextCommand = Command::RDA; - else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - nextCommand = Command::WRA; - else - SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + if (DramExtension::getRow(currentPayload) == openRow) // row hit + { + if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, openRow)) + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + nextCommand = Command::RDA; + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + nextCommand = Command::WRA; + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + else + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + nextCommand = Command::RD; + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + nextCommand = Command::WR; + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + } + else // row miss + nextCommand = Command::PRE; } - else - { - if (currentPayload->get_command() == TLM_READ_COMMAND) - nextCommand = Command::RD; - else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - nextCommand = Command::WR; - else - SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); - } - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); - } - else if (!blocked) // row miss - { - nextCommand = Command::PRE; timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } } @@ -255,48 +238,41 @@ sc_time BankMachineClosedAdaptive::start() timeToSchedule = sc_max_time(); nextCommand = Command::NOP; - if (sleeping) - return timeToSchedule; - - currentPayload = scheduler->getNextRequest(this); - if (currentPayload == nullptr) - return timeToSchedule; - - if (state == State::Precharged && !blocked) // row miss + if (!(sleeping || blocked)) { - nextCommand = Command::ACT; - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); - } - else if (state == State::Activated) - { - if (DramExtension::getRow(currentPayload) == openRow) // row hit + currentPayload = scheduler->getNextRequest(this); + if (currentPayload != nullptr) { - if (scheduler->hasFurtherRowHit(bank, openRow)) + if (state == State::Precharged && !blocked) // bank precharged + nextCommand = Command::ACT; + else if (state == State::Activated) { - if (currentPayload->get_command() == TLM_READ_COMMAND) - nextCommand = Command::RD; - else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - nextCommand = Command::WR; - else - SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); - } - else - { - if (currentPayload->get_command() == TLM_READ_COMMAND) - nextCommand = Command::RDA; - else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - nextCommand = Command::WRA; - else - SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + if (DramExtension::getRow(currentPayload) == openRow) // row hit + { + if (scheduler->hasFurtherRowHit(bank, openRow)) + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + nextCommand = Command::RD; + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + nextCommand = Command::WR; + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + else + { + if (currentPayload->get_command() == TLM_READ_COMMAND) + nextCommand = Command::RDA; + else if (currentPayload->get_command() == TLM_WRITE_COMMAND) + nextCommand = Command::WRA; + else + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + } + } + else // row miss, should never happen + SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy"); } timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } - else if (!blocked) // row miss TODO: remove this, can never happen - { - nextCommand = Command::PRE; - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); - SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy"); - } } return timeToSchedule; } diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 7e21d3cd..6fb9efda 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -72,7 +72,11 @@ Controller::Controller(sc_module_name name) : Configuration &config = Configuration::getInstance(); memSpec = config.memSpec; ranksNumberOfPayloads = std::vector(memSpec->numberOfRanks); - phyDelay = config.phyDelay; + + thinkDelayFw = config.thinkDelayFw; + thinkDelayBw = config.thinkDelayBw; + phyDelayFw = config.phyDelayFw; + phyDelayBw = config.phyDelayBw; // reserve buffer for command tuples readyCommands.reserve(memSpec->numberOfBanks); @@ -285,7 +289,7 @@ void Controller::controllerMethod() bankID < memSpec->banksPerRank; bankID += memSpec->banksPerGroup) bankMachinesOnRank[rank.ID()][bankID]->updateState(command); } - else + else // if (isBankCommand(command)) bankMachines[bank.ID()]->updateState(command); refreshManagers[rank.ID()]->updateState(command); @@ -295,19 +299,21 @@ void Controller::controllerMethod() if (isCasCommand(command)) { scheduler->removeRequest(payload); - respQueue->insertPayload(payload, sc_time_stamp() + phyDelay - + memSpec->getIntervalOnDataStrobe(command).end); + respQueue->insertPayload(payload, sc_time_stamp() + + thinkDelayFw + phyDelayFw + + memSpec->getIntervalOnDataStrobe(command).end + + phyDelayBw + thinkDelayBw); sc_time triggerTime = respQueue->getTriggerTime(); if (triggerTime != sc_max_time()) dataResponseEvent.notify(triggerTime - sc_time_stamp()); - ranksNumberOfPayloads[rank.ID()]--; + ranksNumberOfPayloads[rank.ID()]--; // TODO: move to a different place? } if (ranksNumberOfPayloads[rank.ID()] == 0) powerDownManagers[rank.ID()]->triggerEntry(); - sendToDram(command, payload); + sendToDram(command, payload, thinkDelayFw + phyDelayFw); } else readyCmdBlocked = true; @@ -455,8 +461,8 @@ void Controller::sendToFrontend(tlm_generic_payload *payload, tlm_phase phase, s tSocket->nb_transport_bw(*payload, phase, delay); } -void Controller::sendToDram(Command command, tlm_generic_payload *payload) +void Controller::sendToDram(Command command, tlm_generic_payload *payload, sc_time delay) { tlm_phase phase = commandToPhase(command); - iSocket->nb_transport_fw(*payload, phase, phyDelay); + iSocket->nb_transport_fw(*payload, phase, delay); } diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index 4a6e9c54..bf0e3db1 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -70,14 +70,17 @@ protected: virtual unsigned int transport_dbg(tlm::tlm_generic_payload &) override; virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase, sc_time); - virtual void sendToDram(Command, tlm::tlm_generic_payload *); + virtual void sendToDram(Command, tlm::tlm_generic_payload *, sc_time); virtual void controllerMethod(); SchedulerIF *scheduler; const MemSpec *memSpec; - sc_time phyDelay; + sc_time thinkDelayFw; + sc_time thinkDelayBw; + sc_time phyDelayFw; + sc_time phyDelayBw; private: unsigned totalNumberOfPayloads = 0; diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 74fbeb5e..bd548d50 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -71,17 +71,17 @@ void ControllerRecordable::sendToFrontend(tlm_generic_payload *payload, tlm_phas tSocket->nb_transport_bw(*payload, phase, delay); } -void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payload) +void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payload, sc_time delay) { if (isCasCommand(command)) { TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command); - tlmRecorder->updateDataStrobe(sc_time_stamp() + phyDelay + dataStrobe.start, - sc_time_stamp() + phyDelay + dataStrobe.end, *payload); + tlmRecorder->updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start, + sc_time_stamp() + delay + dataStrobe.end, *payload); } tlm_phase phase = commandToPhase(command); - iSocket->nb_transport_fw(*payload, phase, phyDelay); + iSocket->nb_transport_fw(*payload, phase, delay); } void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_time delay) diff --git a/DRAMSys/library/src/controller/ControllerRecordable.h b/DRAMSys/library/src/controller/ControllerRecordable.h index 8cba8e7a..c2efa334 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.h +++ b/DRAMSys/library/src/controller/ControllerRecordable.h @@ -51,7 +51,7 @@ protected: tlm::tlm_phase &phase, sc_time &delay) override; virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase, sc_time) override; - virtual void sendToDram(Command, tlm::tlm_generic_payload *) override; + virtual void sendToDram(Command, tlm::tlm_generic_payload *, sc_time) override; virtual void controllerMethod() override; diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 7aa15a7f..98cd8fe9 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -46,7 +46,8 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : sc_module(name), payloadEventQueue(this, &Arbiter::peqCallback), maxActiveTransactions(Configuration::getInstance().maxActiveTransactions), tCK(Configuration::getInstance().memSpec->tCK), - arbitrationDelay(Configuration::getInstance().arbitrationDelay) + arbitrationDelayFw(Configuration::getInstance().arbitrationDelayFw), + arbitrationDelayBw(Configuration::getInstance().arbitrationDelayBw) { iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw); tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw); @@ -178,7 +179,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase channelIsBusy[channelId] = true; tlm_phase tPhase = BEGIN_REQ; - sc_time tDelay = arbitrationDelay; + sc_time tDelay = arbitrationDelayFw; iSocket[static_cast(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay); } else @@ -198,7 +199,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase pendingRequests[channelId].pop(); tlm_phase tPhase = BEGIN_REQ; // do not send two requests in the same cycle - sc_time tDelay = tCK + arbitrationDelay; + sc_time tDelay = tCK + arbitrationDelayFw; iSocket[static_cast(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay); } else @@ -209,7 +210,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase if (!threadIsBusy[threadId]) { tlm_phase tPhase = BEGIN_RESP; - sc_time tDelay = arbitrationDelay; + sc_time tDelay = arbitrationDelayBw; tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay); if (returnValue == TLM_UPDATED) payloadEventQueue.notify(cbPayload, tPhase, tDelay); @@ -233,7 +234,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase pendingResponses[threadId].pop(); tlm_phase tPhase = BEGIN_RESP; // do not send two responses in the same cycle - sc_time tDelay = tCK + arbitrationDelay; + sc_time tDelay = tCK + arbitrationDelayBw; tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); if (returnValue == TLM_UPDATED) payloadEventQueue.notify(tPayload, tPhase, tDelay); diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 580665f4..46540dc9 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -90,7 +90,8 @@ protected: unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans); sc_time tCK; - sc_time arbitrationDelay; + sc_time arbitrationDelayFw; + sc_time arbitrationDelayBw; }; class ArbiterSimple final : public Arbiter