refactored refresh manager and powerdown

This commit is contained in:
Janik Schlemminger
2014-04-11 23:08:15 +02:00
45 changed files with 780 additions and 905 deletions

View File

@@ -1,10 +1,10 @@
<memspec>
<memconfig>
<parameter id="bankwiseLogic" type="bool" value="1" />
<parameter id="bankwiseLogic" type="bool" value="0" />
<parameter id="openPagePolicy" type="bool" value="1" />
<parameter id="adaptiveOpenPagePolicy" type="bool" value="0" />
<parameter id="refreshAwareScheduling" type="bool" value="0" />
<parameter id="maxNrOfTransactionsInDram" type="uint" value="50" />
<parameter id="maxNrOfTransactionsInDram" type="uint" value="1" />
<parameter id="scheduler" type="string" value="FR_FCFS" />
<parameter id="capsize" type="uint" value="5" />
</memconfig>

View File

@@ -2,6 +2,7 @@
#include <string>
#include <tlm.h>
#include <fstream>
#include "dramExtension.h"
using namespace std;
using namespace tinyxml2;
@@ -139,3 +140,15 @@ string loadTextFileContents(string filename)
return "";
}
}
void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank)
{
payload.set_address(bank.getStartAddress());
payload.set_command(tlm::TLM_READ_COMMAND);
payload.set_data_length(0);
payload.set_response_status(tlm::TLM_OK_RESPONSE);
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_streaming_width(0);
payload.set_extension(new DramExtension(Thread(0), bank, bank.getBankGroup(), Row(0), Column(0))); //payload takes ownership
}

View File

@@ -13,7 +13,7 @@
#include <string>
#include <ostream>
#include <tlm.h>
#include "dramExtension.h"
#include "third_party/tinyxml2.h"
template<typename Key, typename Val>
@@ -49,4 +49,6 @@ std::string queryStringParameter(tinyxml2::XMLElement* node, std::string name);
bool queryBoolParameter(tinyxml2::XMLElement* node, std::string name);
double queryDoubleParameter(tinyxml2::XMLElement* node, std::string name);
void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank);
#endif /* UTILS_COMMON_H_ */

View File

@@ -12,7 +12,10 @@ DramExtension& DramExtension::getExtension(const tlm_generic_payload *payload)
{
DramExtension *result = NULL;
payload->get_extension(result);
assert(result != NULL);
if(result == NULL)
{
SC_REPORT_FATAL("DRAM Extension","Extension is null.");
}
return *result;
}
@@ -36,7 +39,6 @@ bool operator <(const Thread& lhs, const Thread& rhs)
return lhs.ID() < rhs.ID();
}
bool operator ==(const Channel& lhs, const Channel& rhs)
{
return lhs.ID() == rhs.ID();
@@ -52,11 +54,12 @@ BankGroup Bank::getBankGroup()
static std::map<Bank, BankGroup> bankgroups;
if (bankgroups.size() == 0)
{
core::Configuration& config = core::Configuration::getInstance();
SC_ASSERT_(config.NumberOfBanks % config.NumberOfBankGroups == 0, "Number of banks must be a multiple of number of bankgroups");
for (unsigned int bank = 0; bank < core::Configuration::getInstance().NumberOfBanks; bank++)
for (unsigned int bank = 0; bank < config.NumberOfBanks; bank++)
{
unsigned int group = bank % core::Configuration::getInstance().NumberOfBankGroups;
unsigned int group = bank % config.NumberOfBankGroups;
bankgroups.insert(std::pair<Bank, BankGroup>(Bank(bank), BankGroup(group)));
}
}
@@ -88,12 +91,17 @@ bool operator <(const Bank& lhs, const Bank& rhs)
return lhs.ID() < rhs.ID();
}
const Row Row::NO_ROW;
const Row Row::operator ++()
{
id = (id + 1) % core::Configuration::getInstance().NumberOfRows;
return *this;
}
bool operator ==(const Row& lhs, const Row& rhs)
{
if(lhs.isNoRow != rhs.isNoRow)
if (lhs.isNoRow != rhs.isNoRow)
return false;
return lhs.ID() == rhs.ID();
}
@@ -113,4 +121,53 @@ bool operator !=(const Column& lhs, const Column& rhs)
return !(lhs == rhs);
}
tlm_extension_base* DramExtension::clone() const
{
return new DramExtension(thread, bank, bankgroup, row, column, burstlength);
}
void DramExtension::copy_from(const tlm_extension_base& ext)
{
const DramExtension& cpyFrom = static_cast<const DramExtension&>(ext);
thread = cpyFrom.thread;
bank = cpyFrom.bank;
bankgroup = cpyFrom.bankgroup;
row = cpyFrom.row;
column = cpyFrom.column;
burstlength = cpyFrom.burstlength;
}
const Thread& DramExtension::getThread() const
{
return thread;
}
const Channel& DramExtension::getChannel() const
{
return channel;
}
const Bank& DramExtension::getBank() const
{
return bank;
}
const BankGroup& DramExtension::getBankGroup() const
{
return bankgroup;
}
const Row& DramExtension::getRow() const
{
return row;
}
const Column& DramExtension::getColumn() const
{
return column;
}
const unsigned int DramExtension::getBurstlength() const
{
return burstlength;
}
void DramExtension::increaseRow()
{
++row;
}

View File

@@ -98,6 +98,8 @@ public:
{
return id;
}
const Row operator++();
private:
unsigned int id;
bool isNoRow;
@@ -157,71 +159,39 @@ public:
thread(0), channel(0), bank(0), bankgroup(0), row(0), column(0), burstlength(0)
{
}
DramExtension(const Thread& thread, const Bank& bank, const BankGroup& bankgroup,
const Row& row, const Column& column, unsigned int burstlength = 0) :
thread(thread), channel(0), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(
burstlength)
DramExtension(const Thread& thread, const Bank& bank, const BankGroup& bankgroup, const Row& row, const Column& column,
unsigned int burstlength = 0) :
thread(thread), channel(0), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength)
{
}
DramExtension(const Thread& thread, const Channel& channel, const Bank& bank,
const BankGroup& bankgroup, const Row& row, const Column& column,
unsigned int burstlength = 0) :
thread(thread), channel(channel), bank(bank), bankgroup(bankgroup), row(row), column(
column), burstlength(burstlength)
DramExtension(const Thread& thread, const Channel& channel, const Bank& bank, const BankGroup& bankgroup, const Row& row,
const Column& column, unsigned int burstlength = 0) :
thread(thread), channel(channel), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength)
{
}
~DramExtension()
{
}
virtual tlm_extension_base* clone() const
{
return new DramExtension(thread, bank, bankgroup, row, column, burstlength);
}
virtual void copy_from(const tlm_extension_base& ext)
{
const DramExtension& cpyFrom = static_cast<const DramExtension&>(ext);
thread = cpyFrom.thread;
bank = cpyFrom.bank;
bankgroup = cpyFrom.bankgroup;
row = cpyFrom.row;
column = cpyFrom.column;
burstlength = cpyFrom.burstlength;
}
const Thread& getThread() const
{
return thread;
}
const Channel& getChannel() const
{
return channel;
}
const Bank& getBank() const
{
return bank;
}
const BankGroup& getBankGroup() const
{
return bankgroup;
}
const Row& getRow() const
{
return row;
}
const Column& getColumn() const
{
return column;
}
const unsigned int getBurstlength() const
{
return burstlength;
}
virtual tlm_extension_base* clone() const;
virtual void copy_from(const tlm_extension_base& ext);
void setRow(const Row& row)
{
this->row = row;
}
const Thread& getThread() const;
const Channel& getChannel() const;
const Bank& getBank() const;
const BankGroup& getBankGroup() const;
const Row& getRow() const;
const Column& getColumn() const;
const unsigned int getBurstlength() const;
void increaseRow();
static DramExtension& getExtension(const tlm::tlm_generic_payload *payload);
static DramExtension& getExtension(const tlm::tlm_generic_payload &payload);

View File

@@ -12,23 +12,22 @@
#include "scheduling/checker/PrechargeAllChecker.h"
#include "scheduling/checker/ReadChecker.h"
#include "scheduling/checker/WriteChecker.h"
#include "scheduling/checker/RefreshChecker.h"
#include "refresh/RefreshManagerBankwise.h"
#include "refresh/RefreshManager.h"
#include "../common/dramExtension.h"
#include "../common/Utils.h"
#include "powerdown/PowerDownManager.h"
#include "powerdown/PowerDownManagerGrouped.h"
#include "powerdown/PowerDownManagerBankwise.h"
#include "../common/DebugManager.h"
namespace core {
std::string ControllerCore::senderName = "Controller Core";
ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector,
std::map<Bank, int>& numberOfPayloads) :
ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map<Bank, int>& numberOfPayloads) :
config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), commandChecker(), numberOfPayloads(
numberOfPayloads), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(
*this)
numberOfPayloads), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(*this)
{
commandChecker[Command::Activate] = new ActivateChecker(config, state);
@@ -39,15 +38,17 @@ ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector,
commandChecker[Command::Write] = new WriteChecker(config, state);
commandChecker[Command::WriteA] = commandChecker[Command::Write];
commandChecker[Command::AutoRefresh] = new RefreshChecker(config, state);
if (config.BankwiseLogic)
{
refreshManager = new RefreshManagerBankwise(*this);
powerDownManager = new PowerDownManager(*this);
powerDownManager = new PowerDownManagerBankwise(*this);
}
else
{
refreshManager = new RefreshManager(*this);
powerDownManager = new PowerDownManagerGrouped(*this);
powerDownManager = new PowerDownManager(*this);
}
}
@@ -57,6 +58,7 @@ ControllerCore::~ControllerCore()
delete commandChecker[Command::Precharge];
delete commandChecker[Command::Read];
delete commandChecker[Command::Write];
delete commandChecker[Command::AutoRefresh];
delete refreshManager;
delete powerDownManager;
}
@@ -78,32 +80,12 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time t
state.cleanUp(time);
if (refreshManager->isInvalidated(payload, time))
return;
if (config.BankwiseLogic)
if (!refreshManager->isInvalidated(payload, time) && !powerDownManager->isInSelfRefresh(bank))
{
if (!powerDownManager->isInSelfRefresh(bank))
{
printDebugMessage("Waking up bank " + to_string(bank.ID()) + " for refresh");
powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay
refreshManager->scheduleRefresh(payload, time);
}
printDebugMessage("Waking up bank " + to_string(bank.ID()) + " for refresh");
powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay
refreshManager->scheduleRefresh(payload, time);
}
else if (!config.BankwiseLogic)
{
if (!powerDownManager->allBanksInSelfRefresh())
{
printDebugMessage("Waking up all banks for refresh");
powerDownManager->wakeUpAllForRefresh(time);
refreshManager->scheduleRefresh(payload, time);
}
}
}
void ControllerCore::triggerWakeUp(tlm::tlm_generic_payload& payload, sc_time time)
{
powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), time);
}
bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& payload)

View File

@@ -47,7 +47,7 @@ public:
ControllerState state;
IWrapperConnector& wrapper;
PowerDownManager* powerDownManager;
IPowerDownManager* powerDownManager;
IRefreshManager* refreshManager;
std::map<Bank,int>& numberOfPayloads;
static std::string senderName;

View File

@@ -7,7 +7,7 @@
#include "ControllerState.h"
#include <algorithm>
#include "utils/Utils.h"
#include "TimingCalculation.h"
namespace core {

View File

@@ -6,7 +6,7 @@
*/
#include "Slots.h"
#include "utils/Utils.h"
#include "TimingCalculation.h"
namespace core {

View File

@@ -0,0 +1,130 @@
/*
* Utils.cpp
*
* Created on: Mar 12, 2014
* Author: jonny
*/
#include "TimingCalculation.h"
#include "configuration/TimingConfiguration.h"
#include "ControllerCore.h"
#include "../common/DebugManager.h"
#include "configuration/Configuration.h"
#include "../common/Utils.h"
namespace core {
sc_time getDistance(sc_time a, sc_time b)
{
if (a > b)
return a - b;
else
return b - a;
}
sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint)
{
if (previous + constraint > start)
return previous + constraint - start;
else
return SC_ZERO_TIME;
}
const sc_time clkAlign(sc_time time, Alignment alignment)
{
sc_time clk = Configuration::getInstance().Timings.clk;
if (alignment == UP)
return ceil(time / clk) * clk;
else
return floor(time / clk) * clk;
}
sc_time getExecutionTime(Command command,tlm::tlm_generic_payload& payload)
{
TimingConfiguration& config = Configuration::getInstance().Timings;
if(command == Command::Precharge || command == Command::PrechargeAll)
{
return config.tRP;
}
else if(command == Command::Activate)
{
return config.tRCD;
}
else if(command == Command::Read)
{
return config.tRL + getBurstLengthOnDataStrobe(payload.get_streaming_width());
}
else if(command == Command::ReadA)
{
return getBurstLengthOnDataStrobe(payload.get_streaming_width())
+ max(config.tRP, config.tRL);
}
else if(command == Command::Write || command == Command::WriteA)
{
sc_time lengthOnDataStrobe = getBurstLengthOnDataStrobe(payload.get_streaming_width());
if(Configuration::getInstance().DataRate == 1)
lengthOnDataStrobe -= Configuration::getInstance().Timings.clk;
if (command == Command::Write)
{
return config.tWL + lengthOnDataStrobe;
}
else
{
return config.tWL + lengthOnDataStrobe + config.tWR;
}
}
else if(command == Command::PrechargeAll)
{
return config.tRP;
}
else if(command == Command::AutoRefresh)
{
return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC;
}
else if(command == Command::PDNA || command == Command::PDNP)
{
assert(config.tCKE == config.clk * 3);
return config.tCKE;
}
else if(command == Command::SREF)
{
return config.tCKESR;
}
else if(command == Command::PDNAX || command == Command::PDNPX || command == Command::SREFX)
{
return config.clk;
}
else
{
SC_REPORT_FATAL("getExecutionTime", "unkown command");
return SC_ZERO_TIME;
}
}
bool isClkAligned(sc_time time, sc_time clk)
{
return !((time / clk) - ceil(time / clk));
}
bool TimeInterval::timeIsInInterval(sc_time time)
{
return (start < time && time < end);
}
bool TimeInterval::intersects(TimeInterval other)
{
return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start);
}
sc_time getBurstLengthOnDataStrobe(unsigned int burstlength)
{
Configuration& config = Configuration::getInstance();
sc_assert((burstlength / config.DataRate) > 0);
return config.Timings.clk * (burstlength / config.DataRate);
}
}

View File

@@ -10,11 +10,11 @@
#include <systemc.h>
#include <tlm.h>
#include "../../common/dramExtension.h"
#include "../common/dramExtension.h"
#include "Command.h"
namespace core
{
unsigned int getStartAddress(const Bank& bank);
sc_time getDistance(sc_time a, sc_time b);
struct TimeInterval
@@ -28,16 +28,14 @@ struct TimeInterval
bool intersects(TimeInterval other);
};
sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload);
sc_time getBurstLengthOnDataStrobe(unsigned int burstlength);
struct TimingConfiguration;
sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint);
enum Alignment {UP, DOWN};
const sc_time clkAlign(sc_time time, Alignment alignment = UP);
bool isClkAligned(sc_time time, sc_time clk);
void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank);
};
#endif /* UTILS_H_ */

View File

@@ -9,9 +9,8 @@
#define TIMINGS_H_
#include <systemc.h>
#include "../utils/Utils.h"
#include <map>
#include "../../common/dramExtension.h"
namespace core{
struct RefreshTiming

View File

@@ -0,0 +1,99 @@
/*
* IPowerDownManager.h
*
* Created on: Apr 11, 2014
* Author: jonny
*/
#ifndef IPOWERDOWNMANAGER_H_
#define IPOWERDOWNMANAGER_H_
#include <systemc>
namespace core {
enum class PowerDownState
{
Awake, AwakeForRefresh, PDNActive, PDNPrecharge, PDNSelfRefresh
};
class IPowerDownManager
{
public:
virtual ~IPowerDownManager() {}
virtual void sleep(Bank bank, sc_time time) = 0;
virtual void wakeUp(Bank bank, sc_time time) = 0;
virtual void wakeUpForRefresh(Bank bank, sc_time time) = 0;
virtual bool isInSelfRefresh(Bank bank) = 0;
protected:
Command getSleepCommand(PowerDownState state);
Command getWakeUpCommand(PowerDownState state);
};
inline Command IPowerDownManager::getSleepCommand(PowerDownState state)
{
Command cmd(Command::NOP);
switch (state)
{
case PowerDownState::PDNActive:
cmd = Command::PDNA;
break;
case PowerDownState::PDNPrecharge:
cmd = Command::PDNP;
break;
case PowerDownState::PDNSelfRefresh:
cmd = Command::SREF;
break;
default:
SC_REPORT_FATAL("In PowerDownManager sendPowerdownBegin", "invalid powerDownState");
}
return cmd;
}
inline Command IPowerDownManager::getWakeUpCommand(PowerDownState state)
{
Command cmd(Command::NOP);
switch (state)
{
case PowerDownState::PDNActive:
cmd = Command::PDNAX;
break;
case PowerDownState::PDNPrecharge:
cmd = Command::PDNPX;
break;
case PowerDownState::PDNSelfRefresh:
cmd = Command::SREFX;
break;
default:
SC_REPORT_FATAL("In PowerDownManager sendPowerdownEnd", "invalid powerDownState");
}
return cmd;
}
inline std::string powerDownStateToString(PowerDownState powerDownState)
{
switch (powerDownState)
{
case PowerDownState::Awake:
return "Awake";
case PowerDownState::AwakeForRefresh:
return "Awake for refresh";
case PowerDownState::PDNActive:
return "PDN Active";
case PowerDownState::PDNPrecharge:
return "PDN Precharged";
case PowerDownState::PDNSelfRefresh:
return "PDN Self refresh";
default:
return "unknown state";
}
}
} /* namespace core */
#endif /* IPOWERDOWNMANAGER_H_ */

View File

@@ -1,274 +1,174 @@
/*
* IPowerDownManager.cpp
* PowerDownManager.cpp
*
* Created on: Apr 4, 2014
* Created on: Apr 1, 2014
* Author: jonny
*/
#include <algorithm>
#include <string>
#include "PowerDownManager.h"
#include "../ControllerCore.h"
#include "../TimingCalculation.h"
#include "../../common/DebugManager.h"
#include <algorithm>
#include "../../common/Utils.h"
#include "../utils/Utils.h"
using namespace tlm;
using namespace std;
namespace core {
std::string PowerDownManager::senderName = "pdn manager";
PowerDownManager::PowerDownManager(ControllerCore& controller) :
controller(controller)
{
init();
powerDownState = PowerDownState::Awake;
for (Bank bank : controller.getBanks())
{
setUpDummy(powerDownPayloads[bank], bank);
}
}
PowerDownManager::~PowerDownManager()
{
}
void PowerDownManager::sleep(Bank bank, sc_time time)
{
assert(canSleep(bank));
if (!canSleep() || isInPowerDown())
return;
PowerDownState state = getPowerDownState(bank);
sc_time minTime = controller.config.Timings.tCKE;
PowerDownState state = powerDownState;
if (state == PowerDownState::Awake) //coming from active
{
state = controller.state.bankStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge;
state = controller.state.bankStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
}
else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down
{
sc_assert(!controller.state.bankStates.rowBufferIsOpen(bank));
sc_assert(controller.state.bankStates.allRowBuffersAreClosed());
if (controller.state.getLastCommand(Command::PDNA, bank).getStart()
> controller.state.getLastCommand(Command::PDNP, bank).getStart())
if (controller.state.getLastCommand(Command::PDNA).getStart()
>= controller.state.getLastCommand(Command::PDNP).getStart())
state = PowerDownState::PDNPrecharge;
else
{
state = PowerDownState::PDNSelfRefresh;
minTime = controller.config.Timings.tCKESR;
}
}
ScheduledCommand pdn(getSleepCommand(state), time, minTime, DramExtension::getExtension(getPayload(bank)));
ScheduledCommand pdn(IPowerDownManager::getSleepCommand(state), time,
getExecutionTime(IPowerDownManager::getSleepCommand(state), powerDownPayloads[bank]),
DramExtension::getExtension(powerDownPayloads[bank]));
controller.state.bus.moveCommandToNextFreeSlot(pdn);
//check if pdna or pdnp tcke collides with next refresh
if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn))
{
return;
}
setState(state, bank);
sendPowerDownPayload(pdn);
else
{
setState(state);
sendPowerDownPayloads(pdn);
}
}
void PowerDownManager::wakeUp(Bank bank, sc_time time)
{
if (isAwakeForRefresh(bank))
if (isAwakeForRefresh()) //Request enters system during Refresh
{
//Request enters system during Refresh (power down already waked up and payload sent)
setState(PowerDownState::Awake, bank);
setState(PowerDownState::Awake);
}
else if (isInPowerDown(bank))
else if (isInPowerDown()) //Request wakes up power down
{
time = clkAlign(time);
//Request wakes up power down
sc_time start(SC_ZERO_TIME);
switch (getPowerDownState(bank))
sc_time startOfExitCommand(SC_ZERO_TIME);
switch (powerDownState)
{
case PowerDownState::PDNActive:
start = max(time, controller.state.getLastCommand(Command::PDNA).getEnd());
startOfExitCommand = max(time, controller.state.getLastCommand(Command::PDNA).getEnd());
break;
case PowerDownState::PDNPrecharge:
start = max(time, controller.state.getLastCommand(Command::PDNP).getEnd());
startOfExitCommand = max(time, controller.state.getLastCommand(Command::PDNP).getEnd());
break;
case PowerDownState::PDNSelfRefresh:
start = max(time, controller.state.getLastCommand(Command::SREF).getEnd());
controller.refreshManager->reInitialize(bank, start + controller.config.Timings.clk);
startOfExitCommand = max(time, controller.state.getLastCommand(Command::SREF).getEnd());
controller.refreshManager->reInitialize(bank,
startOfExitCommand + getExecutionTime(Command::SREFX, powerDownPayloads[bank]));
break;
default:
break;
}
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState);
ScheduledCommand pdn(cmd, startOfExitCommand, getExecutionTime(cmd, powerDownPayloads[bank]),
DramExtension::getExtension(powerDownPayloads[bank]));
ScheduledCommand pdn(getWakeUpCommand(getPowerDownState(bank)), start, controller.config.Timings.clk,
DramExtension::getExtension(getPayload(bank)));
setState(PowerDownState::Awake, bank);
sendPowerDownPayload(pdn);
setState(PowerDownState::Awake);
sendPowerDownPayloads(pdn);
}
}
void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time)
{
if (isInPowerDown(bank))
if (isInPowerDown())
{
ScheduledCommand pdn(getWakeUpCommand(getPowerDownState(bank)), time, controller.config.Timings.clk,
DramExtension::getExtension(getPayload(bank)));
setState(PowerDownState::AwakeForRefresh, bank);
sendPowerDownPayload(pdn);
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState);
ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]),
DramExtension::getExtension(powerDownPayloads[bank]));
setState(PowerDownState::AwakeForRefresh);
sendPowerDownPayloads(pdn);
}
}
void PowerDownManager::wakeUpAllForRefresh(sc_time time)
void PowerDownManager::sendPowerDownPayloads(ScheduledCommand& cmd)
{
controller.state.bus.moveCommandToNextFreeSlot(cmd);
for (Bank bank : controller.getBanks())
{
wakeUpForRefresh(bank, time);
tlm_generic_payload& payloadToSend = powerDownPayloads[bank];
ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(),
DramExtension::getExtension(payloadToSend));
controller.state.change(pdnToSend);
controller.wrapper.send(pdnToSend, payloadToSend);
}
}
bool PowerDownManager::isInPowerDown(Bank bank)
void PowerDownManager::setState(PowerDownState state)
{
return isIn(getPowerDownState(bank),
{ PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh });
powerDownState = state;
DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName,
"Is now in state " + powerDownStateToString(powerDownState) + " on all banks");
}
bool PowerDownManager::isInSelfRefresh(Bank bank)
bool PowerDownManager::isInPowerDown()
{
return getPowerDownState(bank) == PowerDownState::PDNSelfRefresh;
return (powerDownState == PowerDownState::PDNActive || powerDownState == PowerDownState::PDNPrecharge
|| powerDownState == PowerDownState::PDNSelfRefresh);
}
bool PowerDownManager::allBanksInSelfRefresh()
bool PowerDownManager::canSleep()
{
for (Bank bank : controller.getBanks())
{
if (!isInSelfRefresh(bank))
if (!controller.numberOfPayloads[bank] == 0)
return false;
}
return true;
}
bool PowerDownManager::isAwakeForRefresh(Bank bank)
bool PowerDownManager::isInSelfRefresh(Bank bank)
{
return getPowerDownState(bank) == PowerDownState::AwakeForRefresh;
return powerDownState == PowerDownState::PDNSelfRefresh;
}
bool PowerDownManager::isAwake(Bank bank)
bool PowerDownManager::isAwakeForRefresh()
{
return getPowerDownState(bank) == PowerDownState::Awake;
return powerDownState == PowerDownState::AwakeForRefresh;
}
void PowerDownManager::setState(PowerDownState state, Bank bank)
{
PowerDownState& bankstate = getPowerDownState(bank);
bankstate = state;
string stateName;
switch (bankstate)
{
case PowerDownState::Awake:
stateName = "Awake";
break;
case PowerDownState::AwakeForRefresh:
stateName = "Awake for refresh";
break;
case PowerDownState::PDNActive:
stateName = "PDN Active";
break;
case PowerDownState::PDNPrecharge:
stateName = "PDN Precharged";
break;
case PowerDownState::PDNSelfRefresh:
stateName = "PDN Self refresh";
break;
default:
stateName = "unknown state";
break;
}
DebugManager::getInstance().printDebugMessage(PowerDownManager::senderName,
"Is now in state " + stateName + " on Bank " + to_string(bank.ID()));
}
Command PowerDownManager::getSleepCommand(PowerDownState state)
{
Command cmd(Command::NOP);
switch (state)
{
case PowerDownState::PDNActive:
cmd = Command::PDNA;
break;
case PowerDownState::PDNPrecharge:
cmd = Command::PDNP;
break;
case PowerDownState::PDNSelfRefresh:
cmd = Command::SREF;
break;
default:
SC_REPORT_FATAL("In PowerDownManager sendPowerdownBegin", "invalid powerDownState");
}
return cmd;
}
Command PowerDownManager::getWakeUpCommand(PowerDownState state)
{
Command cmd(Command::NOP);
switch (state)
{
case PowerDownState::PDNActive:
cmd = Command::PDNAX;
break;
case PowerDownState::PDNPrecharge:
cmd = Command::PDNPX;
break;
case PowerDownState::PDNSelfRefresh:
cmd = Command::SREFX;
break;
default:
SC_REPORT_FATAL("In PowerDownManager sendPowerdownEnd", "invalid powerDownState");
}
return cmd;
}
void PowerDownManager::sendPowerDownPayload(ScheduledCommand& pdn)
{
controller.state.bus.moveCommandToNextFreeSlot(pdn);
controller.state.change(pdn);
controller.wrapper.send(pdn, powerDownPayloads[pdn.getBank()]);
}
PowerDownState& PowerDownManager::getPowerDownState(Bank bank)
{
if (powerDownStates.count(bank) == 0)
{
SC_REPORT_FATAL("Map", "Element not in map");
}
return powerDownStates.at(bank);
}
bool PowerDownManager::canSleep(Bank bank)
{
if (powerDownStates.count(bank) == 0)
{
SC_REPORT_FATAL("Map", "Element not in map");
}
return controller.numberOfPayloads[bank] == 0;
}
tlm::tlm_generic_payload& PowerDownManager::getPayload(Bank bank)
{
if (powerDownPayloads.count(bank) == 0)
{
SC_REPORT_FATAL("Map", "Element not in map");
}
return powerDownPayloads.at(bank);
}
/*
* All Banks are precharged and in Precharge-PowerDown after starting the system
*/
void PowerDownManager::init()
{
for (Bank bank : controller.getBanks())
{
tlm_generic_payload& payload = powerDownPayloads[bank];
setUpDummy(payload, bank);
//send payload
ScheduledCommand pdn(Command::PDNP, SC_ZERO_TIME, SC_ZERO_TIME, DramExtension::getExtension(payload));
controller.state.change(pdn);
controller.wrapper.send(pdn, payload);
powerDownStates[bank] = PowerDownState::PDNPrecharge;
}
}
}/* namespace core */
} /* namespace core */

View File

@@ -1,69 +1,43 @@
/*
* IPowerDownManager.h
* PowerDownManagerGrouped.h
*
* Created on: Mar 31, 2014
* Created on: Apr 1, 2014
* Author: jonny
*/
#ifndef IPOWERDOWNMANAGER_H_
#define IPOWERDOWNMANAGER_H_
#ifndef POWERDOWNMANAGER_H_
#define POWERDOWNMANAGER_H_
#include <systemc.h>
#include <tlm.h>
#include <map>
#include <string>
#include "../Command.h"
#include "../../common/dramExtension.h"
#include "../scheduling/ScheduledCommand.h"
#include "PowerDownManagerBankwise.h"
namespace core {
class ControllerCore;
enum class PowerDownState
{
Awake, AwakeForRefresh, PDNActive, PDNPrecharge, PDNSelfRefresh
};
class PowerDownManager
class PowerDownManager: public IPowerDownManager
{
public:
PowerDownManager(ControllerCore& controller);
virtual ~PowerDownManager()
{
}
virtual void sleep(Bank bank, sc_time time);
virtual void wakeUp(Bank bank, sc_time time);
virtual void wakeUpForRefresh(Bank bank, sc_time time);
virtual void wakeUpAllForRefresh(sc_time time);
virtual ~PowerDownManager();
virtual bool isInSelfRefresh(Bank bank);
virtual bool allBanksInSelfRefresh();
virtual bool isInPowerDown(Bank bank);
virtual bool isAwake(Bank bank);
virtual bool isAwakeForRefresh(Bank bank);
virtual void sleep(Bank bank, sc_time time) override;
virtual void wakeUp(Bank bank, sc_time time) override;
virtual void wakeUpForRefresh(Bank bank, sc_time time) override;
static std::string senderName;
protected:
virtual bool isInSelfRefresh(Bank bank) override;
private:
PowerDownState powerDownState;
void sendPowerDownPayloads(ScheduledCommand& cmd);
ControllerCore& controller;
bool isInPowerDown();
void setState(PowerDownState state);
bool canSleep();
bool isAwakeForRefresh();
std::map<Bank, tlm::tlm_generic_payload> powerDownPayloads;
std::map<Bank, PowerDownState> powerDownStates;
virtual PowerDownState& getPowerDownState(Bank bank);
virtual tlm::tlm_generic_payload& getPayload(Bank bank);
virtual bool canSleep(Bank bank);
void setState(PowerDownState state, Bank bank);
Command getWakeUpCommand(PowerDownState state);
Command getSleepCommand(PowerDownState state);
void sendPowerDownPayload(ScheduledCommand& pdn);
void init();
ControllerCore& controller;
};
}/* namespace core */
} /* namespace core */
#endif /* IPOWERDOWNMANAGER_H_ */
#endif /* POWERDOWNMANAGER_H_ */

View File

@@ -0,0 +1,161 @@
/*
* IPowerDownManager.cpp
*
* Created on: Apr 4, 2014
* Author: jonny
*/
#include "PowerDownManager.h"
#include "../ControllerCore.h"
#include "../../common/Utils.h"
#include "../TimingCalculation.h"
using namespace tlm;
namespace core {
std::string PowerDownManagerBankwise::senderName = "pdn manager";
PowerDownManagerBankwise::PowerDownManagerBankwise(ControllerCore& controller) :
controller(controller)
{
for (Bank bank : controller.getBanks())
{
setUpDummy(powerDownPayloads[bank], bank);
powerDownStates[bank] = PowerDownState::Awake;
}
}
void PowerDownManagerBankwise::sleep(Bank bank, sc_time time)
{
if (!canSleep(bank))
return;
tlm_generic_payload& payload = powerDownPayloads[bank];
sc_time minTime = getExecutionTime(Command::PDNA, payload);
PowerDownState state = powerDownStates[bank];
if (state == PowerDownState::Awake) //coming from active
{
state = controller.state.bankStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge;
}
else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down
{
sc_assert(!controller.state.bankStates.rowBufferIsOpen(bank));
if (controller.state.getLastCommand(Command::PDNA, bank).getStart()
>= controller.state.getLastCommand(Command::PDNP, bank).getStart())
state = PowerDownState::PDNPrecharge;
else
{
state = PowerDownState::PDNSelfRefresh;
minTime = getExecutionTime(Command::SREF, payload);
}
}
ScheduledCommand pdn(IPowerDownManager::getSleepCommand(state), time, minTime, DramExtension::getExtension(payload));
controller.state.bus.moveCommandToNextFreeSlot(pdn);
if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn))
{
return;
}
else
{
setState(state, bank);
sendPowerDownPayload(pdn);
}
}
void PowerDownManagerBankwise::wakeUp(Bank bank, sc_time time)
{
if (isAwakeForRefresh(bank))
{
setState(PowerDownState::Awake, bank);
}
else if (isInPowerDown(bank))
{
//Request wakes up power down
sc_time startOfExitCommand(SC_ZERO_TIME);
switch (powerDownStates[bank])
{
case PowerDownState::PDNActive:
startOfExitCommand = max(time, controller.state.getLastCommand(Command::PDNA).getEnd());
break;
case PowerDownState::PDNPrecharge:
startOfExitCommand = max(time, controller.state.getLastCommand(Command::PDNP).getEnd());
break;
case PowerDownState::PDNSelfRefresh:
startOfExitCommand = max(time, controller.state.getLastCommand(Command::SREF).getEnd());
controller.refreshManager->reInitialize(bank,
startOfExitCommand + getExecutionTime(Command::SREFX, powerDownPayloads[bank]));
break;
default:
break;
}
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]);
ScheduledCommand pdn(cmd, startOfExitCommand, getExecutionTime(cmd, powerDownPayloads[bank]),
DramExtension::getExtension(powerDownPayloads[bank]));
setState(PowerDownState::Awake, bank);
sendPowerDownPayload(pdn);
}
}
void PowerDownManagerBankwise::wakeUpForRefresh(Bank bank, sc_time time)
{
if (isInPowerDown(bank))
{
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]);
ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank]));
setState(PowerDownState::AwakeForRefresh, bank);
sendPowerDownPayload(pdn);
}
}
bool PowerDownManagerBankwise::isInPowerDown(Bank bank)
{
return isIn(powerDownStates[bank],
{ PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh });
}
bool PowerDownManagerBankwise::isInSelfRefresh(Bank bank)
{
return powerDownStates[bank] == PowerDownState::PDNSelfRefresh;
}
bool PowerDownManagerBankwise::isAwakeForRefresh(Bank bank)
{
return powerDownStates[bank] == PowerDownState::AwakeForRefresh;
}
bool PowerDownManagerBankwise::isAwake(Bank bank)
{
return powerDownStates[bank] == PowerDownState::Awake;
}
void PowerDownManagerBankwise::setState(PowerDownState state, Bank bank)
{
PowerDownState& bankstate = powerDownStates[bank];
bankstate = state;
DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName,
"Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID()));
}
void PowerDownManagerBankwise::sendPowerDownPayload(ScheduledCommand& pdn)
{
controller.state.bus.moveCommandToNextFreeSlot(pdn);
controller.state.change(pdn);
controller.wrapper.send(pdn, powerDownPayloads[pdn.getBank()]);
}
bool PowerDownManagerBankwise::canSleep(Bank bank)
{
return controller.numberOfPayloads[bank] == 0;
}
}/* namespace core */

View File

@@ -0,0 +1,59 @@
/*
* PowerDownManagerBankwise.h
*
* Created on: Mar 31, 2014
* Author: jonny
*/
#ifndef POWERDOWNMANAGERBANKWISE_H_
#define POWERDOWNMANAGERBANKWISE_H_
#include <systemc.h>
#include <tlm.h>
#include <map>
#include <string>
#include "../Command.h"
#include "../../common/dramExtension.h"
#include "../scheduling/ScheduledCommand.h"
#include "IPowerDownManager.h"
namespace core {
class ControllerCore;
class PowerDownManagerBankwise: public IPowerDownManager
{
public:
PowerDownManagerBankwise(ControllerCore& controller);
virtual ~PowerDownManagerBankwise()
{
}
virtual void sleep(Bank bank, sc_time time) override;
virtual void wakeUp(Bank bank, sc_time time) override;
virtual void wakeUpForRefresh(Bank bank, sc_time time) override;
virtual bool isInSelfRefresh(Bank bank) override;
static std::string senderName;
private:
virtual bool isInPowerDown(Bank bank);
virtual bool isAwake(Bank bank);
virtual bool isAwakeForRefresh(Bank bank);
ControllerCore& controller;
std::map<Bank, tlm::tlm_generic_payload> powerDownPayloads;
std::map<Bank, PowerDownState> powerDownStates;
virtual bool canSleep(Bank bank);
void setState(PowerDownState state, Bank bank);
Command getWakeUpCommand(PowerDownState state);
Command getSleepCommand(PowerDownState state);
void sendPowerDownPayload(ScheduledCommand& pdn);
};
}/* namespace core */
#endif /* POWERDOWNMANAGERBANKWISE_H_ */

View File

@@ -1,166 +0,0 @@
/*
* PowerDownManager.cpp
*
* Created on: Apr 1, 2014
* Author: jonny
*/
#include <algorithm>
#include <string>
#include "PowerDownManagerGrouped.h"
#include "../ControllerCore.h"
#include "../utils/Utils.h"
#include "../../common/DebugManager.h"
#include <algorithm>
using namespace tlm;
using namespace std;
namespace core {
PowerDownManagerGrouped::~PowerDownManagerGrouped()
{
}
void PowerDownManagerGrouped::sleep(Bank bank, sc_time time)
{
//all banks can sleep and no pending refresh in system
if (!canSleep() || (controller.state.getLastCommand(Command::AutoRefresh).getEnd() > time))
return;
PowerDownState state = getPowerDownState();
if (state == PowerDownState::Awake)//coming from active
{
if (controller.state.bankStates.allRowBuffersAreClosed())
setState(PowerDownState::PDNPrecharge);
else
setState(PowerDownState::PDNActive);
sendPowerDownPayload(time, getSleepCommand(getPowerDownState()));
}
else if (state == PowerDownState::AwakeForRefresh)//coming from refresh interrupting power down
{
if(controller.state.bankStates.allRowBuffersAreClosed())
{
if (controller.state.getLastCommand(Command::PDNA).getStart()
> controller.state.getLastCommand(Command::PDNP).getStart())
setState(PowerDownState::PDNPrecharge);
else
setState(PowerDownState::PDNSelfRefresh);
}
else
{
setState(PowerDownState::PDNActive);
}
sendPowerDownPayload(time, getSleepCommand(getPowerDownState()));
}
}
void PowerDownManagerGrouped::wakeUp(Bank bank, sc_time time)
{
if (isAwakeForRefresh())//Request enters system during Refresh
{
//power down already waked up and payload sent
setState(PowerDownState::Awake);
}
else if(isInPowerDown())//Request wakes up power down
{
sc_time delay(SC_ZERO_TIME);
switch (getPowerDownState())
{
case PowerDownState::PDNActive:
break;
case PowerDownState::PDNPrecharge:
break;
case PowerDownState::PDNSelfRefresh:
delay = getDelayToMeetConstraint(
controller.state.getLastCommand(Command::SREF).getStart(), time,
controller.config.Timings.tCKESR);
break;
default:
break;
}
if (delay == SC_ZERO_TIME)
{
sendPowerDownPayload(time, getWakeUpCommand(getPowerDownState()));
setState(PowerDownState::Awake);
}
else
{
tlm_generic_payload& p = getPayload(bank);
controller.wrapper.send(WakeUpTrigger, time + delay, p);
}
}
}
void PowerDownManagerGrouped::wakeUpForRefresh(Bank bank, sc_time time)
{
wakeUpAllForRefresh(time);
}
void PowerDownManagerGrouped::wakeUpAllForRefresh(sc_time time)
{
if(isInPowerDown())
{
sendPowerDownPayload(time, getWakeUpCommand(getPowerDownState()));
setState(PowerDownState::AwakeForRefresh);
}
}
void PowerDownManagerGrouped::sendPowerDownPayload(sc_time time, Command cmd)
{
time = clkAlign(time);
//just to find slot
tlm_generic_payload& payload = getPayload(Bank(0));
ScheduledCommand pdn(cmd, time, controller.config.Timings.clk, DramExtension::getExtension(payload));
controller.state.bus.moveCommandToNextFreeSlot(pdn);
for (Bank bank : controller.getBanks())
{
tlm_generic_payload& payloadToSend = getPayload(bank);
ScheduledCommand pdnToSend(cmd, pdn.getStart(), controller.config.Timings.clk, DramExtension::getExtension(payloadToSend));
controller.state.change(pdnToSend);
controller.wrapper.send(pdnToSend, payloadToSend);
}
}
void PowerDownManagerGrouped::setState(PowerDownState state)
{
for (Bank bank : controller.getBanks())
{
PowerDownManager::setState(state, bank);
}
}
bool PowerDownManagerGrouped::isInPowerDown()
{
return PowerDownManager::isInPowerDown(Bank(0));
}
bool PowerDownManagerGrouped::canSleep()
{
for (Bank bank : controller.getBanks())
{
if (!PowerDownManager::canSleep(bank))
return false;
}
return true;
}
PowerDownState PowerDownManagerGrouped::getPowerDownState()
{
return PowerDownManager::getPowerDownState(Bank(0));
}
bool PowerDownManagerGrouped::isAwakeForRefresh()
{
return PowerDownManager::isAwakeForRefresh(Bank(0));
}
} /* namespace core */

View File

@@ -1,47 +0,0 @@
/*
* PowerDownManagerGrouped.h
*
* Created on: Apr 1, 2014
* Author: jonny
*/
#ifndef POWERDOWNMANAGER_H_
#define POWERDOWNMANAGER_H_
#include "PowerDownManager.h"
namespace core {
class ControllerCore;
class PowerDownManagerGrouped: public PowerDownManager
{
public:
using PowerDownManager::PowerDownManager;
virtual ~PowerDownManagerGrouped();
virtual void sleep(Bank bank, sc_time time) override;
virtual void wakeUp(Bank bank, sc_time time) override;
virtual void wakeUpForRefresh(Bank bank, sc_time time) override;
virtual void wakeUpAllForRefresh(sc_time time) override;
//virtual bool isInSelfRefresh(Bank bank) override;
//virtual bool isAwakeForRefresh(Bank bank) override;
private:
void sendPowerDownPayload(sc_time time, Command cmd);
void setState(PowerDownState state);
bool isInPowerDown();
bool canSleep();
PowerDownState getPowerDownState();
bool isAwakeForRefresh();
};
} /* namespace core */
#endif /* POWERDOWNMANAGER_H_ */

View File

@@ -7,14 +7,15 @@
#include "RefreshManager.h"
#include "../ControllerCore.h"
#include "../utils/Utils.h"
#include "../TimingCalculation.h"
#include "../../common/Utils.h"
#include "../TimingCalculation.h"
using namespace tlm;
namespace core {
RefreshManager::RefreshManager(ControllerCore& controller) :
controller(controller), timing(controller.config.Timings.refreshTimings[Bank(0)]), nextPlannedRefresh(
SC_ZERO_TIME)
controller(controller), timing(controller.config.Timings.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME)
{
setupTransactions();
planNextRefresh();
@@ -26,12 +27,12 @@ RefreshManager::~RefreshManager()
bool RefreshManager::hasCollision(const CommandSchedule& schedule)
{
return !(schedule.getEnd() < nextPlannedRefresh);
return schedule.getEnd() > nextPlannedRefresh;
}
bool RefreshManager::hasCollision(const ScheduledCommand& command)
{
return !(command.getEnd() < nextPlannedRefresh);
return command.getEnd() > nextPlannedRefresh;
}
void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
@@ -40,41 +41,37 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time
if (!controller.state.bankStates.allRowBuffersAreClosed())
{
ScheduledCommand precharge(Command::PrechargeAll, time, controller.config.Timings.tRP,
ScheduledCommand precharge(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]),
DramExtension::getExtension(refreshPayloads[Bank(0)]));
controller.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(precharge);
for (Bank bank : controller.getBanks())
{
tlm_generic_payload& payload = refreshPayloads[bank];
ScheduledCommand prechargeToSend(Command::PrechargeAll, precharge.getStart(),
controller.config.Timings.tRP, DramExtension::getExtension(payload));
controller.state.change(prechargeToSend);
controller.wrapper.send(prechargeToSend, payload);
}
sendToAllBanks(precharge);
}
ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC,
ScheduledCommand nextRefresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayloads[Bank(0)]),
DramExtension::getExtension(refreshPayloads[Bank(0)]));
controller.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(nextRefresh);
sendToAllBanks(nextRefresh);
for (Bank bank : controller.getBanks())
{
tlm_generic_payload& payload = refreshPayloads[bank];
Row currentrow = DramExtension::getExtension(payload).getRow();
DramExtension::getExtension(payload).setRow(Row((currentrow.ID()+1)%Configuration::getInstance().NumberOfBanks));
ScheduledCommand refreshToSend(Command::AutoRefresh, nextRefresh.getStart(), timing.tRFC,
DramExtension::getExtension(payload));
controller.state.change(refreshToSend);
controller.wrapper.send(refreshToSend, payload);
DramExtension::getExtension(refreshPayloads[bank]).increaseRow();
}
planNextRefresh();
}
void RefreshManager::sendToAllBanks(ScheduledCommand& command)
{
for (Bank bank : controller.getBanks())
{
tlm_generic_payload& payload = refreshPayloads[bank];
DramExtension extension = DramExtension::getExtension(payload);
ScheduledCommand cmd(command.getCommand(), command.getStart(), command.getExecutionTime(), extension);
controller.state.change(cmd);
controller.wrapper.send(cmd, payload);
}
}
void RefreshManager::planNextRefresh()
{
nextPlannedRefresh += timing.tREFI;

View File

@@ -36,6 +36,8 @@ private:
std::map<Bank, tlm::tlm_generic_payload> refreshPayloads;
void planNextRefresh();
void sendToAllBanks(ScheduledCommand& command);
void setupTransactions();
};

View File

@@ -7,7 +7,8 @@
#include "RefreshManagerBankwise.h"
#include "../ControllerCore.h"
#include "../utils/Utils.h"
#include "../TimingCalculation.h"
#include "../../common/Utils.h"
using namespace std;
@@ -16,117 +17,71 @@ namespace core {
RefreshManagerBankwise::RefreshManagerBankwise(ControllerCore& controller) :
controller(controller)
{
for (Bank bank : controller.getBanks())
for(Bank bank : controller.getBanks())
{
refreshManagerForBanks[bank] = new RefreshManagerForBank(controller, bank);
setUpDummy(refreshPayloads[bank], bank);
planNextRefresh(bank);
}
}
RefreshManagerBankwise::~RefreshManagerBankwise()
{
for (Bank bank : controller.getBanks())
{
delete refreshManagerForBanks[bank];
}
}
bool RefreshManagerBankwise::hasCollision(const CommandSchedule& schedule)
{
RefreshManagerForBank& manager = *refreshManagerForBanks[schedule.getBank()];
return manager.hasCollision(schedule);
return schedule.getEnd() > nextPlannedRefreshs[schedule.getBank()];
}
bool RefreshManagerBankwise::hasCollision(const ScheduledCommand& command)
{
RefreshManagerForBank& manager = *refreshManagerForBanks[command.getBank()];
return manager.hasCollision(command);
return command.getEnd() > nextPlannedRefreshs[command.getBank()];
}
void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
{
sc_assert(!isInvalidated(payload, time));
RefreshManagerForBank& manager = *refreshManagerForBanks[DramExtension::getExtension(payload).getBank()];
manager.scheduleRefresh(time);
}
RefreshManagerBankwise::RefreshManagerForBank::RefreshManagerForBank(ControllerCore& controller, Bank bank) :
controller(controller), timing(controller.config.Timings.refreshTimings[bank]), bank(bank), nextPlannedRefresh(
SC_ZERO_TIME)
{
setupTransaction();
planNextRefresh();
}
tlm::tlm_generic_payload& refreshPayload = refreshPayloads[DramExtension::getExtension(payload).getBank()];
RefreshManagerBankwise::RefreshManagerForBank::~RefreshManagerForBank()
{
}
DramExtension& extension = DramExtension::getExtension(refreshPayload);
bool RefreshManagerBankwise::RefreshManagerForBank::hasCollision(const CommandSchedule& schedule)
{
return !(schedule.getEnd() < nextPlannedRefresh);
}
bool RefreshManagerBankwise::RefreshManagerForBank::hasCollision(const ScheduledCommand& command)
{
return !(command.getEnd() < nextPlannedRefresh);
}
void RefreshManagerBankwise::RefreshManagerForBank::scheduleRefresh(sc_time time)
{
ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC, DramExtension::getExtension(refreshPayload));
if (controller.state.bankStates.rowBufferIsOpen(bank))
if (controller.state.bankStates.rowBufferIsOpen(extension.getBank()))
{
ScheduledCommand precharge(Command::Precharge, time, controller.config.Timings.tRP,
DramExtension::getExtension(refreshPayload));
controller.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge);
controller.state.bus.moveCommandToNextFreeSlot(precharge);
nextRefresh.setStart(precharge.getEnd());
ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, refreshPayload), extension);
controller.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge);
controller.state.change(precharge);
controller.wrapper.send(precharge, refreshPayload);
}
controller.state.bus.moveCommandToNextFreeSlot(nextRefresh);
ScheduledCommand nextRefresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayload), extension);
controller.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(nextRefresh);
controller.state.change(nextRefresh);
Row currentrow = DramExtension::getExtension(refreshPayload).getRow();
DramExtension::getExtension(refreshPayload).setRow(Row((currentrow.ID() + 1) % Configuration::getInstance().NumberOfBanks));
controller.wrapper.send(nextRefresh, refreshPayload);
planNextRefresh();
extension.increaseRow();
planNextRefresh(extension.getBank());
}
void RefreshManagerBankwise::RefreshManagerForBank::planNextRefresh()
void RefreshManagerBankwise::planNextRefresh(Bank bank)
{
nextPlannedRefresh += timing.tREFI;
controller.wrapper.send(RefreshTrigger, nextPlannedRefresh, refreshPayload);
}
void RefreshManagerBankwise::RefreshManagerForBank::reInitialize(Bank bank, sc_time time)
{
nextPlannedRefresh = clkAlign(time, Alignment::DOWN);
planNextRefresh();
}
bool RefreshManagerBankwise::RefreshManagerForBank::isInvalidated(sc_time time)
{
return nextPlannedRefresh > time;
}
void RefreshManagerBankwise::RefreshManagerForBank::setupTransaction()
{
setUpDummy(refreshPayload, bank);
nextPlannedRefreshs[bank] += Configuration::getInstance().Timings.refreshTimings[bank].tREFI;
controller.wrapper.send(RefreshTrigger, nextPlannedRefreshs[bank], refreshPayloads[bank]);
}
void RefreshManagerBankwise::reInitialize(Bank bank, sc_time time)
{
refreshManagerForBanks[bank]->reInitialize(bank, time);
nextPlannedRefreshs[bank] = clkAlign(time, Alignment::DOWN);
planNextRefresh(bank);
}
bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time)
{
RefreshManagerForBank& manager = *refreshManagerForBanks[DramExtension::getExtension(payload).getBank()];
return manager.isInvalidated(time);
return nextPlannedRefreshs[DramExtension::getExtension(payload).getBank()] > time;
}
} /* namespace core */

View File

@@ -33,35 +33,12 @@ public:
private:
class RefreshManagerForBank
{
public:
RefreshManagerForBank(ControllerCore& controller, Bank bank);
~RefreshManagerForBank();
bool hasCollision(const CommandSchedule& schedule);
bool hasCollision(const ScheduledCommand& command);
void scheduleRefresh(sc_time time);
void reInitialize(Bank bank, sc_time time);
bool isInvalidated(sc_time);
private:
ControllerCore& controller;
RefreshTiming& timing;
Bank bank;
tlm::tlm_generic_payload refreshPayload;
sc_time nextPlannedRefresh;
void planNextRefresh();
void setupTransaction();
};
ControllerCore& controller;
std::map<Bank, RefreshManagerForBank*> refreshManagerForBanks;
std::map<Bank, tlm::tlm_generic_payload> refreshPayloads;
std::map<Bank, sc_time> nextPlannedRefreshs;
void planNextRefresh(Bank bank);
};
} /* namespace controller */

View File

@@ -8,6 +8,7 @@
#include "CommandSequenceScheduler.h"
#include "../ControllerCore.h"
#include "../../common/DebugManager.h"
#include "../TimingCalculation.h"
namespace core {
@@ -22,7 +23,7 @@ CommandSchedule CommandSequenceScheduler::schedule(CommandSequence commands, sc_
ICommandChecker& checker = controller.getCommandChecker(cmd);
sc_time executionTime = checker.getExecutionTime(transaction, cmd);
sc_time executionTime = getExecutionTime(cmd,transaction);
ScheduledCommand& scheduledCommand = schedule.add(cmd, start, executionTime);
checker.delayToSatisfyConstraints(scheduledCommand);

View File

@@ -5,7 +5,7 @@
* Author: robert
*/
#include "ScheduledCommand.h"
#include "../utils/Utils.h"
#include "../TimingCalculation.h"
#include "../../common/Utils.h"
#include "../configuration/Configuration.h"

View File

@@ -13,7 +13,7 @@
#include "../Command.h"
#include "../../common/dramExtension.h"
#include "../../common/TlmRecorder.h"
#include "../utils/Utils.h"
#include "../TimingCalculation.h"
namespace core {

View File

@@ -8,7 +8,7 @@
#include <algorithm>
#include <set>
#include "ActivateChecker.h"
#include "../../utils/Utils.h"
#include "../../TimingCalculation.h"
#include "../../../common/DebugManager.h"
#include "../../Command.h"
#include "../../../common/Utils.h"
@@ -31,11 +31,11 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
else if (lastCommandOnBank.getCommand() == Command::PDNPX
|| lastCommandOnBank.getCommand() == Command::PDNAX)
{
command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXP);
command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.Timings.tXP);
}
else if (lastCommandOnBank.getCommand() == Command::SREFX)
{
command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXSR);
command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.Timings.tXSR);
}
else
reportFatal("Activate Checker",
@@ -53,13 +53,6 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
}
sc_time ActivateChecker::getExecutionTime(const tlm::tlm_generic_payload& transaction,
Command command) const
{
assert(command == Command::Activate);
return config.Timings.tRCD;
}
void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank(ScheduledCommand& command) const
{
ScheduledCommand lastActivateOnBank = state.getLastCommand(Command::Activate,

View File

@@ -22,8 +22,6 @@ public:
virtual ~ActivateChecker(){}
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override;
private:
const Configuration& config;
ControllerState& state;//TODO make const

View File

@@ -17,9 +17,7 @@ class ICommandChecker
{
public:
virtual ~ICommandChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const = 0;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const = 0;
};
} /* namespace controller */

View File

@@ -51,13 +51,8 @@ void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand& command) c
"Precharge All can not follow " + commandToString(lastCommand.getCommand()));
}
}
state.bus.moveCommandToNextFreeSlot(command);
}
sc_time PrechargeAllChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const
{
sc_assert(command == Command::PrechargeAll);
return config.Timings.tRP;
}
} /* namespace core */

View File

@@ -26,8 +26,6 @@ public:
}
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const
override;
private:
const Configuration& config;

View File

@@ -41,11 +41,4 @@ void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons
state.bus.moveCommandToNextFreeSlot(command);
}
sc_time PrechargeChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
Command command) const
{
sc_assert(command == Command::Precharge || command == Command::PrechargeAll);
return config.Timings.tRP;
}
} /* namespace controller */

View File

@@ -19,9 +19,8 @@ class PrechargeChecker: public core::ICommandChecker
public:
PrechargeChecker(const Configuration& config, ControllerState& state) : config(config), state(state) {}
virtual ~PrechargeChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override;
private:
const Configuration& config;
ControllerState& state;

View File

@@ -6,7 +6,7 @@
*/
#include "ReadChecker.h"
#include "../../utils/Utils.h"
#include "../../TimingCalculation.h"
#include "../../../common/Utils.h"
namespace core {
@@ -29,7 +29,7 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
}
else if (lastCommand.getCommand() == Command::PDNAX)
{
command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tXP);//TODO DLL also for PDNP and SREF .. not onyl last command
command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tXP);//TODO DLL also for PDNP and SREF .. not onyl last command
}
else
reportFatal("Read Checker",
@@ -53,20 +53,6 @@ bool ReadChecker::collidesOnDataStrobe(ScheduledCommand& read) const
return false;
}
sc_time ReadChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
Command command) const
{
if (command == Command::Read)
{
return config.Timings.tRL + getBurstLengthOnDataStrobe(payload.get_streaming_width());
}
else
{
return getBurstLengthOnDataStrobe(payload.get_streaming_width())
+ max(config.Timings.tRP, config.Timings.tRL);
}
}
bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read,
ScheduledCommand& strobeCommand) const
{

View File

@@ -21,7 +21,6 @@ public:
virtual ~ReadChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override;
private:
const Configuration& config;

View File

@@ -30,22 +30,14 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
command.delayToMeetConstraint(lastCommandOnBank.getEnd(), config.Timings.tXSR);
}
else if (lastCommandOnBank.getCommand() == Command::AutoRefresh)
{
}
else
reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand()));
}
while (!state.bus.isFree(command.getStart()))
{
command.delayStart(config.Timings.clk);
}
}
sc_time RefreshChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const
{
assert(command == Command::AutoRefresh);
Bank bank = DramExtension::getExtension(payload).getBank();
RefreshTiming timing = config.Timings.refreshTimings.at(bank);
return timing.tRFC;
state.bus.moveCommandToNextFreeSlot(command);
}
} /* namespace core */

View File

@@ -15,7 +15,7 @@
namespace core {
class RefreshChecker: ICommandChecker
class RefreshChecker: public ICommandChecker
{
public:
RefreshChecker(const Configuration& config, ControllerState& state) :
@@ -27,7 +27,6 @@ public:
}
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override;
private:
const Configuration& config;

View File

@@ -6,7 +6,7 @@
*/
#include "WriteChecker.h"
#include "../../utils/Utils.h"
#include "../../TimingCalculation.h"
#include "../../../common/Utils.h"
namespace core {
@@ -30,7 +30,7 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
}
else if (lastCommand.getCommand() == Command::PDNAX)
{
command.delayToMeetConstraint(lastCommand.getEnd(), config.Timings.tXP);
command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tXP);
}
else
reportFatal("Write Checker",
@@ -43,26 +43,6 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
}
}
sc_time WriteChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
Command command) const
{
assert(command == Command::Write || command == Command::WriteA);
sc_time lengthOnDataStrobe = getBurstLengthOnDataStrobe(payload.get_streaming_width());
if(Configuration::getInstance().DataRate == 1)
lengthOnDataStrobe -= Configuration::getInstance().Timings.clk;
if (command == Command::Write)
{
return config.Timings.tWL + lengthOnDataStrobe;
}
else
{
return config.Timings.tWL + lengthOnDataStrobe + config.Timings.tWR;
}
}
bool WriteChecker::collidesOnDataStrobe(ScheduledCommand& write) const
{
for (ScheduledCommand& strobeCommand : state.lastDataStrobeCommands)

View File

@@ -21,7 +21,6 @@ public:
virtual ~WriteChecker() {}
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override;
private:
bool collidesOnDataStrobe(ScheduledCommand& write) const;
bool collidesWithStrobeCommand(ScheduledCommand& write, ScheduledCommand& strobeCommand) const;

View File

@@ -1,79 +0,0 @@
/*
* Utils.cpp
*
* Created on: Mar 12, 2014
* Author: jonny
*/
#include "Utils.h"
#include "../configuration/TimingConfiguration.h"
#include "../ControllerCore.h"
#include "../../common/DebugManager.h"
#include "../configuration/Configuration.h"
namespace core {
sc_time getDistance(sc_time a, sc_time b)
{
if (a > b)
return a - b;
else
return b - a;
}
sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint)
{
if (previous + constraint > start)
return previous + constraint - start;
else
return SC_ZERO_TIME;
}
const sc_time clkAlign(sc_time time, Alignment alignment)
{
sc_time clk = Configuration::getInstance().Timings.clk;
if (alignment == UP)
return ceil(time / clk) * clk;
else
return floor(time / clk) * clk;
}
bool isClkAligned(sc_time time, sc_time clk)
{
return !((time / clk) - ceil(time / clk));
}
bool TimeInterval::timeIsInInterval(sc_time time)
{
return (start < time && time < end);
}
bool TimeInterval::intersects(TimeInterval other)
{
return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start);
}
sc_time getBurstLengthOnDataStrobe(unsigned int burstlength)
{
Configuration& config = Configuration::getInstance();
sc_assert((burstlength / config.DataRate) > 0);
return config.Timings.clk * (burstlength / config.DataRate);
}
void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank)
{
payload.set_address(bank.getStartAddress());
payload.set_command(tlm::TLM_READ_COMMAND);
payload.set_data_length(0);
payload.set_response_status(tlm::TLM_OK_RESPONSE);
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_streaming_width(0);
payload.set_extension(new DramExtension(Thread(0), bank, bank.getBankGroup(), Row(0), Column(0))); //payload takes ownership
}
}

View File

@@ -17,7 +17,7 @@
#include <tlm_utils/peq_with_cb_and_phase.h>
#include "../common/xmlAddressdecoder.h"
#include "../common/dramExtension.h"
#include "../core/utils/Utils.h"
#include "../core/TimingCalculation.h"
#include <iostream>

View File

@@ -42,8 +42,7 @@ public:
tlm_utils::simple_target_socket<Controller, BUSWIDTH, tlm::tlm_base_protocol_types> tSocket;
Controller(sc_module_name name) :
frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this,
&Controller::dramPEQCallback), controllerPEQ(this,
frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerPEQ(this,
&Controller::controllerPEQCallback), debugManager(DebugManager::getInstance())
{
controller = new ControllerCore(*this, numberOfPayloadsInSystem);
@@ -65,19 +64,13 @@ public:
if (selectedScheduler == "FR_FCFS")
{
// if(Configuration::getInstance().RefreshAwareScheduling)
// cout << "Building refresh aware scheduler" << std::endl;
// else
// cout << "Building refresh un-aware scheduler" << std::endl;
scheduler = new FR_FCFS(controller->state.bankStates,
Configuration::getInstance().RefreshAwareScheduling,
scheduler = new FR_FCFS(controller->state.bankStates, Configuration::getInstance().RefreshAwareScheduling,
Configuration::getInstance().AdaptiveOpenPagePolicy);
}
else if (selectedScheduler == "PAR_BS")
{
scheduler = new PAR_BS(controller->state.bankStates,
Configuration::getInstance().RefreshAwareScheduling,
scheduler = new PAR_BS(controller->state.bankStates, Configuration::getInstance().RefreshAwareScheduling,
Configuration::getInstance().Capsize);
}
else if (selectedScheduler == "FIFO")
@@ -181,15 +174,15 @@ public:
break;
case Command::PDNAX:
dramPEQ.notify(payload, END_PDNA, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, END_PDNA, command.getStart());
rec.recordPhase(payload, END_PDNA, command.getEnd());
break;
case Command::PDNPX:
dramPEQ.notify(payload, END_PDNP, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, END_PDNP, command.getStart());
rec.recordPhase(payload, END_PDNP, command.getEnd());
break;
case Command::SREFX:
dramPEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, END_SREF, command.getStart());
rec.recordPhase(payload, END_SREF, command.getEnd());
break;
default:
SC_REPORT_FATAL(0, "unsupported command in controller");
@@ -207,10 +200,6 @@ public:
{
controllerPEQ.notify(payload, REFRESH_TRIGGER, delay);
}
else if (trigger == Trigger::WakeUpTrigger)
{
controllerPEQ.notify(payload, WAKEUP_TRIGGER, delay);
}
else
{
SC_REPORT_FATAL("controller wrapper", "unknown trigger");
@@ -234,7 +223,7 @@ private:
unsigned int getNumberOfPayloadsInSystem()
{
unsigned int sum = 0;
for(Bank bank : controller->getBanks())
for (Bank bank : controller->getBanks())
{
sum += numberOfPayloadsInSystem[bank];
}
@@ -245,22 +234,15 @@ private:
{
Bank bank = DramExtension::getExtension(payload).getBank();
printDebugMessage("Transaction enters system on bank " + to_string(bank.ID()));
numberOfPayloadsInSystem[bank] = numberOfPayloadsInSystem[bank] + 1;
scheduler->schedule(&payload);
numberOfPayloadsInSystem[bank]++;
}
void payloadLeavesSystem(tlm_generic_payload& payload)
{
Bank bank = DramExtension::getExtension(payload).getBank();
numberOfPayloadsInSystem[bank]--;
if (numberOfPayloadsInSystem[bank] == 0)
{
printDebugMessage(
"Payload leaving system. No more payloads on bank " + to_string(bank.ID())
+ ". Trigger sleep.");
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
void scheduleNextPayload(Bank bank)
@@ -275,15 +257,7 @@ private:
return;
}
if (controller->powerDownManager->isInPowerDown(bank))
{
printDebugMessage("\t-> wake up bank first");
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
}
else if (controller->powerDownManager->isAwakeForRefresh(bank))
{
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
}
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank);
if (controller->scheduleRequest(sc_time_stamp(), *nextTransaction))
@@ -293,13 +267,13 @@ private:
}
else
{
printDebugMessage(
"\t-> break: payload was not scheduled by core (collision with refresh)");
printDebugMessage("\t-> break: payload was not scheduled by core (collision with refresh)");
}
}
else
{
printDebugMessage("\t-> break: no transaction for bank");
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
}
@@ -317,22 +291,25 @@ private:
if (phase == BEGIN_REQ)
{
payload.acquire();
if(getNumberOfPayloadsInSystem() == controller->config.MaxNrOfTransactions)
payloadEntersSystem(payload);
if (getNumberOfPayloadsInSystem() > controller->config.MaxNrOfTransactions)
{
printDebugMessage("##Backpressure: Max number of transactions in system reached");
backpressure = &payload;
return TLM_ACCEPTED;
}
payloadEntersSystem(payload);
frontendPEQ.notify(payload, phase, inputBufferDelay);
frontendPEQ.notify(payload, phase,
clkAlign(sc_time_stamp()) - sc_time_stamp() + Configuration::getInstance().Timings.clk);
}
else if (phase == END_RESP)
{
if(backpressure != NULL)
if (backpressure != NULL)
{
payloadEntersSystem(*backpressure);
frontendPEQ.notify(*backpressure, BEGIN_REQ, inputBufferDelay);
printDebugMessage("##Backpressure released");
//already registered above
frontendPEQ.notify(*backpressure, BEGIN_REQ, Configuration::getInstance().Timings.clk);
backpressure = NULL;
}
@@ -347,6 +324,7 @@ private:
{
if (phase == BEGIN_REQ)
{
scheduler->schedule(&payload);
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
payload.set_response_status(tlm::TLM_OK_RESPONSE);
TlmRecorder::getInstance().recordPhase(payload, END_REQ, sc_time_stamp());
@@ -354,8 +332,7 @@ private:
}
else
{
SC_REPORT_FATAL(0,
"Frontend PEQ event queue in controller wrapper was triggered with unknown phase");
SC_REPORT_FATAL(0, "Frontend PEQ event queue in controller wrapper was triggered with unknown phase");
}
}
@@ -384,16 +361,12 @@ private:
}
else if (isIn(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF }))
{
printDebugMessage(
"Entering PowerDown " + phaseNameToString(phase) + " on bank "
+ to_string(bank.ID()));
printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()));
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if (isIn(phase, { END_PDNA, END_PDNP, END_SREF }))
{
printDebugMessage(
"Leaving PowerDown " + phaseNameToString(phase) + " on bank "
+ to_string(bank.ID()));
printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()));
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if (phase == BEGIN_AUTO_REFRESH)
@@ -404,11 +377,6 @@ private:
else if (phase == END_AUTO_REFRESH)
{
printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID()));
if (numberOfPayloadsInSystem[bank] == 0)
{
printDebugMessage("\t -> Triggering sleep on bank " + to_string(bank.ID()));
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
}
else if (isIn(phase, { END_PRE, END_PRE_ALL, END_ACT }))
@@ -419,9 +387,7 @@ private:
{
ostringstream oss;
oss << phase;
string str = string(
"dramPEQCallback queue in controller wrapper was triggered with unknown phase ")
+ oss.str();
string str = string("dramPEQCallback queue in controller wrapper was triggered with unknown phase ") + oss.str();
SC_REPORT_FATAL(0, str.c_str());
}
}
@@ -432,14 +398,9 @@ private:
{
controller->triggerRefresh(payload, sc_time_stamp());
}
else if (phase == WAKEUP_TRIGGER)
{
controller->triggerWakeUp(payload, sc_time_stamp());
}
else
{
SC_REPORT_FATAL(0,
"controllerPEQCallback queue in controller wrapper was triggered with unknown phase");
SC_REPORT_FATAL(0, "controllerPEQCallback queue in controller wrapper was triggered with unknown phase");
}
}

View File

@@ -61,7 +61,7 @@ Simulation::Simulation(sc_module_name name, string pathToResources, string trace
whiteList.push_back(this->name());
whiteList.push_back(TlmRecorder::senderName);
whiteList.push_back(ControllerCore::senderName);
whiteList.push_back(PowerDownManager::senderName);
whiteList.push_back(PowerDownManagerBankwise::senderName);
}
auto& dbg = DebugManager::getInstance();

View File

@@ -38,7 +38,7 @@ bool runSimulation(string resources, string traceName, DramSetup setup, vector<D
int status = 0;
if (pid == 0)
{
Simulation simulation("sim", resources, traceName, setup, devices, true);
Simulation simulation("sim", resources, traceName, setup, devices, false);
simulation.startSimulation();
return true;
}
@@ -101,6 +101,7 @@ int sc_main(int argc, char **argv)
string trace1 = "chstone-jpeg_32.stl";
//trace1 = "trace.stl";
if (runSimulation(resources, traceName, setup, { Device(trace1), Device(trace2) }))
startTraceAnalyzer(traceName);
return 0;

View File

@@ -6,7 +6,7 @@
*/
#include <gtest/gtest.h>
#include "core/utils/Utils.h"
#include "core/TimingCalculation.h"
#include "core/utils/RingBuffer.h"
//using namespace testing;