precharge all checker, redesign of powerndown manager

This commit is contained in:
robert
2014-04-04 01:16:44 +02:00
47 changed files with 1179 additions and 213 deletions

View File

@@ -29,7 +29,10 @@
<listOptionValue builtIn="false" value="SC_INCLUDE_DYNAMIC_PROCESSES"/>
<listOptionValue builtIn="false" value="TIXML_USE_STL"/>
</option>
<option id="gnu.cpp.compiler.option.other.other.1339801369" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -std=c++11" valueType="string"/>
<option id="gnu.cpp.compiler.option.other.other.1339801369" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -std=c++11 -fprofile-arcs -ftest-coverage" valueType="string"/>
<option id="gnu.cpp.compiler.option.debugging.prof.523954048" name="Generate prof information (-p)" superClass="gnu.cpp.compiler.option.debugging.prof" value="true" valueType="boolean"/>
<option id="gnu.cpp.compiler.option.debugging.gprof.1932984572" name="Generate gprof information (-pg)" superClass="gnu.cpp.compiler.option.debugging.gprof" value="true" valueType="boolean"/>
<option id="gnu.cpp.compiler.option.dialect.std.739859284" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1847876781" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.151665950" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
@@ -52,11 +55,14 @@
<option id="gnu.cpp.link.option.libs.1753762098" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="systemc"/>
<listOptionValue builtIn="false" value="sqlite3"/>
<listOptionValue builtIn="false" value="gcov"/>
<listOptionValue builtIn="false" value="pthread"/>
</option>
<option id="gnu.cpp.link.option.paths.1916142213" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="/opt/systemc-2.3.0/lib-linux64"/>
</option>
<option id="gnu.cpp.link.option.debugging.prof.631946268" name="Generate prof information (-p)" superClass="gnu.cpp.link.option.debugging.prof" value="true" valueType="boolean"/>
<option id="gnu.cpp.link.option.debugging.gprof.1817867753" name="Generate gprof information (-pg)" superClass="gnu.cpp.link.option.debugging.gprof" value="true" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1335058803" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>

View File

@@ -28,7 +28,7 @@ void DebugManager::printDebugMessage(string message, Sender sender, Importance i
std::cout << " at " << sc_time_stamp();
if (printLocation)
std::cout << " in " << senderToString(sender);
cout << ": " << message << endl;
cout << ": \t " << message << endl;
}
}
@@ -45,7 +45,7 @@ void DebugManager::printDebugMessage(std::string message, Sender sender, unsigne
std::cout << " at " << sc_time_stamp();
if (printLocation)
std::cout << " in " << senderToString(sender) << "number " << senderNumber;
cout << ": " << message << endl;
cout << ": \t " << message << endl;
}
}
@@ -61,6 +61,11 @@ void DebugManager::addToWhiteList(Sender sender)
addToWhiteList(sender, Importance::Warning);
}
void DebugManager::addToWhiteList(vector<Sender> senders)
{
for(Sender sender: senders)
addToWhiteList(sender);
}
string DebugManager::importanceToString(Importance importancy)
{
@@ -88,11 +93,9 @@ string DebugManager::senderToString(Sender sender)
return "TracePlayer";
case Sender::TraceRecorder:
return "TraceRecorder";
case Sender::PowerDownManager:
return "PowerDownManger";
}
return "unknown sender";
}
void reportFatal(std::string sender, std::string message)
{
SC_REPORT_FATAL(sender.c_str(), message.c_str());
}

View File

@@ -11,9 +11,7 @@
#include <systemc.h>
enum class Importance {Warning, Info};
enum class Sender {DramController, DramWrapper, Scheduler, TracePlayer, TraceRecorder};
void reportFatal(std::string sender, std::string message);
enum class Sender {DramController, DramWrapper, Scheduler, TracePlayer, TraceRecorder, PowerDownManager};
class DebugManager
@@ -28,6 +26,7 @@ public:
void printDebugMessage(std::string message, Sender sender,unsigned int senderNumber, Importance importance=Importance::Info);
void addToWhiteList(Sender sender, Importance importance);
void addToWhiteList(std::vector<Sender> senders);
void addToWhiteList(Sender sender);
private:

View File

@@ -2,8 +2,10 @@
#include "protocol.h"
#include "dramExtension.h"
#include "xmlAddressdecoder.h"
#include "Utils.h"
#include <iostream>
using namespace std;
TlmRecorder::TlmRecorder(string dbName, string sqlScriptURI) :
@@ -32,7 +34,7 @@ void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase ph
unsigned int id = currentTransactionsInSystem[&trans];
string phaseName = phaseToString(phase);
string phaseName = phaseNameToString(phase);
string phaseBeginPrefix = "BEGIN_";
string phaseEndPrefix = "END_";
@@ -151,7 +153,7 @@ void TlmRecorder::insertRangeInDB(unsigned int id, const sc_time& time)
}
void TlmRecorder::insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans)
{
unsigned int id = currentTransactionsInSystem.at(&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,7 +163,7 @@ void TlmRecorder::insertPhaseInDB(string phaseName, const sc_time& begin, const
void TlmRecorder::updatePhaseEndInDB(string phaseName, const sc_time& time, tlm::tlm_generic_payload& trans)
{
unsigned int id = currentTransactionsInSystem.at(&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);
@@ -187,7 +189,7 @@ void TlmRecorder::introduceNewTransactionToSystem(const sc_time& time,
void TlmRecorder::removeTransactionFromSystem(const sc_time& time, tlm::tlm_generic_payload& trans)
{
unsigned int id = currentTransactionsInSystem.at(&trans);
unsigned int id = getElementFromMap(currentTransactionsInSystem,&trans);
currentTransactionsInSystem.erase(&trans);
sqlite3_bind_int64(updateRangeStatement, 1, time.value());
sqlite3_bind_int(updateRangeStatement, 2, id);
@@ -231,13 +233,14 @@ string TlmRecorder::getFileContents(string filename)
}
throw(errno);
}
string TlmRecorder::phaseToString(tlm::tlm_phase phase)
{
ostringstream oss;
oss << phase;
string str = oss.str();
return str;
}
//
//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)

View File

@@ -32,7 +32,7 @@ public:
private:
std::string dbName;
std::string phaseToString(tlm::tlm_phase phase);
//std::string phaseToString(tlm::tlm_phase phase);
std::string getFileContents(std::string filename);
void executeSqlCommand(std::string command);

19
dram/src/common/Utils.cpp Normal file
View File

@@ -0,0 +1,19 @@
#include "Utils.h"
#include <string>
#include <tlm.h>
using namespace std;
void reportFatal(std::string sender, std::string message)
{
SC_REPORT_FATAL(sender.c_str(), message.c_str());
}
std::string phaseNameToString(tlm::tlm_phase phase)
{
std::ostringstream oss;
oss << phase;
std::string str = oss.str();
return str;
}

32
dram/src/common/Utils.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* Utils.h
*
* Created on: Apr 3, 2014
* Author: robert
*/
#ifndef UTILS_COMMON_UTILS_H_
#define UTILS_COMMON_UTILS_H_
#include <systemc.h>
#include <map>
#include <string>
#include <ostream>
#include <tlm.h>
template<typename Key,typename Val>
Val getElementFromMap(std::map<Key,Val>& m, Key key)
{
if(m.count(key) == 0)
{
SC_REPORT_FATAL("Map", "Element not in map");
}
return m.at(key);
}
void reportFatal(std::string sender, std::string message);
std::string phaseNameToString(tlm::tlm_phase phase);
#endif /* UTILS_COMMON_H_ */

View File

@@ -49,6 +49,16 @@ bool operator !=(const Bank& lhs, const Bank& rhs)
return !(lhs == rhs);
}
bool operator ==(const BankGroup& lhs, const BankGroup& rhs)
{
return lhs.ID() == rhs.ID();
}
bool operator !=(const BankGroup& lhs, const BankGroup& rhs)
{
return !(lhs == rhs);
}
bool operator <(const Bank& lhs, const Bank& rhs)
{
return lhs.ID() < rhs.ID();

View File

@@ -31,6 +31,14 @@ private:
unsigned int id;
};
class BankGroup
{
public :
explicit BankGroup(unsigned int id) : id(id) {}
unsigned int ID() const { return id;}
private:
unsigned int id;
};
class Bank
{
@@ -70,13 +78,20 @@ private:
bool operator==(const Thread &lhs, const Thread &rhs);
bool operator!=(const Thread &lhs, const Thread &rhs);
bool operator==(const Channel &lhs, const Channel &rhs);
bool operator!=(const Channel &lhs, const Channel &rhs);
bool operator==(const BankGroup &lhs, const BankGroup &rhs);
bool operator!=(const BankGroup &lhs, const BankGroup &rhs);
bool operator==(const Bank &lhs, const Bank &rhs);
bool operator!=(const Bank &lhs, const Bank &rhs);
bool operator<(const Bank &lhs, const Bank &rhs);
bool operator==(const Row &lhs, const Row &rhs);
bool operator!=(const Row &lhs, const Row &rhs);
bool operator==(const Column &lhs, const Column &rhs);
bool operator!=(const Column &lhs, const Column &rhs);

View File

@@ -43,6 +43,7 @@ DECLARE_EXTENDED_PHASE(END_SREF);
//Triggers
DECLARE_EXTENDED_PHASE(REFRESH_TRIGGER);
DECLARE_EXTENDED_PHASE(WAKEUP_TRIGGER);
#endif

View File

@@ -15,11 +15,6 @@ namespace core
BankStates::BankStates(unsigned int numberOfBanks) :
rowsInRowBuffers(numberOfBanks)
{
for (unsigned int i = 0; i < numberOfBanks; ++i)
{
banks.push_back(Bank(i));
}
closeAllRowBuffers();
}
@@ -59,9 +54,9 @@ bool BankStates::allRowBuffersAreClosed() const
void BankStates::closeAllRowBuffers()
{
for(vector<Bank>::iterator it = banks.begin(); it != banks.end(); ++it)
for(Row& row : rowsInRowBuffers)
{
closeRowBuffer(*it);
row = Row::NO_ROW;
}
}

View File

@@ -18,9 +18,6 @@ public:
BankStates(unsigned int numberOfBanks);
virtual ~BankStates();
unsigned int getNumberOfBanks() const {return rowsInRowBuffers.size();}
const std::vector<Bank>& getBanks() const {return banks;}
bool rowBufferIsOpen(const Bank &bank) const;
bool allRowBuffersAreClosed() const;
Row getRowInRowBuffer(const Bank &bank) const;
@@ -29,10 +26,7 @@ public:
void closeRowBuffer(const Bank &bank);
void closeAllRowBuffers();
private:
std::vector<Bank> banks;
std::vector<Row> rowsInRowBuffers;
};

View File

@@ -5,7 +5,8 @@ namespace core {
std::string commandToString(Command command)
{
switch (command) {
switch (command)
{
case Command::Read:
return "RD";
break;
@@ -31,8 +32,27 @@ std::string commandToString(Command command)
return "AUTO_REFRESH";
break;
case Command::PDNA:
return "PDNA";
break;
case Command::PDNAX:
return "PDNAX";
break;
case Command::PDNP:
return "PDNP";
break;
case Command::PDNPX:
return "PDNPX";
break;
case Command::SREF:
return "SREF";
break;
case Command::SREFX:
return "SREFX";
break;
default:
SC_REPORT_FATAL("command","commandToString was called with unknown command");
SC_REPORT_FATAL("command", "commandToString was called with unknown command");
break;
}
@@ -41,12 +61,21 @@ std::string commandToString(Command command)
bool commandIsIn(Command command, std::vector<Command> commands)
{
for(Command c : commands)
for (Command c : commands)
{
if(c == command)
if (c == command)
return true;
}
return false;
}
const std::vector<Command>& getAllCommands()
{
static std::vector<Command> allCommands( { Command::Precharge, Command::PrechargeAll,
Command::Activate, Command::Read, Command::Write, Command::ReadA, Command::WriteA,
Command::AutoRefresh, Command::PDNA, Command::PDNAX, Command::PDNP, Command::PDNPX,
Command::SREF, Command::SREFX });
return allCommands;
}
}

View File

@@ -12,10 +12,12 @@
namespace core {
enum class Command {NOP, Precharge, PrechargeAll, Activate, Read, Write, ReadA, WriteA, AutoRefresh};
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();
typedef std::vector<Command> CommandSequence;

View File

@@ -15,16 +15,17 @@ namespace core{
struct Configuration
{
Configuration(): numberOfBanks(8), burstlength(2), Timings(numberOfBanks), RefreshBankwise(true),
Configuration(): NumberOfBanks(8), NumberOfBankGroups(4), Burstlength(2), Timings(NumberOfBanks), BankwiseRefresh(false),BankwisePowerDown(false),
nActivate(2)
{}
unsigned int numberOfBanks;
unsigned int burstlength;
unsigned int NumberOfBanks;
unsigned int NumberOfBankGroups;
unsigned int Burstlength;
TimingConfiguration Timings;
bool RefreshBankwise;
bool BankwiseRefresh;
bool BankwisePowerDown;
unsigned int nActivate;
};
} /* namespace controller */

View File

@@ -9,27 +9,39 @@
#include "Controller.h"
#include "scheduling/checker/ActivateChecker.h"
#include "scheduling/checker/PrechargeChecker.h"
#include "scheduling/checker/PrechargeAllChecker.h"
#include "scheduling/checker/ReadChecker.h"
#include "scheduling/checker/WriteChecker.h"
#include "refresh/RefreshManagerBankwise.h"
#include "refresh/RefreshManager.h"
#include "../common/dramExtension.h"
#include "../common/Utils.h"
#include "powerdown/PowerDownManagerBankwise.h"
#include "powerdown/PowerDownManager.h"
#include "../common/DebugManager.h"
namespace core {
Controller::Controller(IWrapperConnector& wrapperConnector, TlmRecorder& recorder) :
config(), state(&config), wrapper(wrapperConnector), commandChecker(), recorder(recorder), savedState(
Controller::Controller(IWrapperConnector& wrapperConnector, TlmRecorder& recorder, std::map<Bank, int>& numberOfPayloads) :
config(), state(&config), wrapper(wrapperConnector), commandChecker(), recorder(recorder), numberOfPayloads(numberOfPayloads), savedState(
&config), commandSequenceGenerator(state), commandSequenceScheduler(*this)
{
commandChecker[Command::Activate] = new ActivateChecker(config, state);
commandChecker[Command::Precharge] = new PrechargeChecker(config, state);
commandChecker[Command::PrechargeAll] = new PrechargeAllChecker(config, state);
commandChecker[Command::Read] = new ReadChecker(config, state);
commandChecker[Command::Write] = new WriteChecker(config, state);
if (config.RefreshBankwise)
if (config.BankwiseRefresh)
refreshManager = new RefreshManagerBankwise(*this);
else
refreshManager = new RefreshManager(*this);
if (config.BankwisePowerDown)
powerDownManager = new PowerDownManagerBankwise(*this);
else
powerDownManager = new PowerDownManager(*this);
}
Controller::~Controller()
@@ -39,6 +51,7 @@ Controller::~Controller()
delete commandChecker[Command::Read];
delete commandChecker[Command::Write];
delete refreshManager;
delete powerDownManager;
}
void Controller::saveState()
@@ -51,17 +64,34 @@ void Controller::resetState()
state = savedState;
}
void Controller::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
void Controller::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);
state.cleanUp(time);
refreshManager->scheduleRefresh(payload, time);
if (refreshManager->isInvalidated(payload, time))
return;
if (!powerDownManager->isInSelfRefresh(bank))
{
if(powerDownManager->isInPowerDown(bank))
powerDownManager->wakeUpForRefresh(bank, time);//expect PDNA and PDNP to exit without delay
refreshManager->scheduleRefresh(payload, time);
}
}
bool Controller::schedule(sc_time start, tlm::tlm_generic_payload& payload)
void Controller::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)
{
start = clkAlign(start, config.Timings.clk);
state.cleanUp(start);
payload.set_streaming_width(config.burstlength);
payload.set_streaming_width(config.Burstlength);
saveState();
@@ -80,19 +110,23 @@ bool Controller::schedule(sc_time start, tlm::tlm_generic_payload& payload)
}
}
bool Controller::isBusy(sc_time currentTime, Bank bank)
bool Controller::isBusy(sc_time time, Bank bank)
{
ScheduledCommand lastScheduledCommand = state.getLastScheduledCommand(bank);
if (lastScheduledCommand.isNoCommand())
return false;
else if (lastScheduledCommand.getCommand() == Command::Write
|| lastScheduledCommand.getCommand() == Command::Read)
else if (lastScheduledCommand.isIn( { Command::Write, Command::Read }))
{
return (currentTime < lastScheduledCommand.getStart());
return (time < lastScheduledCommand.getStart());
}
else if (lastScheduledCommand.getCommand() == Command::AutoRefresh)
{
return (currentTime < lastScheduledCommand.getEnd());
return (time < lastScheduledCommand.getEnd());
}
else if (lastScheduledCommand.isIn( { Command::SREFX, Command::PDNPX, Command::PDNAX }))
{
return false;
}
else
{
@@ -102,15 +136,49 @@ bool Controller::isBusy(sc_time currentTime, Bank bank)
}
BankGroup Controller::getBankGroup(Bank bank) const
{
static std::map<Bank, BankGroup> bankgroups;
if (bankgroups.size() == 0)
{
SC_ASSERT_(config.NumberOfBanks % config.NumberOfBankGroups == 0, "Number of banks must be a multiple of number of bankgroups");
for (unsigned int bank = 0; bank < config.NumberOfBanks; bank++)
{
unsigned int group = bank / config.NumberOfBankGroups;
bankgroups.insert(std::pair<Bank, BankGroup>(Bank(bank), BankGroup(group)));
}
}
return bankgroups.at(bank);
}
const std::vector<Bank>& Controller::getBanks() const
{
static std::vector<Bank> banks;
if (banks.size() == 0)
{
for (unsigned int i = 0; i < config.NumberOfBanks; i++)
{
banks.push_back(Bank(i));
}
}
return banks;
}
void Controller::send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const
{
for (const ScheduledCommand& cmd : schedule.getScheduledCommands())
{
wrapper.send(cmd, payload);
}
}
ICommandChecker& Controller::getCommandChecker(Command command)
{
return *getElementFromMap(commandChecker, command);
}
} /* namespace controller */

View File

@@ -12,7 +12,7 @@
#include <map>
#include "IWrapperConnector.h"
#include "Configuration.h"
#include "powerdown/PowerDownManager.h"
#include "powerdown/IPowerDownManager.h"
#include "refresh/IRefreshManager.h"
#include "scheduling/CommandSequenceGenerator.h"
#include "scheduling/checker/ICommandChecker.h"
@@ -24,34 +24,38 @@ namespace core {
class Controller
{
public:
Controller(IWrapperConnector& wrapper, TlmRecorder& recorder);
Controller(IWrapperConnector& wrapper, TlmRecorder& recorder, std::map<Bank, int>& numberOfPayloads);
virtual ~Controller() ;
bool schedule(sc_time currentTime, tlm::tlm_generic_payload& payload);
bool isBusy(sc_time currentTime, Bank bank);
void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time);
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);
const BankStates& getBankStates(){return state.bankStates;}
void saveState();
void resetState();
BankGroup getBankGroup(Bank bank) const;
const std::vector<Bank>& getBanks() const;
void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const;
ICommandChecker& getCommandChecker(Command command);
Configuration config;
ControllerState state;
IWrapperConnector& wrapper;
std::map<Command, ICommandChecker*> commandChecker;
TlmRecorder& recorder;
IPowerDownManager* powerDownManager;
IRefreshManager* refreshManager;
std::map<Bank,int>& numberOfPayloads;
private:
std::map<Command, ICommandChecker*> commandChecker;
ControllerState savedState;
CommandSequenceGenerator commandSequenceGenerator;
CommandSequenceScheduler commandSequenceScheduler;
IRefreshManager* refreshManager;
//PowerDownManager powerDownManager;
void addCommandChecker(Command command, ICommandChecker* checker);
};
} /* namespace controller */

View File

@@ -19,7 +19,7 @@ const ScheduledCommand ControllerState::getLastCommand(Command command)
{
ScheduledCommand max;
for (unsigned int i = 0; i < bankStates.getNumberOfBanks(); ++i)
for (unsigned int i = 0; i < config->NumberOfBanks; ++i)
{
ScheduledCommand current = getLastCommand(command, Bank(i));
if (current.getStart() > max.getStart())
@@ -31,18 +31,20 @@ const ScheduledCommand ControllerState::getLastCommand(Command command)
const ScheduledCommand ControllerState::getLastScheduledCommand(Bank bank)
{
ScheduledCommand lastCommand;
for (std::map<Command, std::map<Bank, ScheduledCommand> >::iterator it =
lastCommandsOnBus.begin(); it != lastCommandsOnBus.end(); ++it)
for(Command cmd : getAllCommands())
{
ScheduledCommand& current = lastCommandsOnBus[it->first][bank];
ScheduledCommand& current = lastCommandsOnBus[cmd][bank];
if (current.getStart() > lastCommand.getStart())
lastCommand = current;
lastCommand = current;
}
return lastCommand;
}
void ControllerState::change(const ScheduledCommand& scheduledCommand)
{
//TODO double check if slot free?
bus.blockSlot(scheduledCommand.getStart());
lastCommandsOnBus[scheduledCommand.getCommand()][scheduledCommand.getBank()] = scheduledCommand;

View File

@@ -24,7 +24,7 @@ class ControllerState
{
public:
ControllerState(Configuration* config) :
bankStates(config->numberOfBanks), bus(config->Timings.clk), config(config)
bankStates(config->NumberOfBanks), bus(config->Timings.clk), config(config)
{
}
virtual ~ControllerState()

View File

@@ -22,18 +22,8 @@ Slots::~Slots()
void Slots::moveCommandToNextFreeSlot(ScheduledCommand& command)
{
sc_time newStart = command.getStart();
sc_assert(isClkAligned(newStart, clk));
std::set<sc_time>::iterator it = slotSet.begin();
while (it != slotSet.end() && *it <= newStart)
{
if (*it == newStart)
newStart += clk;
++it;
}
command.setStart(newStart);
while(!isFree(command.getStart()))
command.delayStart(clk);
}
void Slots::cleanUpSlots(sc_time time)

View File

@@ -31,11 +31,12 @@ struct TimingConfiguration
{
sc_time tRFC = clkAlign(sc_time(130,SC_NS),clk);
//sc_time tREFI = 100*clk;
sc_time tREFI = sc_time(15.6, SC_US); //TODO align
//tREFI = sc_time(301268, SC_NS);
sc_time tREFI = clkAlign(sc_time(15.6, SC_US), clk);
refreshTimings.push_back(RefreshTiming(tRFC, tREFI));
}
refreshTimings.at(1).tREFI = clkAlign(sc_time(15.6 / 2, SC_US), clk);
refreshTimings.at(0).tREFI = clkAlign(sc_time(15.6 / 4, SC_US), clk);
tRP = 3*clk; //precharge-time (pre -> act same bank)
tRAS = 6*clk; //active-time (act -> pre same bank)
@@ -52,6 +53,8 @@ struct TimingConfiguration
tActHistory = tTAW;
tStrobeHistory = tWTR;
tCKESR = clkAlign(max(3*clk, sc_time(15, SC_NS)), clk); //min time in sref
}
sc_time clk;
@@ -65,7 +68,7 @@ struct TimingConfiguration
sc_time tWL;
sc_time tWR;
sc_time tWTR;
sc_time tCKESR;
sc_time tActHistory, tStrobeHistory;
std::vector<RefreshTiming> refreshTimings;

View File

@@ -0,0 +1,38 @@
/*
* 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_ */

View File

@@ -1,22 +1,275 @@
/*
* PowerDownManager.cpp
*
* Created on: Mar 9, 2014
* Created on: Apr 1, 2014
* Author: jonny
*/
#include <algorithm>
#include <string>
#include "PowerDownManager.h"
#include "../Controller.h"
#include "../utils/Utils.h"
#include "../../common/DebugManager.h"
using namespace tlm;
using namespace std;
namespace core {
PowerDownManager::PowerDownManager()
PowerDownManager::PowerDownManager(Controller& controller) :
controller(controller), powerDownPayloads(controller.config.NumberOfBanks)
{
// TODO Auto-generated constructor stub
setupPayloads();
init();
}
PowerDownManager::~PowerDownManager()
{
}
} /* namespace controller */
/*
* All Banks are precharged and in Precharge-PowerDown after starting the system
*/
void PowerDownManager::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()));
setState(PowerDownState::PDNPrecharge);
}
}
void PowerDownManager::setState(PowerDownState state)
{
powerDownState = state;
string stateName;
switch (state)
{
case PowerDownState::Awake:
stateName = "Awake";
break;
case PowerDownState::AwakeForRefresh:
stateName = "Awake for refresh";
break;
case PowerDownState::PDNActive:
stateName = "PDN Active";
break;
case PowerDownState::PDNPrecharge:
stateName = "PDN Precharged";
break;
case PowerDownState::PDNSelfRefresh:
stateName = "PDN Self refresh";
break;
default:
break;
}
DebugManager::getInstance().printDebugMessage("Is now in state " + stateName,
Sender::PowerDownManager);
}
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 cmd(Command::NOP);
switch (powerDownState)
{
case PowerDownState::PDNActive:
cmd = Command::PDNA;
break;
case PowerDownState::PDNPrecharge:
cmd = Command::PDNP;
break;
case PowerDownState::PDNSelfRefresh:
cmd = Command::SREF;
break;
default:
SC_REPORT_FATAL("In PowerDownManager sendPowerdownBegin", "invalid powerDownState");
}
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);
}
}
void PowerDownManager::sendPowerdownEnd(sc_time time)
{
Command cmd(Command::NOP);
switch (powerDownState)
{
case PowerDownState::PDNActive:
cmd = Command::PDNAX;
break;
case PowerDownState::PDNPrecharge:
cmd = Command::PDNPX;
break;
case PowerDownState::PDNSelfRefresh:
cmd = Command::SREFX;
break;
default:
SC_REPORT_FATAL("In PowerDownManager sendPowerdownEnd", "invalid powerDownState");
}
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);
}
}
void PowerDownManager::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 */

View File

@@ -1,22 +1,47 @@
/*
* PowerDownManager.h
*
* Created on: Mar 9, 2014
* Created on: Apr 1, 2014
* Author: jonny
*/
#ifndef POWERDOWNMANAGER_H_
#define POWERDOWNMANAGER_H_
#include "IPowerDownManager.h"
namespace core {
class PowerDownManager
class Controller;
class PowerDownManager : public IPowerDownManager
{
public:
PowerDownManager();
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();
};
} /* namespace controller */
} /* namespace core */
#endif /* POWERDOWNMANAGER_H_ */

View File

@@ -0,0 +1,166 @@
/*
* 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 */

View File

@@ -0,0 +1,44 @@
/*
* 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_ */

View File

@@ -12,6 +12,9 @@ public:
virtual ~IRefreshManager(){};
virtual bool hasCollision(const CommandSchedule& schedule) = 0;
virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) = 0;
virtual void reInitialize(tlm::tlm_generic_payload& payload, sc_time time) = 0;
virtual bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) = 0;
};
} // namespace core

View File

@@ -12,8 +12,8 @@ using namespace tlm;
namespace core {
RefreshManager::RefreshManager(Controller& controller) :
controller(controller), nextPlannedRefresh(SC_ZERO_TIME), timing(controller.config.Timings.refreshTimings.at(0)),
refreshPayloads(controller.state.bankStates.getNumberOfBanks())
controller(controller), timing(controller.config.Timings.refreshTimings.at(0)), nextPlannedRefresh(SC_ZERO_TIME),
refreshPayloads(controller.config.NumberOfBanks)
{
setupTransactions();
planNextRefresh();
@@ -30,8 +30,7 @@ bool RefreshManager::hasCollision(const CommandSchedule& schedule)
void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
{
if (time != nextPlannedRefresh)
return;
sc_assert(!isInvalidated(payload, time));
ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC, DramExtension::getExtension(refreshPayloads.at(0)));
@@ -40,25 +39,25 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time
ScheduledCommand precharge(Command::PrechargeAll, time,
controller.config.Timings.tRP, DramExtension::getExtension(refreshPayloads.at(0)));
controller.commandChecker.at(Command::PrechargeAll)->delayToSatisfyConstraints(precharge);
controller.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(precharge);
nextRefresh.setStart(precharge.getEnd());
controller.state.change(precharge);
for (tlm::tlm_generic_payload& payload : refreshPayloads)
{
ScheduledCommand prechargeToSend(Command::PrechargeAll, precharge.getStart(),
controller.config.Timings.tRP, DramExtension::getExtension(payload));
controller.state.change(prechargeToSend);
controller.wrapper.send(prechargeToSend, payload);
}
}
controller.state.change(nextRefresh);
for (tlm::tlm_generic_payload& payload : refreshPayloads)
{
ScheduledCommand refreshToSend(Command::AutoRefresh, nextRefresh.getStart(),
timing.tRFC, DramExtension::getExtension(payload));
controller.state.change(refreshToSend);
controller.wrapper.send(refreshToSend, payload);
}
@@ -72,9 +71,20 @@ void RefreshManager::planNextRefresh()
controller.wrapper.send(RefreshTrigger, nextPlannedRefresh, refreshPayloads.at(0));
}
void RefreshManager::reInitialize(tlm::tlm_generic_payload& payload, sc_time time)
{
nextPlannedRefresh = clkAlign(time, controller.config.Timings.clk, Alignment::DOWN);
planNextRefresh();
}
bool core::RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time)
{
return nextPlannedRefresh > time;
}
void RefreshManager::setupTransactions()
{
for (Bank bank : controller.state.bankStates.getBanks())
for (Bank bank : controller.getBanks())
{
tlm_generic_payload& payload = refreshPayloads.at(bank.ID());
payload.set_address(getStartAddress(bank));
@@ -89,3 +99,4 @@ void RefreshManager::setupTransactions()
}
} /* namespace core */

View File

@@ -24,12 +24,15 @@ public:
bool hasCollision(const CommandSchedule& schedule) override;
void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override;
void reInitialize(tlm::tlm_generic_payload& payload, sc_time time) override;
bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) override;
private:
Controller& controller;
RefreshTiming& timing;
std::vector<tlm::tlm_generic_payload> refreshPayloads;
sc_time nextPlannedRefresh;
std::vector<tlm::tlm_generic_payload> refreshPayloads;
void planNextRefresh();
void setupTransactions();

View File

@@ -18,7 +18,7 @@ RefreshManagerBankwise::RefreshManagerBankwise(Controller& controller) :
{
assert(!controller.config.Timings.refreshTimings.empty());
for (Bank bank : controller.state.bankStates.getBanks())
for (Bank bank : controller.getBanks())
{
refreshManagerForBanks.push_back(new RefreshManagerForBank(controller, bank));
}
@@ -40,6 +40,7 @@ bool RefreshManagerBankwise::hasCollision(const CommandSchedule& schedule)
void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
{
sc_assert(!isInvalidated(payload, time));
RefreshManagerForBank& manager = *refreshManagerForBanks.at(
DramExtension::getExtension(payload).getBank().ID());
manager.scheduleRefresh(time);
@@ -71,15 +72,15 @@ bool RefreshManagerBankwise::RefreshManagerForBank::hasCollision(const CommandSc
void RefreshManagerBankwise::RefreshManagerForBank::scheduleRefresh(sc_time time)
{
if (time != nextPlannedRefresh)
return;
ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC, DramExtension::getExtension(refreshPayload));
ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC,
DramExtension::getExtension(refreshPayload));
if (controller.state.bankStates.rowBufferIsOpen(bank))
{
ScheduledCommand precharge(Command::Precharge, time, controller.config.Timings.tRP, DramExtension::getExtension(refreshPayload));
controller.commandChecker.at(Command::Precharge)->delayToSatisfyConstraints(precharge);
ScheduledCommand precharge(Command::Precharge, time, controller.config.Timings.tRP,
DramExtension::getExtension(refreshPayload));
controller.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge);
controller.state.bus.moveCommandToNextFreeSlot(precharge);
nextRefresh.setStart(precharge.getEnd());
controller.state.change(precharge);
@@ -98,6 +99,18 @@ void RefreshManagerBankwise::RefreshManagerForBank::planNextRefresh()
controller.wrapper.send(RefreshTrigger, nextPlannedRefresh, refreshPayload);
}
void RefreshManagerBankwise::RefreshManagerForBank::reInitialize(tlm::tlm_generic_payload& payload,
sc_time time)
{
nextPlannedRefresh = clkAlign(time, controller.config.Timings.clk, Alignment::DOWN);
planNextRefresh();
}
bool RefreshManagerBankwise::RefreshManagerForBank::isInvalidated(sc_time time)
{
return nextPlannedRefresh > time;
}
void RefreshManagerBankwise::RefreshManagerForBank::setupTransaction()
{
refreshPayload.set_address(getStartAddress(bank));
@@ -110,4 +123,19 @@ void RefreshManagerBankwise::RefreshManagerForBank::setupTransaction()
refreshPayload.set_extension(new DramExtension(Thread(0), bank, Row(0), Column(0))); //payload takes ownership
}
} /* namespace controller */
void RefreshManagerBankwise::reInitialize(tlm::tlm_generic_payload& payload, sc_time time)
{
refreshManagerForBanks.at(DramExtension::getExtension(payload).getBank().ID())->reInitialize(
payload, time);
}
bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time)
{
RefreshManagerForBank& manager = *refreshManagerForBanks.at(
DramExtension::getExtension(payload).getBank().ID());
return manager.isInvalidated(time);
}
} /* namespace core */

View File

@@ -26,6 +26,10 @@ public:
virtual bool hasCollision(const CommandSchedule& schedule) override;
virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override;
void reInitialize(tlm::tlm_generic_payload& payload, sc_time time) override;
bool isInvalidated(tlm::tlm_generic_payload& payload,sc_time time) override;
private:
class RefreshManagerForBank
@@ -37,6 +41,9 @@ private:
bool hasCollision(const CommandSchedule& schedule);
void scheduleRefresh(sc_time time);
void reInitialize(tlm::tlm_generic_payload& payload, sc_time time);
bool isInvalidated(sc_time);
private:
Controller& controller;
RefreshTiming& timing;

View File

@@ -18,15 +18,9 @@ CommandSchedule CommandSequenceScheduler::schedule(CommandSequence commands, sc_
for (Command cmd : commands)
{
if(start >= sc_time(28723164,SC_NS))
{
int i = 5;
i++;
}
DebugManager::getInstance().printDebugMessage("Scheduling command " + commandToString(cmd),Sender::DramWrapper);
ICommandChecker& checker = *controller.commandChecker.at(cmd);
ICommandChecker& checker = controller.getCommandChecker(cmd);
sc_time executionTime = checker.getExecutionTime(transaction, cmd);
ScheduledCommand& scheduledCommand = schedule.add(cmd, start, executionTime);

View File

@@ -76,6 +76,10 @@ 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
{
return commandIsIn(command, commandSet);
}
}

View File

@@ -44,13 +44,14 @@ public:
const Command getCommand() const;
const sc_time getExecutionTime() const;
Bank getBank() const;
Row getRow() const;
unsigned int getBurstLength();
bool operator ==(const ScheduledCommand& b) const;
bool isIn(std::vector<Command> commandSet) const;
private:
Command command;

View File

@@ -10,7 +10,7 @@
namespace core {
enum Trigger {RefreshTrigger};
enum Trigger {RefreshTrigger, WakeUpTrigger};
} /* namespace controller */

View File

@@ -7,11 +7,12 @@
#include <algorithm>
#include <set>
#include "../../utils/Utils.h"
#include "ActivateChecker.h"
#include "../../utils/Utils.h"
#include "../../../common/DebugManager.h"
#include <iostream>
#include "../../Command.h"
#include "../../../common/Utils.h"
#include <iostream>
namespace core {
@@ -29,10 +30,13 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
command.setStart(lastCommandOnBank.getEnd());
}
}
else if (lastCommandOnBank.getCommand() == Command::SREFX ||lastCommandOnBank.getCommand() == Command::PDNPX||lastCommandOnBank.getCommand() == Command::PDNAX)
{
}
else
reportFatal("Activate Checker",
"Activate can not follow " + commandToString(lastCommandOnBank.getCommand()));
reportFatal("Activate Checker", "Activate can not follow " + commandToString(lastCommandOnBank.getCommand()));
}
delay_to_satisfy_activateToActivate_sameBank(command);

View File

@@ -0,0 +1,55 @@
/*
* PrechargeAllChecker.cpp
*
* Created on: Apr 3, 2014
* Author: robert
*/
#include "PrechargeAllChecker.h"
#include "../../../common/Utils.h"
namespace core {
void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
sc_assert(command.getCommand() == Command::PrechargeAll);
for (unsigned int bank = 0; bank < config.NumberOfBanks; ++bank)
{
ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank));
if (lastCommand.isValidCommand())
{
if (lastCommand.getCommand() == Command::Read)
{
command.delayToMeetConstraint(lastCommand.getStart(),
lastCommand.getBurstLength() * config.Timings.clk);
}
else if (lastCommand.getCommand() == Command::Write)
{
command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tWR);
}
else if (lastCommand.isIn( { Command::PDNAX, Command::PDNPX, Command::SREFX,
Command::AutoRefresh }))
{
if (command.getStart() < lastCommand.getEnd())
{
command.setStart(lastCommand.getEnd());
}
}
else
reportFatal("Precharge All Checker",
"Precharge All can not follow "
+ commandToString(lastCommand.getCommand()));
}
}
state.bus.moveCommandToNextFreeSlot(command);
}
sc_time PrechargeAllChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
Command command) const
{
sc_assert(command == Command::PrechargeAll);
return config.Timings.tRP;
}
} /* namespace core */

View File

@@ -0,0 +1,39 @@
/*
* PrechargeAllChecker.h
*
* Created on: Apr 3, 2014
* Author: robert
*/
#ifndef PRECHARGEALLCHECKER_H_
#define PRECHARGEALLCHECKER_H_
#include "ICommandChecker.h"
#include "../../Configuration.h"
#include "../../ControllerState.h"
namespace core {
class PrechargeAllChecker: public core::ICommandChecker
{
public:
PrechargeAllChecker(const Configuration& config, ControllerState& state) :
config(config), state(state)
{
}
virtual ~PrechargeAllChecker()
{
}
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const
override;
private:
const Configuration& config;
ControllerState& state;
};
} /* namespace core */
#endif /* PRECHARGEALLCHECKER_H_ */

View File

@@ -6,6 +6,7 @@
*/
#include "PrechargeChecker.h"
#include "../../../common/Utils.h"
namespace core {
@@ -27,6 +28,10 @@ void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons
else if (lastCommand.getCommand() == Command::Write)
{
command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tWR);
}
else if (lastCommand.getCommand() == Command::PDNAX)
{
}
else
reportFatal("Precharge Checker",

View File

@@ -7,6 +7,7 @@
#include "ReadChecker.h"
#include "../../utils/Utils.h"
#include "../../../common/Utils.h"
namespace core {
@@ -14,24 +15,28 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
assert(command.getCommand() == Command::Read || command.getCommand() == Command::ReadA);
ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank());
ScheduledCommand lastCommand = state.getLastScheduledCommand(command.getBank());
if (lastCommandOnBank.isValidCommand())
if (lastCommand.isValidCommand())
{
if (lastCommandOnBank.getCommand() == Command::Activate)
if (lastCommand.getCommand() == Command::Activate)
{
if (command.getStart() < lastCommandOnBank.getEnd())
if (command.getStart() < lastCommand.getEnd())
{
command.setStart(lastCommandOnBank.getEnd());
command.setStart(lastCommand.getEnd());
}
}
else if (lastCommandOnBank.getCommand() == Command::Read
|| lastCommandOnBank.getCommand() == Command::Write)
else if (lastCommand.getCommand() == Command::Read
|| lastCommand.getCommand() == Command::Write)
{
}
else if (lastCommand.getCommand() == Command::PDNAX)
{
}
else
reportFatal("Read Checker",
"Read can not follow " + commandToString(lastCommandOnBank.getCommand()));
"Read can not follow " + commandToString(lastCommand.getCommand()));
}
while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe(command))

View File

@@ -7,6 +7,7 @@
#include "WriteChecker.h"
#include "../../utils/Utils.h"
#include "../../../common/Utils.h"
namespace core {
@@ -26,7 +27,7 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
}
}
else if (lastCommand.getCommand() == Command::Read
|| lastCommand.getCommand() == Command::Write)
|| lastCommand.getCommand() == Command::Write || lastCommand.getCommand() == Command::PDNAX)
{
}
else

View File

@@ -11,7 +11,7 @@
namespace core
{
unsigned int getStartAddress(Bank bank)
unsigned int getStartAddress(const Bank& bank)
{
return 0;
}

View File

@@ -15,7 +15,7 @@
namespace core
{
unsigned int getStartAddress(Bank bank);
unsigned int getStartAddress(const Bank& bank);
struct TimeInterval
{
@@ -28,7 +28,6 @@ struct TimeInterval
};
struct TimingConfiguration;
sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint);
TimeInterval getIntervalOnDataStrobe(const ScheduledCommand& command, const TimingConfiguration& config);

View File

@@ -9,7 +9,7 @@
#define FIFO_H_
#include "Scheduler.h"
#include "../core/BankStates.h"
#include "../core/Controller.h"
#include <deque>
#include <vector>
@@ -18,7 +18,7 @@ namespace scheduler {
class Fifo : public Scheduler
{
public:
Fifo(const core::BankStates& bankstates) : buffer(bankstates.getNumberOfBanks())
Fifo(const core::Controller& controller) : buffer(controller.getBanks().size())
{}
virtual ~Fifo()
{}

View File

@@ -2,7 +2,7 @@
#define FR_FCFS_H_
#include "Scheduler.h"
#include "../core/BankStates.h"
#include "../core/Controller.h"
#include <list>
#include <vector>
@@ -11,7 +11,7 @@ namespace scheduler {
class FR_FCFS : public Scheduler
{
public:
FR_FCFS(const core::BankStates& bankstates) : bankstates(bankstates), buffer(bankstates.getNumberOfBanks())
FR_FCFS(core::Controller& controller) : bankstates(controller.getBankStates()), buffer(controller.getBanks().size())
{}
virtual ~FR_FCFS()
{}

View File

@@ -17,6 +17,7 @@
#include <map>
#include <string>
#include "../common/Utils.h"
#include "../common/protocol.h"
#include "../common/TlmRecorder.h"
#include "../common/DebugManager.h"
@@ -39,19 +40,18 @@ 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;
ControllerWrapper(sc_module_name name, TlmRecorder& recorder):
frontendPEQ(this, &ControllerWrapper::frontendPEQCallback), dramPEQ(
this, &ControllerWrapper::dramPEQCallback), controllerPEQ(this,
&ControllerWrapper::controllerPEQCallback), recorder(recorder), debugManager(DebugManager::getInstance())
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 = new Controller(*this, recorder);
scheduler = new FR_FCFS(controller->getBankStates());
inputBufferDelay = controller->config.Timings.clk;
controller = new Controller(*this, recorder, numberOfPayloads);
scheduler = new Fifo(*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);
for(Bank bank:controller->getBankStates().getBanks())
bankIsFreeForRequest[bank] = true;
}
~ControllerWrapper()
@@ -60,35 +60,53 @@ public:
delete scheduler;
}
virtual void send(const ScheduledCommand& command,tlm_generic_payload& payload) override
virtual void send(const ScheduledCommand& command, tlm_generic_payload& payload) override
{
assert(command.getStart() >= sc_time_stamp());
switch (command.getCommand())
{
case Command::Read:
dramPEQ.notify(payload,BEGIN_RD, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload,END_RD, command.getEnd() - sc_time_stamp());
dramPEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_RD, command.getEnd() - sc_time_stamp());
break;
case Command::Write:
dramPEQ.notify(payload,BEGIN_WR, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload,END_WR, command.getEnd() - sc_time_stamp());
dramPEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_WR, command.getEnd() - sc_time_stamp());
break;
case Command::AutoRefresh:
dramPEQ.notify(payload,BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload,END_AUTO_REFRESH, command.getEnd() - sc_time_stamp());
dramPEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_AUTO_REFRESH, command.getEnd() - sc_time_stamp());
break;
case Command::Activate:
dramPEQ.notify(payload,BEGIN_ACT, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload,END_ACT, command.getEnd() - sc_time_stamp());
dramPEQ.notify(payload, BEGIN_ACT, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_ACT, command.getEnd() - sc_time_stamp());
break;
case Command::Precharge:
dramPEQ.notify(payload,BEGIN_PRE, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload,END_PRE, command.getEnd() - sc_time_stamp());
dramPEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_PRE, command.getEnd() - sc_time_stamp());
break;
case Command::PrechargeAll:
dramPEQ.notify(payload,BEGIN_PRE_ALL, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload,END_PRE_ALL, command.getEnd() - sc_time_stamp());
dramPEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_PRE_ALL, command.getEnd() - sc_time_stamp());
break;
case Command::PDNA:
dramPEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp());
break;
case Command::PDNP:
dramPEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp());
break;
case Command::SREF:
dramPEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp());
break;
case Command::PDNAX:
dramPEQ.notify(payload, END_PDNA, command.getStart() - sc_time_stamp());
break;
case Command::PDNPX:
dramPEQ.notify(payload, END_PDNP, command.getStart() - sc_time_stamp());
break;
case Command::SREFX:
dramPEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp());
break;
default:
SC_REPORT_FATAL(0, "unsupported command in controller wrapper");
@@ -100,14 +118,26 @@ public:
virtual void send(Trigger trigger, sc_time time, tlm_generic_payload& payload) override
{
assert(time >= sc_time_stamp());
sc_time delay = time - sc_time_stamp();
controllerPEQ.notify(payload, REFRESH_TRIGGER, delay);
}
if(trigger == Trigger::RefreshTrigger)
{
controllerPEQ.notify(payload, REFRESH_TRIGGER, delay);
}
else if(trigger == Trigger::WakeUpTrigger)
{
controllerPEQ.notify(payload, WAKEUP_TRIGGER, delay);
}
else
{
SC_REPORT_FATAL("controller wrapper", "unknown trigger");
}
}
private:
Controller* controller;
Scheduler* scheduler;
map<Bank, bool> bankIsFreeForRequest;
std::map<Bank, int> numberOfPayloads;
tlm_utils::peq_with_cb_and_phase<ControllerWrapper> frontendPEQ;
tlm_utils::peq_with_cb_and_phase<ControllerWrapper> dramPEQ;
@@ -121,31 +151,56 @@ private:
{
printDebugMessage("Transaction enters system");
Bank bank = DramExtension::getExtension(payload).getBank();
numberOfPayloads[bank] = numberOfPayloads[bank] + 1;
scheduler->schedule(&payload);
scheduleNextPayload(bank);
}
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)
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
void scheduleNextPayload(Bank bank)
{
printDebugMessage("In trigger for bank " + to_string(bank.ID()));
if(controller->isBusy(sc_time_stamp(), bank))
return;
else if(scheduler->hasTransactionForBank(bank))
printDebugMessage("Try to schedule next payload on bank " + to_string(bank.ID()));
if (scheduler->hasTransactionForBank(bank))
{
tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank);
if(controller->schedule(sc_time_stamp(), *nextTransaction))
if (controller->isBusy(sc_time_stamp(), bank))
{
printDebugMessage("\t-> break: controller is busy");
return;
}
if (controller->powerDownManager->isInPowerDown(bank))
{
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
printDebugMessage("\t-> break: wake up power down");
return;
}
else if (controller->powerDownManager->isAwakeForRefresh(bank))
{
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
}
tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank);
if (controller->scheduleRequest(sc_time_stamp(), *nextTransaction))
{
printDebugMessage("Next payload was scheduled by core");
scheduler->popTransactionForBank(bank);
printDebugMessage("\t-> payload was scheduled by core");
}
else
{
printDebugMessage("\t-> break: payload was not scheduled by core (collision with refresh)");
}
}
}
void payloadLeavesSystem(tlm_generic_payload& payload)
{
else
{
printDebugMessage("\t-> break: no transaction for bank");
}
}
tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay)
@@ -157,11 +212,12 @@ 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());
recorder.recordPhase(payload, phase, sc_time_stamp());
if (phase == BEGIN_REQ)
{
payload.acquire();
payloadEntersSystem(payload);
frontendPEQ.notify(payload, phase, inputBufferDelay);
}
else if (phase == END_RESP)
@@ -177,7 +233,7 @@ private:
{
if (phase == BEGIN_REQ)
{
payloadEntersSystem(payload);
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
payload.set_response_status(tlm::TLM_OK_RESPONSE);
recorder.recordPhase(payload, END_REQ, sc_time_stamp());
sendToFrontend(payload, END_REQ, SC_ZERO_TIME);
@@ -191,28 +247,50 @@ private:
void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
{
recorder.recordPhase(payload, phase, sc_time_stamp());
recorder.recordPhase(payload, phase, sc_time_stamp());
Bank bank = DramExtension::getExtension(payload).getBank();
if (phase == BEGIN_RD || phase == BEGIN_WR)
{
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
scheduleNextPayload(bank);
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if(phase == BEGIN_AUTO_REFRESH || phase == BEGIN_ACT
|| phase == BEGIN_PRE || phase == BEGIN_PRE_ALL)
{
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if(phase == END_AUTO_REFRESH)
{
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
}
else if (phase == END_RD || phase == END_WR)
{
recorder.recordPhase(payload, BEGIN_RESP, sc_time_stamp());
sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME);
}
else if (phase == END_PRE || phase == END_PRE_ALL || phase == END_ACT)
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}))
{
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()));
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)
{
printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID()));
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if (phase == END_AUTO_REFRESH)
{
printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID()));
if (numberOfPayloads[bank] == 0)
controller->powerDownManager->sleep(bank, sc_time_stamp());
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
}
else if (isIn(phase, { END_PRE, END_PRE_ALL, END_ACT }))
{
}
@@ -220,7 +298,9 @@ private:
{
ostringstream oss;
oss << phase;
string str = string("dramPEQCallback queue in controller wrapper was triggered with unknown phase ") + oss.str();
string str = string(
"dramPEQCallback queue in controller wrapper was triggered with unknown phase ")
+ oss.str();
SC_REPORT_FATAL(0, str.c_str());
}
}
@@ -229,7 +309,11 @@ private:
{
if (phase == REFRESH_TRIGGER)
{
controller->scheduleRefresh(payload, sc_time_stamp());
controller->triggerRefresh(payload, sc_time_stamp());
}
else if (phase == WAKEUP_TRIGGER)
{
controller->triggerWakeUp(payload, sc_time_stamp());
}
else
{
@@ -255,9 +339,26 @@ private:
void printDebugMessage(string message, Importance importance = Importance::Info)
{
debugManager.printDebugMessage(message,Sender::DramWrapper,importance);
debugManager.printDebugMessage(message, Sender::DramWrapper, importance);
}
bool isIn(tlm_phase phase, std::vector<tlm_phase> phases)
{
for (tlm_phase p : phases)
{
if (p == phase)
return true;
}
return false;
}
void stop()
{
for (Bank bank : controller->getBanks())
{
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
}
}
};
#endif /* CONTROLLERWRAPPER_H_ */

View File

@@ -20,6 +20,7 @@
#include <string>
#include <ctime>
#include <algorithm>
#include <time.h>
using namespace std;
@@ -34,7 +35,6 @@ void endOfTrace_callback()
finishedPlayers++;
if(finishedPlayers == 2)
{
sc_stop();
}
}
@@ -45,10 +45,18 @@ int sc_main(int argc, char **argv)
string resources = pathOfFile(argv[0]) + string("/../resources/");
xmlAddressDecoder::addressConfigURI = resources + string("configs/addressConfig.xml");
TlmRecorder recorder("tpr.tdb", resources + string("scripts/createTraceDB.sql"));
TracePlayer<> player("player", resources + string("traces/mediabench-unepic_32.stl"),endOfTrace_callback, 0);
TracePlayer<> player2("player2", resources + string("traces/chstone-mips_32.stl"),endOfTrace_callback, 1);
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");
@@ -60,10 +68,7 @@ int sc_main(int argc, char **argv)
arbiter.iSocket.bind(controller.tSocket);
controller.iSocket.bind(dram.tSocket);
DebugManager::getInstance().addToWhiteList(Sender::TracePlayer);
//DebugManager::getInstance().addToWhiteList(Sender::TraceRecorder);
//DebugManager::getInstance().addToWhiteList(Sender::DramWrapper);
//DebugManager::getInstance().addToWhiteList(Sender::DramController);
DebugManager::getInstance().addToWhiteList({Sender::TracePlayer, Sender::TraceRecorder, Sender::DramWrapper, Sender::DramController, Sender::PowerDownManager});
cout << "Toplevel: simulation start" << std::endl;
clock_t begin = clock();
@@ -76,8 +81,7 @@ int sc_main(int argc, char **argv)
cout << "Simulation took " << elapsed_secs << " seconds." << endl;
string testingScript = resources + string("/scripts/tests.py");
string runTestCommand = string("python ") + testingScript + string(" tpr.tdb");
string run_tpr = "/home/robert/analyzer/build/traceAnalyzer tpr.tdb";
string run_tpr = "/home/robert/analyzer/build/traceAnalyzer " + tracename;
system(run_tpr.c_str());
return 0;
}