changed scheduler interface. Fixed bug with terminateSimulation

This commit is contained in:
robert
2014-06-20 15:49:07 +02:00
parent 96846ca4b4
commit 2b062b86ff
42 changed files with 522 additions and 516 deletions

View File

@@ -14,18 +14,9 @@ INCLUDEPATH += /opt/boost/include
DEFINES += TIXML_USE_STL
DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES
CONFIG(release){
DEFINES += NDEBUG
QMAKE_CXXFLAGS_RELEASE -= -O
QMAKE_CXXFLAGS_RELEASE -= -O1
QMAKE_CXXFLAGS_RELEASE -= -O2
QMAKE_CXXFLAGS_RELEASE *= -O3
}
QMAKE_CXXFLAGS += -std=c++11
QMAKE_CXXFLAGS += -isystem /opt/systemc/include
QMAKE_CXXFLAGS += -isystem /opt/boost/include
#QMAKE_CXXFLAGS = -Wno-unused-variable
SOURCES += \
../src/common/third_party/tinyxml2.cpp \
@@ -60,12 +51,12 @@ SOURCES += \
../src/controller/core/ControllerState.cpp \
../src/controller/core/ControllerCore.cpp \
../src/controller/core/Command.cpp \
../src/controller/core/BankStates.cpp \
../src/simulation/SimulationManager.cpp \
../src/simulation/Simulation.cpp \
../src/simulation/MemoryManager.cpp \
../src/simulation/main.cpp \
../src/common/libDRAMPower.cpp
../src/common/libDRAMPower.cpp \
../src/controller/core/RowBufferStates.cpp
HEADERS += \
../src/common/third_party/tinyxml2.h \
@@ -112,7 +103,6 @@ HEADERS += \
../src/controller/core/ControllerState.h \
../src/controller/core/ControllerCore.h \
../src/controller/core/Command.h \
../src/controller/core/BankStates.h \
../src/simulation/TracePlayer.h \
../src/simulation/SimulationManager.h \
../src/simulation/Simulation.h \
@@ -120,6 +110,7 @@ HEADERS += \
../src/simulation/ISimulation.h \
../src/simulation/Dram.h \
../src/simulation/Arbiter.h \
../src/common/libDRAMPower.h
../src/common/libDRAMPower.h \
../src/controller/core/RowBufferStates.h

View File

@@ -9,5 +9,7 @@
<parameter id="capsize" type="uint" value="5" />
<parameter id="powerDownMode" type="string" value="Staggered" />
<parameter id="powerDownTimeout" type="uint" value="100" />
<parameter id="databaseRecordingEnabled" type="bool" value="1" />
</memconfig>
</memspec>

View File

@@ -1,6 +1,6 @@
<memspec>
<memconfig>
<parameter id="bankwiseLogic" type="bool" value="0" />
<parameter id="bankwiseLogic" type="bool" value="1" />
<parameter id="openPagePolicy" type="bool" value="1" />
<parameter id="adaptiveOpenPagePolicy" type="bool" value="0" />
<parameter id="refreshAwareScheduling" type="bool" value="1" />
@@ -9,5 +9,7 @@
<parameter id="capsize" type="uint" value="5" />
<parameter id="powerDownMode" type="string" value="Staggered" />
<parameter id="powerDownTimeout" type="uint" value="100" />
<parameter id="databaseRecordingEnabled" type="bool" value="1" />
</memconfig>
</memspec>

View File

@@ -9,5 +9,7 @@
<parameter id="capsize" type="uint" value="5" />
<parameter id="powerDownMode" type="string" value="Staggered" />
<parameter id="powerDownTimeout" type="uint" value="3" />
<parameter id="databaseRecordingEnabled" type="bool" value="1" />
</memconfig>
</memspec>

View File

@@ -9,5 +9,7 @@
<parameter id="capsize" type="uint" value="5" />
<parameter id="powerDownMode" type="string" value="Staggered" />
<parameter id="powerDownTimeout" type="uint" value="3" />
<parameter id="databaseRecordingEnabled" type="bool" value="1" />
</memconfig>
</memspec>

View File

@@ -9,5 +9,7 @@
<parameter id="capsize" type="uint" value="5" />
<parameter id="powerDownMode" type="string" value="Staggered" />
<parameter id="powerDownTimeout" type="uint" value="3" />
<parameter id="databaseRecordingEnabled" type="bool" value="1" />
</memconfig>
</memspec>

View File

@@ -9,5 +9,7 @@
<parameter id="capsize" type="uint" value="8" />
<parameter id="powerDownMode" type="string" value="Staggered" />
<parameter id="powerDownTimeout" type="uint" value="3" />
<parameter id="databaseRecordingEnabled" type="bool" value="1" />
</memconfig>
</memspec>

View File

@@ -9,5 +9,7 @@
<parameter id="capsize" type="uint" value="8" />
<parameter id="powerDownMode" type="string" value="Staggered" />
<parameter id="powerDownTimeout" type="uint" value="3" />
<parameter id="databaseRecordingEnabled" type="bool" value="1" />
</memconfig>
</memspec>

View File

@@ -8,9 +8,10 @@
<addressmapping>am_wideio.xml</addressmapping>
<memconfigs>
<memconfig>fifo.xml</memconfig>
<!-- <memconfig>fifo.xml</memconfig>
<memconfig>fr_fcfs.xml</memconfig>
<memconfig>par_bs.xml</memconfig>
--> <memconfig>par_bs.xml</memconfig>
</memconfigs>
<trace-setups>
@@ -18,14 +19,14 @@
<device>chstone-aes_32.stl</device>
</trace-setup>
<trace-setup id="mediabench">
<device >mediabench-h263decode_32.stl</device>
<trace-setup id="motion">
<device>chstone-motion.stl</device>
</trace-setup>
<trace-setup id="shared">
<device >chstone-aes_32.stl</device>
<device >mediabench-h263decode_32.stl</device>
</trace-setup>
<trace-setup id="media">
<device>mediabench-fractal_32.stl</device>
<device>mediabench-epic_32.stl</device>
</trace-setup>
</trace-setups>
</simulation>

View File

@@ -11,41 +11,34 @@ using namespace std;
void DebugManager::printDebugMessage(string sender, string message)
{
#ifndef NDEBUG
if (whiteList.count(sender))
{
if (writeToConsole)
cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message << endl;
if (whiteList.count(sender))
{
if (writeToConsole)
cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message << endl;
if (writeToFile && debugFile)
debugFile << " at " << sc_time_stamp() << " in " << sender << "\t: " << message << "\n";
}
if (writeToFile && debugFile)
debugFile << " at " << sc_time_stamp() << " in " << sender << "\t: " << message << "\n";
}
#endif
}
void DebugManager::addToWhiteList(string sender)
{
whiteList.insert(sender);
whiteList.insert(sender);
}
void DebugManager::addToWhiteList(vector<string> senders)
{
for (string sender : senders)
addToWhiteList(sender);
for (string sender : senders)
addToWhiteList(sender);
}
DebugManager::DebugManager() :
writeToConsole(true), writeToFile(true)
writeToConsole(true), writeToFile(true)
{
}
void DebugManager::setDebugFile(std::string filename)
{
if(debugFile)
debugFile.close();
debugFile.open(filename);
}
DebugManager::~DebugManager()
{
debugFile.close();
debugFile.close();
}

View File

@@ -15,32 +15,32 @@
class DebugManager
{
public:
~DebugManager();
static inline DebugManager& getInstance()
{
static DebugManager manager;
return manager;
}
~DebugManager();
static inline DebugManager& getInstance()
{
static DebugManager manager;
return manager;
}
bool writeToConsole;
bool writeToFile;
bool writeToConsole;
bool writeToFile;
void printDebugMessage(std::string message, std::string sender);
void addToWhiteList(std::string sender);
void addToWhiteList(std::vector<std::string> senders);
void setDebugFile(std::string filename);
void printDebugMessage(std::string message, std::string sender);
void openDebugFile(std::string filename)
{
if(debugFile)
debugFile.close();
debugFile.open(filename);
}
void addToWhiteList(std::string sender);
void addToWhiteList(std::vector<std::string> senders);
private:
DebugManager();
DebugManager(const DebugManager&){}
ofstream debugFile;
DebugManager();
DebugManager(const DebugManager&){};
std::set<std::string> whiteList;
ofstream debugFile;
std::set<std::string> whiteList;
};
#endif /* DEBUGMANAGER_H_ */

View File

@@ -12,27 +12,30 @@ using namespace std;
string TlmRecorder::dbName = "";
string TlmRecorder::sqlScriptURI = "";
string TlmRecorder::senderName = "TlmRecorder";
bool TlmRecorder::recordingEnabled = true;
// ------------- public -----------------------
TlmRecorder::TlmRecorder() :
transactionIDCounter(1), recordingEndTime(SC_ZERO_TIME)
{
recordedData.reserve(transactionCommitRate);
setUpTransactionTerminatingPhases();
openDB(TlmRecorder::dbName.c_str());
char * sErrMsg;
sqlite3_exec(db, "PRAGMA main.page_size = 4096", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.cache_size=10000", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.locking_mode=EXCLUSIVE", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.synchronous=OFF", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &sErrMsg);
if(recordingEnabled)
{
recordedData.reserve(transactionCommitRate);
setUpTransactionTerminatingPhases();
openDB(TlmRecorder::dbName.c_str());
char * sErrMsg;
sqlite3_exec(db, "PRAGMA main.page_size = 4096", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.cache_size=10000", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.locking_mode=EXCLUSIVE", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.synchronous=OFF", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &sErrMsg);
createTables(TlmRecorder::sqlScriptURI);
prepareSqlStatements();
createTables(TlmRecorder::sqlScriptURI);
prepareSqlStatements();
printDebugMessage("Starting new database transaction");
printDebugMessage("Starting new database transaction");
}
}
TlmRecorder::~TlmRecorder()
@@ -41,74 +44,61 @@ TlmRecorder::~TlmRecorder()
closeConnection();
}
void TlmRecorder::recordDummy(tlm::tlm_generic_payload& trans)
{
// static unsigned int id = 0;
// RecordingData data(id);
// insertTransactionInDB(data,trans);
// insertRangeInDB(id,SC_ZERO_TIME,SC_ZERO_TIME);
// for(int i=0;i<5;i++)
// {
// string phaseName("Phase " + to_string(id));
// sqlite3_bind_text(insertPhaseStatement, 1, phaseName.c_str(), phaseName.length(), 0);
// sqlite3_bind_int64(insertPhaseStatement, 2, 0);
// sqlite3_bind_int64(insertPhaseStatement, 3, 2);
// sqlite3_bind_int(insertPhaseStatement, 4, id);
// executeSqlStatement(insertPhaseStatement);
// }
// id++;
}
void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase phase, sc_time time)
{
if (currentTransactionsInSystem.count(&trans) == 0)
introduceNewTransactionToSystem(trans);
string phaseName = phaseNameToString(phase);
string phaseBeginPrefix = "BEGIN_";
string phaseEndPrefix = "END_";
if (phaseName.find(phaseBeginPrefix) != string::npos)
if(TlmRecorder::recordingEnabled)
{
phaseName.erase(0, phaseBeginPrefix.length());
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].insertPhase(phaseName,time);
}
else
{
phaseName.erase(0, phaseEndPrefix.length());
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].setPhaseEnd(phaseName,time);
}
if (currentTransactionsInSystem.count(&trans) == 0)
introduceTransactionSystem(trans);
bool phaseTerminatesTransaction = count(transactionTerminatingPhases.begin(),
transactionTerminatingPhases.end(), phase) == 1;
if (phaseTerminatesTransaction)
removeTransactionFromDBAndInsertInDB(trans);
string phaseName = phaseNameToString(phase);
string phaseBeginPrefix = "BEGIN_";
string phaseEndPrefix = "END_";
recordingEndTime = time;
if (phaseName.find(phaseBeginPrefix) != string::npos)
{
phaseName.erase(0, phaseBeginPrefix.length());
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].insertPhase(phaseName,time);
}
else
{
phaseName.erase(0, phaseEndPrefix.length());
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].setPhaseEnd(phaseName,time);
}
bool phaseTerminatesTransaction = count(transactionTerminatingPhases.begin(),
transactionTerminatingPhases.end(), phase) == 1;
if (phaseTerminatesTransaction)
removeTransactionFromSystem(trans);
recordingEndTime = time;
}
}
void TlmRecorder::updateDataStrobe(const sc_time& begin,const sc_time& end, tlm::tlm_generic_payload& trans)
{
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].timeOnDataStrobe.start = begin;
currentTransactionsInSystem[&trans].timeOnDataStrobe.end = end;
if(TlmRecorder::recordingEnabled)
{
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].timeOnDataStrobe.start = begin;
currentTransactionsInSystem[&trans].timeOnDataStrobe.end = end;
}
}
void TlmRecorder::recordDebugMessage(std::string message, sc_time time)
{
insertDebugMessageInDB(message, time);
if(TlmRecorder::recordingEnabled)
insertDebugMessageInDB(message, time);
}
// ------------- internal -----------------------
void TlmRecorder::introduceNewTransactionToSystem(tlm::tlm_generic_payload& trans)
void TlmRecorder::introduceTransactionSystem(tlm::tlm_generic_payload& trans)
{
unsigned int id = transactionIDCounter++;
currentTransactionsInSystem[&trans].id = id;
@@ -130,7 +120,7 @@ void TlmRecorder::introduceNewTransactionToSystem(tlm::tlm_generic_payload& tran
}
}
void TlmRecorder::removeTransactionFromDBAndInsertInDB(tlm::tlm_generic_payload& trans)
void TlmRecorder::removeTransactionFromSystem(tlm::tlm_generic_payload& trans)
{
assert(currentTransactionsInSystem.count(&trans) != 0);
@@ -324,12 +314,15 @@ void TlmRecorder::printDebugMessage(std::string message)
void TlmRecorder::closeConnection()
{
commitRecordedDataToDB();
insertGeneralInfo();
printDebugMessage(
"Number of transactions written to DB: " + std::to_string(transactionIDCounter - 1));
printDebugMessage("tlmPhaseRecorder:\tEnd Recording");
sqlite3_close(db);
db = NULL;
if(TlmRecorder::recordingEnabled)
{
commitRecordedDataToDB();
insertGeneralInfo();
printDebugMessage(
"Number of transactions written to DB: " + std::to_string(transactionIDCounter - 1));
printDebugMessage("tlmPhaseRecorder:\tEnd Recording");
sqlite3_close(db);
db = NULL;
}
}

View File

@@ -24,6 +24,7 @@ public:
static std::string sqlScriptURI;
static std::string dbName;
static std::string senderName;
static bool recordingEnabled;
static inline TlmRecorder& getInstance()
{
@@ -31,14 +32,14 @@ public:
return decoder;
}
void recordDummy(tlm::tlm_generic_payload& trans);
void recordMemconfig(string memconfig){this->memconfig = memconfig;}
void recordMemspec(string memspec){this->memspec = memspec;}
void recordTracenames(string traces){this->traces = traces;}
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time);
void recordDebugMessage(std::string message, sc_time time);
void updateDataStrobe(const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans);
void closeConnection();
void recordMemconfig(string memconfig){this->memconfig = memconfig;}
void recordMemspec(string memspec){this->memspec = memspec;}
void recordTracenames(string traces){this->traces = traces;}
private:
@@ -64,7 +65,6 @@ private:
void insertPhase(string name,sc_time begin);
void setPhaseEnd(string name,sc_time end);
};
std::string memconfig,memspec,traces;
@@ -80,8 +80,8 @@ private:
void createTables(std::string pathToURI);
void setUpTransactionTerminatingPhases();
void introduceNewTransactionToSystem(tlm::tlm_generic_payload& trans);
void removeTransactionFromDBAndInsertInDB(tlm::tlm_generic_payload& trans);
void introduceTransactionSystem(tlm::tlm_generic_payload& trans);
void removeTransactionFromSystem(tlm::tlm_generic_payload& trans);
void commitRecordedDataToDB();
void insertGeneralInfo();

View File

@@ -61,7 +61,7 @@ private:
class Bank
{
public:
explicit Bank(unsigned int id) :
Bank(unsigned int id) :
id(id)
{
}

View File

@@ -1,5 +1,5 @@
#include "libdrampower.h"
//#include "libdrampower.h"
libDRAMPower::libDRAMPower()
{
}
//libDRAMPower::libDRAMPower()
//{
//}

View File

@@ -8,16 +8,10 @@
#ifndef CONTROLLERWRAPPER_H_
#define CONTROLLERWRAPPER_H_
//#include <systemc.h>
//#include <tlm_utils/peq_with_cb_and_phase.h>
//#include <tlm_utils/simple_initiator_socket.h>
//#include <tlm_utils/simple_target_socket.h>
//#include <iostream>
#include <map>
#include <string>
#include <vector>
//#include <tlm.h>
#include "/opt/systemc-2.3.0/include/systemc"
#include "/opt/systemc-2.3.0/include/tlm"
#include "/opt/systemc-2.3.0/include/tlm_utils/peq_with_cb_and_phase.h"
@@ -59,7 +53,7 @@ public:
frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ(
this, &Controller::controllerCorePEQCallback), debugManager(DebugManager::getInstance())
{
controller = new ControllerCore(*this, numberOfPayloadsInSystem);
controllerCore = new ControllerCore(*this, numberOfPayloadsInSystem);
buildScheduler();
iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw);
tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw);
@@ -72,31 +66,31 @@ public:
if (selectedScheduler == "FR_FCFS")
{
scheduler = new FR_FCFS(controller->state.bankStates, Configuration::getInstance().RefreshAwareScheduling,
scheduler = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling,
Configuration::getInstance().AdaptiveOpenPagePolicy);
}
else if (selectedScheduler == "PAR_BS")
{
scheduler = new PAR_BS(controller->state.bankStates, Configuration::getInstance().RefreshAwareScheduling,
scheduler = new PAR_BS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling,
Configuration::getInstance().Capsize);
}
else if (selectedScheduler == "FIFO")
scheduler = new Fifo();
scheduler = new Fifo(*controllerCore);
else
reportFatal(name(), "unsupported scheduler: " + selectedScheduler);
}
~Controller()
{
delete controller;
delete controllerCore;
delete scheduler;
}
void terminateSimulation()
{
for (Bank bank : controller->getBanks())
for (Bank bank : controllerCore->getBanks())
{
controller->powerDownManager->wakeUp(bank, clkAlign(sc_time_stamp()));
controllerCore->powerDownManager->wakeUp(bank, clkAlign(sc_time_stamp()));
}
}
@@ -129,8 +123,6 @@ public:
controllerCorePEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp());
break;
case Command::AutoRefresh:
TlmRecorder::getInstance().recordDummy(payload);
controllerCorePEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp());
break;
case Command::Activate:
@@ -143,18 +135,12 @@ public:
controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp());
break;
case Command::PDNA:
TlmRecorder::getInstance().recordDummy(payload);
controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp());
break;
case Command::PDNP:
TlmRecorder::getInstance().recordDummy(payload);
controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp());
break;
case Command::SREF:
TlmRecorder::getInstance().recordDummy(payload);
controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp());
break;
case Command::PDNAX:
@@ -196,11 +182,11 @@ public:
{
if (phase == REF_TRIGGER)
{
controller->triggerRefresh(payload, sc_time_stamp());
controllerCore->triggerRefresh(payload, sc_time_stamp());
}
else if (phase == PDN_TRIGGER)
{
controller->powerDownManager->sleep(DramExtension::getExtension(payload).getBank(),sc_time_stamp());
controllerCore->powerDownManager->sleep(DramExtension::getExtension(payload).getBank(),sc_time_stamp());
}
else
{
@@ -208,7 +194,7 @@ public:
sendToDram(payload, phase, SC_ZERO_TIME);
if (phase == BEGIN_RD || phase == BEGIN_WR)
scheduleNextPayload(bank);
scheduleNextPayload();
else if (phase == BEGIN_AUTO_REFRESH)
printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID()));
else if (isIn(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF }))
@@ -224,7 +210,7 @@ public:
}
private:
ControllerCore* controller;
ControllerCore* controllerCore;
Scheduler* scheduler;
std::map<Bank, int> numberOfPayloadsInSystem;
@@ -258,9 +244,10 @@ private:
{
if (phase == BEGIN_REQ)
{
payload.acquire();
payloadEntersSystem(payload);
if (getTotalNumberOfPayloadsInSystem() > controller->config.MaxNrOfTransactions)
if (getTotalNumberOfPayloadsInSystem() > controllerCore->config.MaxNrOfTransactions)
{
printDebugMessage("##Backpressure: Max number of transactions in system reached");
backpressure = &payload;
@@ -269,7 +256,7 @@ private:
payload.set_response_status(tlm::TLM_OK_RESPONSE);
sendToFrontend(payload, END_REQ, SC_ZERO_TIME);
scheduler->schedule(&payload);
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
scheduleNextPayload();
}
else if (phase == END_RESP)
{
@@ -279,12 +266,11 @@ private:
backpressure->set_response_status(tlm::TLM_OK_RESPONSE);
sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME);
scheduler->schedule(backpressure);
scheduleNextPayload(DramExtension::getExtension(backpressure).getBank());
scheduleNextPayload();
backpressure = NULL;
}
payloadLeavesSystem(payload);
TlmRecorder::getInstance().recordDummy(payload);
payload.release();
}
else
@@ -309,48 +295,33 @@ private:
printDebugMessage(
"Payload left system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: "
+ to_string(getTotalNumberOfPayloadsInSystem()));
controller->powerDownManager->triggerSleep(bank, sc_time_stamp());
controllerCore->powerDownManager->triggerSleep(bank, sc_time_stamp());
}
unsigned int getTotalNumberOfPayloadsInSystem()
{
unsigned int sum = 0;
for (Bank bank : controller->getBanks())
for (Bank bank : controllerCore->getBanks())
{
sum += numberOfPayloadsInSystem[bank];
}
return sum;
}
void scheduleNextPayload(Bank bank)
void scheduleNextPayload()
{
printDebugMessage("Triggering schedule next payload on bank " + to_string(bank.ID()));
if (scheduler->hasTransactionForBank(bank))
if(scheduler->hasPayloads())
{
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
if (controller->isBusy(sc_time_stamp(), bank))
tlm_generic_payload* payload = scheduler->getNextPayload();
if(payload != NULL)
{
printDebugMessage("\t-> break: controller is busy");
return;
controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), sc_time_stamp());
if (controllerCore->scheduleRequest(sc_time_stamp(), *payload))
{
scheduler->removePayload(payload);
printDebugMessage("\t-> Next payload was scheduled by core");
}
}
tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank);
if (controller->scheduleRequest(sc_time_stamp(), *nextTransaction))
{
scheduler->popTransactionForBank(bank, nextTransaction);
printDebugMessage("\t-> payload was scheduled by core");
}
else
{
printDebugMessage("\t-> break: payload was not scheduled by core (collision with refresh)");
}
}
else
{
printDebugMessage("\t-> break: no transaction for bank");
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
}
@@ -376,7 +347,7 @@ private:
if (phase == BEGIN_RD || phase == BEGIN_WR)
{
scheduleNextPayload(bank);
scheduleNextPayload();
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if (phase == END_RD || phase == END_WR)
@@ -386,12 +357,14 @@ private:
else if (phase == END_RDA || phase == END_WRA)
{
sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME);
scheduleNextPayload(bank);
scheduleNextPayload();
}
else if (phase == END_AUTO_REFRESH)
{
printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID()));
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
if(numberOfPayloadsInSystem[bank] == 0)
controllerCore->powerDownManager->sleep(bank,sc_time_stamp());
scheduleNextPayload();
}
else if (isIn(phase, { END_PRE, END_PRE_ALL, END_ACT }))
{

View File

@@ -94,12 +94,12 @@ void ControllerCore::resetState()
void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time)
{
Bank bank = DramExtension::getExtension(payload).getBank();
printDebugMessage("Triggering refresh on bank " + to_string(bank.ID()));
state.cleanUp(time);
if (!refreshManager->isInvalidated(payload, time) && !powerDownManager->isInSelfRefresh(bank))
{
printDebugMessage("Triggering refresh on bank " + to_string(bank.ID()));
powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay
refreshManager->scheduleRefresh(payload, time);
}
@@ -127,7 +127,7 @@ bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& pa
}
}
bool ControllerCore::isBusy(sc_time time, Bank bank)
bool ControllerCore::bankIsBusy(sc_time time, Bank bank)
{
ScheduledCommand lastScheduledCommand = state.getLastScheduledCommand(bank);
@@ -158,9 +158,10 @@ bool ControllerCore::isBusy(sc_time time, Bank bank)
}
const std::vector<Bank>& ControllerCore::getBanks() const
const std::vector<Bank>& ControllerCore::getBanks()
{
static std::vector<Bank> banks;
if (banks.size() == 0)
{
for (unsigned int i = 0; i < config.NumberOfBanks; i++)
@@ -172,6 +173,17 @@ const std::vector<Bank>& ControllerCore::getBanks() const
return banks;
}
std::vector<Bank> ControllerCore::getFreeBanks(sc_time currentTime)
{
std::vector<Bank> freeBanks;
for(Bank bank: getBanks())
{
if(!bankIsBusy(currentTime, bank))
freeBanks.push_back(bank);
}
return freeBanks;
}
void ControllerCore::send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const
{
for (const ScheduledCommand& cmd : schedule.getScheduledCommands())

View File

@@ -24,40 +24,39 @@ namespace core {
class ControllerCore
{
public:
ControllerCore(IWrapperConnector& wrapper, std::map<Bank, int>& numberOfPayloads);
virtual ~ControllerCore() ;
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);
void triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time);
void triggerWakeUp(tlm::tlm_generic_payload& payload, sc_time time);
bool bankIsBusy(sc_time currentTime, Bank bank);
bool scheduleRequest(sc_time currentTime, tlm::tlm_generic_payload& payload);
void triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time);
const BankStates& getBankStates(){return state.bankStates;}
void saveState();
void resetState();
void saveState();
void resetState();
const std::vector<Bank>& getBanks() const;//TODO put in config?
const std::vector<Bank>& getBanks();
std::vector<Bank> getFreeBanks(sc_time currentTime);
const RowBufferState& getRowBufferStates(){return state.rowBufferStates;}
void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const;
ICommandChecker& getCommandChecker(Command command);
void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const;
ICommandChecker& getCommandChecker(Command command);
Configuration config;
ControllerState state;
IWrapperConnector& wrapper;
Configuration config;
ControllerState state;
IWrapperConnector& wrapper;
IPowerDownManager* powerDownManager;
IRefreshManager* refreshManager;
std::map<Bank,int>& numberOfPayloads;
static std::string senderName;
static void printDebugMessage(string message);
IPowerDownManager* 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;
CommandSequenceGenerator commandSequenceGenerator;
CommandSequenceScheduler commandSequenceScheduler;
std::map<Command, ICommandChecker*> commandChecker;
ControllerState savedState;
CommandSequenceGenerator commandSequenceGenerator;
CommandSequenceScheduler commandSequenceScheduler;
};
} /* namespace controller */

View File

@@ -79,30 +79,30 @@ void ControllerState::change(const ScheduledCommand& scheduledCommand)
lastDataStrobeCommands.emplace_back(scheduledCommand);
break;
case Command::ReadA:
bankStates.closeRowBuffer(scheduledCommand.getBank());
rowBufferStates.closeRowBuffer(scheduledCommand.getBank());
lastDataStrobeCommands.emplace_back(scheduledCommand);
break;
case Command::Write:
lastDataStrobeCommands.emplace_back(scheduledCommand);
break;
case Command::WriteA:
bankStates.closeRowBuffer(scheduledCommand.getBank());
rowBufferStates.closeRowBuffer(scheduledCommand.getBank());
lastDataStrobeCommands.emplace_back(scheduledCommand);
break;
case Command::AutoRefresh:
break;
case Command::Activate:
bankStates.openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow());
rowBufferStates.openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow());
lastActivates.emplace(scheduledCommand.getStart(), scheduledCommand.getBank());
break;
case Command::Precharge:
bankStates.closeRowBuffer(scheduledCommand.getBank());
rowBufferStates.closeRowBuffer(scheduledCommand.getBank());
break;
case Command::PrechargeAll:
bankStates.closeAllRowBuffers();
rowBufferStates.closeAllRowBuffers();
break;
case Command::SREF:
bankStates.closeRowBuffer(scheduledCommand.getBank());
rowBufferStates.closeRowBuffer(scheduledCommand.getBank());
break;
default:
break;

View File

@@ -9,7 +9,7 @@
#define CONTROLLER_STATE_H_
#include <systemc.h>
#include "BankStates.h"
#include "RowBufferStates.h"
#include "scheduling/ScheduledCommand.h"
#include "Slots.h"
#include "configuration/Configuration.h"
@@ -23,7 +23,7 @@ class ControllerState
{
public:
ControllerState(Configuration* config) :
bankStates(), bus(config->Timings.clk), config(config)
rowBufferStates(), bus(config->Timings.clk), config(config)
{
}
virtual ~ControllerState()
@@ -38,7 +38,7 @@ public:
void change(const ScheduledCommand& scheduledCommand);
void cleanUp(sc_time time);
BankStates bankStates;
RowBufferState rowBufferStates;
//used by the various checkers
std::map<Command, std::map<Bank, ScheduledCommand> > lastScheduledByCommandAndBank;

View File

@@ -5,7 +5,7 @@
* Author: robert
*/
#include "BankStates.h"
#include "RowBufferStates.h"
#include "ControllerCore.h"
#include "../../common/DebugManager.h"
#include "../../common/Utils.h"
@@ -15,38 +15,38 @@ using namespace std;
namespace core
{
BankStates::BankStates()
RowBufferState::RowBufferState()
{
closeAllRowBuffers();
}
BankStates::~BankStates()
RowBufferState::~RowBufferState()
{
}
bool BankStates::rowBufferIsOpen(Bank bank) const
bool RowBufferState::rowBufferIsOpen(Bank bank) const
{
return getElementFromMap(rowsInRowBuffers,bank) != Row::NO_ROW;
}
Row BankStates::getRowInRowBuffer(Bank bank) const
Row RowBufferState::getRowInRowBuffer(Bank bank) const
{
return getElementFromMap(rowsInRowBuffers,bank);
}
void BankStates::openRowInRowBuffer(Bank bank,Row row)
void RowBufferState::openRowInRowBuffer(Bank bank,Row row)
{
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now open");
rowsInRowBuffers[bank] = row;
}
void BankStates::closeRowBuffer(Bank bank)
void RowBufferState::closeRowBuffer(Bank bank)
{
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now closed");
rowsInRowBuffers[bank] = Row::NO_ROW;
}
bool BankStates::allRowBuffersAreClosed() const
bool RowBufferState::allRowBuffersAreClosed() const
{
for(unsigned int i=0; i<Configuration::getInstance().NumberOfBanks;++i)
{
@@ -56,7 +56,7 @@ bool BankStates::allRowBuffersAreClosed() const
return true;
}
void BankStates::closeAllRowBuffers()
void RowBufferState::closeAllRowBuffers()
{
for(unsigned int i=0; i<Configuration::getInstance().NumberOfBanks;++i)
{

View File

@@ -1,22 +1,22 @@
/*
* BankStates.h
* RowBufferStates.h
*
* Created on: Feb 24, 2014
* Author: robert
*/
#ifndef BANKSTATES_H_
#define BANKSTATES_H_
#ifndef ROWBUFFERSTATES_H_
#define ROWBUFFERSTATES_H_
#include <map>
#include "../../common/dramExtension.h"
namespace core
{
class BankStates {
class RowBufferState {
public:
BankStates();
virtual ~BankStates();
RowBufferState();
virtual ~RowBufferState();
bool rowBufferIsOpen(Bank bank) const;
bool allRowBuffersAreClosed() const;

View File

@@ -20,48 +20,48 @@ enum class PowerDownMode{Staggered, TimeoutPDN, TimeoutSREF};
struct Configuration
{
static std::string memspecUri;
static std::string memconfigUri;
static std::string memspecUri;
static std::string memconfigUri;
static inline Configuration& getInstance()
{
static Configuration configuration;
return configuration;
}
static inline Configuration& getInstance()
{
static Configuration configuration;
return configuration;
}
std::string MemoryId;
std::string MemoryType;
//MemConfiguration
bool BankwiseLogic;
bool OpenPagePolicy;
bool AdaptiveOpenPagePolicy;
bool RefreshAwareScheduling;
unsigned int MaxNrOfTransactions;
std::string Scheduler;
unsigned int Capsize;
//MemSpecification
unsigned int NumberOfBanks;
unsigned int NumberOfBankGroups;
unsigned int BurstLength;
unsigned int nActivate;
unsigned int DataRate;
unsigned int NumberOfRows;
bool databaseRecordingEnabled;
//MemSpecification
std::string MemoryId;
std::string MemoryType;
// Powerdown Mode
sc_time powerDownTimeout;
PowerDownMode powerDownMode;
unsigned int NumberOfBanks;
unsigned int NumberOfBankGroups;
unsigned int BurstLength;
unsigned int nActivate;
unsigned int DataRate;
unsigned int NumberOfRows;
bool recordingIsEnabled;
//MemTimings
TimingConfiguration Timings;
//MemConfiguration
bool BankwiseLogic;
bool OpenPagePolicy;
bool AdaptiveOpenPagePolicy;
bool RefreshAwareScheduling;
unsigned int MaxNrOfTransactions;
std::string Scheduler;
unsigned int Capsize;
const std::vector<Bank>& getBanks() const;
// Powerdown Mode
sc_time powerDownTimeout;
PowerDownMode powerDownMode;
//MemTimings
TimingConfiguration Timings;
const std::vector<Bank>& getBanks() const;
private:
Configuration();
Configuration();
};
} /* namespace core */

View File

@@ -16,35 +16,20 @@ namespace core {
void MemSpecLoader::loadConfiguration(Configuration& config, string memspecUri, string memconfigUri)
{
tinyxml2::XMLDocument doc;
loadXML(memspecUri, doc);
XMLElement* memspec = doc.FirstChildElement("memspec");
config.MemoryId = queryStringParameter(memspec, "memoryId");
config.MemoryType = queryStringParameter(memspec, "memoryType");
if (config.MemoryType == "DDR4")
{
loadDDR4(config, memspec);
}
else if (config.MemoryType == "WIDEIO_SDR")
{
loadWideIO(config, memspec);
}
else
{
reportFatal("ConfigurationLoader", "Unsupported Configuration");
}
loadMemSpec(config, memspec);
loadXML(memconfigUri, doc);
memspec = doc.FirstChildElement("memspec");
loadConfig(config, memspec);
XMLElement* memconfig = doc.FirstChildElement("memspec");
loadMemConfig(config, memconfig);
}
void MemSpecLoader::loadConfig(Configuration& config, XMLElement* memspec)
void MemSpecLoader::loadMemConfig(Configuration& config, XMLElement* memconfig)
{
//MemConfiguration
XMLElement* configuration = memspec->FirstChildElement("memconfig");
XMLElement* configuration = memconfig->FirstChildElement("memconfig");
config.BankwiseLogic = queryBoolParameter(configuration, "bankwiseLogic");
config.OpenPagePolicy = queryBoolParameter(configuration, "openPagePolicy");
@@ -68,6 +53,27 @@ void MemSpecLoader::loadConfig(Configuration& config, XMLElement* memspec)
config.powerDownMode = PowerDownMode::TimeoutSREF;
}
config.powerDownTimeout = queryUIntParameter(configuration, "powerDownTimeout") * config.Timings.clk;
config.databaseRecordingEnabled = queryBoolParameter(configuration, "databaseRecordingEnabled");
}
void MemSpecLoader::loadMemSpec(Configuration& config, XMLElement* memspec)
{
config.MemoryId = queryStringParameter(memspec, "memoryId");
config.MemoryType = queryStringParameter(memspec, "memoryType");
if (config.MemoryType == "DDR4")
{
loadDDR4(config, memspec);
}
else if (config.MemoryType == "WIDEIO_SDR")
{
loadWideIO(config, memspec);
}
else
{
reportFatal("ConfigurationLoader", "Unsupported DRAM type");
}
}
void MemSpecLoader::loadDDR4(Configuration& config, XMLElement* memspec)

View File

@@ -18,13 +18,13 @@ namespace core {
class MemSpecLoader
{
public:
void loadConfiguration(Configuration& config, std::string memspec, std::string memconfig);
void loadConfiguration(Configuration& config, std::string memspecUri, std::string memconfigUri);
private:
void loadDDR4(Configuration& config, tinyxml2::XMLElement* memspec);
void loadWideIO(Configuration& config, tinyxml2::XMLElement* memspec);
void loadConfig(Configuration& config, tinyxml2::XMLElement* memspec);
void loadMemConfig(Configuration& config, tinyxml2::XMLElement* memspec);
void loadMemSpec(Configuration& config, tinyxml2::XMLElement* memspec);
void loadDDR4(Configuration& config, tinyxml2::XMLElement* memspec);
void loadWideIO(Configuration& config, tinyxml2::XMLElement* memspec);
};
} /* namespace core */

View File

@@ -43,11 +43,11 @@ void PowerDownManager::sleep(Bank bank, sc_time time)
if (state == PowerDownState::Awake) //coming from active
{
state = controller.state.bankStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
state = controller.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
}
else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down
{
sc_assert(controller.state.bankStates.allRowBuffersAreClosed());
sc_assert(controller.state.rowBufferStates.allRowBuffersAreClosed());
if (controller.state.getLastCommand(Command::PDNA).getStart()
>= controller.state.getLastCommand(Command::PDNP).getStart())

View File

@@ -36,11 +36,11 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time)
PowerDownState state = powerDownStates[bank];
if (state == PowerDownState::Awake) //coming from active
{
state = controller.state.bankStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge;
state = controller.state.rowBufferStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge;
}
else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down
{
sc_assert(!controller.state.bankStates.rowBufferIsOpen(bank));
sc_assert(!controller.state.rowBufferStates.rowBufferIsOpen(bank));
if (controller.state.getLastCommand(Command::PDNA, bank).getStart()
>= controller.state.getLastCommand(Command::PDNP, bank).getStart())

View File

@@ -34,7 +34,7 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time)
PowerDownState newState;
if(Configuration::getInstance().powerDownMode == PowerDownMode::TimeoutPDN)
{
newState = controller.state.bankStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
newState = controller.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
}
else
{

View File

@@ -40,7 +40,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time
{
sc_assert(!isInvalidated(payload, time));
if (!controller.state.bankStates.allRowBuffersAreClosed())
if (!controller.state.rowBufferStates.allRowBuffersAreClosed())
{
ScheduledCommand precharge(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]),
DramExtension::getExtension(refreshPayloads[Bank(0)]));

View File

@@ -49,7 +49,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload,
DramExtension& extension = DramExtension::getExtension(refreshPayload);
if (controller.state.bankStates.rowBufferIsOpen(extension.getBank()))
if (controller.state.rowBufferStates.rowBufferIsOpen(extension.getBank()))
{
ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, refreshPayload), extension);

View File

@@ -21,11 +21,11 @@ CommandSequence CommandSequenceGenerator::generateCommandSequence(tlm::tlm_gener
CommandSequence result;
if (!controllerState.bankStates.rowBufferIsOpen(bank))
if (!controllerState.rowBufferStates.rowBufferIsOpen(bank))
{
return getBankMissCommandSequence(transaction);
}
else if (controllerState.bankStates.getRowInRowBuffer(bank) != row)
else if (controllerState.rowBufferStates.getRowInRowBuffer(bank) != row)
{
return getRowMissCommandSequence(transaction);
}

View File

@@ -10,28 +10,34 @@
namespace scheduler {
bool Fifo::hasTransactionForBank(Bank bank)
bool Fifo::hasPayloads()
{
return !buffer[bank].empty();
return numberOfQueuedPayloads > 0;
}
void Fifo::schedule(gp* payload)
{
buffer[DramExtension::getExtension(payload).getBank()].push_back(payload);
buffer[DramExtension::getExtension(payload).getBank()].push_back(payload);
numberOfQueuedPayloads++;
}
gp* Fifo::getTransactionForBank(Bank bank)
gp* Fifo::getNextPayload()
{
sc_assert(hasTransactionForBank(bank));
gp* result = buffer[bank].front();
return result;
for(Bank bank: controllerCore.getFreeBanks(sc_time_stamp()))
{
if(!buffer[bank].empty())
{
return buffer[bank].front();
}
}
return NULL;
}
void Fifo::popTransactionForBank(Bank bank, gp* payload)
void Fifo::removePayload(gp* payload)
{
sc_assert(DramExtension::getExtension(payload).getBank() == bank);
buffer[bank].pop_front();
buffer[DramExtension::getExtension(payload).getBank()].pop_front();
numberOfQueuedPayloads--;
}
} /* namespace scheduler */

View File

@@ -19,18 +19,20 @@ namespace scheduler {
class Fifo : public Scheduler
{
public:
Fifo()
{}
virtual ~Fifo()
{}
Fifo(core::ControllerCore &controllerCore) : controllerCore(controllerCore), numberOfQueuedPayloads(0)
{}
virtual ~Fifo()
{}
virtual bool hasTransactionForBank(Bank bank) override;
virtual bool hasPayloads() override;
virtual void schedule(gp* payload) override;
virtual gp* getTransactionForBank(Bank bank) override;
virtual void popTransactionForBank(Bank bank, gp* payload) override;
virtual gp* getNextPayload() override;
virtual void removePayload(gp* payload) override;
private:
std::map<Bank, std::deque<gp*>> buffer;
std::map<Bank, std::deque<gp*>> buffer;
core::ControllerCore &controllerCore;
unsigned int numberOfQueuedPayloads;
};
} /* namespace scheduler */

View File

@@ -8,9 +8,9 @@ using namespace core;
namespace scheduler {
FR_FCFS::FR_FCFS(const core::BankStates& bankstates, bool useExternalStates, bool adaptiveOpenPage) :
externalBankstates(bankstates), useExternalStates(useExternalStates), adaptiveOpenPage(
adaptiveOpenPage)
FR_FCFS::FR_FCFS(core::ControllerCore& controllerCore, bool useExternalStates, bool adaptiveOpenPage) :
controllerCore(controllerCore), useExternalStates(useExternalStates), adaptiveOpenPage(
adaptiveOpenPage), numberOfQueuedPayloads(0)
{
}
@@ -18,101 +18,99 @@ FR_FCFS::~FR_FCFS()
{
}
bool FR_FCFS::hasTransactionForBank(Bank bank)
bool FR_FCFS::hasPayloads()
{
return !buffer[bank].empty();
return numberOfQueuedPayloads > 0;
}
bool FR_FCFS::isEmpty()
{
for(unsigned int i = 0; i < Configuration::getInstance().NumberOfBanks;++i)
{
if(!buffer[Bank(i)].empty())
return false;
}
return true;
}
void FR_FCFS::schedule(gp* payload)
{
buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload);
buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload);
numberOfQueuedPayloads++;
}
void FR_FCFS::schedule(std::vector<gp*> payloads)
{
for(gp* payload: payloads)
schedule(payload);
for(gp* payload: payloads)
schedule(payload);
}
gp* FR_FCFS::getTransactionForBank(Bank bank)
gp* FR_FCFS::getNextPayload()
{
sc_assert(hasTransactionForBank(bank));
for(Bank bank: controllerCore.getFreeBanks(sc_time_stamp()))
{
if(!buffer[bank].empty())
{
Row openRowOnBank = (useExternalStates) ? controllerCore.getRowBufferStates().getRowInRowBuffer(bank) : internalBankstates.getRowInRowBuffer(bank);
auto rowHits = findRowHits(bank, openRowOnBank);
gp* result = rowHits.empty() ? buffer[bank].front() : rowHits.front();
Row openRowOnBank = (useExternalStates) ? externalBankstates.getRowInRowBuffer(bank) : internalBankstates.getRowInRowBuffer(bank);
auto rowHits = findRowHits(bank, openRowOnBank);
gp* result = rowHits.empty() ? buffer[bank].front() : rowHits.front();
if (!adaptiveOpenPage)
{
return result;
}
else
{
rowHits = findRowHits(bank, DramExtension::getExtension(result).getRow());
//other row hits are still in buffer, leave page open
if (rowHits.size() > 1)
Configuration::getInstance().OpenPagePolicy = true;
else
Configuration::getInstance().OpenPagePolicy = false;
if (!adaptiveOpenPage)
{
return result;
}
else
{
rowHits = findRowHits(bank, DramExtension::getExtension(result).getRow());
//other row hits are still in buffer, leave page open
if (rowHits.size() > 1)
Configuration::getInstance().OpenPagePolicy = true;
else
Configuration::getInstance().OpenPagePolicy = false;
//other row hits are still in buffer, leave page open
if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() > 1)
Configuration::getInstance().OpenPagePolicy = true;
else
Configuration::getInstance().OpenPagePolicy = false;
//other row hits are still in buffer, leave page open
// if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() > 1)
// Configuration::getInstance().OpenPagePolicy = true;
// else
// Configuration::getInstance().OpenPagePolicy = false;
//no other hit in buffer, but row miss is waiting
if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() == 1 && buffer[bank].size() > 2 )
Configuration::getInstance().OpenPagePolicy = false;
else
Configuration::getInstance().OpenPagePolicy = true;
return result;
}
//no other hit in buffer, but row miss is waiting
// if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() == 1 && buffer[bank].size() > 2 )
// Configuration::getInstance().OpenPagePolicy = false;
// else
// Configuration::getInstance().OpenPagePolicy = true;
return result;
}
}
}
return NULL;
}
gp* FR_FCFS::popOldest(Bank bank)
{
sc_assert(hasTransactionForBank(bank));
gp* result = buffer[bank].front();
buffer[bank].pop_front();
return result;
if(buffer[bank].empty())
return NULL;
gp* result = buffer[bank].front();
buffer[bank].pop_front();
numberOfQueuedPayloads--;
return result;
}
std::vector<gp*> FR_FCFS::findRowHits(Bank bank, Row row)
{
vector<gp*> found;
for (gp* payload : buffer[bank])
{
if (DramExtension::getExtension(payload).getRow() == row)
found.push_back(payload);
}
return found;
vector<gp*> found;
for (gp* payload : buffer[bank])
{
if (DramExtension::getExtension(payload).getRow() == row)
found.push_back(payload);
}
return found;
}
void FR_FCFS::popTransactionForBank(Bank bank, gp* payload)
void FR_FCFS::removePayload(gp* payload)
{
sc_assert(DramExtension::getExtension(payload).getBank() == bank);
Bank bank = DramExtension::getExtension(payload).getBank();
buffer[bank].remove(payload);
buffer[bank].remove(payload);
if (!useExternalStates)
{
internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow());
}
if (!useExternalStates)
{
internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow());
}
numberOfQueuedPayloads--;
}
}

View File

@@ -12,13 +12,13 @@ namespace scheduler {
class FR_FCFS : public Scheduler
{
public:
FR_FCFS(const core::BankStates& bankstates, bool refreshAware, bool adaptiveOpenPage);
virtual ~FR_FCFS();
FR_FCFS(core::ControllerCore& controllerCore, bool refreshAware, bool adaptiveOpenPage);
virtual ~FR_FCFS();
virtual bool hasTransactionForBank(Bank bank) override;
virtual bool hasPayloads() override;
virtual void schedule(gp* payload) override;
virtual gp* getTransactionForBank(Bank bank) override;
virtual void popTransactionForBank(Bank bank, gp* payload) override;
virtual gp* getNextPayload() override;
virtual void removePayload(gp* payload) override;
//used by PAR_BS
void schedule (std::vector<gp*> payloads);
@@ -27,11 +27,12 @@ public:
private:
std::vector<gp*> findRowHits(Bank bank, Row row);
std::map<Bank,std::list<gp*>> buffer;
const core::BankStates& externalBankstates;
core::BankStates internalBankstates;
bool useExternalStates;
bool adaptiveOpenPage;
std::map<Bank,std::list<gp*>> buffer;
core::ControllerCore& controllerCore;
core::RowBufferState internalBankstates;
bool useExternalStates;
bool adaptiveOpenPage;
unsigned int numberOfQueuedPayloads;
};
} /* namespace scheduler */

View File

@@ -1,9 +1,9 @@
/*
* PARBS.cpp
*
* Created on: Apr 9, 2014
* Author: robert
*/
// * PARBS.cpp
// *
// * Created on: Apr 9, 2014
// * Author: robert
// */
#include "PARBS.h"
#include "../core/configuration/Configuration.h"
@@ -17,18 +17,18 @@ namespace scheduler {
using namespace std;
using namespace core;
PAR_BS::PAR_BS(const core::BankStates& bankstates, bool useExternalBankstates, unsigned int capsize) :
externalBankstates(bankstates), useExternalBankstates(useExternalBankstates), capsize(capsize)
PAR_BS::PAR_BS(core::ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize) :
controllerCore(controllerCore), useExternalBankstates(useExternalBankstates), capsize(capsize)
{
if (useExternalBankstates)
{
batch = new FR_FCFS(externalBankstates, true, false);
buffer = new FR_FCFS(externalBankstates, true, false);
batch = new FR_FCFS(controllerCore, true, false);
buffer = new FR_FCFS(controllerCore, true, false);
}
else
{
batch = new FR_FCFS(internalBankstates, true, false);
buffer = new FR_FCFS(internalBankstates, true, false);
batch = new FR_FCFS(controllerCore, true, false);
buffer = new FR_FCFS(controllerCore, true, false);
}
}
@@ -37,9 +37,9 @@ PAR_BS::~PAR_BS()
}
bool PAR_BS::hasTransactionForBank(Bank bank)
bool PAR_BS::hasPayloads()
{
return batch->hasTransactionForBank(bank) || buffer->hasTransactionForBank(bank);
return batch->hasPayloads() || buffer->hasPayloads();
}
void PAR_BS::schedule(gp* payload)
@@ -47,37 +47,31 @@ void PAR_BS::schedule(gp* payload)
buffer->schedule(payload);
}
gp* PAR_BS::getTransactionForBank(Bank bank)
gp* PAR_BS::getNextPayload()
{
sc_assert(hasTransactionForBank(bank));
if (batch->isEmpty())
if (!batch->hasPayloads())
{
formBatch();
cout << "Formed new batch at: " << sc_time_stamp() << std::endl;
sc_assert(!batch->isEmpty());
sc_assert(batch->hasPayloads());
}
//prioritize batch first
if (batch->hasTransactionForBank(bank))
gp* result = batch->getNextPayload();
if(result == NULL)
{
return batch->getTransactionForBank(bank);
}
else
{
return buffer->getTransactionForBank(bank);
return buffer->getNextPayload();
}
}
void PAR_BS::popTransactionForBank(Bank bank, gp* payload)
void PAR_BS::removePayload(gp* payload)
{
sc_assert(DramExtension::getExtension(payload).getBank() == bank);
buffer->popTransactionForBank(bank, payload);
batch->popTransactionForBank(bank, payload);
buffer->removePayload(payload);
batch->removePayload(payload);
if (!useExternalBankstates)
{
internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow());
DramExtension& extension = DramExtension::getExtension(payload);
internalBankstates.openRowInRowBuffer(extension.getBank(), extension.getRow());
}
}
@@ -86,12 +80,13 @@ void PAR_BS::formBatch()
{
map<Thread, ThreadLoad> loads;
for (unsigned int b = 0; b < Configuration::getInstance().NumberOfBanks; ++b)
for (Bank bank : controllerCore.getBanks())
{
Bank bank(b);
for (unsigned int i = 0; i < capsize && buffer->hasTransactionForBank(bank); i++)
for (unsigned int i = 0; i < capsize; i++)
{
gp* payload = buffer->popOldest(bank);
if(payload == NULL)
break;
loads[DramExtension::getExtension(payload).getThread()].addTransaction(payload);
}
}
@@ -111,4 +106,4 @@ void PAR_BS::formBatch()
}
} /* namespace core */
}

View File

@@ -1,9 +1,9 @@
/*
* PARBS.h
*
* Created on: Apr 9, 2014
* Author: robert
*/
// * PARBS.h
// *
// * Created on: Apr 9, 2014
// * Author: robert
// *
#ifndef PARBS_H_
#define PARBS_H_
@@ -16,23 +16,23 @@ namespace scheduler {
class PAR_BS : public Scheduler
{
public:
PAR_BS(const core::BankStates& bankstates, bool useExternalBankstates, unsigned int capsize);
virtual ~PAR_BS();
virtual bool hasTransactionForBank(Bank bank) override;
PAR_BS(core::ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize);
virtual ~PAR_BS();
virtual bool hasPayloads() override;
virtual void schedule(gp* payload) override;
virtual gp* getTransactionForBank(Bank bank) override;
virtual void popTransactionForBank(Bank bank, gp* payload) override;
virtual gp* getNextPayload() override;
virtual void removePayload(gp* payload) override;
private:
void formBatch();
bool useExternalBankstates;
const core::BankStates& externalBankstates;
core::BankStates internalBankstates;
FR_FCFS *batch;
FR_FCFS *buffer;
unsigned int capsize;
bool useExternalBankstates;
core::ControllerCore& controllerCore;
core::RowBufferState internalBankstates;
FR_FCFS *batch;
FR_FCFS *buffer;
unsigned int capsize;
};
} /* scheduler core */
#endif /* PARBS_H_ */
#endif

View File

@@ -10,14 +10,14 @@ typedef tlm::tlm_generic_payload gp;
class Scheduler
{
public:
virtual ~Scheduler(){};
virtual ~Scheduler(){}
virtual void schedule(gp* payload) = 0;
//TODO Rename to payload
virtual bool hasTransactionForBank(Bank bank) = 0;
virtual gp* getTransactionForBank(Bank bank) = 0;
virtual void popTransactionForBank(Bank bank, gp* payload) = 0;
virtual bool hasPayloads() = 0;
virtual gp* getNextPayload() = 0;
virtual void removePayload(gp* payload) = 0;
};
}

View File

@@ -20,45 +20,64 @@ using namespace std;
namespace simulation {
void Simulation::setupDebugManager(bool silent, const string& traceName)
{
vector<string> whiteList;
if (!silent)
{
whiteList.push_back(controller->name());
whiteList.push_back(player2->name());
whiteList.push_back(player1->name());
whiteList.push_back(this->name());
whiteList.push_back(TlmRecorder::senderName);
whiteList.push_back(ControllerCore::senderName);
whiteList.push_back(PowerDownManagerBankwise::senderName);
}
auto& dbg = DebugManager::getInstance();
dbg.addToWhiteList(whiteList);
dbg.setDebugFile(traceName + ".txt");
if (silent)
{
dbg.writeToConsole = false;
dbg.writeToFile = false;
}
}
Simulation::Simulation(sc_module_name name, string pathToResources, string traceName, DramSetup setup,
std::vector<Device> devices, bool silent) :
traceName(traceName), dramSetup(setup)
std::vector<Device> devices) :
traceName(traceName), dramSetup(setup)
{
SC_THREAD(stop);
xmlAddressDecoder::addressConfigURI = pathToResources + string("configs/amconfigs/") + setup.addressmapping;
TlmRecorder::dbName = traceName;
TlmRecorder::sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql");
Configuration::memconfigUri = pathToResources + string("configs/memconfigs/") + setup.memconfig;
Configuration::memspecUri = pathToResources + string("configs/memspecs/") + setup.memspec;
TlmRecorder::getInstance().recordMemconfig(setup.memconfig);
TlmRecorder::getInstance().recordMemspec(setup.memspec);
setupTlmRecorder(traceName, pathToResources, setup, devices);
instantiateModules(pathToResources, devices);
bindSockets();
setupDebugManager(traceName);
calculateNumberOfTransaction(devices, pathToResources);
}
void Simulation::setupDebugManager(const string& traceName)
{
auto& dbg = DebugManager::getInstance();
dbg.addToWhiteList(controller->name());
dbg.addToWhiteList(player2->name());
dbg.addToWhiteList(player1->name());
dbg.addToWhiteList(this->name());
dbg.addToWhiteList(TlmRecorder::senderName);
dbg.addToWhiteList(ControllerCore::senderName);
dbg.addToWhiteList(PowerDownManagerBankwise::senderName);
dbg.writeToConsole = true;
dbg.writeToFile = true;
if(dbg.writeToFile)
dbg.openDebugFile(traceName + ".txt");
}
void Simulation::setupTlmRecorder(const string &traceName, const string &pathToResources, const DramSetup &setup, const std::vector<Device> &devices)
{
if(Configuration::getInstance().databaseRecordingEnabled)
{
TlmRecorder::recordingEnabled = true;
TlmRecorder::dbName = traceName;
TlmRecorder::sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql");
TlmRecorder::getInstance().recordMemconfig(setup.memconfig);
TlmRecorder::getInstance().recordMemspec(setup.memspec);
TlmRecorder::getInstance().recordTracenames(devices[0].trace + "," + devices[1].trace + "," + devices[2].trace + "," + devices[3].trace);
}
else
{
TlmRecorder::recordingEnabled = false;
}
}
void Simulation::instantiateModules(const string &pathToResources, const std::vector<Device>& devices)
{
dram = new Dram<>("dram");
arbiter = new Arbiter<NumberOfTracePlayers, 128>("arbiter");
controller = new Controller<>("controller");
@@ -67,23 +86,24 @@ Simulation::Simulation(sc_module_name name, string pathToResources, string trace
player2 = new TracePlayer<>("player2", pathToResources + string("traces/") + devices[1].trace, devices[1].burstLength, this);
player3 = new TracePlayer<>("player3", pathToResources + string("traces/") + devices[2].trace, devices[2].burstLength, this);
player4 = new TracePlayer<>("player4", pathToResources + string("traces/") + devices[3].trace, devices[3].burstLength, this);
TlmRecorder::getInstance().recordTracenames(devices[0].trace + "," + devices[1].trace + "," + devices[2].trace + "," + devices[3].trace);
}
void Simulation::bindSockets()
{
player1->iSocket.bind(arbiter->tSockets[0]);
player2->iSocket.bind(arbiter->tSockets[1]);
player3->iSocket.bind(arbiter->tSockets[2]);
player4->iSocket.bind(arbiter->tSockets[3]);
arbiter->iSocket.bind(controller->tSocket);
controller->iSocket.bind(dram->tSocket);
}
setupDebugManager(silent, traceName);
void Simulation::calculateNumberOfTransaction(std::vector<Device> devices, string pathToResources)
{
totalTransactions = getNumberOfLines(pathToResources + string("traces/") + devices[0].trace);
totalTransactions += getNumberOfLines(pathToResources + string("traces/") + devices[1].trace);
totalTransactions += getNumberOfLines(pathToResources + string("traces/") + devices[2].trace);
totalTransactions += getNumberOfLines(pathToResources + string("traces/") + devices[3].trace);
remainingTransactions = totalTransactions;
}
@@ -129,9 +149,8 @@ void Simulation::stop()
{
wait(terminateSimulation);
report("\nTerminating simulation");
wait(sc_time(50, SC_NS));
controller->terminateSimulation();
wait(sc_time(50, SC_NS));
wait(sc_time(200, SC_NS));
TlmRecorder::getInstance().closeConnection();
sc_stop();

View File

@@ -42,7 +42,7 @@ class Simulation: public ISimulation, public sc_module
public:
SC_HAS_PROCESS(Simulation);
Simulation(sc_module_name name, string pathToResources, string traceName, DramSetup setup,
std::vector<Device> devices, bool silent = false);
std::vector<Device> devices);
~Simulation();
void start();
@@ -51,6 +51,8 @@ public:
void inline transactionFinished() override;
constexpr static unsigned int NumberOfTracePlayers = 4;
void bindSockets();
void calculateNumberOfTransaction(std::vector<Device> devices, string pathToResources);
private:
std::string traceName;
DramSetup dramSetup;
@@ -72,7 +74,9 @@ private:
unsigned int getNumberOfLines(string uri);
void report(std::string message);
void setupDebugManager(bool silent, const string& traceName);
void setupDebugManager(const string& traceName);
void setupTlmRecorder(const string &traceName, const string &pathToResources, const DramSetup &setup, const std::vector<Device> &devices);
void instantiateModules(const string &pathToResources, const std::vector<Device> &devices);
};
} /* namespace simulation */

View File

@@ -122,7 +122,7 @@ void SimulationManager::runSimulation(string traceName, DramSetup dramSetup, vec
int status = 0;
if (pid == 0)
{
Simulation* simulation = new Simulation("sim", resources, traceName, dramSetup, traceSetup, silent);
Simulation* simulation = new Simulation("sim", resources, traceName, dramSetup, traceSetup);
simulation->start();
delete simulation;
_Exit(0);

View File

@@ -43,7 +43,6 @@ int sc_main(int argc, char **argv)
SimulationManager manager(resources);
manager.loadSimulationsFromXML(resources + "/simulations/" + simulationToRun);
manager.silent = false;
manager.runSimulations();
return 0;