powerdown manager. simulation manager introduced
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/dram}/build-simulation" cleanBuildTarget="clean" enableAutoBuild="false" id="org.eclipse.cdt.build.core.internal.builder.1698165306" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.internal.builder"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1509734096" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.789860529" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.2041174282" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.2041174282" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.2092267417" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.include.paths.1823643375" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="/opt/systemc-2.3.0/include"/>
|
||||
@@ -96,24 +96,24 @@
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="unit_test"/>
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/DRAM-Model"/>
|
||||
</configuration>
|
||||
<configuration configurationName="unit_test"/>
|
||||
<configuration configurationName="platformArchitect">
|
||||
<resource resourceType="PROJECT" workspacePath="/DRAM"/>
|
||||
</configuration>
|
||||
<configuration configurationName="build-simulation"/>
|
||||
<configuration configurationName="testing"/>
|
||||
<configuration configurationName="simulation-build">
|
||||
<resource resourceType="PROJECT" workspacePath="/dram"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/DRAM-Model"/>
|
||||
</configuration>
|
||||
<configuration configurationName="simulation-build">
|
||||
<resource resourceType="PROJECT" workspacePath="/dram"/>
|
||||
</configuration>
|
||||
<configuration configurationName="standalone"/>
|
||||
<configuration configurationName="simulation"/>
|
||||
<configuration configurationName="build-testing"/>
|
||||
<configuration configurationName="simulation"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings">
|
||||
<doc-comment-owner id="org.eclipse.cdt.internal.ui.text.doctools.NullDocCommentOwner">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-64906255729110141" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} -E -P -v -dD "${INPUTS}" -std=c++11">
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-2055719358" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} -E -P -v -dD "${INPUTS}" -std=c++11">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
||||
BIN
dram/gmon.out
Normal file
BIN
dram/gmon.out
Normal file
Binary file not shown.
@@ -6,8 +6,6 @@
|
||||
*/
|
||||
|
||||
#include "DebugManager.h"
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
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>(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>(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<string> senders)
|
||||
{
|
||||
whiteList.push_back(pair<Sender, Importance>(sender, importance));
|
||||
}
|
||||
|
||||
void DebugManager::addToWhiteList(Sender sender)
|
||||
{
|
||||
addToWhiteList(sender, Importance::Info);
|
||||
addToWhiteList(sender, Importance::Warning);
|
||||
}
|
||||
|
||||
void DebugManager::addToWhiteList(vector<Sender> 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";
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
#define DEBUGMANAGER_H_
|
||||
|
||||
#include <systemc.h>
|
||||
|
||||
enum class Importance {Warning, Info};
|
||||
enum class Sender {DramController, DramWrapper, Scheduler, TracePlayer, TraceRecorder, PowerDownManager};
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
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<Sender> senders);
|
||||
void addToWhiteList(Sender sender);
|
||||
void addToWhiteList(std::string sender);
|
||||
void addToWhiteList(std::vector<std::string> senders);
|
||||
|
||||
private:
|
||||
DebugManager() : printTime(true), printLocation(true) {};
|
||||
DebugManager(const DebugManager&);
|
||||
|
||||
std::vector<std::pair<Sender, Importance>> whiteList;
|
||||
std::string senderToString(Sender sender);
|
||||
std::string importanceToString(Importance importancy);
|
||||
std::set<std::string> whiteList;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -5,15 +5,18 @@
|
||||
#include "Utils.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
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()
|
||||
|
||||
@@ -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<tlm::tlm_generic_payload*, unsigned int> currentTransactionsInSystem;
|
||||
|
||||
@@ -14,11 +14,10 @@
|
||||
#include <ostream>
|
||||
#include <tlm.h>
|
||||
|
||||
|
||||
template<typename Key,typename Val>
|
||||
Val getElementFromMap(std::map<Key,Val>& m, Key key)
|
||||
template<typename Key, typename Val>
|
||||
Val getElementFromMap(std::map<Key, Val>& 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<Key,Val>& m, Key key)
|
||||
return m.at(key);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool isIn(const T& value, const std::vector<T>& 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);
|
||||
|
||||
|
||||
@@ -59,16 +59,6 @@ std::string commandToString(Command command)
|
||||
return "";
|
||||
}
|
||||
|
||||
bool commandIsIn(Command command, std::vector<Command> commands)
|
||||
{
|
||||
for (Command c : commands)
|
||||
{
|
||||
if (c == command)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::vector<Command>& getAllCommands()
|
||||
{
|
||||
static std::vector<Command> allCommands( { Command::Precharge, Command::PrechargeAll,
|
||||
|
||||
@@ -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<Command> commands);
|
||||
|
||||
const std::vector<Command>& getAllCommands();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <systemc.h>
|
||||
#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<Bank, int>& numberOfPayloads) :
|
||||
config(), state(&config), wrapper(wrapperConnector), commandChecker(), recorder(recorder), numberOfPayloads(numberOfPayloads), savedState(
|
||||
std::string ControllerCore::senderName = "Controller Core";
|
||||
|
||||
ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map<Bank, int>& 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<Bank, BankGroup> bankgroups;
|
||||
if (bankgroups.size() == 0)
|
||||
@@ -152,7 +157,7 @@ BankGroup Controller::getBankGroup(Bank bank) const
|
||||
return bankgroups.at(bank);
|
||||
}
|
||||
|
||||
const std::vector<Bank>& Controller::getBanks() const
|
||||
const std::vector<Bank>& ControllerCore::getBanks() const
|
||||
{
|
||||
static std::vector<Bank> banks;
|
||||
if (banks.size() == 0)
|
||||
@@ -166,7 +171,7 @@ const std::vector<Bank>& 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 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* controller.h
|
||||
* ControllerCore.h
|
||||
*
|
||||
* Created on: Mar 5, 2014
|
||||
* Author: jonny
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <map>
|
||||
#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<Bank, int>& numberOfPayloads);
|
||||
virtual ~Controller() ;
|
||||
ControllerCore(IWrapperConnector& wrapper, std::map<Bank, int>& 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<Bank,int>& numberOfPayloads;
|
||||
static std::string senderName;
|
||||
static void printDebugMessage(string message);
|
||||
|
||||
private:
|
||||
std::map<Command, ICommandChecker*> commandChecker;
|
||||
ControllerState savedState;
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* IPowerDownManager.h
|
||||
*
|
||||
* Created on: Mar 31, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#ifndef IPOWERDOWNMANAGER_H_
|
||||
#define IPOWERDOWNMANAGER_H_
|
||||
|
||||
#include <systemc.h>
|
||||
#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_ */
|
||||
@@ -1,53 +1,140 @@
|
||||
/*
|
||||
* PowerDownManager.cpp
|
||||
* IPowerDownManager.cpp
|
||||
*
|
||||
* Created on: Apr 1, 2014
|
||||
* Created on: Apr 4, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#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 */
|
||||
|
||||
|
||||
@@ -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 <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#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<tlm::tlm_generic_payload> 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<Bank, tlm::tlm_generic_payload> powerDownPayloads;
|
||||
std::map<Bank, PowerDownState> 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_ */
|
||||
|
||||
@@ -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 */
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* PowerDownManager.h
|
||||
*
|
||||
* Created on: Mar 9, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#ifndef POWERDOWNMANAGERBANKWISE_H_
|
||||
#define POWERDOWNMANAGERBANKWISE_H_
|
||||
|
||||
#include <systemc.h>
|
||||
#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<PowerDownState> powerDownStates;
|
||||
std::vector<tlm::tlm_generic_payload> powerDownPayloads;
|
||||
|
||||
void sendBegin(Bank bank, sc_time time);
|
||||
void sendEnd(Bank bank, sc_time time);
|
||||
|
||||
void setupPayloads();
|
||||
void init();
|
||||
};
|
||||
|
||||
} /* namespace core */
|
||||
|
||||
#endif /* POWERDOWNMANAGERBANKWISE_H_ */
|
||||
170
dram/src/core/powerdown/PowerDownManagerGrouped.cpp
Normal file
170
dram/src/core/powerdown/PowerDownManagerGrouped.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* PowerDownManager.cpp
|
||||
*
|
||||
* Created on: Apr 1, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include "PowerDownManagerGrouped.h"
|
||||
#include "../ControllerCore.h"
|
||||
#include "../utils/Utils.h"
|
||||
#include "../../common/DebugManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
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 */
|
||||
|
||||
47
dram/src/core/powerdown/PowerDownManagerGrouped.h
Normal file
47
dram/src/core/powerdown/PowerDownManagerGrouped.h
Normal file
@@ -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_ */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<tlm::tlm_generic_payload> refreshPayloads;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<RefreshManagerForBank*> refreshManagerForBanks;
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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<Command> commandSet) const
|
||||
bool ScheduledCommand::commandIsIn(const std::vector<Command>& commandSet) const
|
||||
{
|
||||
return commandIsIn(command, commandSet);
|
||||
return isIn(command, commandSet);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
unsigned int getBurstLength();
|
||||
bool operator ==(const ScheduledCommand& b) const;
|
||||
|
||||
bool isIn(std::vector<Command> commandSet) const;
|
||||
bool commandIsIn(const std::vector<Command>& commandSet) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "Utils.h"
|
||||
#include "../TimingConfiguration.h"
|
||||
#include "../ControllerCore.h"
|
||||
#include "../../common/DebugManager.h"
|
||||
|
||||
namespace core
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define FIFO_H_
|
||||
|
||||
#include "Scheduler.h"
|
||||
#include "../core/Controller.h"
|
||||
#include "../core/ControllerCore.h"
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
@@ -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()
|
||||
{}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define FR_FCFS_H_
|
||||
|
||||
#include "Scheduler.h"
|
||||
#include "../core/Controller.h"
|
||||
#include "../core/ControllerCore.h"
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
@@ -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()
|
||||
{}
|
||||
|
||||
@@ -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<unsigned int BUSWIDTH = 128>
|
||||
struct ControllerWrapper: public sc_module, public IWrapperConnector
|
||||
struct Controller: public sc_module, public IWrapperConnector
|
||||
{
|
||||
public:
|
||||
|
||||
tlm_utils::simple_initiator_socket<ControllerWrapper, BUSWIDTH, tlm::tlm_base_protocol_types> iSocket;
|
||||
tlm_utils::simple_target_socket<ControllerWrapper, BUSWIDTH, tlm::tlm_base_protocol_types> tSocket;
|
||||
tlm_utils::simple_initiator_socket<Controller, BUSWIDTH, tlm::tlm_base_protocol_types> iSocket;
|
||||
tlm_utils::simple_target_socket<Controller, BUSWIDTH, tlm::tlm_base_protocol_types> 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<Bank, int> numberOfPayloads;
|
||||
std::map<Bank, int> numberOfPayloadsInSystem;
|
||||
|
||||
tlm_utils::peq_with_cb_and_phase<ControllerWrapper> frontendPEQ;
|
||||
tlm_utils::peq_with_cb_and_phase<ControllerWrapper> dramPEQ;
|
||||
tlm_utils::peq_with_cb_and_phase<ControllerWrapper> controllerPEQ;
|
||||
tlm_utils::peq_with_cb_and_phase<Controller> frontendPEQ;
|
||||
tlm_utils::peq_with_cb_and_phase<Controller> dramPEQ;
|
||||
tlm_utils::peq_with_cb_and_phase<Controller> 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<tlm_phase> 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_ */
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* GroupPlayer.h
|
||||
*
|
||||
* Created on: Apr 1, 2014
|
||||
* Author: robert
|
||||
*/
|
||||
|
||||
#ifndef GROUPPLAYER_H_
|
||||
#define GROUPPLAYER_H_
|
||||
|
||||
//
|
||||
//#include <deque>
|
||||
//#include <tlm.h>
|
||||
//#include <systemc.h>
|
||||
//#include <tlm_utils/simple_initiator_socket.h>
|
||||
//#include <tlm_utils/peq_with_cb_and_phase.h>
|
||||
//#include <iostream>
|
||||
//#include <string>
|
||||
//#include "MemoryManager.h"
|
||||
//#include "../common/DebugManager.h"
|
||||
//#include "../common/xmlAddressdecoder.h"
|
||||
//
|
||||
//using namespace std;
|
||||
//using namespace tlm;
|
||||
//
|
||||
//template<unsigned int BUSWIDTH = 128>
|
||||
//struct GroupedPlayer: public sc_module
|
||||
//{
|
||||
//public:
|
||||
// tlm_utils::simple_initiator_socket<GroupedPlayer, BUSWIDTH, tlm::tlm_base_protocol_types> 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<GroupedPlayer> 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_ */
|
||||
17
dram/src/simulation/ISimulationManager.h
Normal file
17
dram/src/simulation/ISimulationManager.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef ISIMULATIONMANAGER_H_
|
||||
#define ISIMULATIONMANAGER_H_
|
||||
|
||||
|
||||
namespace simulation {
|
||||
|
||||
class ISimulationManager
|
||||
{
|
||||
public:
|
||||
virtual ~ISimulationManager(){}
|
||||
virtual void tracePlayerFinishedCallback() = 0;
|
||||
};
|
||||
|
||||
} // namespace simulation
|
||||
|
||||
|
||||
#endif
|
||||
85
dram/src/simulation/SimulationManager.cpp
Normal file
85
dram/src/simulation/SimulationManager.cpp
Normal file
@@ -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 <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
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<string> 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 */
|
||||
44
dram/src/simulation/SimulationManager.h
Normal file
44
dram/src/simulation/SimulationManager.h
Normal file
@@ -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 <string>
|
||||
#include <systemc.h>
|
||||
|
||||
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<numberOfTracePlayers,128> arbiter;
|
||||
Controller<> controller;
|
||||
TracePlayer<> player1;
|
||||
TracePlayer<> player2;
|
||||
};
|
||||
|
||||
} /* namespace simulation */
|
||||
|
||||
#endif /* SIMULATIONMANAGER_H_ */
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#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<TracePlayer, BUSWIDTH, tlm::tlm_base_protocol_types> 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)
|
||||
@@ -6,83 +6,26 @@
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <systemc.h>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#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 <string>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
#include <time.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "tlm/IControllerWrapper.h"
|
||||
#include "testUtils.h"
|
||||
#include "../common/dramExtension.h"
|
||||
#include "core/Controller.h"
|
||||
#include "core/ControllerCore.h"
|
||||
#include <tlm.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Reference in New Issue
Block a user