diff --git a/dram/.cproject b/dram/.cproject index d744cb34..f25fb107 100644 --- a/dram/.cproject +++ b/dram/.cproject @@ -19,7 +19,7 @@ - + @@ -90,24 +90,24 @@ + - - - - + + + - + diff --git a/dram/src/common/TlmRecorder.cpp b/dram/src/common/TlmRecorder.cpp index f0b5b403..37d6adf6 100644 --- a/dram/src/common/TlmRecorder.cpp +++ b/dram/src/common/TlmRecorder.cpp @@ -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) diff --git a/dram/src/common/TlmRecorder.h b/dram/src/common/TlmRecorder.h index 391589fc..5b64b7a7 100755 --- a/dram/src/common/TlmRecorder.h +++ b/dram/src/common/TlmRecorder.h @@ -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); diff --git a/dram/src/core/BankStates.cpp b/dram/src/core/BankStates.cpp index bc645f7e..6cbe07f1 100644 --- a/dram/src/core/BankStates.cpp +++ b/dram/src/core/BankStates.cpp @@ -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::iterator it = banks.begin(); it != banks.end(); ++it) diff --git a/dram/src/core/BankStates.h b/dram/src/core/BankStates.h index 7b741796..dfa3432d 100644 --- a/dram/src/core/BankStates.h +++ b/dram/src/core/BankStates.h @@ -22,6 +22,7 @@ public: const std::vector& 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); diff --git a/dram/src/core/Configuration.h b/dram/src/core/Configuration.h index a0d47ad8..90a88619 100644 --- a/dram/src/core/Configuration.h +++ b/dram/src/core/Configuration.h @@ -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; diff --git a/dram/src/core/Controller.cpp b/dram/src/core/Controller.cpp index 55879be0..b7a36690 100644 --- a/dram/src/core/Controller.cpp +++ b/dram/src/core/Controller.cpp @@ -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(), diff --git a/dram/src/core/Controller.h b/dram/src/core/Controller.h index a2ba6d2e..2cad8892 100644 --- a/dram/src/core/Controller.h +++ b/dram/src/core/Controller.h @@ -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); diff --git a/dram/src/core/ControllerState.cpp b/dram/src/core/ControllerState.cpp index 6a3388b7..90a1314a 100644 --- a/dram/src/core/ControllerState.cpp +++ b/dram/src/core/ControllerState.cpp @@ -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()); diff --git a/dram/src/core/refresh/IRefreshManager.h b/dram/src/core/refresh/IRefreshManager.h new file mode 100644 index 00000000..b419577e --- /dev/null +++ b/dram/src/core/refresh/IRefreshManager.h @@ -0,0 +1,19 @@ +#ifndef IREFRESHMANAGER_H_ +#define IREFRESHMANAGER_H_ + +#include +#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 diff --git a/dram/src/core/refresh/RefreshManager.cpp b/dram/src/core/refresh/RefreshManager.cpp index f71f5a68..0a90c2eb 100644 --- a/dram/src/core/refresh/RefreshManager.cpp +++ b/dram/src/core/refresh/RefreshManager.cpp @@ -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 */ diff --git a/dram/src/core/refresh/RefreshManager.h b/dram/src/core/refresh/RefreshManager.h index a23b4f19..311ff723 100644 --- a/dram/src/core/refresh/RefreshManager.h +++ b/dram/src/core/refresh/RefreshManager.h @@ -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 refreshManagerForBanks; + RefreshTiming& timing; + + std::vector refreshPayloads; + sc_time nextPlannedRefresh; + + void planNextRefresh(); + void setupTransactions(); }; -} /* namespace controller */ +} /* namespace core */ -#endif /* BANKWISEREFRESHMANAGER_H_ */ +#endif /* REFRESHMANAGER_H_ */ diff --git a/dram/src/core/refresh/RefreshManagerBankwise.cpp b/dram/src/core/refresh/RefreshManagerBankwise.cpp new file mode 100644 index 00000000..877f0f59 --- /dev/null +++ b/dram/src/core/refresh/RefreshManagerBankwise.cpp @@ -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 */ diff --git a/dram/src/core/refresh/RefreshManagerBankwise.h b/dram/src/core/refresh/RefreshManagerBankwise.h new file mode 100644 index 00000000..a1235d51 --- /dev/null +++ b/dram/src/core/refresh/RefreshManagerBankwise.h @@ -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 refreshManagerForBanks; + + +}; + +} /* namespace controller */ + +#endif /* BANKWISEREFRESHMANAGER_H_ */ diff --git a/dram/src/core/refresh/RefreshManagerForBank.cpp b/dram/src/core/refresh/RefreshManagerForBank.cpp deleted file mode 100644 index af731d13..00000000 --- a/dram/src/core/refresh/RefreshManagerForBank.cpp +++ /dev/null @@ -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 */ diff --git a/dram/src/core/refresh/RefreshManagerForBank.h b/dram/src/core/refresh/RefreshManagerForBank.h deleted file mode 100644 index 2ebc0507..00000000 --- a/dram/src/core/refresh/RefreshManagerForBank.h +++ /dev/null @@ -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 - -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_ */ diff --git a/dram/src/core/scheduling/CommandSchedule.h b/dram/src/core/scheduling/CommandSchedule.h index c6806da8..b979ef74 100644 --- a/dram/src/core/scheduling/CommandSchedule.h +++ b/dram/src/core/scheduling/CommandSchedule.h @@ -58,14 +58,6 @@ public: return extension.getBank(); } - void record(TlmRecorder& recorder) - { - for(ScheduledCommand& command : scheduledCommands) - { - command.record(recorder); - } - } - private: std::vector scheduledCommands; tlm::tlm_generic_payload* transaction; diff --git a/dram/src/core/scheduling/ScheduledCommand.h b/dram/src/core/scheduling/ScheduledCommand.h index 954c1bff..75f7dc08 100644 --- a/dram/src/core/scheduling/ScheduledCommand.h +++ b/dram/src/core/scheduling/ScheduledCommand.h @@ -98,10 +98,6 @@ public: payload = NULL; } - void record(TlmRecorder& recorder) - { - recorder.recordPhase(*payload, commandToString(command), getStart(), getEnd()); - } private: tlm::tlm_generic_payload* payload; diff --git a/dram/src/simulation/controllerwrapper.h b/dram/src/simulation/controllerwrapper.h index e178d09e..0e3dd7bc 100644 --- a/dram/src/simulation/controllerwrapper.h +++ b/dram/src/simulation/controllerwrapper.h @@ -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) { }