diff --git a/dram/.cproject b/dram/.cproject index 65ad912f..8f265b3c 100644 --- a/dram/.cproject +++ b/dram/.cproject @@ -19,7 +19,7 @@ - + @@ -96,24 +96,24 @@ - + - - - + + + - + diff --git a/dram/.settings/language.settings.xml b/dram/.settings/language.settings.xml index 278289a3..127cd8ac 100644 --- a/dram/.settings/language.settings.xml +++ b/dram/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + diff --git a/dram/gmon.out b/dram/gmon.out new file mode 100644 index 00000000..6be26781 Binary files /dev/null and b/dram/gmon.out differ diff --git a/dram/src/common/DebugManager.cpp b/dram/src/common/DebugManager.cpp index f8de5633..6ec24ec0 100644 --- a/dram/src/common/DebugManager.cpp +++ b/dram/src/common/DebugManager.cpp @@ -6,8 +6,6 @@ */ #include "DebugManager.h" -#include -#include using namespace std; @@ -17,85 +15,27 @@ DebugManager& DebugManager::getInstance() return manager; } -void DebugManager::printDebugMessage(string message, Sender sender, Importance importance) +void DebugManager::printDebugMessage(string sender,string message) { - bool show = count(whiteList.begin(), whiteList.end(), - pair(sender, importance)); - if (show) + if (whiteList.count(sender)) { - cout << importanceToString(importance); if (printTime) std::cout << " at " << sc_time_stamp(); if (printLocation) - std::cout << " in " << senderToString(sender); - cout << ": \t " << message << endl; + std::cout << " in " << sender; + cout << "\t: " << message << endl; } } -void DebugManager::printDebugMessage(std::string message, Sender sender, unsigned int senderNumber, - Importance importance) +void DebugManager::addToWhiteList(string sender) { - bool show = count(whiteList.begin(), whiteList.end(), - pair(sender, importance)); - - if (show) - { - cout << importanceToString(importance); - if (printTime) - std::cout << " at " << sc_time_stamp(); - if (printLocation) - std::cout << " in " << senderToString(sender) << "number " << senderNumber; - cout << ": \t " << message << endl; - } + whiteList.insert(sender); } - -void DebugManager::addToWhiteList(Sender sender, Importance importance) +void DebugManager::addToWhiteList(vector senders) { - whiteList.push_back(pair(sender, importance)); -} - -void DebugManager::addToWhiteList(Sender sender) -{ - addToWhiteList(sender, Importance::Info); - addToWhiteList(sender, Importance::Warning); -} - -void DebugManager::addToWhiteList(vector senders) -{ - for(Sender sender: senders) + for(string sender: senders) addToWhiteList(sender); } -string DebugManager::importanceToString(Importance importancy) -{ - switch (importancy) - { - case Importance::Info: - return ""; - case Importance::Warning: - return "[Warning]"; - } - return "unknown importance"; -} - -string DebugManager::senderToString(Sender sender) -{ - switch (sender) - { - case Sender::DramController: - return "DRAM core"; - case Sender::DramWrapper: - return "DRAM Wrapper"; - case Sender::Scheduler: - return "Scheduler"; - case Sender::TracePlayer: - return "TracePlayer"; - case Sender::TraceRecorder: - return "TraceRecorder"; - case Sender::PowerDownManager: - return "PowerDownManger"; - } - return "unknown sender"; -} diff --git a/dram/src/common/DebugManager.h b/dram/src/common/DebugManager.h index f94d3fb8..ac8a2bb3 100644 --- a/dram/src/common/DebugManager.h +++ b/dram/src/common/DebugManager.h @@ -9,10 +9,8 @@ #define DEBUGMANAGER_H_ #include - -enum class Importance {Warning, Info}; -enum class Sender {DramController, DramWrapper, Scheduler, TracePlayer, TraceRecorder, PowerDownManager}; - +#include +#include class DebugManager { @@ -22,20 +20,16 @@ public: bool printTime; bool printLocation; - void printDebugMessage(std::string message, Sender sender, Importance importance=Importance::Info); - void printDebugMessage(std::string message, Sender sender,unsigned int senderNumber, Importance importance=Importance::Info); + void printDebugMessage(std::string message, std::string sender); - void addToWhiteList(Sender sender, Importance importance); - void addToWhiteList(std::vector senders); - void addToWhiteList(Sender sender); + void addToWhiteList(std::string sender); + void addToWhiteList(std::vector senders); private: DebugManager() : printTime(true), printLocation(true) {}; DebugManager(const DebugManager&); - std::vector> whiteList; - std::string senderToString(Sender sender); - std::string importanceToString(Importance importancy); + std::set whiteList; }; diff --git a/dram/src/common/TlmRecorder.cpp b/dram/src/common/TlmRecorder.cpp index f23e932f..286c8ced 100644 --- a/dram/src/common/TlmRecorder.cpp +++ b/dram/src/common/TlmRecorder.cpp @@ -5,15 +5,18 @@ #include "Utils.h" #include - using namespace std; -TlmRecorder::TlmRecorder(string dbName, string sqlScriptURI) : - dbName(dbName), transactionIDCounter(1), recordingEndTime(SC_ZERO_TIME) +string TlmRecorder::dbName = ""; +string TlmRecorder::sqlScriptURI = ""; +string TlmRecorder::senderName = "TlmRecorder"; + +TlmRecorder::TlmRecorder() : + transactionIDCounter(1), recordingEndTime(SC_ZERO_TIME) { setUpTransactionTerminatingPhases(); - openDB(dbName.c_str()); - createTables(sqlScriptURI); + openDB(TlmRecorder::dbName.c_str()); + createTables(TlmRecorder::sqlScriptURI); prepareSqlStatements(); sqlite3_exec(db, "BEGIN", 0, 0, 0); @@ -26,8 +29,13 @@ TlmRecorder::~TlmRecorder() closeConnection(); } -void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase phase, - sc_time time) +TlmRecorder& TlmRecorder::getInstance() +{ + static TlmRecorder decoder; + return decoder; +} + +void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase phase, sc_time time) { if (currentTransactionsInSystem.count(&trans) == 0) introduceNewTransactionToSystem(time, trans); @@ -46,7 +54,7 @@ void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase ph else { phaseName.erase(0, phaseEndPrefix.length()); - updatePhaseEndInDB(phaseName,time, trans); + updatePhaseEndInDB(phaseName, time, trans); } bool phaseTerminatesTransaction = count(transactionTerminatingPhases.begin(), @@ -57,7 +65,6 @@ void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase ph recordingEndTime = time; } - void TlmRecorder::recordDebugMessage(std::string message, sc_time time) { insertDebugMessageInDB(message, time); @@ -151,9 +158,10 @@ void TlmRecorder::insertRangeInDB(unsigned int id, const sc_time& time) sqlite3_bind_int64(insertRangeStatement, 3, time.value()); executeSqlStatement(insertRangeStatement); } -void TlmRecorder::insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans) +void TlmRecorder::insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, + tlm::tlm_generic_payload& trans) { - unsigned int id = getElementFromMap(currentTransactionsInSystem,&trans); + unsigned int id = getElementFromMap(currentTransactionsInSystem, &trans); sqlite3_bind_text(insertPhaseStatement, 1, phaseName.c_str(), phaseName.length(), 0); sqlite3_bind_int64(insertPhaseStatement, 2, begin.value()); sqlite3_bind_int64(insertPhaseStatement, 3, end.value()); @@ -161,9 +169,10 @@ void TlmRecorder::insertPhaseInDB(string phaseName, const sc_time& begin, const executeSqlStatement(insertPhaseStatement); } -void TlmRecorder::updatePhaseEndInDB(string phaseName, const sc_time& time, tlm::tlm_generic_payload& trans) +void TlmRecorder::updatePhaseEndInDB(string phaseName, const sc_time& time, + tlm::tlm_generic_payload& trans) { - unsigned int id = getElementFromMap(currentTransactionsInSystem,&trans); + unsigned int id = getElementFromMap(currentTransactionsInSystem, &trans); sqlite3_bind_int64(updatePhaseStatement, 1, time.value()); sqlite3_bind_int(updatePhaseStatement, 2, id); sqlite3_bind_text(updatePhaseStatement, 3, phaseName.c_str(), phaseName.length(), 0); @@ -189,7 +198,7 @@ void TlmRecorder::introduceNewTransactionToSystem(const sc_time& time, void TlmRecorder::removeTransactionFromSystem(const sc_time& time, tlm::tlm_generic_payload& trans) { - unsigned int id = getElementFromMap(currentTransactionsInSystem,&trans); + unsigned int id = getElementFromMap(currentTransactionsInSystem, &trans); currentTransactionsInSystem.erase(&trans); sqlite3_bind_int64(updateRangeStatement, 1, time.value()); sqlite3_bind_int(updateRangeStatement, 2, id); @@ -233,20 +242,10 @@ string TlmRecorder::getFileContents(string filename) } throw(errno); } -// -//string TlmRecorder::phaseToString(tlm::tlm_phase phase) -//{ -// ostringstream oss; -// oss << phase; -// string str = oss.str(); -// return str; -//} - -void TlmRecorder::printDebugMessage(std::string message, Importance importance) +void TlmRecorder::printDebugMessage(std::string message) { - DebugManager::getInstance().printDebugMessage(dbName + " - " + message, Sender::TraceRecorder, - Importance::Info); + DebugManager::getInstance().printDebugMessage(TlmRecorder::senderName, message); } void TlmRecorder::closeConnection() diff --git a/dram/src/common/TlmRecorder.h b/dram/src/common/TlmRecorder.h index 3aa8a0f1..707a1d9b 100755 --- a/dram/src/common/TlmRecorder.h +++ b/dram/src/common/TlmRecorder.h @@ -20,19 +20,20 @@ using namespace std; class TlmRecorder { public: - - TlmRecorder(std::string dbName, std::string sqlScriptURI); - ~TlmRecorder(); + static std::string sqlScriptURI; + static std::string dbName; + static std::string senderName; + static TlmRecorder& getInstance(); void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time); void recordPhase(tlm::tlm_generic_payload &trans, std::string name, sc_time begin, sc_time end); void recordDebugMessage(std::string message, sc_time time); - void closeConnection(); private: - std::string dbName; - //std::string phaseToString(tlm::tlm_phase phase); + TlmRecorder(); + ~TlmRecorder(); + std::string getFileContents(std::string filename); void executeSqlCommand(std::string command); @@ -41,7 +42,6 @@ private: void openDB(std::string name); void setUpTransactionTerminatingPhases(); - void createTables(std::string pathToURI); void insertGeneralInfo(); void introduceNewTransactionToSystem(const sc_time& time, tlm::tlm_generic_payload& trans); @@ -52,7 +52,7 @@ private: void updatePhaseEndInDB(string phaseName, const sc_time& time, tlm::tlm_generic_payload& trans); void insertDebugMessageInDB(string message, const sc_time& time); - void printDebugMessage(std::string message, Importance importance = Importance::Info); + void printDebugMessage(std::string message); static const int transactionCommitRate = 10000; map currentTransactionsInSystem; diff --git a/dram/src/common/Utils.h b/dram/src/common/Utils.h index 568826d2..71c5d4ae 100644 --- a/dram/src/common/Utils.h +++ b/dram/src/common/Utils.h @@ -14,11 +14,10 @@ #include #include - -template -Val getElementFromMap(std::map& m, Key key) +template +Val getElementFromMap(std::map& m, Key key) { - if(m.count(key) == 0) + if (m.count(key) == 0) { SC_REPORT_FATAL("Map", "Element not in map"); } @@ -26,6 +25,17 @@ Val getElementFromMap(std::map& m, Key key) return m.at(key); } +template +bool isIn(const T& value, const std::vector& collection) +{ + for (T t : collection) + { + if (t == value) + return true; + } + return false; +} + void reportFatal(std::string sender, std::string message); std::string phaseNameToString(tlm::tlm_phase phase); diff --git a/dram/src/core/Command.cpp b/dram/src/core/Command.cpp index a4629ed6..53310152 100644 --- a/dram/src/core/Command.cpp +++ b/dram/src/core/Command.cpp @@ -59,16 +59,6 @@ std::string commandToString(Command command) return ""; } -bool commandIsIn(Command command, std::vector commands) -{ - for (Command c : commands) - { - if (c == command) - return true; - } - return false; -} - const std::vector& getAllCommands() { static std::vector allCommands( { Command::Precharge, Command::PrechargeAll, diff --git a/dram/src/core/Command.h b/dram/src/core/Command.h index 3f4c1596..db88ca12 100644 --- a/dram/src/core/Command.h +++ b/dram/src/core/Command.h @@ -14,7 +14,6 @@ namespace core { enum class Command {NOP, Precharge, PrechargeAll, Activate, Read, Write, ReadA, WriteA, AutoRefresh, PDNA, PDNAX, PDNP, PDNPX, SREF, SREFX}; std::string commandToString(Command command); -bool commandIsIn(Command command, std::vector commands); const std::vector& getAllCommands(); diff --git a/dram/src/core/Configuration.h b/dram/src/core/Configuration.h index 3b6399e2..3e4224ff 100644 --- a/dram/src/core/Configuration.h +++ b/dram/src/core/Configuration.h @@ -15,7 +15,7 @@ namespace core{ struct Configuration { - Configuration(): NumberOfBanks(8), NumberOfBankGroups(4), Burstlength(2), Timings(NumberOfBanks), BankwiseRefresh(false),BankwisePowerDown(false), + Configuration(): NumberOfBanks(8), NumberOfBankGroups(4), Burstlength(2), Timings(NumberOfBanks), BankwiseRefresh(true),BankwisePowerDown(true), nActivate(2) {} unsigned int NumberOfBanks; diff --git a/dram/src/core/Controller.cpp b/dram/src/core/ControllerCore.cpp similarity index 71% rename from dram/src/core/Controller.cpp rename to dram/src/core/ControllerCore.cpp index e296ed72..bd116391 100644 --- a/dram/src/core/Controller.cpp +++ b/dram/src/core/ControllerCore.cpp @@ -6,7 +6,7 @@ */ #include -#include "Controller.h" +#include "ControllerCore.h" #include "scheduling/checker/ActivateChecker.h" #include "scheduling/checker/PrechargeChecker.h" #include "scheduling/checker/PrechargeAllChecker.h" @@ -16,14 +16,16 @@ #include "refresh/RefreshManager.h" #include "../common/dramExtension.h" #include "../common/Utils.h" -#include "powerdown/PowerDownManagerBankwise.h" #include "powerdown/PowerDownManager.h" +#include "powerdown/PowerDownManagerGrouped.h" #include "../common/DebugManager.h" namespace core { -Controller::Controller(IWrapperConnector& wrapperConnector, TlmRecorder& recorder, std::map& numberOfPayloads) : - config(), state(&config), wrapper(wrapperConnector), commandChecker(), recorder(recorder), numberOfPayloads(numberOfPayloads), savedState( +std::string ControllerCore::senderName = "Controller Core"; + +ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map& numberOfPayloads) : + config(), state(&config), wrapper(wrapperConnector), commandChecker(), numberOfPayloads(numberOfPayloads), savedState( &config), commandSequenceGenerator(state), commandSequenceScheduler(*this) { @@ -39,12 +41,12 @@ Controller::Controller(IWrapperConnector& wrapperConnector, TlmRecorder& recorde refreshManager = new RefreshManager(*this); if (config.BankwisePowerDown) - powerDownManager = new PowerDownManagerBankwise(*this); - else powerDownManager = new PowerDownManager(*this); + else + powerDownManager = new PowerDownManagerGrouped(*this); } -Controller::~Controller() +ControllerCore::~ControllerCore() { delete commandChecker[Command::Activate]; delete commandChecker[Command::Precharge]; @@ -54,20 +56,20 @@ Controller::~Controller() delete powerDownManager; } -void Controller::saveState() +void ControllerCore::saveState() { savedState = state; } -void Controller::resetState() +void ControllerCore::resetState() { state = savedState; } -void Controller::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time) +void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time) { Bank bank = DramExtension::getExtension(payload).getBank(); - DebugManager::getInstance().printDebugMessage("Scheduling refresh on bank " + to_string(bank.ID()), Sender::DramController); + printDebugMessage("Scheduling refresh on bank " + to_string(bank.ID())); state.cleanUp(time); @@ -76,18 +78,21 @@ void Controller::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time) if (!powerDownManager->isInSelfRefresh(bank)) { - if(powerDownManager->isInPowerDown(bank)) + if(config.BankwiseRefresh) powerDownManager->wakeUpForRefresh(bank, time);//expect PDNA and PDNP to exit without delay + else + powerDownManager->wakeUpAllForRefresh(time); + refreshManager->scheduleRefresh(payload, time); } } -void Controller::triggerWakeUp(tlm::tlm_generic_payload& payload, sc_time time) +void ControllerCore::triggerWakeUp(tlm::tlm_generic_payload& payload, sc_time time) { powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), time); } -bool Controller::scheduleRequest(sc_time start, tlm::tlm_generic_payload& payload) +bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& payload) { start = clkAlign(start, config.Timings.clk); state.cleanUp(start); @@ -110,13 +115,13 @@ bool Controller::scheduleRequest(sc_time start, tlm::tlm_generic_payload& payloa } } -bool Controller::isBusy(sc_time time, Bank bank) +bool ControllerCore::isBusy(sc_time time, Bank bank) { ScheduledCommand lastScheduledCommand = state.getLastScheduledCommand(bank); if (lastScheduledCommand.isNoCommand()) return false; - else if (lastScheduledCommand.isIn( { Command::Write, Command::Read })) + else if (lastScheduledCommand.commandIsIn( { Command::Write, Command::Read })) { return (time < lastScheduledCommand.getStart()); } @@ -124,7 +129,7 @@ bool Controller::isBusy(sc_time time, Bank bank) { return (time < lastScheduledCommand.getEnd()); } - else if (lastScheduledCommand.isIn( { Command::SREFX, Command::PDNPX, Command::PDNAX })) + else if (lastScheduledCommand.commandIsIn( { Command::SREFX, Command::PDNPX, Command::PDNAX })) { return false; } @@ -136,7 +141,7 @@ bool Controller::isBusy(sc_time time, Bank bank) } -BankGroup Controller::getBankGroup(Bank bank) const +BankGroup ControllerCore::getBankGroup(Bank bank) const { static std::map bankgroups; if (bankgroups.size() == 0) @@ -152,7 +157,7 @@ BankGroup Controller::getBankGroup(Bank bank) const return bankgroups.at(bank); } -const std::vector& Controller::getBanks() const +const std::vector& ControllerCore::getBanks() const { static std::vector banks; if (banks.size() == 0) @@ -166,7 +171,7 @@ const std::vector& Controller::getBanks() const return banks; } -void Controller::send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const +void ControllerCore::send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const { for (const ScheduledCommand& cmd : schedule.getScheduledCommands()) { @@ -175,10 +180,15 @@ void Controller::send(const CommandSchedule& schedule, tlm::tlm_generic_payload& } -ICommandChecker& Controller::getCommandChecker(Command command) +ICommandChecker& ControllerCore::getCommandChecker(Command command) { return *getElementFromMap(commandChecker, command); } +void ControllerCore::printDebugMessage(string message) +{ + DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, message); +} + } /* namespace controller */ diff --git a/dram/src/core/Controller.h b/dram/src/core/ControllerCore.h similarity index 82% rename from dram/src/core/Controller.h rename to dram/src/core/ControllerCore.h index baae0ba3..92f16786 100644 --- a/dram/src/core/Controller.h +++ b/dram/src/core/ControllerCore.h @@ -1,5 +1,5 @@ /* - * controller.h + * ControllerCore.h * * Created on: Mar 5, 2014 * Author: jonny @@ -12,7 +12,7 @@ #include #include "IWrapperConnector.h" #include "Configuration.h" -#include "powerdown/IPowerDownManager.h" +#include "powerdown/PowerDownManager.h" #include "refresh/IRefreshManager.h" #include "scheduling/CommandSequenceGenerator.h" #include "scheduling/checker/ICommandChecker.h" @@ -21,11 +21,11 @@ namespace core { -class Controller +class ControllerCore { public: - Controller(IWrapperConnector& wrapper, TlmRecorder& recorder, std::map& numberOfPayloads); - virtual ~Controller() ; + ControllerCore(IWrapperConnector& wrapper, std::map& numberOfPayloads); + virtual ~ControllerCore() ; bool isBusy(sc_time currentTime, Bank bank); bool scheduleRequest(sc_time currentTime, tlm::tlm_generic_payload& payload); @@ -46,11 +46,13 @@ public: Configuration config; ControllerState state; IWrapperConnector& wrapper; - TlmRecorder& recorder; - IPowerDownManager* powerDownManager; + PowerDownManager* powerDownManager; IRefreshManager* refreshManager; std::map& numberOfPayloads; + static std::string senderName; + static void printDebugMessage(string message); + private: std::map commandChecker; ControllerState savedState; diff --git a/dram/src/core/powerdown/IPowerDownManager.h b/dram/src/core/powerdown/IPowerDownManager.h deleted file mode 100644 index 9caead10..00000000 --- a/dram/src/core/powerdown/IPowerDownManager.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * IPowerDownManager.h - * - * Created on: Mar 31, 2014 - * Author: jonny - */ - -#ifndef IPOWERDOWNMANAGER_H_ -#define IPOWERDOWNMANAGER_H_ - -#include -#include "../../common/dramExtension.h" - -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; - virtual bool isInPowerDown(Bank bank) = 0; - virtual bool isAwakeForRefresh(Bank bank) = 0; - -}; - -}/* namespace core */ - -#endif /* IPOWERDOWNMANAGER_H_ */ diff --git a/dram/src/core/powerdown/PowerDownManager.cpp b/dram/src/core/powerdown/PowerDownManager.cpp index 3b112afe..eba8b183 100644 --- a/dram/src/core/powerdown/PowerDownManager.cpp +++ b/dram/src/core/powerdown/PowerDownManager.cpp @@ -1,53 +1,140 @@ /* - * PowerDownManager.cpp + * IPowerDownManager.cpp * - * Created on: Apr 1, 2014 + * Created on: Apr 4, 2014 * Author: jonny */ -#include -#include #include "PowerDownManager.h" -#include "../Controller.h" -#include "../utils/Utils.h" -#include "../../common/DebugManager.h" +#include "../ControllerCore.h" +#include "../../common/Utils.h" using namespace tlm; -using namespace std; namespace core { -PowerDownManager::PowerDownManager(Controller& controller) : - controller(controller), powerDownPayloads(controller.config.NumberOfBanks) +std::string PowerDownManager::senderName = "Powerdown Manager"; +PowerDownManager::PowerDownManager(ControllerCore& controller) : + controller(controller) { - setupPayloads(); init(); } - -PowerDownManager::~PowerDownManager() +void PowerDownManager::sleep(Bank bank, sc_time time) { -} + assert(canSleep(bank)); -/* - * All Banks are precharged and in Precharge-PowerDown after starting the system - */ -void PowerDownManager::init() -{ - for (Bank bank : controller.getBanks()) + PowerDownState state = getPowerDownState(bank); + if (state == PowerDownState::Awake) //coming from active { - ScheduledCommand pdn(Command::PDNP, SC_ZERO_TIME, SC_ZERO_TIME, - DramExtension::getExtension(powerDownPayloads.at(bank.ID()))); - controller.state.change(pdn); - controller.wrapper.send(pdn, powerDownPayloads.at(bank.ID())); - setState(PowerDownState::PDNPrecharge); + if (controller.state.bankStates.rowBufferIsOpen(bank)) + setState(PowerDownState::PDNActive, bank); + else + setState(PowerDownState::PDNPrecharge, bank); + + sendPowerDownPayload(time, bank, getSleepCommand(getPowerDownState(bank))); + } + else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down + { + sc_assert(!controller.state.bankStates.rowBufferIsOpen(bank)); + + if (controller.state.getLastCommand(Command::PDNA).getStart() + > controller.state.getLastCommand(Command::PDNP).getStart()) + setState(PowerDownState::PDNPrecharge, bank); + else + setState(PowerDownState::PDNSelfRefresh, bank); + + sendPowerDownPayload(time, bank, getSleepCommand(getPowerDownState(bank))); + } + else + { + SC_REPORT_FATAL("Power Down Manager", "Sleep triggered even though already in sleep"); } } -void PowerDownManager::setState(PowerDownState state) +void PowerDownManager::wakeUp(Bank bank, sc_time time) { - powerDownState = state; + if (isAwakeForRefresh(bank)) + { + //Request enters system during Refresh (power down already waked up and payload sent) + setState(PowerDownState::Awake, bank); + } + else if (isInPowerDown(bank)) + { + //Request wakes up power down + sc_time delay(SC_ZERO_TIME); + switch (getPowerDownState(bank)) + { + 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, bank, getWakeUpCommand(getPowerDownState(bank))); + setState(PowerDownState::Awake, bank); + } + else + { + tlm_generic_payload& p = getPayload(bank); + controller.wrapper.send(WakeUpTrigger, time + delay, p); + } + } +} + +void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time) +{ + if (isInPowerDown(bank)) + { + sendPowerDownPayload(time, bank, getWakeUpCommand(getPowerDownState(bank))); + setState(PowerDownState::AwakeForRefresh, bank); + } +} + +void PowerDownManager::wakeUpAllForRefresh(sc_time time) +{ + for (Bank bank : controller.getBanks()) + { + wakeUpForRefresh(bank, time); + } +} + +bool PowerDownManager::isInPowerDown(Bank bank) +{ + return isIn(getPowerDownState(bank), { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, + PowerDownState::PDNSelfRefresh }); +} + +bool PowerDownManager::isInSelfRefresh(Bank bank) +{ + return getPowerDownState(bank) == PowerDownState::PDNSelfRefresh; +} + +bool PowerDownManager::isAwakeForRefresh(Bank bank) +{ + return getPowerDownState(bank) == PowerDownState::AwakeForRefresh; +} + +bool PowerDownManager::isAwake(Bank bank) +{ + return getPowerDownState(bank) == PowerDownState::Awake; +} + +void PowerDownManager::setState(PowerDownState state, Bank bank) +{ + PowerDownState& bankstate = getPowerDownState(bank); + bankstate = state; + string stateName; - switch (state) + switch (bankstate) { case PowerDownState::Awake: stateName = "Awake"; @@ -65,133 +152,17 @@ void PowerDownManager::setState(PowerDownState state) stateName = "PDN Self refresh"; break; default: + stateName = "unknown state"; break; } - DebugManager::getInstance().printDebugMessage("Is now in state " + stateName, - Sender::PowerDownManager); + DebugManager::getInstance().printDebugMessage(PowerDownManager::senderName, + "Is now in state " + stateName + " on Bank " + to_string(bank.ID())); } -bool PowerDownManager::canSleep() -{ - int numberOfPayloadsInSystem = 0; - //TODO check pending refresh - for (Bank bank : controller.getBanks()) - { - numberOfPayloadsInSystem += controller.numberOfPayloads[bank]; - } - return (numberOfPayloadsInSystem == 0); -} - -void PowerDownManager::sleep(Bank bank, sc_time time) -{ - if (isInPowerDown(bank)) - return; - - if (!canSleep()) - return; - - if (powerDownState == PowerDownState::Awake) - { - if (controller.state.bankStates.allRowBuffersAreClosed()) - { - setState(PowerDownState::PDNPrecharge); - } - else - { - setState(PowerDownState::PDNActive); - } - sendPowerdownBegin(time); - } - else if (powerDownState == PowerDownState::AwakeForRefresh) - { - - sc_assert(controller.state.bankStates.allRowBuffersAreClosed()); - //wait for last autorefresh in system - if (controller.state.getLastCommand(Command::AutoRefresh).getBank() != bank) - return; - - //last running refresh triggers sleep - if (controller.state.getLastCommand(Command::PDNA).getStart() - > controller.state.getLastCommand(Command::PDNP).getStart()) - setState(PowerDownState::PDNPrecharge); - else - setState(PowerDownState::PDNSelfRefresh); - - sendPowerdownBegin(time); - } - else - { - SC_REPORT_FATAL("Power Down Manager", "Sleep triggered even though already in sleep"); - } -} - -void PowerDownManager::wakeUp(Bank bank, sc_time time) -{ - if (isInPowerDown(bank)) - { - //Request wakes up power down - - sc_time delay(SC_ZERO_TIME); - switch (powerDownState) - { - 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; - } - - if (delay == SC_ZERO_TIME) - { - sendPowerdownEnd(time); - setState(PowerDownState::Awake); - } - else - { - controller.wrapper.send(WakeUpTrigger, time + delay, powerDownPayloads.at(0)); - } - } - else if (powerDownState == PowerDownState::AwakeForRefresh) - { - //Request enters system during Refresh (power down already waked up) - setState(PowerDownState::Awake); - } -} - -void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time) -{ - if (isInPowerDown(bank)) - { - sendPowerdownEnd(time); - setState(PowerDownState::AwakeForRefresh); - } -} - -bool PowerDownManager::isInSelfRefresh(Bank bank) -{ - return powerDownState == PowerDownState::PDNSelfRefresh; -} - -bool PowerDownManager::isInPowerDown(Bank bank) -{ - return powerDownState != PowerDownState::Awake - && powerDownState != PowerDownState::AwakeForRefresh; -} - -bool PowerDownManager::isAwakeForRefresh(Bank bank) -{ - return powerDownState == PowerDownState::AwakeForRefresh; -} - -void PowerDownManager::sendPowerdownBegin(sc_time time) +Command PowerDownManager::getSleepCommand(PowerDownState state) { Command cmd(Command::NOP); - - switch (powerDownState) + switch (state) { case PowerDownState::PDNActive: cmd = Command::PDNA; @@ -205,28 +176,13 @@ void PowerDownManager::sendPowerdownBegin(sc_time time) default: SC_REPORT_FATAL("In PowerDownManager sendPowerdownBegin", "invalid powerDownState"); } - - time = clkAlign(time, controller.config.Timings.clk); - - ScheduledCommand pdn(cmd, time, SC_ZERO_TIME, - DramExtension::getExtension(powerDownPayloads.at(0))); - - controller.state.bus.moveCommandToNextFreeSlot(pdn); - - for (tlm::tlm_generic_payload& payload : powerDownPayloads) - { - ScheduledCommand pdnToSend(cmd, pdn.getStart(), SC_ZERO_TIME, - DramExtension::getExtension(payload)); - controller.state.change(pdnToSend); - controller.wrapper.send(pdnToSend, payload); - } + return cmd; } -void PowerDownManager::sendPowerdownEnd(sc_time time) +Command PowerDownManager::getWakeUpCommand(PowerDownState state) { Command cmd(Command::NOP); - - switch (powerDownState) + switch (state) { case PowerDownState::PDNActive: cmd = Command::PDNAX; @@ -240,26 +196,55 @@ void PowerDownManager::sendPowerdownEnd(sc_time time) default: SC_REPORT_FATAL("In PowerDownManager sendPowerdownEnd", "invalid powerDownState"); } - - time = clkAlign(time, controller.config.Timings.clk); //TODO is clkaligned already? - - ScheduledCommand pdn(cmd, time, SC_ZERO_TIME, - DramExtension::getExtension(powerDownPayloads.at(0))); - - for (tlm::tlm_generic_payload& payload : powerDownPayloads) - { - ScheduledCommand pdnToSend(cmd, pdn.getStart(), SC_ZERO_TIME, - DramExtension::getExtension(payload)); - controller.state.change(pdnToSend); - controller.wrapper.send(pdnToSend, payload); - } + return cmd; } -void PowerDownManager::setupPayloads() +void PowerDownManager::sendPowerDownPayload(sc_time time, Bank bank, Command cmd) +{ + time = clkAlign(time, controller.config.Timings.clk); //TODO is clkaligned already? + + tlm_generic_payload& payload = getPayload(bank); + ScheduledCommand pdn(cmd, time, SC_ZERO_TIME, DramExtension::getExtension(payload)); + controller.state.bus.moveCommandToNextFreeSlot(pdn); + controller.state.change(pdn); + controller.wrapper.send(pdn, payload); +} + +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.at(bank.ID()); + tlm_generic_payload& payload = powerDownPayloads[bank]; payload.set_address(getStartAddress(bank)); payload.set_command(tlm::TLM_READ_COMMAND); payload.set_data_length(0); @@ -268,8 +253,16 @@ void PowerDownManager::setupPayloads() payload.set_byte_enable_length(0); payload.set_streaming_width(0); payload.set_extension(new DramExtension(Thread(0), bank, Row(0), Column(0))); //payload takes ownership + + //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; + //setState(PowerDownState::PDNPrecharge, bank); } } -} /* namespace core */ +}/* namespace core */ diff --git a/dram/src/core/powerdown/PowerDownManager.h b/dram/src/core/powerdown/PowerDownManager.h index 9a4dc535..4ae685e0 100644 --- a/dram/src/core/powerdown/PowerDownManager.h +++ b/dram/src/core/powerdown/PowerDownManager.h @@ -1,47 +1,67 @@ /* - * PowerDownManager.h + * IPowerDownManager.h * - * Created on: Apr 1, 2014 + * Created on: Mar 31, 2014 * Author: jonny */ -#ifndef POWERDOWNMANAGER_H_ -#define POWERDOWNMANAGER_H_ +#ifndef IPOWERDOWNMANAGER_H_ +#define IPOWERDOWNMANAGER_H_ -#include "IPowerDownManager.h" +#include +#include +#include +#include +#include "../Command.h" +#include "../../common/dramExtension.h" namespace core { -class Controller; +class ControllerCore; -class PowerDownManager : public IPowerDownManager +enum class PowerDownState { -public: - PowerDownManager(Controller& controller); - virtual ~PowerDownManager(); - - 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; - virtual bool isInPowerDown(Bank bank) override; - virtual bool isAwakeForRefresh(Bank bank) override; - -private: - Controller& controller; - std::vector powerDownPayloads; - PowerDownState powerDownState; - - bool canSleep(); - void sendPowerdownEnd(sc_time time); - void sendPowerdownBegin(sc_time time); - void setState(PowerDownState state); - - void setupPayloads(); - void init(); - + Awake, AwakeForRefresh, PDNActive, PDNPrecharge, PDNSelfRefresh }; -} /* namespace core */ +class PowerDownManager +{ +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); -#endif /* POWERDOWNMANAGER_H_ */ + virtual bool isInSelfRefresh(Bank bank); + virtual bool isInPowerDown(Bank bank); + virtual bool isAwake(Bank bank); + virtual bool isAwakeForRefresh(Bank bank); + + static std::string senderName; +protected: + + ControllerCore& controller; + 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(sc_time time, Bank bank, Command cmd); + + void init(); +}; + +}/* namespace core */ + +#endif /* IPOWERDOWNMANAGER_H_ */ diff --git a/dram/src/core/powerdown/PowerDownManagerBankwise.cpp b/dram/src/core/powerdown/PowerDownManagerBankwise.cpp deleted file mode 100644 index ab0cbd29..00000000 --- a/dram/src/core/powerdown/PowerDownManagerBankwise.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * PowerDownManager.cpp - * - * Created on: Mar 9, 2014 - * Author: jonny - */ - -#include "PowerDownManagerBankwise.h" -#include "../utils/Utils.h" -#include "../Controller.h" - -using namespace tlm; - -namespace core { - -PowerDownManagerBankwise::PowerDownManagerBankwise(Controller& controller) : - controller(controller), powerDownStates(controller.config.NumberOfBanks, - PowerDownState::Awake), powerDownPayloads( - controller.config.NumberOfBanks) -{ - setupPayloads(); - init(); -} - -PowerDownManagerBankwise::~PowerDownManagerBankwise() -{ -} - -/* - * All Banks are precharged and in Precharge-PowerDown after starting the system - */ -void PowerDownManagerBankwise::init() -{ - for (Bank bank : controller.getBanks()) - { - ScheduledCommand pdn(Command::PDNP, SC_ZERO_TIME, SC_ZERO_TIME, - DramExtension::getExtension(powerDownPayloads.at(bank.ID()))); - controller.state.change(pdn); - controller.wrapper.send(pdn, powerDownPayloads.at(bank.ID())); - powerDownStates.at(bank.ID()) = PowerDownState::PDNPrecharge; - } -} - -bool PowerDownManagerBankwise::isInPowerDown(Bank bank) -{ - return powerDownStates.at(bank.ID()) != PowerDownState::Awake; -} - -bool PowerDownManagerBankwise::isInSelfRefresh(Bank bank) -{ - return powerDownStates.at(bank.ID()) == PowerDownState::PDNSelfRefresh; -} - -void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) -{ - if (powerDownStates.at(bank.ID()) == PowerDownState::PDNPrecharge) - { - powerDownStates.at(bank.ID()) = PowerDownState::PDNSelfRefresh; - } - else - { - if (controller.state.bankStates.rowBufferIsOpen(bank)) - { - powerDownStates.at(bank.ID()) = PowerDownState::PDNActive; - } - else - { - powerDownStates.at(bank.ID()) = PowerDownState::PDNPrecharge; - } - } - - sendBegin(bank, time); -} - -void PowerDownManagerBankwise::wakeUp(Bank bank, sc_time time) -{ - wakeUpForRefresh(bank, time); - powerDownStates.at(bank.ID()) = PowerDownState::Awake; -} - -void PowerDownManagerBankwise::wakeUpForRefresh(Bank bank, sc_time time) -{ - if(powerDownStates.at(bank.ID()) != PowerDownState::Awake) - { - sendEnd(bank, time); - } -} - -void PowerDownManagerBankwise::sendBegin(Bank bank, sc_time time) -{ - Command cmd(Command::NOP); - - switch (powerDownStates.at(bank.ID())) - { - case PowerDownState::PDNActive: - cmd = Command::PDNA; - break; - case PowerDownState::PDNPrecharge: - cmd = Command::PDNP; - break; - case PowerDownState::PDNSelfRefresh: - cmd = Command::SREF; - break; - } - - sc_assert(cmd != Command::NOP); - - - //time = clkAlign(time, controller.config.Timings.clk); - - ScheduledCommand pdn(cmd, time, SC_ZERO_TIME, - DramExtension::getExtension(powerDownPayloads.at(bank.ID()))); - - controller.state.bus.moveCommandToNextFreeSlot(pdn); - controller.state.change(pdn); - controller.wrapper.send(pdn, powerDownPayloads.at(bank.ID())); -} - -void PowerDownManagerBankwise::sendEnd(Bank bank, sc_time time) -{ - Command cmd(Command::NOP); - - switch (powerDownStates.at(bank.ID())) - { - case PowerDownState::PDNActive: - cmd = Command::PDNAX; - break; - case PowerDownState::PDNPrecharge: - cmd = Command::PDNPX; - break; - case PowerDownState::PDNSelfRefresh: - time += getDelayToMeetConstraint( - controller.state.getLastCommand(Command::SREF, bank).getStart(), time, - controller.config.Timings.tCKESR); - cmd = Command::SREFX; - break; - } - - sc_assert(cmd != Command::NOP); - - time = clkAlign(time, controller.config.Timings.clk); - - ScheduledCommand pdn(cmd, time, SC_ZERO_TIME, - DramExtension::getExtension(powerDownPayloads.at(bank.ID()))); - controller.state.bus.moveCommandToNextFreeSlot(pdn); - controller.state.change(pdn); - controller.wrapper.send(pdn, powerDownPayloads.at(bank.ID())); -} - -void PowerDownManagerBankwise::setupPayloads() -{ - for (Bank bank : controller.getBanks()) - { - tlm_generic_payload& payload = powerDownPayloads.at(bank.ID()); - payload.set_address(getStartAddress(bank)); - 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, Row(0), Column(0))); //payload takes ownership - } -} - -} /* namespace core */ diff --git a/dram/src/core/powerdown/PowerDownManagerBankwise.h b/dram/src/core/powerdown/PowerDownManagerBankwise.h deleted file mode 100644 index 55eee1f6..00000000 --- a/dram/src/core/powerdown/PowerDownManagerBankwise.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * PowerDownManager.h - * - * Created on: Mar 9, 2014 - * Author: jonny - */ - -#ifndef POWERDOWNMANAGERBANKWISE_H_ -#define POWERDOWNMANAGERBANKWISE_H_ - -#include -#include "IPowerDownManager.h" - -namespace core { - -class Controller; - -class PowerDownManagerBankwise : public IPowerDownManager -{ -public: - PowerDownManagerBankwise(Controller& 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; - virtual bool isInPowerDown(Bank bank) override; - virtual bool isAwakeForRefresh(Bank bank) override {return true;}; -private: - Controller& controller; - std::vector powerDownStates; - std::vector powerDownPayloads; - - void sendBegin(Bank bank, sc_time time); - void sendEnd(Bank bank, sc_time time); - - void setupPayloads(); - void init(); -}; - -} /* namespace core */ - -#endif /* POWERDOWNMANAGERBANKWISE_H_ */ diff --git a/dram/src/core/powerdown/PowerDownManagerGrouped.cpp b/dram/src/core/powerdown/PowerDownManagerGrouped.cpp new file mode 100644 index 00000000..62dd10ea --- /dev/null +++ b/dram/src/core/powerdown/PowerDownManagerGrouped.cpp @@ -0,0 +1,170 @@ +/* + * 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) +{ + assert(!isInPowerDown());//cause nobody calls sleep if already sleeping on all banks + + //all banks can sleep and no pending refresh + 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 + { + //last running refresh triggers sleep + if (controller.state.getLastCommand(Command::PDNA).getStart() + > controller.state.getLastCommand(Command::PDNP).getStart()) + setState(PowerDownState::PDNPrecharge); + else + setState(PowerDownState::PDNSelfRefresh); + + sendPowerDownPayload(time, getSleepCommand(getPowerDownState())); + } + else + { + SC_REPORT_FATAL("PowerDownManagerGrouped", "Sleep triggered even though already in sleep"); + } +} + +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()) + { + for (Bank bank : controller.getBanks()) + { + sendPowerDownPayload(time, getWakeUpCommand(getPowerDownState())); + } + setState(PowerDownState::AwakeForRefresh); + } + +} + +void PowerDownManagerGrouped::sendPowerDownPayload(sc_time time, Command cmd) +{ + time = clkAlign(time, controller.config.Timings.clk); + + //just to find slot + tlm_generic_payload& payload = getPayload(Bank(0)); + ScheduledCommand pdn(cmd, time, SC_ZERO_TIME, DramExtension::getExtension(payload)); + controller.state.bus.moveCommandToNextFreeSlot(pdn); + + + for (Bank bank : controller.getBanks()) + { + tlm_generic_payload& payloadToSend = getPayload(bank); + ScheduledCommand pdnToSend(cmd, pdn.getStart(), SC_ZERO_TIME, 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 new file mode 100644 index 00000000..69c333ad --- /dev/null +++ b/dram/src/core/powerdown/PowerDownManagerGrouped.h @@ -0,0 +1,47 @@ +/* + * 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 411f156d..e88891af 100644 --- a/dram/src/core/refresh/RefreshManager.cpp +++ b/dram/src/core/refresh/RefreshManager.cpp @@ -6,14 +6,14 @@ */ #include "RefreshManager.h" -#include "../Controller.h" +#include "../ControllerCore.h" using namespace tlm; namespace core { -RefreshManager::RefreshManager(Controller& controller) : - controller(controller), timing(controller.config.Timings.refreshTimings.at(0)), nextPlannedRefresh(SC_ZERO_TIME), - refreshPayloads(controller.config.NumberOfBanks) +RefreshManager::RefreshManager(ControllerCore& controller) : + controller(controller), timing(controller.config.Timings.refreshTimings.at(0)), nextPlannedRefresh( + SC_ZERO_TIME), refreshPayloads(controller.config.NumberOfBanks) { setupTransactions(); planNextRefresh(); @@ -32,18 +32,17 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time { sc_assert(!isInvalidated(payload, time)); - ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC, DramExtension::getExtension(refreshPayloads.at(0))); + ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC, + DramExtension::getExtension(refreshPayloads.at(0))); if (!controller.state.bankStates.allRowBuffersAreClosed()) { - ScheduledCommand precharge(Command::PrechargeAll, time, - controller.config.Timings.tRP, DramExtension::getExtension(refreshPayloads.at(0))); - + ScheduledCommand precharge(Command::PrechargeAll, time, controller.config.Timings.tRP, + DramExtension::getExtension(refreshPayloads.at(0))); controller.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(precharge); nextRefresh.setStart(precharge.getEnd()); - for (tlm::tlm_generic_payload& payload : refreshPayloads) { ScheduledCommand prechargeToSend(Command::PrechargeAll, precharge.getStart(), @@ -52,11 +51,15 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time controller.wrapper.send(prechargeToSend, payload); } } - + else + { + //no precharge all + controller.state.bus.moveCommandToNextFreeSlot(nextRefresh); + } for (tlm::tlm_generic_payload& payload : refreshPayloads) { - ScheduledCommand refreshToSend(Command::AutoRefresh, nextRefresh.getStart(), - timing.tRFC, DramExtension::getExtension(payload)); + ScheduledCommand refreshToSend(Command::AutoRefresh, nextRefresh.getStart(), timing.tRFC, + DramExtension::getExtension(payload)); controller.state.change(refreshToSend); controller.wrapper.send(refreshToSend, payload); } diff --git a/dram/src/core/refresh/RefreshManager.h b/dram/src/core/refresh/RefreshManager.h index 4a88d445..f86b7f4d 100644 --- a/dram/src/core/refresh/RefreshManager.h +++ b/dram/src/core/refresh/RefreshManager.h @@ -13,12 +13,12 @@ namespace core { -class Controller; +class ControllerCore; class RefreshManager : public IRefreshManager { public: - RefreshManager(Controller& controller); + RefreshManager(ControllerCore& controller); virtual ~RefreshManager(); bool hasCollision(const CommandSchedule& schedule) override; @@ -29,7 +29,7 @@ public: bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) override; private: - Controller& controller; + ControllerCore& controller; RefreshTiming& timing; sc_time nextPlannedRefresh; std::vector refreshPayloads; diff --git a/dram/src/core/refresh/RefreshManagerBankwise.cpp b/dram/src/core/refresh/RefreshManagerBankwise.cpp index dd059df9..fae2c8eb 100644 --- a/dram/src/core/refresh/RefreshManagerBankwise.cpp +++ b/dram/src/core/refresh/RefreshManagerBankwise.cpp @@ -6,14 +6,14 @@ */ #include "RefreshManagerBankwise.h" -#include "../Controller.h" +#include "../ControllerCore.h" #include "../utils/Utils.h" using namespace std; namespace core { -RefreshManagerBankwise::RefreshManagerBankwise(Controller& controller) : +RefreshManagerBankwise::RefreshManagerBankwise(ControllerCore& controller) : controller(controller) { assert(!controller.config.Timings.refreshTimings.empty()); @@ -46,7 +46,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, manager.scheduleRefresh(time); } -RefreshManagerBankwise::RefreshManagerForBank::RefreshManagerForBank(Controller& controller, +RefreshManagerBankwise::RefreshManagerForBank::RefreshManagerForBank(ControllerCore& controller, Bank bank) : controller(controller), timing(controller.config.Timings.refreshTimings.at(bank.ID())), bank( bank), nextPlannedRefresh(SC_ZERO_TIME) diff --git a/dram/src/core/refresh/RefreshManagerBankwise.h b/dram/src/core/refresh/RefreshManagerBankwise.h index e6e1de1f..310b5987 100644 --- a/dram/src/core/refresh/RefreshManagerBankwise.h +++ b/dram/src/core/refresh/RefreshManagerBankwise.h @@ -15,12 +15,12 @@ namespace core { -class Controller; +class ControllerCore; class RefreshManagerBankwise : public IRefreshManager { public: - RefreshManagerBankwise(Controller& controller); + RefreshManagerBankwise(ControllerCore& controller); virtual ~RefreshManagerBankwise(); virtual bool hasCollision(const CommandSchedule& schedule) override; @@ -35,7 +35,7 @@ private: class RefreshManagerForBank { public: - RefreshManagerForBank(Controller& controller, Bank bank); + RefreshManagerForBank(ControllerCore& controller, Bank bank); ~RefreshManagerForBank(); bool hasCollision(const CommandSchedule& schedule); @@ -45,7 +45,7 @@ private: bool isInvalidated(sc_time); private: - Controller& controller; + ControllerCore& controller; RefreshTiming& timing; Bank bank; @@ -56,7 +56,7 @@ private: void setupTransaction(); }; - Controller& controller; + ControllerCore& controller; std::vector refreshManagerForBanks; diff --git a/dram/src/core/scheduling/CommandSequenceScheduler.cpp b/dram/src/core/scheduling/CommandSequenceScheduler.cpp index 56be77f0..825e5c07 100644 --- a/dram/src/core/scheduling/CommandSequenceScheduler.cpp +++ b/dram/src/core/scheduling/CommandSequenceScheduler.cpp @@ -6,7 +6,7 @@ */ #include "CommandSequenceScheduler.h" -#include "../Controller.h" +#include "../ControllerCore.h" #include "../../common/DebugManager.h" namespace core { @@ -18,7 +18,7 @@ CommandSchedule CommandSequenceScheduler::schedule(CommandSequence commands, sc_ for (Command cmd : commands) { - DebugManager::getInstance().printDebugMessage("Scheduling command " + commandToString(cmd),Sender::DramWrapper); + ControllerCore::printDebugMessage("Scheduling command " + commandToString(cmd)); ICommandChecker& checker = controller.getCommandChecker(cmd); diff --git a/dram/src/core/scheduling/CommandSequenceScheduler.h b/dram/src/core/scheduling/CommandSequenceScheduler.h index 58ab94c1..39800ef6 100644 --- a/dram/src/core/scheduling/CommandSequenceScheduler.h +++ b/dram/src/core/scheduling/CommandSequenceScheduler.h @@ -12,18 +12,18 @@ namespace core { -class Controller; +class ControllerCore; class CommandSequenceScheduler { public: - CommandSequenceScheduler(Controller& controller) : controller(controller){} + CommandSequenceScheduler(ControllerCore& controller) : controller(controller){} virtual ~CommandSequenceScheduler(){} CommandSchedule schedule(CommandSequence commands, sc_time start, tlm::tlm_generic_payload& transaction); private: - Controller& controller; + ControllerCore& controller; }; } /* namespace controller */ diff --git a/dram/src/core/scheduling/ScheduledCommand.cpp b/dram/src/core/scheduling/ScheduledCommand.cpp index a7fbf0ce..d3b35fef 100644 --- a/dram/src/core/scheduling/ScheduledCommand.cpp +++ b/dram/src/core/scheduling/ScheduledCommand.cpp @@ -6,6 +6,7 @@ */ #include "ScheduledCommand.h" #include "../utils/Utils.h" +#include "../../common/Utils.h" namespace core { @@ -76,9 +77,9 @@ bool ScheduledCommand::operator ==(const ScheduledCommand& b) const return b.command == command && b.start == start && b.executionTime == executionTime && b.end == end; } -bool ScheduledCommand::isIn(std::vector commandSet) const +bool ScheduledCommand::commandIsIn(const std::vector& commandSet) const { - return commandIsIn(command, commandSet); + return isIn(command, commandSet); } } diff --git a/dram/src/core/scheduling/ScheduledCommand.h b/dram/src/core/scheduling/ScheduledCommand.h index aaf74432..a393ef67 100644 --- a/dram/src/core/scheduling/ScheduledCommand.h +++ b/dram/src/core/scheduling/ScheduledCommand.h @@ -50,7 +50,7 @@ public: unsigned int getBurstLength(); bool operator ==(const ScheduledCommand& b) const; - bool isIn(std::vector commandSet) const; + bool commandIsIn(const std::vector& commandSet) const; private: diff --git a/dram/src/core/scheduling/checker/ActivateChecker.cpp b/dram/src/core/scheduling/checker/ActivateChecker.cpp index e038d145..b700a65d 100644 --- a/dram/src/core/scheduling/checker/ActivateChecker.cpp +++ b/dram/src/core/scheduling/checker/ActivateChecker.cpp @@ -23,7 +23,7 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const if (lastCommandOnBank.isValidCommand()) { - if (commandIsIn(lastCommandOnBank.getCommand(), { Command::Precharge, Command::PrechargeAll, + if (isIn(lastCommandOnBank.getCommand(), { Command::Precharge, Command::PrechargeAll, Command::AutoRefresh, Command::ReadA, Command::WriteA })) { if (command.getStart() < lastCommandOnBank.getEnd()) diff --git a/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp b/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp index 8895c819..673986bb 100644 --- a/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp +++ b/dram/src/core/scheduling/checker/PrechargeAllChecker.cpp @@ -28,7 +28,7 @@ void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand& command) c { command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tWR); } - else if (lastCommand.isIn( { Command::PDNAX, Command::PDNPX, Command::SREFX, + else if (lastCommand.commandIsIn( { Command::PDNAX, Command::PDNPX, Command::SREFX, Command::AutoRefresh })) { if (command.getStart() < lastCommand.getEnd()) diff --git a/dram/src/core/utils/Utils.cpp b/dram/src/core/utils/Utils.cpp index 0ac3499e..c71014b7 100644 --- a/dram/src/core/utils/Utils.cpp +++ b/dram/src/core/utils/Utils.cpp @@ -7,6 +7,8 @@ #include "Utils.h" #include "../TimingConfiguration.h" +#include "../ControllerCore.h" +#include "../../common/DebugManager.h" namespace core { diff --git a/dram/src/scheduler/Fifo.h b/dram/src/scheduler/Fifo.h index cb1dcacf..c8092cd6 100644 --- a/dram/src/scheduler/Fifo.h +++ b/dram/src/scheduler/Fifo.h @@ -9,7 +9,7 @@ #define FIFO_H_ #include "Scheduler.h" -#include "../core/Controller.h" +#include "../core/ControllerCore.h" #include #include @@ -18,7 +18,7 @@ namespace scheduler { class Fifo : public Scheduler { public: - Fifo(const core::Controller& controller) : buffer(controller.getBanks().size()) + Fifo(const core::ControllerCore& controller) : buffer(controller.getBanks().size()) {} virtual ~Fifo() {} diff --git a/dram/src/scheduler/Fr_Fcfs.h b/dram/src/scheduler/Fr_Fcfs.h index f76593e7..f8f5f011 100644 --- a/dram/src/scheduler/Fr_Fcfs.h +++ b/dram/src/scheduler/Fr_Fcfs.h @@ -2,7 +2,7 @@ #define FR_FCFS_H_ #include "Scheduler.h" -#include "../core/Controller.h" +#include "../core/ControllerCore.h" #include #include @@ -11,7 +11,7 @@ namespace scheduler { class FR_FCFS : public Scheduler { public: - FR_FCFS(core::Controller& controller) : bankstates(controller.getBankStates()), buffer(controller.getBanks().size()) + FR_FCFS(core::ControllerCore& controller) : bankstates(controller.getBankStates()), buffer(controller.getBanks().size()) {} virtual ~FR_FCFS() {} diff --git a/dram/src/simulation/arbiter.h b/dram/src/simulation/Arbiter.h similarity index 100% rename from dram/src/simulation/arbiter.h rename to dram/src/simulation/Arbiter.h diff --git a/dram/src/simulation/controllerwrapper.h b/dram/src/simulation/Controller.h similarity index 77% rename from dram/src/simulation/controllerwrapper.h rename to dram/src/simulation/Controller.h index 048ab1d8..26bbf6f1 100644 --- a/dram/src/simulation/controllerwrapper.h +++ b/dram/src/simulation/Controller.h @@ -22,7 +22,7 @@ #include "../common/TlmRecorder.h" #include "../common/DebugManager.h" #include "../core/IWrapperConnector.h" -#include "../core/Controller.h" +#include "../core/ControllerCore.h" #include "../scheduler/Scheduler.h" #include "../scheduler/Fifo.h" #include "../scheduler/Fr_Fcfs.h" @@ -33,33 +33,40 @@ using namespace core; using namespace scheduler; template -struct ControllerWrapper: public sc_module, public IWrapperConnector +struct Controller: public sc_module, public IWrapperConnector { public: - tlm_utils::simple_initiator_socket iSocket; - tlm_utils::simple_target_socket tSocket; + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; - ControllerWrapper(sc_module_name name, TlmRecorder& recorder) : - frontendPEQ(this, &ControllerWrapper::frontendPEQCallback), dramPEQ(this, - &ControllerWrapper::dramPEQCallback), controllerPEQ(this, - &ControllerWrapper::controllerPEQCallback), recorder(recorder), debugManager( - DebugManager::getInstance()) + Controller(sc_module_name name) : + frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, + &Controller::dramPEQCallback), controllerPEQ(this, + &Controller::controllerPEQCallback), debugManager(DebugManager::getInstance()) { - controller = new Controller(*this, recorder, numberOfPayloads); - scheduler = new Fifo(*controller); + controller = new ControllerCore(*this, numberOfPayloadsInSystem); + scheduler = new FR_FCFS(*controller); inputBufferDelay = controller->config.Timings.clk; - iSocket.register_nb_transport_bw(this, &ControllerWrapper::nb_transport_bw); - tSocket.register_nb_transport_fw(this, &ControllerWrapper::nb_transport_fw); + iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); } - ~ControllerWrapper() + ~Controller() { delete controller; delete scheduler; } + void terminateSimulation() + { + for (Bank bank : controller->getBanks()) + { + controller->powerDownManager->wakeUp(bank, sc_time_stamp()); + } + } + virtual void send(const ScheduledCommand& command, tlm_generic_payload& payload) override { assert(command.getStart() >= sc_time_stamp()); @@ -120,11 +127,11 @@ public: assert(time >= sc_time_stamp()); sc_time delay = time - sc_time_stamp(); - if(trigger == Trigger::RefreshTrigger) + if (trigger == Trigger::RefreshTrigger) { controllerPEQ.notify(payload, REFRESH_TRIGGER, delay); } - else if(trigger == Trigger::WakeUpTrigger) + else if (trigger == Trigger::WakeUpTrigger) { controllerPEQ.notify(payload, WAKEUP_TRIGGER, delay); } @@ -135,33 +142,37 @@ public: } private: - Controller* controller; + ControllerCore* controller; Scheduler* scheduler; - std::map numberOfPayloads; + std::map numberOfPayloadsInSystem; - tlm_utils::peq_with_cb_and_phase frontendPEQ; - tlm_utils::peq_with_cb_and_phase dramPEQ; - tlm_utils::peq_with_cb_and_phase controllerPEQ; + tlm_utils::peq_with_cb_and_phase frontendPEQ; + tlm_utils::peq_with_cb_and_phase dramPEQ; + tlm_utils::peq_with_cb_and_phase controllerPEQ; sc_time inputBufferDelay; - TlmRecorder& recorder; DebugManager& debugManager; void payloadEntersSystem(tlm_generic_payload& payload) { printDebugMessage("Transaction enters system"); Bank bank = DramExtension::getExtension(payload).getBank(); - numberOfPayloads[bank] = numberOfPayloads[bank] + 1; + numberOfPayloadsInSystem[bank] = numberOfPayloadsInSystem[bank] + 1; scheduler->schedule(&payload); } void payloadLeavesSystem(tlm_generic_payload& payload) { Bank bank = DramExtension::getExtension(payload).getBank(); - numberOfPayloads[bank] = numberOfPayloads[bank] - 1; - sc_assert(numberOfPayloads[bank] >= 0); - if (numberOfPayloads[bank] == 0) + 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()); + } } void scheduleNextPayload(Bank bank) @@ -194,7 +205,8 @@ 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 @@ -212,7 +224,7 @@ private: tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay) { DramExtension::getExtension(payload); - recorder.recordPhase(payload, phase, sc_time_stamp()); + TlmRecorder::getInstance().recordPhase(payload, phase, sc_time_stamp()); if (phase == BEGIN_REQ) { @@ -222,7 +234,6 @@ private: } else if (phase == END_RESP) { - payloadLeavesSystem(payload); payload.release(); } @@ -235,7 +246,7 @@ private: { scheduleNextPayload(DramExtension::getExtension(payload).getBank()); payload.set_response_status(tlm::TLM_OK_RESPONSE); - recorder.recordPhase(payload, END_REQ, sc_time_stamp()); + TlmRecorder::getInstance().recordPhase(payload, END_REQ, sc_time_stamp()); sendToFrontend(payload, END_REQ, SC_ZERO_TIME); } else @@ -247,7 +258,7 @@ private: void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase) { - recorder.recordPhase(payload, phase, sc_time_stamp()); + TlmRecorder::getInstance().recordPhase(payload, phase, sc_time_stamp()); Bank bank = DramExtension::getExtension(payload).getBank(); if (phase == BEGIN_RD || phase == BEGIN_WR) @@ -255,30 +266,34 @@ private: scheduleNextPayload(bank); sendToDram(payload, phase, SC_ZERO_TIME); } - else if (phase == END_RD || phase == END_WR) + else if (phase == END_RD || phase == END_WR || phase == END_RDA || phase == END_WRA) { - recorder.recordPhase(payload, BEGIN_RESP, sc_time_stamp()); + TlmRecorder::getInstance().recordPhase(payload, BEGIN_RESP, sc_time_stamp()); sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + payloadLeavesSystem(payload); } - else if (isIn(phase, {BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL })) + else if (isIn(phase, { BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL })) { sendToDram(payload, phase, SC_ZERO_TIME); } - else if(isIn(phase, {BEGIN_PDNA, - BEGIN_PDNP, BEGIN_SREF})) + 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); if (phase == END_SREF) controller->refreshManager->reInitialize(payload, sc_time_stamp()); scheduleNextPayload(bank); } - else if(phase == BEGIN_AUTO_REFRESH) + else if (phase == BEGIN_AUTO_REFRESH) { printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID())); sendToDram(payload, phase, SC_ZERO_TIME); @@ -286,7 +301,7 @@ private: else if (phase == END_AUTO_REFRESH) { printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); - if (numberOfPayloads[bank] == 0) + if (numberOfPayloadsInSystem[bank] == 0) controller->powerDownManager->sleep(bank, sc_time_stamp()); scheduleNextPayload(DramExtension::getExtension(payload).getBank()); } @@ -337,9 +352,9 @@ private: tSocket->nb_transport_bw(payload, TPhase, TDelay); } - void printDebugMessage(string message, Importance importance = Importance::Info) + void printDebugMessage(string message) { - debugManager.printDebugMessage(message, Sender::DramWrapper, importance); + debugManager.printDebugMessage(name(), message); } bool isIn(tlm_phase phase, std::vector phases) @@ -352,13 +367,6 @@ private: return false; } - void stop() - { - for (Bank bank : controller->getBanks()) - { - controller->powerDownManager->wakeUp(bank, sc_time_stamp()); - } - } }; #endif /* CONTROLLERWRAPPER_H_ */ diff --git a/dram/src/simulation/dram.h b/dram/src/simulation/Dram.h similarity index 100% rename from dram/src/simulation/dram.h rename to dram/src/simulation/Dram.h diff --git a/dram/src/simulation/GroupPlayer.h b/dram/src/simulation/GroupPlayer.h deleted file mode 100644 index 97666b5e..00000000 --- a/dram/src/simulation/GroupPlayer.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * GroupPlayer.h - * - * Created on: Apr 1, 2014 - * Author: robert - */ - -#ifndef GROUPPLAYER_H_ -#define GROUPPLAYER_H_ - -// -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include "MemoryManager.h" -//#include "../common/DebugManager.h" -//#include "../common/xmlAddressdecoder.h" -// -//using namespace std; -//using namespace tlm; -// -//template -//struct GroupedPlayer: public sc_module -//{ -//public: -// tlm_utils::simple_initiator_socket iSocket; -// -// GroupedPlayer(sc_module_name name, string pathToTrace,void (*callback_finished)(void), unsigned int senderNumber = 0) : -// payloadEventQueue(this, &GroupedPlayer::peqCallback), file(pathToTrace), numberOfPendingTransactions( -// 0), transactionsSent(0), senderNumber(senderNumber), callback_finished(callback_finished) -// { -// if (!file.is_open()) -// SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); -// -// if (!file) -// { -// SC_REPORT_FATAL(0, "trace is empty! Simulation stops"); -// } -// -// iSocket.register_nb_transport_bw(this, &GroupedPlayer::nb_transport_bw); -// -// scheduleNextPayload(); -// } -// -//private: -// tlm_utils::peq_with_cb_and_phase payloadEventQueue; -// MemoryManager memoryManager; -// ifstream file; -// unsigned int numberOfPendingTransactions; -// unsigned int transactionsSent; -// unsigned int senderNumber; -// void (*callback_finished)(void); -// -// void scheduleNextPayload() -// { -// string time, command, address; -// file >> time >> command >> address; -// -// long parsedAdress = std::stoi(address.c_str(), 0, 16); -// -// gp* payload = memoryManager.allocate(); -// payload->set_address(parsedAdress); -// -// if (command == "read") -// { -// payload->set_command(TLM_READ_COMMAND); -// } -// else if (command == "write") -// { -// payload->set_command(TLM_WRITE_COMMAND); -// } -// else -// { -// SC_REPORT_FATAL(0, -// (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str()); -// } -// -// payload->set_data_length(BUSWIDTH / 8); -// payload->set_response_status(TLM_INCOMPLETE_RESPONSE); -// payload->set_dmi_allowed(false); -// payload->set_byte_enable_length(0); -// payload->set_streaming_width(0); -// -// sc_time sendingTime = sc_time(std::stoi(time.c_str()), SC_NS); -// if (sendingTime <= sc_time_stamp()) -// { -// payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); -// } -// else -// { -// payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime - sc_time_stamp()); -// } -// numberOfPendingTransactions++; -// } -// -// tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay) -// { -// payloadEventQueue.notify(payload, phase, bwDelay); -// return TLM_ACCEPTED; -// } -// -// void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase) -// { -// if (phase == BEGIN_REQ) -// { -// payload.acquire(); -// sendToTarget(payload, phase, SC_ZERO_TIME); -// transactionsSent++; -// DebugManager::getInstance().printDebugMessage( -// "Sending transaction number: " + std::to_string(transactionsSent), -// Sender::TracePlayer, senderNumber); -// } -// -// else if (phase == END_REQ) -// { -// scheduleNextPayload(); -// } -// else if (phase == BEGIN_RESP) -// { -// payload.release(); -// sendToTarget(payload, END_RESP, SC_ZERO_TIME); -// numberOfPendingTransactions--; -// -// DebugManager::getInstance().printDebugMessage( -// "Number of pending transactions: " -// + std::to_string(numberOfPendingTransactions), Sender::TracePlayer, -// senderNumber); -// if (numberOfPendingTransactions == 0) -// { -// callback_finished(); -//// cout << "simulation stop at " << sc_time_stamp() << std::endl; -//// sc_stop(); -// } -// } -// -// else if (phase == END_RESP) -// { -// } -// -// else -// { -// SC_REPORT_FATAL(0, "GroupedPlayer PEQ was triggered with unknown phase"); -// } -// } -// -// void sendToTarget(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) -// { -// tlm_phase TPhase = phase; -// sc_time TDelay = delay; -// iSocket->nb_transport_fw(payload, TPhase, TDelay); -// } -//}; - - - -#endif /* GROUPPLAYER_H_ */ diff --git a/dram/src/simulation/ISimulationManager.h b/dram/src/simulation/ISimulationManager.h new file mode 100644 index 00000000..cb0dbd2c --- /dev/null +++ b/dram/src/simulation/ISimulationManager.h @@ -0,0 +1,17 @@ +#ifndef ISIMULATIONMANAGER_H_ +#define ISIMULATIONMANAGER_H_ + + +namespace simulation { + +class ISimulationManager +{ +public: + virtual ~ISimulationManager(){} + virtual void tracePlayerFinishedCallback() = 0; +}; + +} // namespace simulation + + +#endif diff --git a/dram/src/simulation/SimulationManager.cpp b/dram/src/simulation/SimulationManager.cpp new file mode 100644 index 00000000..f01706ed --- /dev/null +++ b/dram/src/simulation/SimulationManager.cpp @@ -0,0 +1,85 @@ +/* + * SimulationManager.cpp + * + * Created on: Apr 4, 2014 + * Author: jonny + */ + +#include "SimulationManager.h" +#include "../common/TlmRecorder.h" +#include "../common/DebugManager.h" +#include "../common/xmlAddressdecoder.h" +#include "../core/ControllerCore.h" +#include +#include +#include +using namespace std; + +namespace simulation { + +SimulationManager::SimulationManager(sc_module_name name, std::string stl1, std::string stl2, + std::string traceName, std::string pathToResources) : + dram("dram"), arbiter("arbiter"), controller("controller"), player1("player1", + pathToResources + string("traces/") + stl1, this), player2("player2", + pathToResources + string("traces/") + stl2, this), traceName(traceName) + +{ + SC_THREAD(terminationThread); + xmlAddressDecoder::addressConfigURI = pathToResources + string("configs/addressConfig.xml"); + TlmRecorder::dbName = traceName; + TlmRecorder::sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql"); + + player1.iSocket.bind(arbiter.tSockets[0]); + player2.iSocket.bind(arbiter.tSockets[1]); + arbiter.iSocket.bind(controller.tSocket); + controller.iSocket.bind(dram.tSocket); + + vector whiteList; + whiteList.push_back(controller.name()); + whiteList.push_back(player2.name()); + whiteList.push_back(player1.name()); + whiteList.push_back(TlmRecorder::senderName); + whiteList.push_back(ControllerCore::senderName); + whiteList.push_back(PowerDownManager::senderName); + DebugManager::getInstance().addToWhiteList(whiteList); +} + +void SimulationManager::startSimulation() +{ + + clock_t begin = clock(); + + cout << "Toplevel: simulation start" << std::endl; + sc_start(); + + clock_t end = clock(); + double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC; + cout << "Simulation took " << elapsed_secs << " seconds." << endl; + cout << this->name(); + + string p = getenv("trace"); + string run_tpr = p + " " + traceName; + system(run_tpr.c_str()); +} + +void SimulationManager::tracePlayerFinishedCallback() +{ + static int finishedPlayers = 0; + finishedPlayers++; + if (finishedPlayers == numberOfTracePlayers) + { + terminateSimulation.notify(); + } +} + +void SimulationManager::terminationThread() +{ + wait(terminateSimulation); + controller.terminateSimulation(); + //waits for the termination of all pending powerdown phases in the dram system + wait(sc_time(50,SC_NS)); + TlmRecorder::getInstance().closeConnection(); + sc_stop(); +} + +} /* namespace simulation */ diff --git a/dram/src/simulation/SimulationManager.h b/dram/src/simulation/SimulationManager.h new file mode 100644 index 00000000..6b459917 --- /dev/null +++ b/dram/src/simulation/SimulationManager.h @@ -0,0 +1,44 @@ +/* + * SimulationManager.h + * + * Created on: Apr 4, 2014 + * Author: jonny + */ + +#ifndef SIMULATIONMANAGER_H_ +#define SIMULATIONMANAGER_H_ + +#include "Dram.h" +#include "Arbiter.h" +#include "TracePlayer.h" +#include "Controller.h" +#include "ISimulationManager.h" +#include +#include + +namespace simulation { + +class SimulationManager : public ISimulationManager, public sc_module +{ +public: + SC_HAS_PROCESS(SimulationManager); + SimulationManager(sc_module_name name,std::string stl1, std::string stl2, + std::string traceName, std::string pathToResources); + void startSimulation(); + void tracePlayerFinishedCallback() override; + +private: + void terminationThread(); + sc_event terminateSimulation; + constexpr static unsigned int numberOfTracePlayers = 2; + std::string traceName; + Dram<> dram; + Arbiter arbiter; + Controller<> controller; + TracePlayer<> player1; + TracePlayer<> player2; +}; + +} /* namespace simulation */ + +#endif /* SIMULATIONMANAGER_H_ */ diff --git a/dram/src/simulation/traceplayer.h b/dram/src/simulation/TracePlayer.h similarity index 83% rename from dram/src/simulation/traceplayer.h rename to dram/src/simulation/TracePlayer.h index 83994548..9f858ec6 100644 --- a/dram/src/simulation/traceplayer.h +++ b/dram/src/simulation/TracePlayer.h @@ -16,6 +16,7 @@ #include #include #include "MemoryManager.h" +#include "ISimulationManager.h" #include "../common/DebugManager.h" #include "../common/xmlAddressdecoder.h" @@ -27,10 +28,11 @@ struct TracePlayer: public sc_module { public: tlm_utils::simple_initiator_socket iSocket; - - TracePlayer(sc_module_name name, string pathToTrace,void (*callback_finished)(void), unsigned int senderNumber = 0) : + TracePlayer(sc_module_name name, string pathToTrace, + simulation::ISimulationManager* simulationManager) : payloadEventQueue(this, &TracePlayer::peqCallback), file(pathToTrace), numberOfPendingTransactions( - 0), transactionsSent(0), senderNumber(senderNumber), callback_finished(callback_finished) + 0), transactionsSent(0), transactionsReceived(0), simulationManager( + simulationManager) { if (!file.is_open()) SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); @@ -50,8 +52,8 @@ private: ifstream file; unsigned int numberOfPendingTransactions; unsigned int transactionsSent; - unsigned int senderNumber; - void (*callback_finished)(void); + unsigned int transactionsReceived; + simulation::ISimulationManager* simulationManager; void scheduleNextPayload() { @@ -115,9 +117,8 @@ private: payload.acquire(); sendToTarget(payload, phase, SC_ZERO_TIME); transactionsSent++; - DebugManager::getInstance().printDebugMessage( - "Sending transaction number: " + std::to_string(transactionsSent), - Sender::TracePlayer, senderNumber); + DebugManager::getInstance().printDebugMessage(name(), + "Sending transaction number: " + std::to_string(transactionsSent)); } else if (phase == END_REQ) @@ -129,17 +130,14 @@ private: payload.release(); sendToTarget(payload, END_RESP, SC_ZERO_TIME); numberOfPendingTransactions--; + transactionsReceived++; + + DebugManager::getInstance().printDebugMessage(name(), + "Pending transactions in core: " + + std::to_string(transactionsSent - transactionsReceived)); - DebugManager::getInstance().printDebugMessage( - "Number of pending transactions: " - + std::to_string(numberOfPendingTransactions), Sender::TracePlayer, - senderNumber); if (numberOfPendingTransactions == 0) - { - callback_finished(); -// cout << "simulation stop at " << sc_time_stamp() << std::endl; -// sc_stop(); - } + simulationManager->tracePlayerFinishedCallback(); } else if (phase == END_RESP) diff --git a/dram/src/simulation/main.cpp b/dram/src/simulation/main.cpp index 9b168f1e..1be2ce4a 100644 --- a/dram/src/simulation/main.cpp +++ b/dram/src/simulation/main.cpp @@ -6,83 +6,26 @@ */ #include -#include -#include -#include #include -#include "../common/TlmRecorder.h" -#include "../common/DebugManager.h" -#include "../common/xmlAddressdecoder.h" -#include "controllerwrapper.h" -#include "dram.h" -#include "arbiter.h" -#include "traceplayer.h" -#include -#include -#include -#include +#include "SimulationManager.h" using namespace std; +using namespace simulation; string pathOfFile(string file) { return file.substr(0, file.find_last_of('/')); } -void endOfTrace_callback() -{ - static int finishedPlayers = 0; - finishedPlayers++; - if(finishedPlayers == 2) - { - sc_stop(); - } -} - int sc_main(int argc, char **argv) { sc_set_time_resolution(1, SC_NS); string resources = pathOfFile(argv[0]) + string("/../resources/"); - xmlAddressDecoder::addressConfigURI = resources + string("configs/addressConfig.xml"); - - time_t rawtime; - time (&rawtime); -// string tracename = c_time(&rawtime) + string(".tdb"); - string tracename = string("tpr.tdb"); - TlmRecorder recorder(tracename, resources + string("scripts/createTraceDB.sql")); - - TracePlayer<> player("player", resources + string("traces/mediabench-fractal_32.stl"),endOfTrace_callback, 0); - TracePlayer<> player2("player2", resources + string("traces/mediabench-jpegdecode_32.stl"),endOfTrace_callback, 1); - - //TracePlayer<> player("player", resources + string("traces/trace2.stl"),endOfTrace_callback, 0); - //TracePlayer<> player2("player2", resources + string("traces/chstone-aes_32.stl"),endOfTrace_callback, 1); - - Dram<> dram("dram"); - Arbiter<2,128> arbiter("arbiter"); - ControllerWrapper<> controller("controller", recorder); - - - player.iSocket.bind(arbiter.tSockets[0]); - player2.iSocket.bind(arbiter.tSockets[1]); - arbiter.iSocket.bind(controller.tSocket); - controller.iSocket.bind(dram.tSocket); - - DebugManager::getInstance().addToWhiteList({Sender::TracePlayer, Sender::TraceRecorder, Sender::DramWrapper, Sender::DramController, Sender::PowerDownManager}); - - cout << "Toplevel: simulation start" << std::endl; - clock_t begin = clock(); - - sc_start(); - clock_t end = clock(); - double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC; - - recorder.closeConnection(); - cout << "Simulation took " << elapsed_secs << " seconds." << endl; - - string testingScript = resources + string("/scripts/tests.py"); - string run_tpr = "/home/robert/analyzer/build/traceAnalyzer " + tracename; - system(run_tpr.c_str()); + string stl1 = "chstone-mips_32.stl"; + string stl2 = "chstone-motion_32.stl"; + SimulationManager simulationManager("sim",stl1,stl2,"tpr.tdb", resources); + simulationManager.startSimulation(); return 0; } diff --git a/dram/testing/Controller_test.cpp b/dram/testing/Controller_test.cpp index 38c510c3..8a48c1c6 100644 --- a/dram/testing/Controller_test.cpp +++ b/dram/testing/Controller_test.cpp @@ -15,7 +15,7 @@ #include "tlm/IControllerWrapper.h" #include "testUtils.h" #include "../common/dramExtension.h" -#include "core/Controller.h" +#include "core/ControllerCore.h" #include using namespace std;