Included interface and dummy for power-down manager.

This commit is contained in:
Lukas Steiner
2019-11-21 00:03:15 +01:00
parent 6e6d839bd1
commit 9d7f17451a
13 changed files with 310 additions and 73 deletions

View File

@@ -66,13 +66,11 @@ void BankMachine::updateState(Command command)
currentState = BmState::Precharged;
currentPayload = nullptr;
}
else if (command == Command::PDEA || command == Command::PDEP)
else if (command == Command::PDEA || command == Command::PDEP || command == Command::SREFEN)
blocked = true;
else if (command == Command::REFA || command == Command::REFB
|| command == Command::PDXA || command == Command::PDXP)
blocked = false;
else
SC_REPORT_FATAL("BankMachine", "Unknown phase");
}
void BankMachine::block()

View File

@@ -53,6 +53,8 @@
#include "refresh/RefreshManager.h"
#include "refresh/RefreshManagerDummy.h"
#include "refresh/RefreshManagerBankwise.h"
#include "powerdown/PowerDownManager.h"
#include "powerdown/PowerDownManagerDummy.h"
Controller::Controller(sc_module_name name) :
GenericController(name)
@@ -66,6 +68,7 @@ Controller::Controller(sc_module_name name) :
maxNumberOfPayloads = config.MaxNrOfTransactions;
ranksNumberOfPayloads = std::vector<unsigned>(memSpec->NumberOfRanks, 0);
// instantiate timing checker
if (memSpec->MemoryType == "DDR3")
checker = new CheckerDDR3();
else if (memSpec->MemoryType == "DDR4")
@@ -85,8 +88,9 @@ Controller::Controller(sc_module_name name) :
else if (memSpec->MemoryType == "GDDR6")
checker = new CheckerGDDR6();
else
SC_REPORT_FATAL("Controller", "Unsupported DRAM type");
SC_REPORT_FATAL("Controller", "Unsupported DRAM type!");
// instantiate scheduler and command mux
if (config.Scheduler == "FifoStrict")
{
scheduler = new SchedulerFifo();
@@ -98,8 +102,9 @@ Controller::Controller(sc_module_name name) :
commandMux = new CmdMuxOldest();
}
else
SC_REPORT_FATAL("Controller", "Selected scheduler not supported");
SC_REPORT_FATAL("Controller", "Selected scheduler not supported!");
// instantiate bank machines (one per bank)
if (config.OpenPagePolicy)
{
if (config.AdaptivePagePolicy)
@@ -133,14 +138,29 @@ Controller::Controller(sc_module_name name) :
bankMachines.begin() + (rankID + 1) * memSpec->BanksPerRank));
}
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
// instantiate power-down managers (one per rank)
if (config.PowerDownMode == EPowerDownMode::NoPowerDown)
{
PowerDownManager *manager = new PowerDownManager(bankMachinesOnRank[rankID], Rank(rankID), checker);
powerDownManagers.push_back(manager);
manager->triggerEntry();
controllerEvent.notify(manager->start());
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
{
PowerDownManagerIF *manager = new PowerDownManagerDummy();
powerDownManagers.push_back(manager);
}
}
else if (config.PowerDownMode == EPowerDownMode::Staggered)
{
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
{
PowerDownManagerIF *manager = new PowerDownManager(Rank(rankID), checker);
powerDownManagers.push_back(manager);
manager->triggerEntry(TriggerSource::Constructor);
controllerEvent.notify(manager->start());
}
}
else
SC_REPORT_FATAL("Controller", "Selected power-down mode not supported!");
// instantiate refresh managers (one per rank)
if (config.ControllerCoreRefDisable)
{
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
@@ -176,6 +196,8 @@ Controller::~Controller()
for (auto it : refreshManagers)
delete it;
for (auto it : powerDownManagers)
delete it;
for (auto it : bankMachines)
delete it;
delete commandMux;
@@ -216,7 +238,7 @@ void Controller::controllerMethod()
PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!");
}
// (4) Start refresh managers to issue requests for the current time
// (4) Start refresh and power-down managers to issue requests for the current time
for (auto it : refreshManagers)
it->start();
for (auto it : powerDownManagers)
@@ -354,7 +376,7 @@ void Controller::releasePayload()
startBandwidthIdleCollector();
if (ranksNumberOfPayloads[rank.ID()] == 0)
powerDownManagers[rank.ID()]->triggerEntry();
powerDownManagers[rank.ID()]->triggerEntry(TriggerSource::Controller);
}
void Controller::acquirePayload()
@@ -368,7 +390,7 @@ void Controller::acquirePayload()
endBandwithIdleCollector();
if(ranksNumberOfPayloads[rank.ID()] == 0)
powerDownManagers[rank.ID()]->triggerExit();
powerDownManagers[rank.ID()]->triggerExit(TriggerSource::Controller);
totalNumberOfPayloads++;
ranksNumberOfPayloads[rank.ID()]++;

View File

@@ -50,7 +50,7 @@
#include "../common/DebugManager.h"
#include "checker/CheckerIF.h"
#include "refresh/RefreshManagerIF.h"
#include "powerdown/PowerDownManager.h"
#include "powerdown/PowerDownManagerIF.h"
using namespace tlm;
@@ -89,7 +89,7 @@ private:
SchedulerIF *scheduler;
CheckerIF *checker;
std::vector<RefreshManagerIF *> refreshManagers;
std::vector<PowerDownManager *> powerDownManagers;
std::vector<PowerDownManagerIF *> powerDownManagers;
void releasePayload();
void acquirePayload();

View File

@@ -35,24 +35,39 @@
#include "PowerDownManager.h"
#include "../../common/utils.h"
PowerDownManager::PowerDownManager(std::vector<BankMachine *> &bankMachines, Rank rank, CheckerIF *checker)
: bankMachines(bankMachines), rank(rank), checker(checker)
PowerDownManager::PowerDownManager(Rank rank, CheckerIF *checker)
: rank(rank), checker(checker)
{
setUpDummy(powerDownPayload, rank);
}
void PowerDownManager::triggerEntry()
void PowerDownManager::triggerEntry(TriggerSource source)
{
if (state == PdmState::Idle)
if (source == TriggerSource::Controller)
controllerIdle = true;
// TODO: check if state is always idle here
if (state == PdmState::Idle && controllerIdle)
triggered = true;
}
void PowerDownManager::triggerExit()
void PowerDownManager::triggerExit(TriggerSource source)
{
if (state == PdmState::Idle)
if (source == TriggerSource::Controller)
controllerIdle = false;
if (state == PdmState::Idle) // Controller triggered entry, refresh triggers exit
triggered = false;
else
else if (state == PdmState::PrechargePd && source == TriggerSource::RefreshManager && !triggered)
{ // last !triggered has to be checked that normal trigger is not overwritten
triggered = true;
enterSelfRefresh = true;
}
else
{
triggered = true;
enterSelfRefresh = false;
}
}
std::pair<Command, tlm_generic_payload *> PowerDownManager::getNextCommand()
@@ -72,21 +87,25 @@ sc_time PowerDownManager::start()
{
if (state == PdmState::Idle)
{
nextCommand = Command::PDEP;
for (auto it : bankMachines)
{
if(it->getState() == BmState::Activated)
{
nextCommand = Command::PDEA;
break;
}
}
if (activatedBanks == 0)
nextCommand = Command::PDEP;
else
nextCommand = Command::PDEA;
}
else if (state == PdmState::ActivePd)
nextCommand = Command::PDXA;
else if (state == PdmState::PrechargePd)
nextCommand = Command::PDXP;
// TODO: add self refresh
{
if (enterSelfRefresh)
nextCommand = Command::SREFEN;
else
nextCommand = Command::PDXP;
}
else if (state == PdmState::SelfRefresh)
nextCommand = Command::SREFEX;
else // if (state == PdmState::Refresh)
nextCommand = Command::REFA;
delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
timeToSchedule = sc_time_stamp() + delay;
}
@@ -96,7 +115,13 @@ sc_time PowerDownManager::start()
void PowerDownManager::updateState(Command command)
{
if (command == Command::PDEA)
if (command == Command::ACT)
activatedBanks++;
else if (command == Command::PRE)
activatedBanks--;
else if (command == Command::PREA)
activatedBanks = 0;
else if (command == Command::PDEA)
{
state = PdmState::ActivePd;
triggered = false;
@@ -106,9 +131,24 @@ void PowerDownManager::updateState(Command command)
state = PdmState::PrechargePd;
triggered = false;
}
else if (command == Command::SREFEN)
{
state = PdmState::SelfRefresh;
triggered = false;
enterSelfRefresh = false;
}
else if (command == Command::PDXA || command == Command::PDXP)
{
state = PdmState::Idle;
triggered = false;
}
else if (command == Command::SREFEX)
{
state = PdmState::Refresh;
}
else if (command == Command::REFA && state == PdmState::Refresh)
{
state = PdmState::Idle;
triggered = false;
}
}

View File

@@ -35,35 +35,37 @@
#ifndef POWERDOWNMANAGER_H
#define POWERDOWNMANAGER_H
#include "PowerDownManagerIF.h"
#include "../BankMachine.h"
#include "../checker/CheckerIF.h"
using namespace tlm;
class BankMachine;
class PowerDownManager
class PowerDownManager final : public PowerDownManagerIF
{
public:
PowerDownManager(std::vector<BankMachine *> &, Rank, CheckerIF *);
PowerDownManager(Rank, CheckerIF *);
void triggerEntry();
void triggerExit();
virtual void triggerEntry(TriggerSource) override;
virtual void triggerExit(TriggerSource) override;
std::pair<Command, tlm_generic_payload *> getNextCommand();
void updateState(Command);
sc_time start();
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
virtual void updateState(Command) override;
virtual sc_time start() override;
private:
enum class PdmState {Idle, ActivePd, PrechargePd, SelfRefresh} state = PdmState::Idle;
bool triggered = false;
std::vector<BankMachine *> &bankMachines;
enum class PdmState {Idle, ActivePd, PrechargePd, SelfRefresh, Refresh} state = PdmState::Idle;
tlm_generic_payload powerDownPayload;
Rank rank;
CheckerIF *checker;
sc_time timeToSchedule;
Command nextCommand;
bool triggered = false;
bool enterSelfRefresh = false;
bool controllerIdle = true;
unsigned activatedBanks = 0;
};
#endif // POWERDOWNMANAGER_H

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2019, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Lukas Steiner
*/
#include "PowerDownManagerDummy.h"
std::pair<Command, tlm_generic_payload *> PowerDownManagerDummy::getNextCommand()
{
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
}
sc_time PowerDownManagerDummy::start()
{
return sc_max_time() - sc_time_stamp();
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2019, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Lukas Steiner
*/
#ifndef POWERDOWNMANAGERDUMMY_H
#define POWERDOWNMANAGERDUMMY_H
#include "PowerDownManagerIF.h"
using namespace tlm;
class PowerDownManagerDummy final : public PowerDownManagerIF
{
public:
PowerDownManagerDummy() {}
virtual void triggerEntry(TriggerSource) override {}
virtual void triggerExit(TriggerSource) override {}
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
virtual void updateState(Command) override {}
virtual sc_time start() override;
};
#endif // POWERDOWNMANAGERDUMMY_H

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2019, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Lukas Steiner
*/
#ifndef POWERDOWNMANAGERIF_H
#define POWERDOWNMANAGERIF_H
#include <utility>
#include <systemc.h>
#include <tlm.h>
#include "../Command.h"
using namespace tlm;
enum class TriggerSource {Constructor, Controller, RefreshManager};
class PowerDownManagerIF
{
public:
virtual ~PowerDownManagerIF() {}
virtual void triggerEntry(TriggerSource) = 0;
virtual void triggerExit(TriggerSource) = 0;
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() = 0;
virtual void updateState(Command) = 0;
virtual sc_time start() = 0;
};
#endif // POWERDOWNMANAGERIF_H

View File

@@ -38,7 +38,7 @@
#include "../../common/utils.h"
RefreshManager::RefreshManager(std::vector<BankMachine *> &bankMachines,
PowerDownManager *powerDownManager, Rank rank, CheckerIF *checker)
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
: bankMachines(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
{
Configuration &config = Configuration::getInstance();
@@ -66,7 +66,7 @@ sc_time RefreshManager::start()
if (sc_time_stamp() >= timeForNextTrigger)
{
powerDownManager->triggerExit();
powerDownManager->triggerExit(TriggerSource::RefreshManager);
if (blocked)
return sc_max_time() - sc_time_stamp();
@@ -147,19 +147,29 @@ sc_time RefreshManager::start()
void RefreshManager::updateState(Command command, tlm_generic_payload *)
{
// TODO: first ask if RAS command, otherwise ignore it
if (command == Command::REFA)
{
if (state == RmState::Pulledin)
flexibilityCounter--;
else
state = RmState::Pulledin;
if (flexibilityCounter == maxPulledin)
if (blocked)
{
state = RmState::Regular;
timeForNextTrigger += memSpec->getRefreshIntervalAB();
// TODO: is only allowed if all banks are still idle
//powerDownManager->triggerEntry();
// Refresh command after SREFEX
state = RmState::Regular; // TODO: check if this assignment is necessary
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalAB();
blocked = false;
}
else
{
if (state == RmState::Pulledin)
flexibilityCounter--;
else
state = RmState::Pulledin;
if (flexibilityCounter == maxPulledin)
{
state = RmState::Regular;
timeForNextTrigger += memSpec->getRefreshIntervalAB();
powerDownManager->triggerEntry(TriggerSource::RefreshManager);
}
}
}
else if (command == Command::PREA)
@@ -172,6 +182,11 @@ void RefreshManager::updateState(Command command, tlm_generic_payload *)
}
else if (command == Command::PDEA || command == Command::PDEP)
blocked = true;
else if (command == Command::SREFEN)
{
blocked = true;
timeForNextTrigger = sc_max_time();
}
else if (command == Command::PDXA || command == Command::PDXP)
blocked = false;
}

View File

@@ -46,17 +46,17 @@ using namespace tlm;
class RefreshManager final : public RefreshManagerIF
{
public:
RefreshManager(std::vector<BankMachine *> &, PowerDownManager *, Rank, CheckerIF *);
RefreshManager(std::vector<BankMachine *> &, PowerDownManagerIF *, Rank, CheckerIF *);
std::pair<Command, tlm_generic_payload *> getNextCommand();
sc_time start();
void updateState(Command, tlm_generic_payload *);
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
virtual sc_time start() override;
virtual void updateState(Command, tlm_generic_payload *) override;
private:
enum class RmState {Regular, Precharged, Pulledin} state = RmState::Regular;
const MemSpec *memSpec;
std::vector<BankMachine *> &bankMachines;
PowerDownManager *powerDownManager;
PowerDownManagerIF *powerDownManager;
tlm_generic_payload refreshPayload;
sc_time timeForNextTrigger = sc_max_time();
sc_time timeToSchedule = sc_max_time();

View File

@@ -38,7 +38,7 @@
#include "../../common/dramExtensions.h"
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachines,
PowerDownManager *powerDownManager, Rank rank, CheckerIF *checker)
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
: bankMachines(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
{
Configuration &config = Configuration::getInstance();

View File

@@ -38,7 +38,7 @@
#include "RefreshManagerIF.h"
#include "../../configuration/memspec/MemSpec.h"
#include "../BankMachine.h"
#include "../powerdown/PowerDownManager.h"
#include "../powerdown/PowerDownManagerIF.h"
#include <vector>
#include <utility>
#include <list>
@@ -48,17 +48,17 @@ using namespace tlm;
class RefreshManagerBankwise final : public RefreshManagerIF
{
public:
RefreshManagerBankwise(std::vector<BankMachine *> &, PowerDownManager *, Rank, CheckerIF *);
RefreshManagerBankwise(std::vector<BankMachine *> &, PowerDownManagerIF *, Rank, CheckerIF *);
std::pair<Command, tlm_generic_payload *> getNextCommand();
sc_time start();
void updateState(Command, tlm_generic_payload *);
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
virtual sc_time start() override;
virtual void updateState(Command, tlm_generic_payload *) override;
private:
enum class RmState {Regular, Precharged, Pulledin} state = RmState::Regular;
const MemSpec *memSpec;
std::vector<BankMachine *> &bankMachines;
PowerDownManager *powerDownManager;
PowerDownManagerIF *powerDownManager;
std::vector<tlm_generic_payload> refreshPayloads;
sc_time timeForNextTrigger = sc_max_time();
sc_time timeToSchedule = sc_max_time();

View File

@@ -46,9 +46,9 @@ using namespace tlm;
class RefreshManagerDummy final : public RefreshManagerIF
{
public:
std::pair<Command, tlm_generic_payload *> getNextCommand();
sc_time start();
void updateState(Command, tlm_generic_payload *) {}
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
virtual sc_time start() override;
virtual void updateState(Command, tlm_generic_payload *) override {}
};
#endif // REFRESHMANAGERDUMMY_H