refresh manger and bankwise refresh manager
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/dram}/build-simulation" cleanBuildTarget="clean" enableAutoBuild="false" id="org.eclipse.cdt.build.core.internal.builder.1698165306" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.internal.builder"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1509734096" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.789860529" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.2041174282" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.2041174282" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.2092267417" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.include.paths.1823643375" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="/opt/systemc-2.3.0/include"/>
|
||||
@@ -90,24 +90,24 @@
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="unit_test"/>
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/DRAM-Model"/>
|
||||
</configuration>
|
||||
<configuration configurationName="unit_test"/>
|
||||
<configuration configurationName="platformArchitect">
|
||||
<resource resourceType="PROJECT" workspacePath="/DRAM"/>
|
||||
</configuration>
|
||||
<configuration configurationName="build-simulation"/>
|
||||
<configuration configurationName="testing"/>
|
||||
<configuration configurationName="Debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/DRAM-Model"/>
|
||||
</configuration>
|
||||
<configuration configurationName="simulation-build">
|
||||
<resource resourceType="PROJECT" workspacePath="/dram"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/DRAM-Model"/>
|
||||
</configuration>
|
||||
<configuration configurationName="standalone"/>
|
||||
<configuration configurationName="build-testing"/>
|
||||
<configuration configurationName="simulation"/>
|
||||
<configuration configurationName="build-testing"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings">
|
||||
<doc-comment-owner id="org.eclipse.cdt.internal.ui.text.doctools.NullDocCommentOwner">
|
||||
|
||||
@@ -27,37 +27,32 @@ TlmRecorder::~TlmRecorder()
|
||||
void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase phase,
|
||||
sc_time time)
|
||||
{
|
||||
if(phase == tlm::BEGIN_REQ)
|
||||
{
|
||||
if (currentTransactionsInSystem.count(&trans) == 0)
|
||||
introduceNewTransactionToSystem(time, trans);
|
||||
recordPhase(trans, "REQ", time, time);
|
||||
}
|
||||
else if(phase == tlm::END_REQ)
|
||||
|
||||
unsigned int id = currentTransactionsInSystem[&trans];
|
||||
|
||||
string phaseName = phaseToString(phase);
|
||||
string phaseBeginPrefix = "BEGIN_";
|
||||
string phaseEndPrefix = "END_";
|
||||
|
||||
if (phaseName.find(phaseBeginPrefix) != string::npos)
|
||||
{
|
||||
updatePhaseEndInDB("REQ", time, trans);
|
||||
}
|
||||
else if(phase == tlm::BEGIN_RESP)
|
||||
{
|
||||
recordPhase(trans, "RESP", time, time);
|
||||
}
|
||||
else if(phase == tlm::END_RESP)
|
||||
{
|
||||
updatePhaseEndInDB("RESP", time, trans);
|
||||
removeTransactionFromSystem(time, trans);
|
||||
phaseName.erase(0, phaseBeginPrefix.length());
|
||||
insertPhaseInDB(phaseName, time, time, trans);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("Trace Recorder", "Method recordPhase with unknown phase");
|
||||
phaseName.erase(0, phaseEndPrefix.length());
|
||||
updatePhaseEndInDB(phaseName,time, trans);
|
||||
}
|
||||
|
||||
}
|
||||
bool phaseTerminatesTransaction = count(transactionTerminatingPhases.begin(),
|
||||
transactionTerminatingPhases.end(), phase) == 1;
|
||||
if (phaseTerminatesTransaction)
|
||||
removeTransactionFromSystem(time, trans);
|
||||
|
||||
void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, std::string name,
|
||||
sc_time begin, sc_time end)
|
||||
{
|
||||
|
||||
unsigned int id = currentTransactionsInSystem.at(&trans);
|
||||
insertPhaseInDB(name, begin, end, id);
|
||||
recordingEndTime = time;
|
||||
}
|
||||
|
||||
|
||||
@@ -154,8 +149,9 @@ void TlmRecorder::insertRangeInDB(unsigned int id, const sc_time& time)
|
||||
sqlite3_bind_int64(insertRangeStatement, 3, time.value());
|
||||
executeSqlStatement(insertRangeStatement);
|
||||
}
|
||||
void TlmRecorder::insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, unsigned int id)
|
||||
void TlmRecorder::insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
unsigned int id = currentTransactionsInSystem.at(&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());
|
||||
@@ -196,8 +192,6 @@ void TlmRecorder::removeTransactionFromSystem(const sc_time& time, tlm::tlm_gene
|
||||
sqlite3_bind_int64(updateRangeStatement, 1, time.value());
|
||||
sqlite3_bind_int(updateRangeStatement, 2, id);
|
||||
executeSqlStatement(updateRangeStatement);
|
||||
if(time > recordingEndTime)
|
||||
recordingEndTime = time;
|
||||
}
|
||||
|
||||
void TlmRecorder::executeSqlStatement(sqlite3_stmt* statement)
|
||||
|
||||
@@ -28,9 +28,6 @@ public:
|
||||
void recordPhase(tlm::tlm_generic_payload &trans, std::string name, sc_time begin, sc_time end);
|
||||
void recordDebugMessage(std::string message, sc_time time);
|
||||
|
||||
void introduceNewTransactionToSystem(const sc_time& time, tlm::tlm_generic_payload& trans);
|
||||
void removeTransactionFromSystem(const sc_time& time, tlm::tlm_generic_payload& trans);
|
||||
|
||||
void closeConnection();
|
||||
|
||||
private:
|
||||
@@ -47,9 +44,11 @@ private:
|
||||
|
||||
void createTables(std::string pathToURI);
|
||||
void insertGeneralInfo();
|
||||
void introduceNewTransactionToSystem(const sc_time& time, tlm::tlm_generic_payload& trans);
|
||||
void removeTransactionFromSystem(const sc_time& time, tlm::tlm_generic_payload& trans);
|
||||
void insertTransactionInDB(unsigned int transactionID, tlm::tlm_generic_payload& trans);
|
||||
void insertRangeInDB(unsigned int transactionID, const sc_time& time);
|
||||
void insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, unsigned int id);
|
||||
void insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans);
|
||||
void updatePhaseEndInDB(string phaseName, const sc_time& time, tlm::tlm_generic_payload& trans);
|
||||
void insertDebugMessageInDB(string message, const sc_time& time);
|
||||
|
||||
|
||||
@@ -47,6 +47,16 @@ void BankStates::closeRowBuffer(const Bank &bank)
|
||||
rowsInRowBuffers.at(bank.ID()) = Row::NO_ROW;
|
||||
}
|
||||
|
||||
bool BankStates::allRowBuffersAreClosed() const
|
||||
{
|
||||
for(auto row : rowsInRowBuffers)
|
||||
{
|
||||
if(row != Row::NO_ROW)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BankStates::closeAllRowBuffers()
|
||||
{
|
||||
for(vector<Bank>::iterator it = banks.begin(); it != banks.end(); ++it)
|
||||
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
const std::vector<Bank>& getBanks() const {return banks;}
|
||||
|
||||
bool rowBufferIsOpen(const Bank &bank) const;
|
||||
bool allRowBuffersAreClosed() const;
|
||||
Row getRowInRowBuffer(const Bank &bank) const;
|
||||
|
||||
void openRowInRowBuffer(const Bank &bank, const Row &row);
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace core{
|
||||
|
||||
struct Configuration
|
||||
{
|
||||
Configuration(): numberOfBanks(8), burstlength(2), Timings(numberOfBanks), RefreshBankwise(true),
|
||||
Configuration(): numberOfBanks(8), burstlength(2), Timings(numberOfBanks), RefreshBankwise(false),
|
||||
nActivate(2)
|
||||
{}
|
||||
unsigned int numberOfBanks;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "scheduling/checker/PrechargeChecker.h"
|
||||
#include "scheduling/checker/ReadChecker.h"
|
||||
#include "scheduling/checker/WriteChecker.h"
|
||||
#include "refresh/RefreshManagerBankwise.h"
|
||||
#include "refresh/RefreshManager.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -18,14 +20,18 @@ Controller::Controller(IWrapperConnector& wrapperConnector, TlmRecorder& recorde
|
||||
config(), state(config.numberOfBanks, config.nActivate), busChecker(config, state), wrapper(
|
||||
wrapperConnector), commandChecker(), recorder(recorder), savedState(
|
||||
config.numberOfBanks, config.nActivate), commandSequenceGenerator(state), commandSequenceScheduler(
|
||||
*this), refreshManager(*this)
|
||||
*this)
|
||||
|
||||
{
|
||||
commandChecker[Command::Activate] = new ActivateChecker(config, state);
|
||||
|
||||
commandChecker[Command::Precharge] = new PrechargeChecker(config, state);
|
||||
commandChecker[Command::Read] = new ReadChecker(config, state);
|
||||
commandChecker[Command::Write] = new WriteChecker(config, state);
|
||||
|
||||
if(config.RefreshBankwise)
|
||||
refreshManager = new RefreshManagerBankwise(*this);
|
||||
else
|
||||
refreshManager = new RefreshManager(*this);
|
||||
}
|
||||
|
||||
Controller::~Controller()
|
||||
@@ -34,6 +40,7 @@ Controller::~Controller()
|
||||
delete commandChecker[Command::Precharge];
|
||||
delete commandChecker[Command::Read];
|
||||
delete commandChecker[Command::Write];
|
||||
delete refreshManager;
|
||||
}
|
||||
|
||||
void Controller::saveState()
|
||||
@@ -49,7 +56,7 @@ void Controller::resetState()
|
||||
void Controller::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
|
||||
{
|
||||
cleanUpBus(time);
|
||||
refreshManager.scheduleRefresh(payload, time);
|
||||
refreshManager->scheduleRefresh(payload, time);
|
||||
}
|
||||
|
||||
bool Controller::schedule(sc_time start, tlm::tlm_generic_payload& payload)
|
||||
@@ -64,14 +71,13 @@ bool Controller::schedule(sc_time start, tlm::tlm_generic_payload& payload)
|
||||
CommandSequence sequence = commandSequenceGenerator.generateCommandSequence(payload);
|
||||
CommandSchedule schedule = commandSequenceScheduler.schedule(sequence, start, payload);
|
||||
|
||||
if (refreshManager.hasCollision(schedule))
|
||||
if (refreshManager->hasCollision(schedule))
|
||||
{
|
||||
resetState();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
schedule.record(recorder);
|
||||
send(schedule);
|
||||
return true;
|
||||
}
|
||||
@@ -105,9 +111,9 @@ void Controller::send(const CommandSchedule& schedule) const
|
||||
{
|
||||
wrapper.send(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Controller::cleanUpBus(sc_time currentTime)
|
||||
{
|
||||
state.pendingBusCommands.erase(state.pendingBusCommands.begin(),
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "IWrapperConnector.h"
|
||||
#include "Configuration.h"
|
||||
#include "powerdown/PowerDownManager.h"
|
||||
#include "refresh/RefreshManager.h"
|
||||
#include "refresh/IRefreshManager.h"
|
||||
#include "scheduling/CommandSequenceGenerator.h"
|
||||
#include "scheduling/checker/ICommandChecker.h"
|
||||
#include "scheduling/checker/BusChecker.h"
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
ControllerState savedState;
|
||||
CommandSequenceGenerator commandSequenceGenerator;
|
||||
CommandSequenceScheduler commandSequenceScheduler;
|
||||
RefreshManager refreshManager;
|
||||
IRefreshManager* refreshManager;
|
||||
//PowerDownManager powerDownManager;
|
||||
|
||||
void addCommandChecker(Command command, ICommandChecker* checker);
|
||||
|
||||
@@ -49,7 +49,6 @@ void ControllerState::change(const ScheduledCommand& scheduledCommand)
|
||||
switch (scheduledCommand.getCommand())
|
||||
{
|
||||
case Command::AutoRefresh:
|
||||
bankStates.closeRowBuffer(scheduledCommand.getBank());
|
||||
break;
|
||||
case Command::Activate:
|
||||
bankStates.openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow());
|
||||
|
||||
19
dram/src/core/refresh/IRefreshManager.h
Normal file
19
dram/src/core/refresh/IRefreshManager.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef IREFRESHMANAGER_H_
|
||||
#define IREFRESHMANAGER_H_
|
||||
|
||||
#include <systemc.h>
|
||||
#include "../scheduling/CommandSchedule.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class IRefreshManager
|
||||
{
|
||||
public:
|
||||
virtual ~IRefreshManager(){};
|
||||
virtual bool hasCollision(const CommandSchedule& schedule) = 0;
|
||||
virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) = 0;
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
|
||||
#endif
|
||||
@@ -1,46 +1,90 @@
|
||||
/*
|
||||
* BankwiseRefreshManager.cpp
|
||||
* RefreshManager.cpp
|
||||
*
|
||||
* Created on: Mar 9, 2014
|
||||
* Author: jonny
|
||||
* Created on: Mar 29, 2014
|
||||
* Author: robert
|
||||
*/
|
||||
|
||||
#include "RefreshManager.h"
|
||||
#include "../Controller.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace tlm;
|
||||
namespace core {
|
||||
|
||||
RefreshManager::RefreshManager(Controller& controller) : controller(controller)
|
||||
RefreshManager::RefreshManager(Controller& controller) :
|
||||
controller(controller), nextPlannedRefresh(SC_ZERO_TIME), timing(controller.config.Timings.refreshTimings.at(0)),
|
||||
refreshPayloads(controller.state.bankStates.getNumberOfBanks())
|
||||
{
|
||||
assert(!controller.config.Timings.refreshTimings.empty());
|
||||
|
||||
for(Bank bank : controller.state.bankStates.getBanks())
|
||||
{
|
||||
refreshManagerForBanks.push_back(new RefreshManagerForBank(controller, bank));
|
||||
}
|
||||
setupTransactions();
|
||||
planNextRefresh();
|
||||
}
|
||||
|
||||
RefreshManager::~RefreshManager()
|
||||
{
|
||||
|
||||
for(RefreshManagerForBank* manager : refreshManagerForBanks)
|
||||
{
|
||||
delete manager;
|
||||
}
|
||||
}
|
||||
|
||||
bool RefreshManager::hasCollision(const CommandSchedule& schedule)
|
||||
{
|
||||
RefreshManagerForBank& manager = *refreshManagerForBanks.at(schedule.getBank().ID());
|
||||
return manager.hasCollision(schedule);
|
||||
return !(schedule.getEnd() < nextPlannedRefresh);
|
||||
}
|
||||
|
||||
void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
|
||||
{
|
||||
RefreshManagerForBank& manager = *refreshManagerForBanks.at(DramExtension::getExtension(payload).getBank().ID());
|
||||
manager.scheduleRefresh(time);
|
||||
if (time != nextPlannedRefresh)
|
||||
return;
|
||||
|
||||
ScheduledCommand nextRefresh(refreshPayloads.at(0), Command::AutoRefresh, time, timing.tRFC);
|
||||
|
||||
if (!controller.state.bankStates.allRowBuffersAreClosed())
|
||||
{
|
||||
ScheduledCommand precharge(refreshPayloads.at(0), Command::PrechargeAll, time,
|
||||
controller.config.Timings.tRP);
|
||||
|
||||
nextRefresh.setStart(precharge.getEnd());
|
||||
|
||||
controller.state.change(precharge);
|
||||
|
||||
for (tlm::tlm_generic_payload& payload : refreshPayloads)
|
||||
{
|
||||
ScheduledCommand prechargeToSend(payload, Command::PrechargeAll, precharge.getStart(),
|
||||
controller.config.Timings.tRP);
|
||||
controller.wrapper.send(prechargeToSend);
|
||||
}
|
||||
}
|
||||
|
||||
controller.state.change(nextRefresh);
|
||||
|
||||
for (tlm::tlm_generic_payload& payload : refreshPayloads)
|
||||
{
|
||||
ScheduledCommand refreshToSend(payload, Command::AutoRefresh, nextRefresh.getStart(),
|
||||
timing.tRFC);
|
||||
controller.wrapper.send(refreshToSend);
|
||||
}
|
||||
|
||||
planNextRefresh();
|
||||
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
void RefreshManager::planNextRefresh()
|
||||
{
|
||||
nextPlannedRefresh += timing.tREFI;
|
||||
controller.wrapper.send(RefreshTrigger, nextPlannedRefresh, refreshPayloads.at(0));
|
||||
}
|
||||
|
||||
void RefreshManager::setupTransactions()
|
||||
{
|
||||
for (Bank bank : controller.state.bankStates.getBanks())
|
||||
{
|
||||
tlm_generic_payload& payload = refreshPayloads.at(bank.ID());
|
||||
payload.set_address(getStartAddress(bank));
|
||||
payload.set_command(tlm::TLM_READ_COMMAND);
|
||||
payload.set_data_length(0);
|
||||
payload.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
payload.set_dmi_allowed(false);
|
||||
payload.set_byte_enable_length(0);
|
||||
payload.set_streaming_width(0);
|
||||
payload.set_extension(new DramExtension(Thread(0), bank, Row(0), Column(0))); //payload takes ownership
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace core */
|
||||
|
||||
@@ -1,35 +1,40 @@
|
||||
/*
|
||||
* BankwiseRefreshManager.h
|
||||
* RefreshManager.h
|
||||
*
|
||||
* Created on: Mar 9, 2014
|
||||
* Author: jonny
|
||||
* Created on: Mar 29, 2014
|
||||
* Author: robert
|
||||
*/
|
||||
|
||||
#ifndef BANKWISEREFRESHMANAGER_H_
|
||||
#define BANKWISEREFRESHMANAGER_H_
|
||||
#ifndef REFRESHMANAGER_H_
|
||||
#define REFRESHMANAGER_H_
|
||||
|
||||
#include "../scheduling/CommandSchedule.h"
|
||||
#include "../../common/dramExtension.h"
|
||||
#include "RefreshManagerForBank.h"
|
||||
#include "IRefreshManager.h"
|
||||
#include "../TimingConfiguration.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class Controller;
|
||||
|
||||
class RefreshManager
|
||||
class RefreshManager : public IRefreshManager
|
||||
{
|
||||
public:
|
||||
RefreshManager(Controller& controller);
|
||||
~RefreshManager();
|
||||
virtual ~RefreshManager();
|
||||
|
||||
bool hasCollision(const CommandSchedule& schedule);
|
||||
void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time);
|
||||
bool hasCollision(const CommandSchedule& schedule) override;
|
||||
void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override;
|
||||
|
||||
private:
|
||||
Controller& controller;
|
||||
std::vector<RefreshManagerForBank*> refreshManagerForBanks;
|
||||
RefreshTiming& timing;
|
||||
|
||||
std::vector<tlm::tlm_generic_payload> refreshPayloads;
|
||||
sc_time nextPlannedRefresh;
|
||||
|
||||
void planNextRefresh();
|
||||
void setupTransactions();
|
||||
};
|
||||
|
||||
} /* namespace controller */
|
||||
} /* namespace core */
|
||||
|
||||
#endif /* BANKWISEREFRESHMANAGER_H_ */
|
||||
#endif /* REFRESHMANAGER_H_ */
|
||||
|
||||
115
dram/src/core/refresh/RefreshManagerBankwise.cpp
Normal file
115
dram/src/core/refresh/RefreshManagerBankwise.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* BankwiseRefreshManager.cpp
|
||||
*
|
||||
* Created on: Mar 9, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#include "RefreshManagerBankwise.h"
|
||||
#include "../Controller.h"
|
||||
#include "../utils/Utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace core {
|
||||
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(Controller& controller) :
|
||||
controller(controller)
|
||||
{
|
||||
assert(!controller.config.Timings.refreshTimings.empty());
|
||||
|
||||
for (Bank bank : controller.state.bankStates.getBanks())
|
||||
{
|
||||
refreshManagerForBanks.push_back(new RefreshManagerForBank(controller, bank));
|
||||
}
|
||||
}
|
||||
|
||||
RefreshManagerBankwise::~RefreshManagerBankwise()
|
||||
{
|
||||
for (RefreshManagerForBank* manager : refreshManagerForBanks)
|
||||
{
|
||||
delete manager;
|
||||
}
|
||||
}
|
||||
|
||||
bool RefreshManagerBankwise::hasCollision(const CommandSchedule& schedule)
|
||||
{
|
||||
RefreshManagerForBank& manager = *refreshManagerForBanks.at(schedule.getBank().ID());
|
||||
return manager.hasCollision(schedule);
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
|
||||
{
|
||||
RefreshManagerForBank& manager = *refreshManagerForBanks.at(
|
||||
DramExtension::getExtension(payload).getBank().ID());
|
||||
manager.scheduleRefresh(time);
|
||||
}
|
||||
|
||||
RefreshManagerBankwise::RefreshManagerForBank::RefreshManagerForBank(Controller& controller,
|
||||
Bank bank) :
|
||||
controller(controller), timing(controller.config.Timings.refreshTimings.at(bank.ID())), bank(
|
||||
bank), nextPlannedRefresh(SC_ZERO_TIME)
|
||||
{
|
||||
setupTransaction();
|
||||
planNextRefresh();
|
||||
}
|
||||
|
||||
RefreshManagerBankwise::RefreshManagerForBank::~RefreshManagerForBank()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks for a scheduled CommandSequence, if there is a collision with the current planned,
|
||||
* not yet scheduled, refresh command. In case of a collision the manager schedules the refresh
|
||||
* (sends it out) and plans the next refresh. Afterwards the CommandSequence is re-scheduled
|
||||
* with the new controller state (earliest start time is the end of the just scheduled refresh).
|
||||
*/
|
||||
bool RefreshManagerBankwise::RefreshManagerForBank::hasCollision(const CommandSchedule& schedule)
|
||||
{
|
||||
return !(schedule.getEnd() < nextPlannedRefresh);
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::RefreshManagerForBank::scheduleRefresh(sc_time time)
|
||||
{
|
||||
if (time != nextPlannedRefresh)
|
||||
return;
|
||||
|
||||
ScheduledCommand nextRefresh(refreshPayload, Command::AutoRefresh, time, timing.tRFC);
|
||||
|
||||
if (controller.state.bankStates.rowBufferIsOpen(bank))
|
||||
{
|
||||
ScheduledCommand precharge(refreshPayload, Command::Precharge, time,
|
||||
controller.config.Timings.tRP);
|
||||
|
||||
controller.busChecker.findSlotOnBus(precharge);
|
||||
nextRefresh.setStart(precharge.getEnd());
|
||||
|
||||
controller.state.change(precharge);
|
||||
controller.wrapper.send(precharge);
|
||||
}
|
||||
controller.busChecker.findSlotOnBus(nextRefresh);
|
||||
controller.state.change(nextRefresh);
|
||||
controller.wrapper.send(nextRefresh);
|
||||
|
||||
planNextRefresh();
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::RefreshManagerForBank::planNextRefresh()
|
||||
{
|
||||
nextPlannedRefresh += timing.tREFI;
|
||||
controller.wrapper.send(RefreshTrigger, nextPlannedRefresh, refreshPayload);
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::RefreshManagerForBank::setupTransaction()
|
||||
{
|
||||
refreshPayload.set_address(getStartAddress(bank));
|
||||
refreshPayload.set_command(tlm::TLM_READ_COMMAND);
|
||||
refreshPayload.set_data_length(0);
|
||||
refreshPayload.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
refreshPayload.set_dmi_allowed(false);
|
||||
refreshPayload.set_byte_enable_length(0);
|
||||
refreshPayload.set_streaming_width(0);
|
||||
refreshPayload.set_extension(new DramExtension(Thread(0), bank, Row(0), Column(0))); //payload takes ownership
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
60
dram/src/core/refresh/RefreshManagerBankwise.h
Normal file
60
dram/src/core/refresh/RefreshManagerBankwise.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* BankwiseRefreshManager.h
|
||||
*
|
||||
* Created on: Mar 9, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#ifndef BANKWISEREFRESHMANAGER_H_
|
||||
#define BANKWISEREFRESHMANAGER_H_
|
||||
|
||||
#include "../scheduling/CommandSchedule.h"
|
||||
#include "../../common/dramExtension.h"
|
||||
#include "../TimingConfiguration.h"
|
||||
#include "IRefreshManager.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class Controller;
|
||||
|
||||
class RefreshManagerBankwise : public IRefreshManager
|
||||
{
|
||||
public:
|
||||
RefreshManagerBankwise(Controller& controller);
|
||||
virtual ~RefreshManagerBankwise();
|
||||
|
||||
virtual bool hasCollision(const CommandSchedule& schedule) override;
|
||||
virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override;
|
||||
|
||||
private:
|
||||
|
||||
class RefreshManagerForBank
|
||||
{
|
||||
public:
|
||||
RefreshManagerForBank(Controller& controller, Bank bank);
|
||||
~RefreshManagerForBank();
|
||||
|
||||
bool hasCollision(const CommandSchedule& schedule);
|
||||
void scheduleRefresh(sc_time time);
|
||||
|
||||
private:
|
||||
Controller& controller;
|
||||
RefreshTiming& timing;
|
||||
Bank bank;
|
||||
|
||||
tlm::tlm_generic_payload refreshPayload;
|
||||
sc_time nextPlannedRefresh;
|
||||
|
||||
void planNextRefresh();
|
||||
void setupTransaction();
|
||||
};
|
||||
|
||||
Controller& controller;
|
||||
std::vector<RefreshManagerForBank*> refreshManagerForBanks;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
#endif /* BANKWISEREFRESHMANAGER_H_ */
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* RefreshManager.cpp
|
||||
*
|
||||
* Created on: Mar 6, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#include "RefreshManagerForBank.h"
|
||||
#include "../utils/Utils.h"
|
||||
#include "../Controller.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
RefreshManagerForBank::RefreshManagerForBank(Controller& controller, Bank bank) :
|
||||
controller(controller), timing(controller.config.Timings.refreshTimings.at(bank.ID())), bank(
|
||||
bank), nextPlannedRefresh(SC_ZERO_TIME)
|
||||
{
|
||||
setupTransaction(refreshTransaction);
|
||||
planNextRefresh();
|
||||
}
|
||||
|
||||
RefreshManagerForBank::~RefreshManagerForBank()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks for a scheduled CommandSequence, if there is a collision with the current planned,
|
||||
* not yet scheduled, refresh command. In case of a collision the manager schedules the refresh
|
||||
* (sends it out) and plans the next refresh. Afterwards the CommandSequence is re-scheduled
|
||||
* with the new controller state (earliest start time is the end of the just scheduled refresh).
|
||||
*/
|
||||
bool RefreshManagerForBank::hasCollision(const CommandSchedule& schedule)
|
||||
{
|
||||
if (schedule.getEnd() < nextPlannedRefresh)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshManagerForBank::scheduleRefresh(sc_time time)
|
||||
{
|
||||
if (time == nextPlannedRefresh)
|
||||
{
|
||||
controller.recorder.introduceNewTransactionToSystem(time, refreshTransaction);
|
||||
|
||||
if (controller.config.RefreshBankwise)
|
||||
{
|
||||
if (controller.state.bankStates.rowBufferIsOpen(bank))
|
||||
{
|
||||
ScheduledCommand precharge(refreshTransaction, Command::Precharge, time,
|
||||
controller.config.Timings.tRP);
|
||||
controller.busChecker.findSlotOnBus(precharge);
|
||||
ScheduledCommand nextRefresh(refreshTransaction, Command::AutoRefresh,
|
||||
precharge.getEnd(), timing.tRFC);
|
||||
controller.busChecker.findSlotOnBus(nextRefresh);
|
||||
controller.state.change(precharge);
|
||||
controller.state.change(nextRefresh);
|
||||
precharge.record(controller.recorder);
|
||||
nextRefresh.record(controller.recorder);
|
||||
controller.wrapper.send(precharge);
|
||||
controller.wrapper.send(nextRefresh);
|
||||
controller.recorder.removeTransactionFromSystem(nextRefresh.getEnd(),refreshTransaction);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScheduledCommand nextRefresh(refreshTransaction, Command::AutoRefresh, time,
|
||||
timing.tRFC);
|
||||
controller.busChecker.findSlotOnBus(nextRefresh);
|
||||
controller.state.change(nextRefresh);
|
||||
nextRefresh.record(controller.recorder);
|
||||
controller.wrapper.send(nextRefresh);
|
||||
controller.recorder.removeTransactionFromSystem(nextRefresh.getEnd(),refreshTransaction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ScheduledCommand precharge(refreshTransaction, Command::PrechargeAll, time,
|
||||
controller.config.Timings.tRP);
|
||||
ScheduledCommand nextRefresh(refreshTransaction, Command::AutoRefresh,
|
||||
precharge.getEnd(), timing.tRFC);
|
||||
controller.state.change(precharge);
|
||||
controller.state.change(nextRefresh);
|
||||
precharge.record(controller.recorder);
|
||||
nextRefresh.record(controller.recorder);
|
||||
controller.wrapper.send(precharge);
|
||||
controller.wrapper.send(nextRefresh);
|
||||
controller.recorder.removeTransactionFromSystem(nextRefresh.getEnd(),refreshTransaction);
|
||||
}
|
||||
|
||||
planNextRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshManagerForBank::planNextRefresh()
|
||||
{
|
||||
nextPlannedRefresh += timing.tREFI;
|
||||
controller.wrapper.send(RefreshTrigger, nextPlannedRefresh, refreshTransaction);
|
||||
}
|
||||
|
||||
void RefreshManagerForBank::setupTransaction(tlm::tlm_generic_payload& transaction)
|
||||
{
|
||||
transaction.set_address(getStartAddress(bank));
|
||||
transaction.set_command(tlm::TLM_READ_COMMAND);
|
||||
transaction.set_data_length(0);
|
||||
transaction.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
transaction.set_dmi_allowed(false);
|
||||
transaction.set_byte_enable_length(0);
|
||||
transaction.set_streaming_width(0);
|
||||
transaction.set_extension(new DramExtension(Thread(0), bank, Row(0), Column(0))); //payload takes ownership
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* RefreshManager.h
|
||||
*
|
||||
* Created on: Mar 6, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#ifndef REFRESHMANAGER_H_
|
||||
#define REFRESHMANAGER_H_
|
||||
|
||||
#include "../TimingConfiguration.h"
|
||||
#include "../scheduling/CommandSchedule.h"
|
||||
#include "../../common/dramExtension.h"
|
||||
#include <systemc.h>
|
||||
|
||||
namespace core {
|
||||
|
||||
class Controller;
|
||||
|
||||
class RefreshManagerForBank
|
||||
{
|
||||
public:
|
||||
RefreshManagerForBank(Controller& controller, Bank bank);
|
||||
~RefreshManagerForBank();
|
||||
|
||||
bool hasCollision(const CommandSchedule& schedule);
|
||||
void scheduleRefresh(sc_time time);
|
||||
|
||||
private:
|
||||
Controller& controller;
|
||||
RefreshTiming& timing;
|
||||
Bank bank;
|
||||
|
||||
tlm::tlm_generic_payload refreshTransaction;
|
||||
sc_time nextPlannedRefresh;
|
||||
|
||||
void planNextRefresh();
|
||||
void setupTransaction(tlm::tlm_generic_payload& transaction);
|
||||
};
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
#endif /* REFRESHMANAGER_H_ */
|
||||
@@ -58,14 +58,6 @@ public:
|
||||
return extension.getBank();
|
||||
}
|
||||
|
||||
void record(TlmRecorder& recorder)
|
||||
{
|
||||
for(ScheduledCommand& command : scheduledCommands)
|
||||
{
|
||||
command.record(recorder);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ScheduledCommand> scheduledCommands;
|
||||
tlm::tlm_generic_payload* transaction;
|
||||
|
||||
@@ -98,10 +98,6 @@ public:
|
||||
payload = NULL;
|
||||
}
|
||||
|
||||
void record(TlmRecorder& recorder)
|
||||
{
|
||||
recorder.recordPhase(*payload, commandToString(command), getStart(), getEnd());
|
||||
}
|
||||
|
||||
private:
|
||||
tlm::tlm_generic_payload* payload;
|
||||
|
||||
@@ -78,10 +78,16 @@ public:
|
||||
dramPEQ.notify(command.getTransaction(),END_AUTO_REFRESH, command.getEnd() - sc_time_stamp());
|
||||
break;
|
||||
case Command::Activate:
|
||||
dramPEQ.notify(command.getTransaction(),BEGIN_ACT, command.getStart() - sc_time_stamp());
|
||||
dramPEQ.notify(command.getTransaction(),END_ACT, command.getEnd() - sc_time_stamp());
|
||||
break;
|
||||
case Command::Precharge:
|
||||
dramPEQ.notify(command.getTransaction(),BEGIN_PRE, command.getStart() - sc_time_stamp());
|
||||
dramPEQ.notify(command.getTransaction(),END_PRE, command.getEnd() - sc_time_stamp());
|
||||
break;
|
||||
case Command::PrechargeAll:
|
||||
dramPEQ.notify(command.getTransaction(),BEGIN_PRE_ALL, command.getStart() - sc_time_stamp());
|
||||
dramPEQ.notify(command.getTransaction(),END_PRE_ALL, command.getEnd() - sc_time_stamp());
|
||||
break;
|
||||
default:
|
||||
SC_REPORT_FATAL(0, "unsupported command in controller wrapper");
|
||||
@@ -168,7 +174,6 @@ private:
|
||||
|
||||
void frontendPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
|
||||
{
|
||||
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
payloadEntersSystem(payload);
|
||||
@@ -185,6 +190,8 @@ private:
|
||||
|
||||
void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
|
||||
{
|
||||
recorder.recordPhase(payload, phase, sc_time_stamp());
|
||||
|
||||
if (phase == BEGIN_RD || phase == BEGIN_WR)
|
||||
{
|
||||
scheduleNextPayload(DramExtension::getExtension(payload).getBank());
|
||||
@@ -204,7 +211,7 @@ private:
|
||||
recorder.recordPhase(payload, BEGIN_RESP, sc_time_stamp());
|
||||
sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME);
|
||||
}
|
||||
else if (phase == END_PRE || phase == END_ACT)
|
||||
else if (phase == END_PRE || phase == END_PRE_ALL || phase == END_ACT)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user