diff --git a/dram/resources/configs/memconfigs/memconfig.xml b/dram/resources/configs/memconfigs/memconfig.xml index e21c26b4..c1dc5677 100644 --- a/dram/resources/configs/memconfigs/memconfig.xml +++ b/dram/resources/configs/memconfigs/memconfig.xml @@ -1,10 +1,10 @@ - + - + diff --git a/dram/src/common/Utils.cpp b/dram/src/common/Utils.cpp index 2b9fd287..c6e6a757 100644 --- a/dram/src/common/Utils.cpp +++ b/dram/src/common/Utils.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "dramExtension.h" using namespace std; using namespace tinyxml2; @@ -139,3 +140,15 @@ string loadTextFileContents(string filename) return ""; } } + +void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank) +{ + payload.set_address(bank.getStartAddress()); + payload.set_command(tlm::TLM_READ_COMMAND); + payload.set_data_length(0); + payload.set_response_status(tlm::TLM_OK_RESPONSE); + payload.set_dmi_allowed(false); + payload.set_byte_enable_length(0); + payload.set_streaming_width(0); + payload.set_extension(new DramExtension(Thread(0), bank, bank.getBankGroup(), Row(0), Column(0))); //payload takes ownership +} diff --git a/dram/src/common/Utils.h b/dram/src/common/Utils.h index 209a54a0..bb0a60cd 100644 --- a/dram/src/common/Utils.h +++ b/dram/src/common/Utils.h @@ -13,7 +13,7 @@ #include #include #include - +#include "dramExtension.h" #include "third_party/tinyxml2.h" template @@ -49,4 +49,6 @@ std::string queryStringParameter(tinyxml2::XMLElement* node, std::string name); bool queryBoolParameter(tinyxml2::XMLElement* node, std::string name); double queryDoubleParameter(tinyxml2::XMLElement* node, std::string name); +void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank); + #endif /* UTILS_COMMON_H_ */ diff --git a/dram/src/common/dramExtension.cpp b/dram/src/common/dramExtension.cpp index ec2adb0f..46c59eee 100644 --- a/dram/src/common/dramExtension.cpp +++ b/dram/src/common/dramExtension.cpp @@ -12,7 +12,10 @@ DramExtension& DramExtension::getExtension(const tlm_generic_payload *payload) { DramExtension *result = NULL; payload->get_extension(result); - assert(result != NULL); + if(result == NULL) + { + SC_REPORT_FATAL("DRAM Extension","Extension is null."); + } return *result; } @@ -36,7 +39,6 @@ bool operator <(const Thread& lhs, const Thread& rhs) return lhs.ID() < rhs.ID(); } - bool operator ==(const Channel& lhs, const Channel& rhs) { return lhs.ID() == rhs.ID(); @@ -52,11 +54,12 @@ BankGroup Bank::getBankGroup() static std::map bankgroups; if (bankgroups.size() == 0) { + core::Configuration& config = core::Configuration::getInstance(); SC_ASSERT_(config.NumberOfBanks % config.NumberOfBankGroups == 0, "Number of banks must be a multiple of number of bankgroups"); - for (unsigned int bank = 0; bank < core::Configuration::getInstance().NumberOfBanks; bank++) + for (unsigned int bank = 0; bank < config.NumberOfBanks; bank++) { - unsigned int group = bank % core::Configuration::getInstance().NumberOfBankGroups; + unsigned int group = bank % config.NumberOfBankGroups; bankgroups.insert(std::pair(Bank(bank), BankGroup(group))); } } @@ -88,12 +91,17 @@ bool operator <(const Bank& lhs, const Bank& rhs) return lhs.ID() < rhs.ID(); } - const Row Row::NO_ROW; +const Row Row::operator ++() +{ + id = (id + 1) % core::Configuration::getInstance().NumberOfRows; + return *this; +} + bool operator ==(const Row& lhs, const Row& rhs) { - if(lhs.isNoRow != rhs.isNoRow) + if (lhs.isNoRow != rhs.isNoRow) return false; return lhs.ID() == rhs.ID(); } @@ -113,4 +121,53 @@ bool operator !=(const Column& lhs, const Column& rhs) return !(lhs == rhs); } +tlm_extension_base* DramExtension::clone() const +{ + return new DramExtension(thread, bank, bankgroup, row, column, burstlength); +} +void DramExtension::copy_from(const tlm_extension_base& ext) +{ + const DramExtension& cpyFrom = static_cast(ext); + thread = cpyFrom.thread; + bank = cpyFrom.bank; + bankgroup = cpyFrom.bankgroup; + row = cpyFrom.row; + column = cpyFrom.column; + burstlength = cpyFrom.burstlength; +} +const Thread& DramExtension::getThread() const +{ + return thread; +} +const Channel& DramExtension::getChannel() const +{ + return channel; +} +const Bank& DramExtension::getBank() const +{ + return bank; +} +const BankGroup& DramExtension::getBankGroup() const +{ + return bankgroup; +} + +const Row& DramExtension::getRow() const +{ + return row; +} + +const Column& DramExtension::getColumn() const +{ + return column; +} +const unsigned int DramExtension::getBurstlength() const +{ + return burstlength; +} + +void DramExtension::increaseRow() +{ + ++row; +} diff --git a/dram/src/common/dramExtension.h b/dram/src/common/dramExtension.h index 3c377c3a..fa5b19fd 100644 --- a/dram/src/common/dramExtension.h +++ b/dram/src/common/dramExtension.h @@ -98,6 +98,8 @@ public: { return id; } + + const Row operator++(); private: unsigned int id; bool isNoRow; @@ -157,71 +159,39 @@ public: thread(0), channel(0), bank(0), bankgroup(0), row(0), column(0), burstlength(0) { } - DramExtension(const Thread& thread, const Bank& bank, const BankGroup& bankgroup, - const Row& row, const Column& column, unsigned int burstlength = 0) : - thread(thread), channel(0), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength( - burstlength) + DramExtension(const Thread& thread, const Bank& bank, const BankGroup& bankgroup, const Row& row, const Column& column, + unsigned int burstlength = 0) : + thread(thread), channel(0), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength) { } - DramExtension(const Thread& thread, const Channel& channel, const Bank& bank, - const BankGroup& bankgroup, const Row& row, const Column& column, - unsigned int burstlength = 0) : - thread(thread), channel(channel), bank(bank), bankgroup(bankgroup), row(row), column( - column), burstlength(burstlength) + DramExtension(const Thread& thread, const Channel& channel, const Bank& bank, const BankGroup& bankgroup, const Row& row, + const Column& column, unsigned int burstlength = 0) : + thread(thread), channel(channel), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength) { } ~DramExtension() { } - virtual tlm_extension_base* clone() const - { - return new DramExtension(thread, bank, bankgroup, row, column, burstlength); - } - virtual void copy_from(const tlm_extension_base& ext) - { - const DramExtension& cpyFrom = static_cast(ext); - thread = cpyFrom.thread; - bank = cpyFrom.bank; - bankgroup = cpyFrom.bankgroup; - row = cpyFrom.row; - column = cpyFrom.column; - burstlength = cpyFrom.burstlength; - } - const Thread& getThread() const - { - return thread; - } - const Channel& getChannel() const - { - return channel; - } - const Bank& getBank() const - { - return bank; - } - const BankGroup& getBankGroup() const - { - return bankgroup; - } - const Row& getRow() const - { - return row; - } - const Column& getColumn() const - { - return column; - } - const unsigned int getBurstlength() const - { - return burstlength; - } + virtual tlm_extension_base* clone() const; + virtual void copy_from(const tlm_extension_base& ext); - void setRow(const Row& row) - { - this->row = row; - } + const Thread& getThread() const; + + const Channel& getChannel() const; + + const Bank& getBank() const; + + const BankGroup& getBankGroup() const; + + const Row& getRow() const; + + const Column& getColumn() const; + + const unsigned int getBurstlength() const; + + void increaseRow(); static DramExtension& getExtension(const tlm::tlm_generic_payload *payload); static DramExtension& getExtension(const tlm::tlm_generic_payload &payload); diff --git a/dram/src/core/ControllerCore.cpp b/dram/src/core/ControllerCore.cpp index d8fdd2b0..86abdbd9 100644 --- a/dram/src/core/ControllerCore.cpp +++ b/dram/src/core/ControllerCore.cpp @@ -12,23 +12,22 @@ #include "scheduling/checker/PrechargeAllChecker.h" #include "scheduling/checker/ReadChecker.h" #include "scheduling/checker/WriteChecker.h" +#include "scheduling/checker/RefreshChecker.h" #include "refresh/RefreshManagerBankwise.h" #include "refresh/RefreshManager.h" #include "../common/dramExtension.h" #include "../common/Utils.h" #include "powerdown/PowerDownManager.h" -#include "powerdown/PowerDownManagerGrouped.h" +#include "powerdown/PowerDownManagerBankwise.h" #include "../common/DebugManager.h" namespace core { std::string ControllerCore::senderName = "Controller Core"; -ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, - std::map& numberOfPayloads) : +ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map& numberOfPayloads) : config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), commandChecker(), numberOfPayloads( - numberOfPayloads), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler( - *this) + numberOfPayloads), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(*this) { commandChecker[Command::Activate] = new ActivateChecker(config, state); @@ -39,15 +38,17 @@ ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, commandChecker[Command::Write] = new WriteChecker(config, state); commandChecker[Command::WriteA] = commandChecker[Command::Write]; + commandChecker[Command::AutoRefresh] = new RefreshChecker(config, state); + if (config.BankwiseLogic) { refreshManager = new RefreshManagerBankwise(*this); - powerDownManager = new PowerDownManager(*this); + powerDownManager = new PowerDownManagerBankwise(*this); } else { refreshManager = new RefreshManager(*this); - powerDownManager = new PowerDownManagerGrouped(*this); + powerDownManager = new PowerDownManager(*this); } } @@ -57,6 +58,7 @@ ControllerCore::~ControllerCore() delete commandChecker[Command::Precharge]; delete commandChecker[Command::Read]; delete commandChecker[Command::Write]; + delete commandChecker[Command::AutoRefresh]; delete refreshManager; delete powerDownManager; } @@ -78,32 +80,12 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time t state.cleanUp(time); - if (refreshManager->isInvalidated(payload, time)) - return; - - if (config.BankwiseLogic) + if (!refreshManager->isInvalidated(payload, time) && !powerDownManager->isInSelfRefresh(bank)) { - if (!powerDownManager->isInSelfRefresh(bank)) - { - printDebugMessage("Waking up bank " + to_string(bank.ID()) + " for refresh"); - powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay - refreshManager->scheduleRefresh(payload, time); - } + printDebugMessage("Waking up bank " + to_string(bank.ID()) + " for refresh"); + powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay + refreshManager->scheduleRefresh(payload, time); } - else if (!config.BankwiseLogic) - { - if (!powerDownManager->allBanksInSelfRefresh()) - { - printDebugMessage("Waking up all banks for refresh"); - powerDownManager->wakeUpAllForRefresh(time); - refreshManager->scheduleRefresh(payload, time); - } - } -} - -void ControllerCore::triggerWakeUp(tlm::tlm_generic_payload& payload, sc_time time) -{ - powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), time); } bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& payload) diff --git a/dram/src/core/ControllerCore.h b/dram/src/core/ControllerCore.h index 0e3d7d19..1ab399c4 100644 --- a/dram/src/core/ControllerCore.h +++ b/dram/src/core/ControllerCore.h @@ -47,7 +47,7 @@ public: ControllerState state; IWrapperConnector& wrapper; - PowerDownManager* powerDownManager; + IPowerDownManager* powerDownManager; IRefreshManager* refreshManager; std::map& numberOfPayloads; static std::string senderName; diff --git a/dram/src/core/ControllerState.cpp b/dram/src/core/ControllerState.cpp index c2cb15d0..96234288 100644 --- a/dram/src/core/ControllerState.cpp +++ b/dram/src/core/ControllerState.cpp @@ -7,7 +7,7 @@ #include "ControllerState.h" #include -#include "utils/Utils.h" +#include "TimingCalculation.h" namespace core { diff --git a/dram/src/core/Slots.cpp b/dram/src/core/Slots.cpp index 02079aea..8e1cacc4 100644 --- a/dram/src/core/Slots.cpp +++ b/dram/src/core/Slots.cpp @@ -6,7 +6,7 @@ */ #include "Slots.h" -#include "utils/Utils.h" +#include "TimingCalculation.h" namespace core { diff --git a/dram/src/core/TimingCalculation.cpp b/dram/src/core/TimingCalculation.cpp new file mode 100644 index 00000000..643b02a7 --- /dev/null +++ b/dram/src/core/TimingCalculation.cpp @@ -0,0 +1,130 @@ +/* + * Utils.cpp + * + * Created on: Mar 12, 2014 + * Author: jonny + */ + +#include "TimingCalculation.h" +#include "configuration/TimingConfiguration.h" +#include "ControllerCore.h" +#include "../common/DebugManager.h" +#include "configuration/Configuration.h" +#include "../common/Utils.h" + +namespace core { + + +sc_time getDistance(sc_time a, sc_time b) +{ + if (a > b) + return a - b; + else + return b - a; +} + +sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint) +{ + if (previous + constraint > start) + return previous + constraint - start; + else + return SC_ZERO_TIME; +} + +const sc_time clkAlign(sc_time time, Alignment alignment) +{ + sc_time clk = Configuration::getInstance().Timings.clk; + if (alignment == UP) + return ceil(time / clk) * clk; + else + return floor(time / clk) * clk; +} + +sc_time getExecutionTime(Command command,tlm::tlm_generic_payload& payload) +{ + TimingConfiguration& config = Configuration::getInstance().Timings; + + if(command == Command::Precharge || command == Command::PrechargeAll) + { + return config.tRP; + } + else if(command == Command::Activate) + { + return config.tRCD; + } + else if(command == Command::Read) + { + return config.tRL + getBurstLengthOnDataStrobe(payload.get_streaming_width()); + } + else if(command == Command::ReadA) + { + return getBurstLengthOnDataStrobe(payload.get_streaming_width()) + + max(config.tRP, config.tRL); + } + else if(command == Command::Write || command == Command::WriteA) + { + sc_time lengthOnDataStrobe = getBurstLengthOnDataStrobe(payload.get_streaming_width()); + if(Configuration::getInstance().DataRate == 1) + lengthOnDataStrobe -= Configuration::getInstance().Timings.clk; + + if (command == Command::Write) + { + return config.tWL + lengthOnDataStrobe; + } + else + { + return config.tWL + lengthOnDataStrobe + config.tWR; + } + } + else if(command == Command::PrechargeAll) + { + return config.tRP; + } + else if(command == Command::AutoRefresh) + { + return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC; + } + else if(command == Command::PDNA || command == Command::PDNP) + { + assert(config.tCKE == config.clk * 3); + return config.tCKE; + } + else if(command == Command::SREF) + { + return config.tCKESR; + } + else if(command == Command::PDNAX || command == Command::PDNPX || command == Command::SREFX) + { + return config.clk; + } + else + { + SC_REPORT_FATAL("getExecutionTime", "unkown command"); + return SC_ZERO_TIME; + } +} + +bool isClkAligned(sc_time time, sc_time clk) +{ + return !((time / clk) - ceil(time / clk)); +} + +bool TimeInterval::timeIsInInterval(sc_time time) +{ + return (start < time && time < end); +} + +bool TimeInterval::intersects(TimeInterval other) +{ + return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start); +} + +sc_time getBurstLengthOnDataStrobe(unsigned int burstlength) +{ + Configuration& config = Configuration::getInstance(); + sc_assert((burstlength / config.DataRate) > 0); + + return config.Timings.clk * (burstlength / config.DataRate); +} + +} diff --git a/dram/src/core/utils/Utils.h b/dram/src/core/TimingCalculation.h similarity index 82% rename from dram/src/core/utils/Utils.h rename to dram/src/core/TimingCalculation.h index a153d5da..a6f5bbb3 100644 --- a/dram/src/core/utils/Utils.h +++ b/dram/src/core/TimingCalculation.h @@ -10,11 +10,11 @@ #include #include -#include "../../common/dramExtension.h" +#include "../common/dramExtension.h" +#include "Command.h" namespace core { -unsigned int getStartAddress(const Bank& bank); sc_time getDistance(sc_time a, sc_time b); struct TimeInterval @@ -28,16 +28,14 @@ struct TimeInterval bool intersects(TimeInterval other); }; +sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload); sc_time getBurstLengthOnDataStrobe(unsigned int burstlength); - -struct TimingConfiguration; sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint); enum Alignment {UP, DOWN}; const sc_time clkAlign(sc_time time, Alignment alignment = UP); bool isClkAligned(sc_time time, sc_time clk); -void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank); }; #endif /* UTILS_H_ */ diff --git a/dram/src/core/configuration/TimingConfiguration.h b/dram/src/core/configuration/TimingConfiguration.h index 61ab2571..64c336ed 100644 --- a/dram/src/core/configuration/TimingConfiguration.h +++ b/dram/src/core/configuration/TimingConfiguration.h @@ -9,9 +9,8 @@ #define TIMINGS_H_ #include -#include "../utils/Utils.h" #include - +#include "../../common/dramExtension.h" namespace core{ struct RefreshTiming diff --git a/dram/src/core/powerdown/IPowerDownManager.h b/dram/src/core/powerdown/IPowerDownManager.h new file mode 100644 index 00000000..2e9ef29b --- /dev/null +++ b/dram/src/core/powerdown/IPowerDownManager.h @@ -0,0 +1,99 @@ +/* + * IPowerDownManager.h + * + * Created on: Apr 11, 2014 + * Author: jonny + */ + +#ifndef IPOWERDOWNMANAGER_H_ +#define IPOWERDOWNMANAGER_H_ + +#include + +namespace core { + +enum class PowerDownState +{ + Awake, AwakeForRefresh, PDNActive, PDNPrecharge, PDNSelfRefresh +}; + +class IPowerDownManager +{ +public: + virtual ~IPowerDownManager() {} + + virtual void sleep(Bank bank, sc_time time) = 0; + virtual void wakeUp(Bank bank, sc_time time) = 0; + virtual void wakeUpForRefresh(Bank bank, sc_time time) = 0; + + virtual bool isInSelfRefresh(Bank bank) = 0; + +protected: + Command getSleepCommand(PowerDownState state); + Command getWakeUpCommand(PowerDownState state); + +}; + +inline Command IPowerDownManager::getSleepCommand(PowerDownState state) +{ + Command cmd(Command::NOP); + switch (state) + { + case PowerDownState::PDNActive: + cmd = Command::PDNA; + break; + case PowerDownState::PDNPrecharge: + cmd = Command::PDNP; + break; + case PowerDownState::PDNSelfRefresh: + cmd = Command::SREF; + break; + default: + SC_REPORT_FATAL("In PowerDownManager sendPowerdownBegin", "invalid powerDownState"); + } + return cmd; +} + +inline Command IPowerDownManager::getWakeUpCommand(PowerDownState state) + +{ + Command cmd(Command::NOP); + switch (state) + { + case PowerDownState::PDNActive: + cmd = Command::PDNAX; + break; + case PowerDownState::PDNPrecharge: + cmd = Command::PDNPX; + break; + case PowerDownState::PDNSelfRefresh: + cmd = Command::SREFX; + break; + default: + SC_REPORT_FATAL("In PowerDownManager sendPowerdownEnd", "invalid powerDownState"); + } + return cmd; +} + +inline std::string powerDownStateToString(PowerDownState powerDownState) +{ + switch (powerDownState) + { + case PowerDownState::Awake: + return "Awake"; + case PowerDownState::AwakeForRefresh: + return "Awake for refresh"; + case PowerDownState::PDNActive: + return "PDN Active"; + case PowerDownState::PDNPrecharge: + return "PDN Precharged"; + case PowerDownState::PDNSelfRefresh: + return "PDN Self refresh"; + default: + return "unknown state"; + } +} + +} /* namespace core */ + +#endif /* IPOWERDOWNMANAGER_H_ */ diff --git a/dram/src/core/powerdown/PowerDownManager.cpp b/dram/src/core/powerdown/PowerDownManager.cpp index bf6294ca..431e8501 100644 --- a/dram/src/core/powerdown/PowerDownManager.cpp +++ b/dram/src/core/powerdown/PowerDownManager.cpp @@ -1,274 +1,174 @@ /* - * IPowerDownManager.cpp + * PowerDownManager.cpp * - * Created on: Apr 4, 2014 + * Created on: Apr 1, 2014 * Author: jonny */ +#include +#include #include "PowerDownManager.h" #include "../ControllerCore.h" +#include "../TimingCalculation.h" +#include "../../common/DebugManager.h" +#include #include "../../common/Utils.h" -#include "../utils/Utils.h" using namespace tlm; +using namespace std; namespace core { -std::string PowerDownManager::senderName = "pdn manager"; PowerDownManager::PowerDownManager(ControllerCore& controller) : controller(controller) { - init(); + powerDownState = PowerDownState::Awake; + for (Bank bank : controller.getBanks()) + { + setUpDummy(powerDownPayloads[bank], bank); + } } + +PowerDownManager::~PowerDownManager() +{ + +} + void PowerDownManager::sleep(Bank bank, sc_time time) { - assert(canSleep(bank)); + if (!canSleep() || isInPowerDown()) + return; - PowerDownState state = getPowerDownState(bank); - sc_time minTime = controller.config.Timings.tCKE; + PowerDownState state = powerDownState; if (state == PowerDownState::Awake) //coming from active { - state = controller.state.bankStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; + state = controller.state.bankStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; + } else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down { - sc_assert(!controller.state.bankStates.rowBufferIsOpen(bank)); + sc_assert(controller.state.bankStates.allRowBuffersAreClosed()); - if (controller.state.getLastCommand(Command::PDNA, bank).getStart() - > controller.state.getLastCommand(Command::PDNP, bank).getStart()) + if (controller.state.getLastCommand(Command::PDNA).getStart() + >= controller.state.getLastCommand(Command::PDNP).getStart()) state = PowerDownState::PDNPrecharge; else { state = PowerDownState::PDNSelfRefresh; - minTime = controller.config.Timings.tCKESR; } } - ScheduledCommand pdn(getSleepCommand(state), time, minTime, DramExtension::getExtension(getPayload(bank))); + ScheduledCommand pdn(IPowerDownManager::getSleepCommand(state), time, + getExecutionTime(IPowerDownManager::getSleepCommand(state), powerDownPayloads[bank]), + DramExtension::getExtension(powerDownPayloads[bank])); + + controller.state.bus.moveCommandToNextFreeSlot(pdn); - //check if pdna or pdnp tcke collides with next refresh if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn)) { return; } - - setState(state, bank); - sendPowerDownPayload(pdn); + else + { + setState(state); + sendPowerDownPayloads(pdn); + } } void PowerDownManager::wakeUp(Bank bank, sc_time time) { - if (isAwakeForRefresh(bank)) + if (isAwakeForRefresh()) //Request enters system during Refresh { - //Request enters system during Refresh (power down already waked up and payload sent) - setState(PowerDownState::Awake, bank); + setState(PowerDownState::Awake); } - else if (isInPowerDown(bank)) + else if (isInPowerDown()) //Request wakes up power down { - time = clkAlign(time); - //Request wakes up power down - sc_time start(SC_ZERO_TIME); - - switch (getPowerDownState(bank)) + sc_time startOfExitCommand(SC_ZERO_TIME); + switch (powerDownState) { case PowerDownState::PDNActive: - start = max(time, controller.state.getLastCommand(Command::PDNA).getEnd()); + startOfExitCommand = max(time, controller.state.getLastCommand(Command::PDNA).getEnd()); break; case PowerDownState::PDNPrecharge: - start = max(time, controller.state.getLastCommand(Command::PDNP).getEnd()); + startOfExitCommand = max(time, controller.state.getLastCommand(Command::PDNP).getEnd()); break; case PowerDownState::PDNSelfRefresh: - start = max(time, controller.state.getLastCommand(Command::SREF).getEnd()); - controller.refreshManager->reInitialize(bank, start + controller.config.Timings.clk); + startOfExitCommand = max(time, controller.state.getLastCommand(Command::SREF).getEnd()); + controller.refreshManager->reInitialize(bank, + startOfExitCommand + getExecutionTime(Command::SREFX, powerDownPayloads[bank])); break; default: break; } + Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); + ScheduledCommand pdn(cmd, startOfExitCommand, getExecutionTime(cmd, powerDownPayloads[bank]), + DramExtension::getExtension(powerDownPayloads[bank])); - - ScheduledCommand pdn(getWakeUpCommand(getPowerDownState(bank)), start, controller.config.Timings.clk, - DramExtension::getExtension(getPayload(bank))); - - setState(PowerDownState::Awake, bank); - sendPowerDownPayload(pdn); - + setState(PowerDownState::Awake); + sendPowerDownPayloads(pdn); } } void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time) { - if (isInPowerDown(bank)) + if (isInPowerDown()) { - ScheduledCommand pdn(getWakeUpCommand(getPowerDownState(bank)), time, controller.config.Timings.clk, - DramExtension::getExtension(getPayload(bank))); - setState(PowerDownState::AwakeForRefresh, bank); - sendPowerDownPayload(pdn); + Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); + ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), + DramExtension::getExtension(powerDownPayloads[bank])); + + setState(PowerDownState::AwakeForRefresh); + sendPowerDownPayloads(pdn); } } -void PowerDownManager::wakeUpAllForRefresh(sc_time time) +void PowerDownManager::sendPowerDownPayloads(ScheduledCommand& cmd) { + controller.state.bus.moveCommandToNextFreeSlot(cmd); for (Bank bank : controller.getBanks()) { - wakeUpForRefresh(bank, time); + tlm_generic_payload& payloadToSend = powerDownPayloads[bank]; + ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(), + DramExtension::getExtension(payloadToSend)); + controller.state.change(pdnToSend); + controller.wrapper.send(pdnToSend, payloadToSend); } } -bool PowerDownManager::isInPowerDown(Bank bank) +void PowerDownManager::setState(PowerDownState state) { - return isIn(getPowerDownState(bank), - { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh }); + powerDownState = state; + DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName, + "Is now in state " + powerDownStateToString(powerDownState) + " on all banks"); } -bool PowerDownManager::isInSelfRefresh(Bank bank) +bool PowerDownManager::isInPowerDown() { - return getPowerDownState(bank) == PowerDownState::PDNSelfRefresh; + return (powerDownState == PowerDownState::PDNActive || powerDownState == PowerDownState::PDNPrecharge + || powerDownState == PowerDownState::PDNSelfRefresh); } -bool PowerDownManager::allBanksInSelfRefresh() +bool PowerDownManager::canSleep() { for (Bank bank : controller.getBanks()) { - if (!isInSelfRefresh(bank)) + if (!controller.numberOfPayloads[bank] == 0) return false; } return true; } -bool PowerDownManager::isAwakeForRefresh(Bank bank) +bool PowerDownManager::isInSelfRefresh(Bank bank) { - return getPowerDownState(bank) == PowerDownState::AwakeForRefresh; + return powerDownState == PowerDownState::PDNSelfRefresh; } -bool PowerDownManager::isAwake(Bank bank) +bool PowerDownManager::isAwakeForRefresh() { - return getPowerDownState(bank) == PowerDownState::Awake; + return powerDownState == PowerDownState::AwakeForRefresh; } -void PowerDownManager::setState(PowerDownState state, Bank bank) -{ - PowerDownState& bankstate = getPowerDownState(bank); - bankstate = state; - - string stateName; - switch (bankstate) - { - case PowerDownState::Awake: - stateName = "Awake"; - break; - case PowerDownState::AwakeForRefresh: - stateName = "Awake for refresh"; - break; - case PowerDownState::PDNActive: - stateName = "PDN Active"; - break; - case PowerDownState::PDNPrecharge: - stateName = "PDN Precharged"; - break; - case PowerDownState::PDNSelfRefresh: - stateName = "PDN Self refresh"; - break; - default: - stateName = "unknown state"; - break; - } - DebugManager::getInstance().printDebugMessage(PowerDownManager::senderName, - "Is now in state " + stateName + " on Bank " + to_string(bank.ID())); -} - -Command PowerDownManager::getSleepCommand(PowerDownState state) -{ - Command cmd(Command::NOP); - switch (state) - { - case PowerDownState::PDNActive: - cmd = Command::PDNA; - break; - case PowerDownState::PDNPrecharge: - cmd = Command::PDNP; - break; - case PowerDownState::PDNSelfRefresh: - cmd = Command::SREF; - break; - default: - SC_REPORT_FATAL("In PowerDownManager sendPowerdownBegin", "invalid powerDownState"); - } - return cmd; -} - -Command PowerDownManager::getWakeUpCommand(PowerDownState state) -{ - Command cmd(Command::NOP); - switch (state) - { - case PowerDownState::PDNActive: - cmd = Command::PDNAX; - break; - case PowerDownState::PDNPrecharge: - cmd = Command::PDNPX; - break; - case PowerDownState::PDNSelfRefresh: - cmd = Command::SREFX; - break; - default: - SC_REPORT_FATAL("In PowerDownManager sendPowerdownEnd", "invalid powerDownState"); - } - return cmd; -} - -void PowerDownManager::sendPowerDownPayload(ScheduledCommand& pdn) -{ - controller.state.bus.moveCommandToNextFreeSlot(pdn); - controller.state.change(pdn); - controller.wrapper.send(pdn, powerDownPayloads[pdn.getBank()]); -} - -PowerDownState& PowerDownManager::getPowerDownState(Bank bank) -{ - if (powerDownStates.count(bank) == 0) - { - SC_REPORT_FATAL("Map", "Element not in map"); - } - return powerDownStates.at(bank); -} - -bool PowerDownManager::canSleep(Bank bank) -{ - if (powerDownStates.count(bank) == 0) - { - SC_REPORT_FATAL("Map", "Element not in map"); - } - return controller.numberOfPayloads[bank] == 0; -} - -tlm::tlm_generic_payload& PowerDownManager::getPayload(Bank bank) -{ - if (powerDownPayloads.count(bank) == 0) - { - SC_REPORT_FATAL("Map", "Element not in map"); - } - return powerDownPayloads.at(bank); -} - -/* - * All Banks are precharged and in Precharge-PowerDown after starting the system - */ -void PowerDownManager::init() -{ - for (Bank bank : controller.getBanks()) - { - tlm_generic_payload& payload = powerDownPayloads[bank]; - setUpDummy(payload, bank); - - //send payload - ScheduledCommand pdn(Command::PDNP, SC_ZERO_TIME, SC_ZERO_TIME, DramExtension::getExtension(payload)); - controller.state.change(pdn); - controller.wrapper.send(pdn, payload); - powerDownStates[bank] = PowerDownState::PDNPrecharge; - } -} - -}/* namespace core */ +} /* namespace core */ diff --git a/dram/src/core/powerdown/PowerDownManager.h b/dram/src/core/powerdown/PowerDownManager.h index be1ed821..d7a25b5f 100644 --- a/dram/src/core/powerdown/PowerDownManager.h +++ b/dram/src/core/powerdown/PowerDownManager.h @@ -1,69 +1,43 @@ /* - * IPowerDownManager.h + * PowerDownManagerGrouped.h * - * Created on: Mar 31, 2014 + * Created on: Apr 1, 2014 * Author: jonny */ -#ifndef IPOWERDOWNMANAGER_H_ -#define IPOWERDOWNMANAGER_H_ +#ifndef POWERDOWNMANAGER_H_ +#define POWERDOWNMANAGER_H_ -#include -#include -#include -#include -#include "../Command.h" -#include "../../common/dramExtension.h" -#include "../scheduling/ScheduledCommand.h" +#include "PowerDownManagerBankwise.h" namespace core { class ControllerCore; -enum class PowerDownState -{ - Awake, AwakeForRefresh, PDNActive, PDNPrecharge, PDNSelfRefresh -}; - -class PowerDownManager +class PowerDownManager: public IPowerDownManager { public: PowerDownManager(ControllerCore& controller); - virtual ~PowerDownManager() - { - } - virtual void sleep(Bank bank, sc_time time); - virtual void wakeUp(Bank bank, sc_time time); - virtual void wakeUpForRefresh(Bank bank, sc_time time); - virtual void wakeUpAllForRefresh(sc_time time); + virtual ~PowerDownManager(); - virtual bool isInSelfRefresh(Bank bank); - virtual bool allBanksInSelfRefresh(); - virtual bool isInPowerDown(Bank bank); - virtual bool isAwake(Bank bank); - virtual bool isAwakeForRefresh(Bank bank); + virtual void sleep(Bank bank, sc_time time) override; + virtual void wakeUp(Bank bank, sc_time time) override; + virtual void wakeUpForRefresh(Bank bank, sc_time time) override; - static std::string senderName; -protected: + virtual bool isInSelfRefresh(Bank bank) override; +private: + PowerDownState powerDownState; + void sendPowerDownPayloads(ScheduledCommand& cmd); - ControllerCore& controller; + bool isInPowerDown(); + + void setState(PowerDownState state); + bool canSleep(); + bool isAwakeForRefresh(); std::map powerDownPayloads; - std::map powerDownStates; - - virtual PowerDownState& getPowerDownState(Bank bank); - virtual tlm::tlm_generic_payload& getPayload(Bank bank); - virtual bool canSleep(Bank bank); - - void setState(PowerDownState state, Bank bank); - - Command getWakeUpCommand(PowerDownState state); - Command getSleepCommand(PowerDownState state); - - void sendPowerDownPayload(ScheduledCommand& pdn); - - void init(); + ControllerCore& controller; }; -}/* namespace core */ +} /* namespace core */ -#endif /* IPOWERDOWNMANAGER_H_ */ +#endif /* POWERDOWNMANAGER_H_ */ diff --git a/dram/src/core/powerdown/PowerDownManagerBankwise.cpp b/dram/src/core/powerdown/PowerDownManagerBankwise.cpp new file mode 100644 index 00000000..0b7ea60a --- /dev/null +++ b/dram/src/core/powerdown/PowerDownManagerBankwise.cpp @@ -0,0 +1,161 @@ +/* + * IPowerDownManager.cpp + * + * Created on: Apr 4, 2014 + * Author: jonny + */ + +#include "PowerDownManager.h" +#include "../ControllerCore.h" +#include "../../common/Utils.h" +#include "../TimingCalculation.h" + +using namespace tlm; + +namespace core { + +std::string PowerDownManagerBankwise::senderName = "pdn manager"; + +PowerDownManagerBankwise::PowerDownManagerBankwise(ControllerCore& controller) : + controller(controller) +{ + for (Bank bank : controller.getBanks()) + { + setUpDummy(powerDownPayloads[bank], bank); + powerDownStates[bank] = PowerDownState::Awake; + } +} + +void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) +{ + if (!canSleep(bank)) + return; + + tlm_generic_payload& payload = powerDownPayloads[bank]; + sc_time minTime = getExecutionTime(Command::PDNA, payload); + + PowerDownState state = powerDownStates[bank]; + if (state == PowerDownState::Awake) //coming from active + { + state = controller.state.bankStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; + } + else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down + { + sc_assert(!controller.state.bankStates.rowBufferIsOpen(bank)); + + if (controller.state.getLastCommand(Command::PDNA, bank).getStart() + >= controller.state.getLastCommand(Command::PDNP, bank).getStart()) + state = PowerDownState::PDNPrecharge; + else + { + state = PowerDownState::PDNSelfRefresh; + minTime = getExecutionTime(Command::SREF, payload); + } + } + + ScheduledCommand pdn(IPowerDownManager::getSleepCommand(state), time, minTime, DramExtension::getExtension(payload)); + controller.state.bus.moveCommandToNextFreeSlot(pdn); + + if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn)) + { + return; + } + else + { + setState(state, bank); + sendPowerDownPayload(pdn); + } +} + +void PowerDownManagerBankwise::wakeUp(Bank bank, sc_time time) +{ + if (isAwakeForRefresh(bank)) + { + setState(PowerDownState::Awake, bank); + } + else if (isInPowerDown(bank)) + { + //Request wakes up power down + sc_time startOfExitCommand(SC_ZERO_TIME); + switch (powerDownStates[bank]) + { + case PowerDownState::PDNActive: + startOfExitCommand = max(time, controller.state.getLastCommand(Command::PDNA).getEnd()); + break; + case PowerDownState::PDNPrecharge: + startOfExitCommand = max(time, controller.state.getLastCommand(Command::PDNP).getEnd()); + break; + case PowerDownState::PDNSelfRefresh: + startOfExitCommand = max(time, controller.state.getLastCommand(Command::SREF).getEnd()); + controller.refreshManager->reInitialize(bank, + startOfExitCommand + getExecutionTime(Command::SREFX, powerDownPayloads[bank])); + break; + default: + break; + } + + Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); + ScheduledCommand pdn(cmd, startOfExitCommand, getExecutionTime(cmd, powerDownPayloads[bank]), + DramExtension::getExtension(powerDownPayloads[bank])); + + setState(PowerDownState::Awake, bank); + sendPowerDownPayload(pdn); + } +} + +void PowerDownManagerBankwise::wakeUpForRefresh(Bank bank, sc_time time) +{ + if (isInPowerDown(bank)) + { + Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); + ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); + + setState(PowerDownState::AwakeForRefresh, bank); + sendPowerDownPayload(pdn); + } +} + +bool PowerDownManagerBankwise::isInPowerDown(Bank bank) +{ + return isIn(powerDownStates[bank], + { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh }); +} + +bool PowerDownManagerBankwise::isInSelfRefresh(Bank bank) +{ + return powerDownStates[bank] == PowerDownState::PDNSelfRefresh; +} + +bool PowerDownManagerBankwise::isAwakeForRefresh(Bank bank) +{ + return powerDownStates[bank] == PowerDownState::AwakeForRefresh; +} + +bool PowerDownManagerBankwise::isAwake(Bank bank) +{ + return powerDownStates[bank] == PowerDownState::Awake; +} + +void PowerDownManagerBankwise::setState(PowerDownState state, Bank bank) +{ + PowerDownState& bankstate = powerDownStates[bank]; + bankstate = state; + + DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName, + "Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID())); +} + +void PowerDownManagerBankwise::sendPowerDownPayload(ScheduledCommand& pdn) +{ + controller.state.bus.moveCommandToNextFreeSlot(pdn); + controller.state.change(pdn); + controller.wrapper.send(pdn, powerDownPayloads[pdn.getBank()]); +} + +bool PowerDownManagerBankwise::canSleep(Bank bank) +{ + return controller.numberOfPayloads[bank] == 0; +} + +}/* namespace core */ + diff --git a/dram/src/core/powerdown/PowerDownManagerBankwise.h b/dram/src/core/powerdown/PowerDownManagerBankwise.h new file mode 100644 index 00000000..05761beb --- /dev/null +++ b/dram/src/core/powerdown/PowerDownManagerBankwise.h @@ -0,0 +1,59 @@ +/* + * PowerDownManagerBankwise.h + * + * Created on: Mar 31, 2014 + * Author: jonny + */ + +#ifndef POWERDOWNMANAGERBANKWISE_H_ +#define POWERDOWNMANAGERBANKWISE_H_ + +#include +#include +#include +#include +#include "../Command.h" +#include "../../common/dramExtension.h" +#include "../scheduling/ScheduledCommand.h" +#include "IPowerDownManager.h" + +namespace core { + +class ControllerCore; + +class PowerDownManagerBankwise: public IPowerDownManager +{ +public: + PowerDownManagerBankwise(ControllerCore& controller); + virtual ~PowerDownManagerBankwise() + { + } + virtual void sleep(Bank bank, sc_time time) override; + virtual void wakeUp(Bank bank, sc_time time) override; + virtual void wakeUpForRefresh(Bank bank, sc_time time) override; + virtual bool isInSelfRefresh(Bank bank) override; + + static std::string senderName; + +private: + virtual bool isInPowerDown(Bank bank); + virtual bool isAwake(Bank bank); + virtual bool isAwakeForRefresh(Bank bank); + + ControllerCore& controller; + std::map powerDownPayloads; + std::map powerDownStates; + + virtual bool canSleep(Bank bank); + + void setState(PowerDownState state, Bank bank); + + Command getWakeUpCommand(PowerDownState state); + Command getSleepCommand(PowerDownState state); + + void sendPowerDownPayload(ScheduledCommand& pdn); +}; + +}/* namespace core */ + +#endif /* POWERDOWNMANAGERBANKWISE_H_ */ diff --git a/dram/src/core/powerdown/PowerDownManagerGrouped.cpp b/dram/src/core/powerdown/PowerDownManagerGrouped.cpp deleted file mode 100644 index ea232562..00000000 --- a/dram/src/core/powerdown/PowerDownManagerGrouped.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * PowerDownManager.cpp - * - * Created on: Apr 1, 2014 - * Author: jonny - */ - -#include -#include -#include "PowerDownManagerGrouped.h" -#include "../ControllerCore.h" -#include "../utils/Utils.h" -#include "../../common/DebugManager.h" -#include - -using namespace tlm; -using namespace std; - -namespace core { - -PowerDownManagerGrouped::~PowerDownManagerGrouped() -{ - -} - -void PowerDownManagerGrouped::sleep(Bank bank, sc_time time) -{ - //all banks can sleep and no pending refresh in system - if (!canSleep() || (controller.state.getLastCommand(Command::AutoRefresh).getEnd() > time)) - return; - - PowerDownState state = getPowerDownState(); - if (state == PowerDownState::Awake)//coming from active - { - if (controller.state.bankStates.allRowBuffersAreClosed()) - setState(PowerDownState::PDNPrecharge); - else - setState(PowerDownState::PDNActive); - - sendPowerDownPayload(time, getSleepCommand(getPowerDownState())); - } - else if (state == PowerDownState::AwakeForRefresh)//coming from refresh interrupting power down - { - if(controller.state.bankStates.allRowBuffersAreClosed()) - { - if (controller.state.getLastCommand(Command::PDNA).getStart() - > controller.state.getLastCommand(Command::PDNP).getStart()) - setState(PowerDownState::PDNPrecharge); - else - setState(PowerDownState::PDNSelfRefresh); - } - else - { - setState(PowerDownState::PDNActive); - } - sendPowerDownPayload(time, getSleepCommand(getPowerDownState())); - } -} - -void PowerDownManagerGrouped::wakeUp(Bank bank, sc_time time) -{ - if (isAwakeForRefresh())//Request enters system during Refresh - { - //power down already waked up and payload sent - setState(PowerDownState::Awake); - } - else if(isInPowerDown())//Request wakes up power down - { - sc_time delay(SC_ZERO_TIME); - switch (getPowerDownState()) - { - case PowerDownState::PDNActive: - break; - case PowerDownState::PDNPrecharge: - break; - case PowerDownState::PDNSelfRefresh: - delay = getDelayToMeetConstraint( - controller.state.getLastCommand(Command::SREF).getStart(), time, - controller.config.Timings.tCKESR); - break; - default: - break; - } - - if (delay == SC_ZERO_TIME) - { - sendPowerDownPayload(time, getWakeUpCommand(getPowerDownState())); - setState(PowerDownState::Awake); - } - else - { - tlm_generic_payload& p = getPayload(bank); - controller.wrapper.send(WakeUpTrigger, time + delay, p); - } - } -} - -void PowerDownManagerGrouped::wakeUpForRefresh(Bank bank, sc_time time) -{ - wakeUpAllForRefresh(time); -} - -void PowerDownManagerGrouped::wakeUpAllForRefresh(sc_time time) -{ - if(isInPowerDown()) - { - sendPowerDownPayload(time, getWakeUpCommand(getPowerDownState())); - setState(PowerDownState::AwakeForRefresh); - } - -} - -void PowerDownManagerGrouped::sendPowerDownPayload(sc_time time, Command cmd) -{ - time = clkAlign(time); - - //just to find slot - tlm_generic_payload& payload = getPayload(Bank(0)); - ScheduledCommand pdn(cmd, time, controller.config.Timings.clk, DramExtension::getExtension(payload)); - controller.state.bus.moveCommandToNextFreeSlot(pdn); - - - for (Bank bank : controller.getBanks()) - { - tlm_generic_payload& payloadToSend = getPayload(bank); - ScheduledCommand pdnToSend(cmd, pdn.getStart(), controller.config.Timings.clk, DramExtension::getExtension(payloadToSend)); - controller.state.change(pdnToSend); - controller.wrapper.send(pdnToSend, payloadToSend); - } -} - -void PowerDownManagerGrouped::setState(PowerDownState state) -{ - for (Bank bank : controller.getBanks()) - { - PowerDownManager::setState(state, bank); - } -} - -bool PowerDownManagerGrouped::isInPowerDown() -{ - return PowerDownManager::isInPowerDown(Bank(0)); -} - -bool PowerDownManagerGrouped::canSleep() -{ - for (Bank bank : controller.getBanks()) - { - if (!PowerDownManager::canSleep(bank)) - return false; - } - return true; -} - -PowerDownState PowerDownManagerGrouped::getPowerDownState() -{ - return PowerDownManager::getPowerDownState(Bank(0)); -} - -bool PowerDownManagerGrouped::isAwakeForRefresh() -{ - return PowerDownManager::isAwakeForRefresh(Bank(0)); -} - -} /* namespace core */ - diff --git a/dram/src/core/powerdown/PowerDownManagerGrouped.h b/dram/src/core/powerdown/PowerDownManagerGrouped.h deleted file mode 100644 index 69c333ad..00000000 --- a/dram/src/core/powerdown/PowerDownManagerGrouped.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * PowerDownManagerGrouped.h - * - * Created on: Apr 1, 2014 - * Author: jonny - */ - -#ifndef POWERDOWNMANAGER_H_ -#define POWERDOWNMANAGER_H_ - -#include "PowerDownManager.h" - -namespace core { - -class ControllerCore; - -class PowerDownManagerGrouped: public PowerDownManager -{ -public: - using PowerDownManager::PowerDownManager; - virtual ~PowerDownManagerGrouped(); - - virtual void sleep(Bank bank, sc_time time) override; - virtual void wakeUp(Bank bank, sc_time time) override; - virtual void wakeUpForRefresh(Bank bank, sc_time time) override; - virtual void wakeUpAllForRefresh(sc_time time) override; - - //virtual bool isInSelfRefresh(Bank bank) override; - //virtual bool isAwakeForRefresh(Bank bank) override; - -private: - - void sendPowerDownPayload(sc_time time, Command cmd); - - void setState(PowerDownState state); - - bool isInPowerDown(); - bool canSleep(); - PowerDownState getPowerDownState(); - bool isAwakeForRefresh(); - - -}; - -} /* namespace core */ - -#endif /* POWERDOWNMANAGER_H_ */ diff --git a/dram/src/core/refresh/RefreshManager.cpp b/dram/src/core/refresh/RefreshManager.cpp index a2fd970f..5c8536fc 100644 --- a/dram/src/core/refresh/RefreshManager.cpp +++ b/dram/src/core/refresh/RefreshManager.cpp @@ -7,14 +7,15 @@ #include "RefreshManager.h" #include "../ControllerCore.h" -#include "../utils/Utils.h" +#include "../TimingCalculation.h" +#include "../../common/Utils.h" +#include "../TimingCalculation.h" using namespace tlm; namespace core { RefreshManager::RefreshManager(ControllerCore& controller) : - controller(controller), timing(controller.config.Timings.refreshTimings[Bank(0)]), nextPlannedRefresh( - SC_ZERO_TIME) + controller(controller), timing(controller.config.Timings.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME) { setupTransactions(); planNextRefresh(); @@ -26,12 +27,12 @@ RefreshManager::~RefreshManager() bool RefreshManager::hasCollision(const CommandSchedule& schedule) { - return !(schedule.getEnd() < nextPlannedRefresh); + return schedule.getEnd() > nextPlannedRefresh; } bool RefreshManager::hasCollision(const ScheduledCommand& command) { - return !(command.getEnd() < nextPlannedRefresh); + return command.getEnd() > nextPlannedRefresh; } void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) @@ -40,41 +41,37 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time if (!controller.state.bankStates.allRowBuffersAreClosed()) { - ScheduledCommand precharge(Command::PrechargeAll, time, controller.config.Timings.tRP, + ScheduledCommand precharge(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]), DramExtension::getExtension(refreshPayloads[Bank(0)])); - controller.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(precharge); - - for (Bank bank : controller.getBanks()) - { - tlm_generic_payload& payload = refreshPayloads[bank]; - ScheduledCommand prechargeToSend(Command::PrechargeAll, precharge.getStart(), - controller.config.Timings.tRP, DramExtension::getExtension(payload)); - controller.state.change(prechargeToSend); - controller.wrapper.send(prechargeToSend, payload); - } + sendToAllBanks(precharge); } - - ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC, + ScheduledCommand nextRefresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayloads[Bank(0)]), DramExtension::getExtension(refreshPayloads[Bank(0)])); - controller.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(nextRefresh); + sendToAllBanks(nextRefresh); for (Bank bank : controller.getBanks()) { - tlm_generic_payload& payload = refreshPayloads[bank]; - Row currentrow = DramExtension::getExtension(payload).getRow(); - DramExtension::getExtension(payload).setRow(Row((currentrow.ID()+1)%Configuration::getInstance().NumberOfBanks)); - ScheduledCommand refreshToSend(Command::AutoRefresh, nextRefresh.getStart(), timing.tRFC, - DramExtension::getExtension(payload)); - controller.state.change(refreshToSend); - controller.wrapper.send(refreshToSend, payload); + DramExtension::getExtension(refreshPayloads[bank]).increaseRow(); } planNextRefresh(); } +void RefreshManager::sendToAllBanks(ScheduledCommand& command) +{ + for (Bank bank : controller.getBanks()) + { + tlm_generic_payload& payload = refreshPayloads[bank]; + DramExtension extension = DramExtension::getExtension(payload); + ScheduledCommand cmd(command.getCommand(), command.getStart(), command.getExecutionTime(), extension); + controller.state.change(cmd); + controller.wrapper.send(cmd, payload); + } +} + void RefreshManager::planNextRefresh() { nextPlannedRefresh += timing.tREFI; diff --git a/dram/src/core/refresh/RefreshManager.h b/dram/src/core/refresh/RefreshManager.h index 43f472ba..3ffff7c3 100644 --- a/dram/src/core/refresh/RefreshManager.h +++ b/dram/src/core/refresh/RefreshManager.h @@ -36,6 +36,8 @@ private: std::map refreshPayloads; void planNextRefresh(); + + void sendToAllBanks(ScheduledCommand& command); void setupTransactions(); }; diff --git a/dram/src/core/refresh/RefreshManagerBankwise.cpp b/dram/src/core/refresh/RefreshManagerBankwise.cpp index bba98978..2d058f5d 100644 --- a/dram/src/core/refresh/RefreshManagerBankwise.cpp +++ b/dram/src/core/refresh/RefreshManagerBankwise.cpp @@ -7,7 +7,8 @@ #include "RefreshManagerBankwise.h" #include "../ControllerCore.h" -#include "../utils/Utils.h" +#include "../TimingCalculation.h" +#include "../../common/Utils.h" using namespace std; @@ -16,117 +17,71 @@ namespace core { RefreshManagerBankwise::RefreshManagerBankwise(ControllerCore& controller) : controller(controller) { - for (Bank bank : controller.getBanks()) + for(Bank bank : controller.getBanks()) { - refreshManagerForBanks[bank] = new RefreshManagerForBank(controller, bank); + setUpDummy(refreshPayloads[bank], bank); + planNextRefresh(bank); } } RefreshManagerBankwise::~RefreshManagerBankwise() { - for (Bank bank : controller.getBanks()) - { - delete refreshManagerForBanks[bank]; - } } bool RefreshManagerBankwise::hasCollision(const CommandSchedule& schedule) { - RefreshManagerForBank& manager = *refreshManagerForBanks[schedule.getBank()]; - return manager.hasCollision(schedule); + return schedule.getEnd() > nextPlannedRefreshs[schedule.getBank()]; } bool RefreshManagerBankwise::hasCollision(const ScheduledCommand& command) { - RefreshManagerForBank& manager = *refreshManagerForBanks[command.getBank()]; - return manager.hasCollision(command); + return command.getEnd() > nextPlannedRefreshs[command.getBank()]; } void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) { sc_assert(!isInvalidated(payload, time)); - RefreshManagerForBank& manager = *refreshManagerForBanks[DramExtension::getExtension(payload).getBank()]; - manager.scheduleRefresh(time); -} -RefreshManagerBankwise::RefreshManagerForBank::RefreshManagerForBank(ControllerCore& controller, Bank bank) : - controller(controller), timing(controller.config.Timings.refreshTimings[bank]), bank(bank), nextPlannedRefresh( - SC_ZERO_TIME) -{ - setupTransaction(); - planNextRefresh(); -} + tlm::tlm_generic_payload& refreshPayload = refreshPayloads[DramExtension::getExtension(payload).getBank()]; -RefreshManagerBankwise::RefreshManagerForBank::~RefreshManagerForBank() -{ -} + DramExtension& extension = DramExtension::getExtension(refreshPayload); -bool RefreshManagerBankwise::RefreshManagerForBank::hasCollision(const CommandSchedule& schedule) -{ - return !(schedule.getEnd() < nextPlannedRefresh); -} -bool RefreshManagerBankwise::RefreshManagerForBank::hasCollision(const ScheduledCommand& command) -{ - return !(command.getEnd() < nextPlannedRefresh); -} - -void RefreshManagerBankwise::RefreshManagerForBank::scheduleRefresh(sc_time time) -{ - ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC, DramExtension::getExtension(refreshPayload)); - - if (controller.state.bankStates.rowBufferIsOpen(bank)) + if (controller.state.bankStates.rowBufferIsOpen(extension.getBank())) { - ScheduledCommand precharge(Command::Precharge, time, controller.config.Timings.tRP, - DramExtension::getExtension(refreshPayload)); - controller.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge); - controller.state.bus.moveCommandToNextFreeSlot(precharge); - nextRefresh.setStart(precharge.getEnd()); + ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, refreshPayload), extension); + controller.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge); controller.state.change(precharge); controller.wrapper.send(precharge, refreshPayload); } - controller.state.bus.moveCommandToNextFreeSlot(nextRefresh); + + ScheduledCommand nextRefresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayload), extension); + controller.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(nextRefresh); controller.state.change(nextRefresh); - Row currentrow = DramExtension::getExtension(refreshPayload).getRow(); - DramExtension::getExtension(refreshPayload).setRow(Row((currentrow.ID() + 1) % Configuration::getInstance().NumberOfBanks)); controller.wrapper.send(nextRefresh, refreshPayload); - planNextRefresh(); + extension.increaseRow(); + planNextRefresh(extension.getBank()); } -void RefreshManagerBankwise::RefreshManagerForBank::planNextRefresh() +void RefreshManagerBankwise::planNextRefresh(Bank bank) { - nextPlannedRefresh += timing.tREFI; - controller.wrapper.send(RefreshTrigger, nextPlannedRefresh, refreshPayload); -} - -void RefreshManagerBankwise::RefreshManagerForBank::reInitialize(Bank bank, sc_time time) -{ - nextPlannedRefresh = clkAlign(time, Alignment::DOWN); - planNextRefresh(); -} - -bool RefreshManagerBankwise::RefreshManagerForBank::isInvalidated(sc_time time) -{ - return nextPlannedRefresh > time; -} - -void RefreshManagerBankwise::RefreshManagerForBank::setupTransaction() -{ - setUpDummy(refreshPayload, bank); + nextPlannedRefreshs[bank] += Configuration::getInstance().Timings.refreshTimings[bank].tREFI; + controller.wrapper.send(RefreshTrigger, nextPlannedRefreshs[bank], refreshPayloads[bank]); } void RefreshManagerBankwise::reInitialize(Bank bank, sc_time time) { - - refreshManagerForBanks[bank]->reInitialize(bank, time); + nextPlannedRefreshs[bank] = clkAlign(time, Alignment::DOWN); + planNextRefresh(bank); } bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) { - RefreshManagerForBank& manager = *refreshManagerForBanks[DramExtension::getExtension(payload).getBank()]; - return manager.isInvalidated(time); + return nextPlannedRefreshs[DramExtension::getExtension(payload).getBank()] > time; } + + } /* namespace core */ diff --git a/dram/src/core/refresh/RefreshManagerBankwise.h b/dram/src/core/refresh/RefreshManagerBankwise.h index 8361e650..b758e028 100644 --- a/dram/src/core/refresh/RefreshManagerBankwise.h +++ b/dram/src/core/refresh/RefreshManagerBankwise.h @@ -33,35 +33,12 @@ public: private: - class RefreshManagerForBank - { - public: - RefreshManagerForBank(ControllerCore& controller, Bank bank); - ~RefreshManagerForBank(); - - bool hasCollision(const CommandSchedule& schedule); - bool hasCollision(const ScheduledCommand& command); - void scheduleRefresh(sc_time time); - - void reInitialize(Bank bank, sc_time time); - - bool isInvalidated(sc_time); - private: - ControllerCore& controller; - RefreshTiming& timing; - Bank bank; - - tlm::tlm_generic_payload refreshPayload; - sc_time nextPlannedRefresh; - - void planNextRefresh(); - void setupTransaction(); - }; - ControllerCore& controller; - std::map refreshManagerForBanks; + std::map refreshPayloads; + std::map nextPlannedRefreshs; + void planNextRefresh(Bank bank); }; } /* namespace controller */ diff --git a/dram/src/core/scheduling/CommandSequenceScheduler.cpp b/dram/src/core/scheduling/CommandSequenceScheduler.cpp index 825e5c07..fd165a1f 100644 --- a/dram/src/core/scheduling/CommandSequenceScheduler.cpp +++ b/dram/src/core/scheduling/CommandSequenceScheduler.cpp @@ -8,6 +8,7 @@ #include "CommandSequenceScheduler.h" #include "../ControllerCore.h" #include "../../common/DebugManager.h" +#include "../TimingCalculation.h" namespace core { @@ -22,7 +23,7 @@ CommandSchedule CommandSequenceScheduler::schedule(CommandSequence commands, sc_ ICommandChecker& checker = controller.getCommandChecker(cmd); - sc_time executionTime = checker.getExecutionTime(transaction, cmd); + sc_time executionTime = getExecutionTime(cmd,transaction); ScheduledCommand& scheduledCommand = schedule.add(cmd, start, executionTime); checker.delayToSatisfyConstraints(scheduledCommand); diff --git a/dram/src/core/scheduling/ScheduledCommand.cpp b/dram/src/core/scheduling/ScheduledCommand.cpp index f1510b9e..1a78eca4 100644 --- a/dram/src/core/scheduling/ScheduledCommand.cpp +++ b/dram/src/core/scheduling/ScheduledCommand.cpp @@ -5,7 +5,7 @@ * Author: robert */ #include "ScheduledCommand.h" -#include "../utils/Utils.h" +#include "../TimingCalculation.h" #include "../../common/Utils.h" #include "../configuration/Configuration.h" diff --git a/dram/src/core/scheduling/ScheduledCommand.h b/dram/src/core/scheduling/ScheduledCommand.h index 9141cbe4..44bb4412 100644 --- a/dram/src/core/scheduling/ScheduledCommand.h +++ b/dram/src/core/scheduling/ScheduledCommand.h @@ -13,7 +13,7 @@ #include "../Command.h" #include "../../common/dramExtension.h" #include "../../common/TlmRecorder.h" -#include "../utils/Utils.h" +#include "../TimingCalculation.h" namespace core { diff --git a/dram/src/core/scheduling/checker/ActivateChecker.cpp b/dram/src/core/scheduling/checker/ActivateChecker.cpp index efdd02c2..3ad821df 100644 --- a/dram/src/core/scheduling/checker/ActivateChecker.cpp +++ b/dram/src/core/scheduling/checker/ActivateChecker.cpp @@ -8,7 +8,7 @@ #include #include #include "ActivateChecker.h" -#include "../../utils/Utils.h" +#include "../../TimingCalculation.h" #include "../../../common/DebugManager.h" #include "../../Command.h" #include "../../../common/Utils.h" @@ -31,11 +31,11 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXP); + command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.Timings.tXP); } else if (lastCommandOnBank.getCommand() == Command::SREFX) { - command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXSR); + command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.Timings.tXSR); } else reportFatal("Activate Checker", @@ -53,13 +53,6 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const } -sc_time ActivateChecker::getExecutionTime(const tlm::tlm_generic_payload& transaction, - Command command) const -{ - assert(command == Command::Activate); - return config.Timings.tRCD; -} - void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank(ScheduledCommand& command) const { ScheduledCommand lastActivateOnBank = state.getLastCommand(Command::Activate, diff --git a/dram/src/core/scheduling/checker/ActivateChecker.h b/dram/src/core/scheduling/checker/ActivateChecker.h index 7888c57e..2a31407c 100644 --- a/dram/src/core/scheduling/checker/ActivateChecker.h +++ b/dram/src/core/scheduling/checker/ActivateChecker.h @@ -22,8 +22,6 @@ public: virtual ~ActivateChecker(){} virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override; - private: const Configuration& config; ControllerState& state;//TODO make const diff --git a/dram/src/core/scheduling/checker/ICommandChecker.h b/dram/src/core/scheduling/checker/ICommandChecker.h index e9b8cb4c..ae73c5b1 100644 --- a/dram/src/core/scheduling/checker/ICommandChecker.h +++ b/dram/src/core/scheduling/checker/ICommandChecker.h @@ -17,9 +17,7 @@ class ICommandChecker { public: virtual ~ICommandChecker() {} - virtual void delayToSatisfyConstraints(ScheduledCommand& command) const = 0; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const = 0; }; } /* namespace controller */ diff --git a/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp b/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp index 522e5a2c..780462a6 100644 --- a/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp +++ b/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp @@ -51,13 +51,8 @@ void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand& command) c "Precharge All can not follow " + commandToString(lastCommand.getCommand())); } } + state.bus.moveCommandToNextFreeSlot(command); } -sc_time PrechargeAllChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const -{ - sc_assert(command == Command::PrechargeAll); - return config.Timings.tRP; -} - } /* namespace core */ diff --git a/dram/src/core/scheduling/checker/PrechargeAllChecker.h b/dram/src/core/scheduling/checker/PrechargeAllChecker.h index 92a39eec..f536a1a2 100644 --- a/dram/src/core/scheduling/checker/PrechargeAllChecker.h +++ b/dram/src/core/scheduling/checker/PrechargeAllChecker.h @@ -26,8 +26,6 @@ public: } virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const - override; private: const Configuration& config; diff --git a/dram/src/core/scheduling/checker/PrechargeChecker.cpp b/dram/src/core/scheduling/checker/PrechargeChecker.cpp index 5c8dda3c..a365f7d0 100644 --- a/dram/src/core/scheduling/checker/PrechargeChecker.cpp +++ b/dram/src/core/scheduling/checker/PrechargeChecker.cpp @@ -41,11 +41,4 @@ void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons state.bus.moveCommandToNextFreeSlot(command); } -sc_time PrechargeChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, - Command command) const -{ - sc_assert(command == Command::Precharge || command == Command::PrechargeAll); - return config.Timings.tRP; -} - } /* namespace controller */ diff --git a/dram/src/core/scheduling/checker/PrechargeChecker.h b/dram/src/core/scheduling/checker/PrechargeChecker.h index 81d27817..e93d4b73 100644 --- a/dram/src/core/scheduling/checker/PrechargeChecker.h +++ b/dram/src/core/scheduling/checker/PrechargeChecker.h @@ -19,9 +19,8 @@ class PrechargeChecker: public core::ICommandChecker public: PrechargeChecker(const Configuration& config, ControllerState& state) : config(config), state(state) {} virtual ~PrechargeChecker() {} - virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override; + private: const Configuration& config; ControllerState& state; diff --git a/dram/src/core/scheduling/checker/ReadChecker.cpp b/dram/src/core/scheduling/checker/ReadChecker.cpp index 7324081b..6536904a 100644 --- a/dram/src/core/scheduling/checker/ReadChecker.cpp +++ b/dram/src/core/scheduling/checker/ReadChecker.cpp @@ -6,7 +6,7 @@ */ #include "ReadChecker.h" -#include "../../utils/Utils.h" +#include "../../TimingCalculation.h" #include "../../../common/Utils.h" namespace core { @@ -29,7 +29,7 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const } else if (lastCommand.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tXP);//TODO DLL also for PDNP and SREF .. not onyl last command + command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tXP);//TODO DLL also for PDNP and SREF .. not onyl last command } else reportFatal("Read Checker", @@ -53,20 +53,6 @@ bool ReadChecker::collidesOnDataStrobe(ScheduledCommand& read) const return false; } -sc_time ReadChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, - Command command) const -{ - if (command == Command::Read) - { - return config.Timings.tRL + getBurstLengthOnDataStrobe(payload.get_streaming_width()); - } - else - { - return getBurstLengthOnDataStrobe(payload.get_streaming_width()) - + max(config.Timings.tRP, config.Timings.tRL); - } -} - bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read, ScheduledCommand& strobeCommand) const { diff --git a/dram/src/core/scheduling/checker/ReadChecker.h b/dram/src/core/scheduling/checker/ReadChecker.h index 60c8f514..58af651e 100644 --- a/dram/src/core/scheduling/checker/ReadChecker.h +++ b/dram/src/core/scheduling/checker/ReadChecker.h @@ -21,7 +21,6 @@ public: virtual ~ReadChecker() {} virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override; private: const Configuration& config; diff --git a/dram/src/core/scheduling/checker/RefreshChecker.cpp b/dram/src/core/scheduling/checker/RefreshChecker.cpp index 6e790338..0066173c 100644 --- a/dram/src/core/scheduling/checker/RefreshChecker.cpp +++ b/dram/src/core/scheduling/checker/RefreshChecker.cpp @@ -30,22 +30,14 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXSR); } + else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) + { + } else reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand())); } - while (!state.bus.isFree(command.getStart())) - { - command.delayStart(config.Timings.clk); - } -} - -sc_time RefreshChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const -{ - assert(command == Command::AutoRefresh); - Bank bank = DramExtension::getExtension(payload).getBank(); - RefreshTiming timing = config.Timings.refreshTimings.at(bank); - return timing.tRFC; + state.bus.moveCommandToNextFreeSlot(command); } } /* namespace core */ diff --git a/dram/src/core/scheduling/checker/RefreshChecker.h b/dram/src/core/scheduling/checker/RefreshChecker.h index 3f2c43b0..fca86dc3 100644 --- a/dram/src/core/scheduling/checker/RefreshChecker.h +++ b/dram/src/core/scheduling/checker/RefreshChecker.h @@ -15,7 +15,7 @@ namespace core { -class RefreshChecker: ICommandChecker +class RefreshChecker: public ICommandChecker { public: RefreshChecker(const Configuration& config, ControllerState& state) : @@ -27,7 +27,6 @@ public: } virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override; private: const Configuration& config; diff --git a/dram/src/core/scheduling/checker/WriteChecker.cpp b/dram/src/core/scheduling/checker/WriteChecker.cpp index b00347aa..ad8f86ac 100644 --- a/dram/src/core/scheduling/checker/WriteChecker.cpp +++ b/dram/src/core/scheduling/checker/WriteChecker.cpp @@ -6,7 +6,7 @@ */ #include "WriteChecker.h" -#include "../../utils/Utils.h" +#include "../../TimingCalculation.h" #include "../../../common/Utils.h" namespace core { @@ -30,7 +30,7 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const } else if (lastCommand.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tXP); + command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tXP); } else reportFatal("Write Checker", @@ -43,26 +43,6 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const } } -sc_time WriteChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, - Command command) const -{ - assert(command == Command::Write || command == Command::WriteA); - - sc_time lengthOnDataStrobe = getBurstLengthOnDataStrobe(payload.get_streaming_width()); - if(Configuration::getInstance().DataRate == 1) - lengthOnDataStrobe -= Configuration::getInstance().Timings.clk; - - - if (command == Command::Write) - { - return config.Timings.tWL + lengthOnDataStrobe; - } - else - { - return config.Timings.tWL + lengthOnDataStrobe + config.Timings.tWR; - } -} - bool WriteChecker::collidesOnDataStrobe(ScheduledCommand& write) const { for (ScheduledCommand& strobeCommand : state.lastDataStrobeCommands) diff --git a/dram/src/core/scheduling/checker/WriteChecker.h b/dram/src/core/scheduling/checker/WriteChecker.h index b174bf76..48cc2ed9 100644 --- a/dram/src/core/scheduling/checker/WriteChecker.h +++ b/dram/src/core/scheduling/checker/WriteChecker.h @@ -21,7 +21,6 @@ public: virtual ~WriteChecker() {} virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override; private: bool collidesOnDataStrobe(ScheduledCommand& write) const; bool collidesWithStrobeCommand(ScheduledCommand& write, ScheduledCommand& strobeCommand) const; diff --git a/dram/src/core/utils/Utils.cpp b/dram/src/core/utils/Utils.cpp deleted file mode 100644 index 163c2cb7..00000000 --- a/dram/src/core/utils/Utils.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Utils.cpp - * - * Created on: Mar 12, 2014 - * Author: jonny - */ - -#include "Utils.h" -#include "../configuration/TimingConfiguration.h" -#include "../ControllerCore.h" -#include "../../common/DebugManager.h" -#include "../configuration/Configuration.h" - -namespace core { - - -sc_time getDistance(sc_time a, sc_time b) -{ - if (a > b) - return a - b; - else - return b - a; -} - -sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint) -{ - if (previous + constraint > start) - return previous + constraint - start; - else - return SC_ZERO_TIME; -} - -const sc_time clkAlign(sc_time time, Alignment alignment) -{ - sc_time clk = Configuration::getInstance().Timings.clk; - if (alignment == UP) - return ceil(time / clk) * clk; - else - return floor(time / clk) * clk; -} - -bool isClkAligned(sc_time time, sc_time clk) -{ - return !((time / clk) - ceil(time / clk)); -} - -bool TimeInterval::timeIsInInterval(sc_time time) -{ - return (start < time && time < end); -} - -bool TimeInterval::intersects(TimeInterval other) -{ - return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start); -} - -sc_time getBurstLengthOnDataStrobe(unsigned int burstlength) -{ - Configuration& config = Configuration::getInstance(); - sc_assert((burstlength / config.DataRate) > 0); - - return config.Timings.clk * (burstlength / config.DataRate); -} - - - -void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank) -{ - payload.set_address(bank.getStartAddress()); - payload.set_command(tlm::TLM_READ_COMMAND); - payload.set_data_length(0); - payload.set_response_status(tlm::TLM_OK_RESPONSE); - payload.set_dmi_allowed(false); - payload.set_byte_enable_length(0); - payload.set_streaming_width(0); - payload.set_extension(new DramExtension(Thread(0), bank, bank.getBankGroup(), Row(0), Column(0))); //payload takes ownership -} - -} diff --git a/dram/src/simulation/Arbiter.h b/dram/src/simulation/Arbiter.h index 10eb0723..cfc3a4bf 100644 --- a/dram/src/simulation/Arbiter.h +++ b/dram/src/simulation/Arbiter.h @@ -17,7 +17,7 @@ #include #include "../common/xmlAddressdecoder.h" #include "../common/dramExtension.h" -#include "../core/utils/Utils.h" +#include "../core/TimingCalculation.h" #include diff --git a/dram/src/simulation/Controller.h b/dram/src/simulation/Controller.h index 4619ad0d..58aee120 100644 --- a/dram/src/simulation/Controller.h +++ b/dram/src/simulation/Controller.h @@ -42,8 +42,7 @@ public: tlm_utils::simple_target_socket tSocket; Controller(sc_module_name name) : - frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, - &Controller::dramPEQCallback), controllerPEQ(this, + frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerPEQ(this, &Controller::controllerPEQCallback), debugManager(DebugManager::getInstance()) { controller = new ControllerCore(*this, numberOfPayloadsInSystem); @@ -65,19 +64,13 @@ public: if (selectedScheduler == "FR_FCFS") { -// if(Configuration::getInstance().RefreshAwareScheduling) -// cout << "Building refresh aware scheduler" << std::endl; -// else -// cout << "Building refresh un-aware scheduler" << std::endl; - scheduler = new FR_FCFS(controller->state.bankStates, - Configuration::getInstance().RefreshAwareScheduling, + scheduler = new FR_FCFS(controller->state.bankStates, Configuration::getInstance().RefreshAwareScheduling, Configuration::getInstance().AdaptiveOpenPagePolicy); } else if (selectedScheduler == "PAR_BS") { - scheduler = new PAR_BS(controller->state.bankStates, - Configuration::getInstance().RefreshAwareScheduling, + scheduler = new PAR_BS(controller->state.bankStates, Configuration::getInstance().RefreshAwareScheduling, Configuration::getInstance().Capsize); } else if (selectedScheduler == "FIFO") @@ -181,15 +174,15 @@ public: break; case Command::PDNAX: dramPEQ.notify(payload, END_PDNA, command.getStart() - sc_time_stamp()); - rec.recordPhase(payload, END_PDNA, command.getStart()); + rec.recordPhase(payload, END_PDNA, command.getEnd()); break; case Command::PDNPX: dramPEQ.notify(payload, END_PDNP, command.getStart() - sc_time_stamp()); - rec.recordPhase(payload, END_PDNP, command.getStart()); + rec.recordPhase(payload, END_PDNP, command.getEnd()); break; case Command::SREFX: dramPEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp()); - rec.recordPhase(payload, END_SREF, command.getStart()); + rec.recordPhase(payload, END_SREF, command.getEnd()); break; default: SC_REPORT_FATAL(0, "unsupported command in controller"); @@ -207,10 +200,6 @@ public: { controllerPEQ.notify(payload, REFRESH_TRIGGER, delay); } - else if (trigger == Trigger::WakeUpTrigger) - { - controllerPEQ.notify(payload, WAKEUP_TRIGGER, delay); - } else { SC_REPORT_FATAL("controller wrapper", "unknown trigger"); @@ -234,7 +223,7 @@ private: unsigned int getNumberOfPayloadsInSystem() { unsigned int sum = 0; - for(Bank bank : controller->getBanks()) + for (Bank bank : controller->getBanks()) { sum += numberOfPayloadsInSystem[bank]; } @@ -245,22 +234,15 @@ private: { Bank bank = DramExtension::getExtension(payload).getBank(); printDebugMessage("Transaction enters system on bank " + to_string(bank.ID())); - numberOfPayloadsInSystem[bank] = numberOfPayloadsInSystem[bank] + 1; - scheduler->schedule(&payload); + numberOfPayloadsInSystem[bank]++; } void payloadLeavesSystem(tlm_generic_payload& payload) { Bank bank = DramExtension::getExtension(payload).getBank(); numberOfPayloadsInSystem[bank]--; - if (numberOfPayloadsInSystem[bank] == 0) - { - printDebugMessage( - "Payload leaving system. No more payloads on bank " + to_string(bank.ID()) - + ". Trigger sleep."); - controller->powerDownManager->sleep(bank, sc_time_stamp()); - } + controller->powerDownManager->sleep(bank, sc_time_stamp()); } void scheduleNextPayload(Bank bank) @@ -275,15 +257,7 @@ private: return; } - if (controller->powerDownManager->isInPowerDown(bank)) - { - printDebugMessage("\t-> wake up bank first"); - controller->powerDownManager->wakeUp(bank, sc_time_stamp()); - } - else if (controller->powerDownManager->isAwakeForRefresh(bank)) - { - controller->powerDownManager->wakeUp(bank, sc_time_stamp()); - } + controller->powerDownManager->wakeUp(bank, sc_time_stamp()); tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank); if (controller->scheduleRequest(sc_time_stamp(), *nextTransaction)) @@ -293,13 +267,13 @@ private: } else { - printDebugMessage( - "\t-> break: payload was not scheduled by core (collision with refresh)"); + printDebugMessage("\t-> break: payload was not scheduled by core (collision with refresh)"); } } else { printDebugMessage("\t-> break: no transaction for bank"); + controller->powerDownManager->sleep(bank, sc_time_stamp()); } } @@ -317,22 +291,25 @@ private: if (phase == BEGIN_REQ) { payload.acquire(); - if(getNumberOfPayloadsInSystem() == controller->config.MaxNrOfTransactions) + payloadEntersSystem(payload); + + if (getNumberOfPayloadsInSystem() > controller->config.MaxNrOfTransactions) { printDebugMessage("##Backpressure: Max number of transactions in system reached"); backpressure = &payload; return TLM_ACCEPTED; } - payloadEntersSystem(payload); - frontendPEQ.notify(payload, phase, inputBufferDelay); + frontendPEQ.notify(payload, phase, + clkAlign(sc_time_stamp()) - sc_time_stamp() + Configuration::getInstance().Timings.clk); } else if (phase == END_RESP) { - if(backpressure != NULL) + if (backpressure != NULL) { - payloadEntersSystem(*backpressure); - frontendPEQ.notify(*backpressure, BEGIN_REQ, inputBufferDelay); + printDebugMessage("##Backpressure released"); + //already registered above + frontendPEQ.notify(*backpressure, BEGIN_REQ, Configuration::getInstance().Timings.clk); backpressure = NULL; } @@ -347,6 +324,7 @@ private: { if (phase == BEGIN_REQ) { + scheduler->schedule(&payload); scheduleNextPayload(DramExtension::getExtension(payload).getBank()); payload.set_response_status(tlm::TLM_OK_RESPONSE); TlmRecorder::getInstance().recordPhase(payload, END_REQ, sc_time_stamp()); @@ -354,8 +332,7 @@ private: } else { - SC_REPORT_FATAL(0, - "Frontend PEQ event queue in controller wrapper was triggered with unknown phase"); + SC_REPORT_FATAL(0, "Frontend PEQ event queue in controller wrapper was triggered with unknown phase"); } } @@ -384,16 +361,12 @@ private: } else if (isIn(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) { - printDebugMessage( - "Entering PowerDown " + phaseNameToString(phase) + " on bank " - + to_string(bank.ID())); + printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); sendToDram(payload, phase, SC_ZERO_TIME); } else if (isIn(phase, { END_PDNA, END_PDNP, END_SREF })) { - printDebugMessage( - "Leaving PowerDown " + phaseNameToString(phase) + " on bank " - + to_string(bank.ID())); + printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); sendToDram(payload, phase, SC_ZERO_TIME); } else if (phase == BEGIN_AUTO_REFRESH) @@ -404,11 +377,6 @@ private: else if (phase == END_AUTO_REFRESH) { printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); - if (numberOfPayloadsInSystem[bank] == 0) - { - printDebugMessage("\t -> Triggering sleep on bank " + to_string(bank.ID())); - controller->powerDownManager->sleep(bank, sc_time_stamp()); - } scheduleNextPayload(DramExtension::getExtension(payload).getBank()); } else if (isIn(phase, { END_PRE, END_PRE_ALL, END_ACT })) @@ -419,9 +387,7 @@ private: { ostringstream oss; oss << phase; - string str = string( - "dramPEQCallback queue in controller wrapper was triggered with unknown phase ") - + oss.str(); + string str = string("dramPEQCallback queue in controller wrapper was triggered with unknown phase ") + oss.str(); SC_REPORT_FATAL(0, str.c_str()); } } @@ -432,14 +398,9 @@ private: { controller->triggerRefresh(payload, sc_time_stamp()); } - else if (phase == WAKEUP_TRIGGER) - { - controller->triggerWakeUp(payload, sc_time_stamp()); - } else { - SC_REPORT_FATAL(0, - "controllerPEQCallback queue in controller wrapper was triggered with unknown phase"); + SC_REPORT_FATAL(0, "controllerPEQCallback queue in controller wrapper was triggered with unknown phase"); } } diff --git a/dram/src/simulation/SimulationManager.cpp b/dram/src/simulation/SimulationManager.cpp index 99bbfb69..4099e197 100644 --- a/dram/src/simulation/SimulationManager.cpp +++ b/dram/src/simulation/SimulationManager.cpp @@ -61,7 +61,7 @@ Simulation::Simulation(sc_module_name name, string pathToResources, string trace whiteList.push_back(this->name()); whiteList.push_back(TlmRecorder::senderName); whiteList.push_back(ControllerCore::senderName); - whiteList.push_back(PowerDownManager::senderName); + whiteList.push_back(PowerDownManagerBankwise::senderName); } auto& dbg = DebugManager::getInstance(); diff --git a/dram/src/simulation/main.cpp b/dram/src/simulation/main.cpp index 9383da0f..8c67fa28 100644 --- a/dram/src/simulation/main.cpp +++ b/dram/src/simulation/main.cpp @@ -38,7 +38,7 @@ bool runSimulation(string resources, string traceName, DramSetup setup, vector -#include "core/utils/Utils.h" +#include "core/TimingCalculation.h" #include "core/utils/RingBuffer.h" //using namespace testing;