refresh manger and bankwise refresh manager

This commit is contained in:
robert
2014-03-29 11:48:18 +01:00
parent 04e38d6663
commit e13f2b0868
19 changed files with 344 additions and 256 deletions

View File

@@ -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">

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;

View File

@@ -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(),

View File

@@ -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);

View File

@@ -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());

View 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

View File

@@ -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 */

View File

@@ -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_ */

View 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 */

View 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_ */

View File

@@ -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 */

View File

@@ -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_ */

View File

@@ -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;

View File

@@ -98,10 +98,6 @@ public:
payload = NULL;
}
void record(TlmRecorder& recorder)
{
recorder.recordPhase(*payload, commandToString(command), getStart(), getEnd());
}
private:
tlm::tlm_generic_payload* payload;

View File

@@ -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)
{
}