diff --git a/dram/.settings/language.settings.xml b/dram/.settings/language.settings.xml index 6d713a79..c75ff474 100644 --- a/dram/.settings/language.settings.xml +++ b/dram/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + @@ -14,7 +14,7 @@ - + diff --git a/dram/src/core/BankStates.cpp b/dram/src/core/BankStates.cpp new file mode 100644 index 00000000..bc645f7e --- /dev/null +++ b/dram/src/core/BankStates.cpp @@ -0,0 +1,59 @@ +/* + * BankStates.cpp + * + * Created on: Feb 24, 2014 + * Author: robert + */ + +#include "BankStates.h" + +using namespace std; + +namespace core +{ + +BankStates::BankStates(unsigned int numberOfBanks) : + rowsInRowBuffers(numberOfBanks) +{ + for (unsigned int i = 0; i < numberOfBanks; ++i) + { + banks.push_back(Bank(i)); + } + + closeAllRowBuffers(); +} + +BankStates::~BankStates() +{ +} + +bool BankStates::rowBufferIsOpen(const Bank &bank) const +{ + return rowsInRowBuffers.at(bank.ID()) != Row::NO_ROW; +} + +Row BankStates::getRowInRowBuffer(const Bank &bank) const +{ + return rowsInRowBuffers.at(bank.ID()); +} + +void BankStates::openRowInRowBuffer(const Bank &bank, const Row &row) +{ + rowsInRowBuffers.at(bank.ID()) = row; +} + +void BankStates::closeRowBuffer(const Bank &bank) +{ + rowsInRowBuffers.at(bank.ID()) = Row::NO_ROW; +} + +void BankStates::closeAllRowBuffers() +{ + for(vector::iterator it = banks.begin(); it != banks.end(); ++it) + { + closeRowBuffer(*it); + } +} + +} + diff --git a/dram/src/core/BankStates.h b/dram/src/core/BankStates.h new file mode 100644 index 00000000..824a694d --- /dev/null +++ b/dram/src/core/BankStates.h @@ -0,0 +1,38 @@ +/* + * BankStates.h + * + * Created on: Feb 24, 2014 + * Author: robert + */ + +#ifndef BANKSTATES_H_ +#define BANKSTATES_H_ +#include +#include "common/dramExtension.h" + +namespace core +{ + +class BankStates { +public: + BankStates(unsigned int numberOfBanks); + virtual ~BankStates(); + + unsigned int getNumberOfBanks() const {return rowsInRowBuffers.size();} + const std::vector& getBanks() const {return banks;} + + bool rowBufferIsOpen(const Bank &bank) const; + Row getRowInRowBuffer(const Bank &bank) const; + + void openRowInRowBuffer(const Bank &bank, const Row &row); + void closeRowBuffer(const Bank &bank); + void closeAllRowBuffers(); + +private: + std::vector banks; + std::vector rowsInRowBuffers; +}; + +} + +#endif /* BANKSTATES_H_ */ diff --git a/dram/src/core/CommandBus.cpp b/dram/src/core/CommandBus.cpp index 95bbda40..57b27e8e 100644 --- a/dram/src/core/CommandBus.cpp +++ b/dram/src/core/CommandBus.cpp @@ -19,8 +19,20 @@ void CommandBus::schedule(ScheduledCommand& command) changeControllerState(command); state.pendingBusCommands.insert(command.getStart()); - state.lastCommandsOnBus[command.getCommand()][command.getBank()] = command; - state.lastCommandsOnBus[command.getCommand()][command.getBank()].invalidateTransaction(); + //TODO do in refresh manager + if(command.getCommand() == Refresh) + { + for(unsigned int i = 0; i < config.numberOfBanks; ++i) + { + state.lastCommandsOnBus[command.getCommand()][Bank(i)] = command; + } + } + else + { + state.lastCommandsOnBus[command.getCommand()][command.getBank()] = command; + //state.lastCommandsOnBus[command.getCommand()][command.getBank()].invalidateTransaction(); + } + if(command.getCommand() == Activate) { @@ -28,11 +40,12 @@ void CommandBus::schedule(ScheduledCommand& command) } } + void CommandBus::scheduleOnBus(ScheduledCommand& command) { - //TODO write nicer + //TODO write nicer -- make own bus checker sc_time newStart = command.getStart(); - assert(isClkAligned(newStart, config.Timings.clk)); + sc_assert(isClkAligned(newStart, config.Timings.clk)); std::set::iterator it = state.pendingBusCommands.begin(); while (it != state.pendingBusCommands.end() && *it <= newStart) diff --git a/dram/src/core/Controller.cpp b/dram/src/core/Controller.cpp index bb1cbdec..caac221e 100644 --- a/dram/src/core/Controller.cpp +++ b/dram/src/core/Controller.cpp @@ -49,7 +49,7 @@ void DramController::scheduleRefresh(sc_time time) refreshManager.scheduleRefresh(time); } -void DramController::schedule(sc_time start, tlm::tlm_generic_payload& payload) +bool DramController::schedule(sc_time start, tlm::tlm_generic_payload& payload) { bus.cleanUpBus(start); @@ -62,30 +62,39 @@ void DramController::schedule(sc_time start, tlm::tlm_generic_payload& payload) payload); CommandSchedule schedule = commandSequenceScheduler.schedule(sequence, start, payload); - //commandbuschecker (schedule) - - while (refreshManager.hasCollision(schedule)) + if (refreshManager.hasCollision(schedule)) { resetState(); - refreshManager.scheduleRefresh(start); - saveState(); - - - sequence = commandSequenceGenerator.generateCommandSequence(payload); - schedule = commandSequenceScheduler.schedule(sequence, start, payload); - assert(schedule.getExecutionTime() < config.Timings.refreshTimings[0].tREFI); //TODO make nice + return false; + } + else + { + bus.send(schedule); + return true; } - - bus.send(schedule); } - -/*const ICommandChecker& DramController::getChecker(Command command) const +bool core::DramController::isBusy(sc_time currentTime, Bank bank) { - std::map::const_iterator result = commandChecker.find(command); - assert(result != commandChecker.end()); - return *(result->second); -}*/ + ScheduledCommand lastScheduledCommand = state.getLastCommand(bank); + if(lastScheduledCommand.isNoCommand()) + return false; + else if(lastScheduledCommand.getCommand() == Write || lastScheduledCommand.getCommand() == Read) + { + return (currentTime < lastScheduledCommand.getStart()); + } + else if(lastScheduledCommand.getCommand() == Refresh) + { + return (currentTime < lastScheduledCommand.getEnd()); + } + else + { + SC_ASSERT_(false, "last command in command sequence was activate or precharge"); + return false; + } + +} } /* namespace controller */ + diff --git a/dram/src/core/Controller.h b/dram/src/core/Controller.h index 57e1ba4c..ad7eaec1 100644 --- a/dram/src/core/Controller.h +++ b/dram/src/core/Controller.h @@ -27,10 +27,14 @@ public: DramController(IWrapperConnector& wrapper); virtual ~DramController() ; - void schedule(sc_time currentTime, tlm::tlm_generic_payload& payload); + bool schedule(sc_time currentTime, tlm::tlm_generic_payload& payload); + bool isBusy(sc_time currentTime, Bank bank); void scheduleRefresh(sc_time time); + + const ICommandChecker& getChecker(Command command) const; Configuration config; + const BankStates& getBankStates(){return state.bankStates;} void saveState(); void resetState(); diff --git a/dram/src/core/ControllerState.h b/dram/src/core/ControllerState.h index 7481b33c..c12d1b01 100644 --- a/dram/src/core/ControllerState.h +++ b/dram/src/core/ControllerState.h @@ -9,7 +9,7 @@ #define CONTROLLER_STATE_H_ #include -#include "common/BankStates.h" +#include "BankStates.h" #include "utils/RingBuffer.h" #include "scheduling/ScheduledCommand.h" #include @@ -29,6 +29,7 @@ public: BankStates bankStates; + //used by the various checkers RingBuffer nActivateWindow; std::vector nACT; std::map > lastCommandsOnBus; diff --git a/dram/src/core/TimingConfiguration.h b/dram/src/core/TimingConfiguration.h index 2e5d6b7f..9bd1ffc6 100644 --- a/dram/src/core/TimingConfiguration.h +++ b/dram/src/core/TimingConfiguration.h @@ -29,7 +29,8 @@ struct TimingConfiguration for (unsigned int i = 0; i < numberOfBanks; ++i) { - sc_time tRFC = 18*clk; + sc_time tRFC = 21*clk; + //sc_time tREFI = 100*clk; sc_time tREFI = sc_time(15.6, SC_US); //TODO align //tREFI = sc_time(301268, SC_NS); refreshTimings.push_back(RefreshTiming(tRFC, tREFI)); diff --git a/dram/src/core/powerdown/PowerDownManager.cpp b/dram/src/core/powerdown/PowerDownManager.cpp index a1588773..47513493 100644 --- a/dram/src/core/powerdown/PowerDownManager.cpp +++ b/dram/src/core/powerdown/PowerDownManager.cpp @@ -17,7 +17,6 @@ PowerDownManager::PowerDownManager() PowerDownManager::~PowerDownManager() { - // TODO Auto-generated destructor stub } } /* namespace controller */ diff --git a/dram/src/core/refresh/RefreshManager.cpp b/dram/src/core/refresh/RefreshManager.cpp index 4c760e09..46f28298 100644 --- a/dram/src/core/refresh/RefreshManager.cpp +++ b/dram/src/core/refresh/RefreshManager.cpp @@ -18,8 +18,8 @@ RefreshManager::RefreshManager(CommandBus& bus, const RefreshTiming& refreshTimi setupTransaction(refreshTransaction, Bank(0)); nextPlannedRefresh = new ScheduledCommand(refreshTransaction, Refresh, SC_ZERO_TIME, refreshTiming.tRFC); - assert(refreshTiming.tRFC > SC_ZERO_TIME); - assert(nextPlannedRefresh->getExecutionTime()>SC_ZERO_TIME); + sc_assert(refreshTiming.tRFC > SC_ZERO_TIME); + sc_assert(nextPlannedRefresh->getExecutionTime()>SC_ZERO_TIME); planNextRefresh(*nextPlannedRefresh); } diff --git a/dram/src/core/scheduling/CommandSequenceScheduler.cpp b/dram/src/core/scheduling/CommandSequenceScheduler.cpp index c1cf1d79..053a5e43 100644 --- a/dram/src/core/scheduling/CommandSequenceScheduler.cpp +++ b/dram/src/core/scheduling/CommandSequenceScheduler.cpp @@ -15,14 +15,16 @@ CommandSchedule CommandSequenceScheduler::schedule(CommandSequence commands, sc_ { CommandSchedule schedule(transaction); + sc_time endOfPrevious = start; for (Command cmd : commands) { ICommandChecker& checker = *commandChecker.at(cmd); sc_time executionTime = checker.getExecutionTime(transaction, cmd); - ScheduledCommand& scheduledCommand = schedule.add(cmd, start, executionTime); + ScheduledCommand& scheduledCommand = schedule.add(cmd, endOfPrevious, executionTime); checker.delayToSatisfyConstraints(scheduledCommand); bus.schedule(scheduledCommand); + endOfPrevious = scheduledCommand.getEnd(); } return schedule; diff --git a/dram/src/core/scheduling/ScheduledCommand.h b/dram/src/core/scheduling/ScheduledCommand.h index a11945f8..8b0e2530 100644 --- a/dram/src/core/scheduling/ScheduledCommand.h +++ b/dram/src/core/scheduling/ScheduledCommand.h @@ -73,7 +73,7 @@ public: tlm::tlm_generic_payload& getTransaction() const { - assert(transaction); + sc_assert(transaction); return *transaction; } diff --git a/dram/src/core/scheduling/checker/ActivateChecker.cpp b/dram/src/core/scheduling/checker/ActivateChecker.cpp index 6ba01b26..70130f18 100644 --- a/dram/src/core/scheduling/checker/ActivateChecker.cpp +++ b/dram/src/core/scheduling/checker/ActivateChecker.cpp @@ -19,11 +19,11 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const if (command.getCommand() != Activate) return; satisfy_activateToActivate_sameBank(command); - satisfy_activateToActivate_differentBank(command); - satisfy_nActivateWindow(command); - satisfy_prechargeToActivate(command); + //satisfy_activateToActivate_differentBank(command); + //satisfy_nActivateWindow(command); + //satisfy_prechargeToActivate(command); - satisfy_refreshToActivate(command); + //satisfy_refreshToActivate(command); } sc_time ActivateChecker::getExecutionTime(const tlm::tlm_generic_payload& transaction, diff --git a/dram/src/core/scheduling/checker/ActivateChecker.h b/dram/src/core/scheduling/checker/ActivateChecker.h index 2b4f99ab..3c2dc4d4 100644 --- a/dram/src/core/scheduling/checker/ActivateChecker.h +++ b/dram/src/core/scheduling/checker/ActivateChecker.h @@ -22,8 +22,8 @@ public: ActivateChecker(const Configuration& config, ControllerState& state) : config(config), state(state){} virtual ~ActivateChecker(){} - virtual void delayToSatisfyConstraints(ScheduledCommand& command) const; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const; + virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; + virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override; private: const Configuration& config; diff --git a/dram/src/core/scheduling/checker/PrechargeChecker.h b/dram/src/core/scheduling/checker/PrechargeChecker.h index 109f8c82..0c02ccad 100644 --- a/dram/src/core/scheduling/checker/PrechargeChecker.h +++ b/dram/src/core/scheduling/checker/PrechargeChecker.h @@ -20,8 +20,8 @@ public: PrechargeChecker(const Configuration& config, ControllerState& state) : config(config), state(state) {} virtual ~PrechargeChecker() {} - virtual void delayToSatisfyConstraints(ScheduledCommand& command) const; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const; + virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; + virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override; private: const Configuration& config; ControllerState& state;//TODO make const diff --git a/dram/src/core/scheduling/checker/ReadChecker.cpp b/dram/src/core/scheduling/checker/ReadChecker.cpp index 3c1fd733..9075a3a6 100644 --- a/dram/src/core/scheduling/checker/ReadChecker.cpp +++ b/dram/src/core/scheduling/checker/ReadChecker.cpp @@ -25,7 +25,8 @@ sc_time ReadChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, { assert(command == Read || command == ReadA); //return config.Timings.tRL + config.Timings.clk*getBurstLengthInBytes(transaction, config.buswidth); - return config.Timings.tRL + config.Timings.clk*payload.get_streaming_width(); + sc_time result = config.Timings.tRL + config.Timings.clk*payload.get_streaming_width(); + return result; } } /* namespace controller */ diff --git a/dram/src/core/scheduling/checker/ReadChecker.h b/dram/src/core/scheduling/checker/ReadChecker.h index e7228d29..ff52f5ce 100644 --- a/dram/src/core/scheduling/checker/ReadChecker.h +++ b/dram/src/core/scheduling/checker/ReadChecker.h @@ -20,8 +20,8 @@ public: ReadChecker(Configuration& config, ControllerState& state) : config(config), state(state) {} virtual ~ReadChecker() {} - virtual void delayToSatisfyConstraints(ScheduledCommand& command) const; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const; + virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; + virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override; private: const Configuration& config; ControllerState& state; diff --git a/dram/src/core/scheduling/checker/WriteChecker.cpp b/dram/src/core/scheduling/checker/WriteChecker.cpp index 376533e8..dd465dee 100644 --- a/dram/src/core/scheduling/checker/WriteChecker.cpp +++ b/dram/src/core/scheduling/checker/WriteChecker.cpp @@ -11,6 +11,12 @@ namespace core { void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { + + ScheduledCommand lastCommand = state.getLastCommand(command.getBank()); + if(lastCommand.isValidCommand() && lastCommand.getEnd() > command.getStart()) + { + command.delayStart(lastCommand.getEnd()-command.getStart()); + } } sc_time WriteChecker::getExecutionTime(const tlm::tlm_generic_payload& payload, diff --git a/dram/src/core/scheduling/checker/WriteChecker.h b/dram/src/core/scheduling/checker/WriteChecker.h index c2427007..f29c513a 100644 --- a/dram/src/core/scheduling/checker/WriteChecker.h +++ b/dram/src/core/scheduling/checker/WriteChecker.h @@ -20,8 +20,8 @@ public: WriteChecker(const Configuration& config, ControllerState& state) : config(config), state(state) {} virtual ~WriteChecker() {} - virtual void delayToSatisfyConstraints(ScheduledCommand& command) const; - virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const; + virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; + virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const override; private: const Configuration& config; ControllerState& state; diff --git a/dram/src/scheduler/Fifo.cpp b/dram/src/scheduler/Fifo.cpp new file mode 100644 index 00000000..50822348 --- /dev/null +++ b/dram/src/scheduler/Fifo.cpp @@ -0,0 +1,37 @@ +/* + * Fifo.cpp + * + * Created on: Mar 19, 2014 + * Author: robert + */ + +#include "Fifo.h" + + +namespace scheduler { + +bool scheduler::Fifo::hasTransactionForBank(Bank bank) +{ + return (!buffer.at(bank.ID()).empty()); +} + +void scheduler::Fifo::schedule(gp* payload) +{ + buffer.at(DramExtension::getExtension(payload).getBank().ID()).push_back(payload); +} + +gp* scheduler::Fifo::getTransactionForBank(Bank bank) +{ + sc_assert(hasTransactionForBank(bank)); + gp* result = buffer.at(bank.ID()).front(); + return result; +} + +void scheduler::Fifo::popTransactionForBank(Bank bank) +{ + sc_assert(hasTransactionForBank(bank)); + buffer.at(bank.ID()).pop_front(); +} + +} /* namespace scheduler */ + diff --git a/dram/src/scheduler/Fifo.h b/dram/src/scheduler/Fifo.h new file mode 100644 index 00000000..eaddc980 --- /dev/null +++ b/dram/src/scheduler/Fifo.h @@ -0,0 +1,37 @@ +/* + * Fifo.h + * + * Created on: Mar 19, 2014 + * Author: robert + */ + +#ifndef FIFO_H_ +#define FIFO_H_ + +#include "Scheduler.h" +#include "../core/BankStates.h" +#include +#include + +namespace scheduler { + +class Fifo : public Scheduler +{ +public: + Fifo(const core::BankStates& bankstates) : buffer(bankstates.getNumberOfBanks()) + {} + virtual ~Fifo() + {} + + virtual bool hasTransactionForBank(Bank bank) override; + virtual void schedule(gp* payload) override; + virtual gp* getTransactionForBank(Bank bank) override; + virtual void popTransactionForBank(Bank bank) override; + +private: + std::vector> buffer; +}; + +} /* namespace scheduler */ + +#endif /* FIFO_H_ */ diff --git a/dram/src/scheduler/Fr_Fcfs.cpp b/dram/src/scheduler/Fr_Fcfs.cpp new file mode 100644 index 00000000..a514f3bb --- /dev/null +++ b/dram/src/scheduler/Fr_Fcfs.cpp @@ -0,0 +1,26 @@ +//#include "Fr_Fcfs.h" +//#include "assert.h" +//#include "common/dramExtension.h" +// +//using namespace tlm; +//using namespace std; +// +//namespace scheduler { +// +//bool FR_FCFS::hasScheduledTransactions(Bank bank) +//{ +// return rowHitBuffer.hasBufferedTransaction(bank); +//} +// +//gp* FR_FCFS::getNextScheduledTransaction(Bank bank) +//{ +// gp* result = rowHitBuffer.getRowHitOrOldest(bank); +// return result; +//} +// +//void FR_FCFS::schedule(gp* payload) +//{ +// rowHitBuffer.bufferTransaction(payload); +//} +// +//} diff --git a/dram/src/scheduler/Fr_Fcfs.h b/dram/src/scheduler/Fr_Fcfs.h new file mode 100644 index 00000000..5b237bf6 --- /dev/null +++ b/dram/src/scheduler/Fr_Fcfs.h @@ -0,0 +1,26 @@ +//#ifndef FR_FCFS_H +//#define FR_FCFS_H +//#include +//#include +//#include "Scheduler.h" +//#include "RowHitBuffer.h" +//#include "../core/BankStates.h" +// +//namespace scheduler{ +// +//class FR_FCFS : public Scheduler +//{ +//public: +// FR_FCFS(const core::BankStates& bankstates): rowHitBuffer(bankstates){} +// virtual ~FR_FCFS(){} +// virtual bool hasScheduledTransactions(Bank bank) override; +// virtual void schedule(gp* payload) override; +// virtual gp* getNextScheduledTransaction(Bank bank) override; +// +//private: +// RowHitBuffer rowHitBuffer; +//}; +// +//} +// +//#endif // FR_FCFS_H diff --git a/dram/src/scheduler/Scheduler.h b/dram/src/scheduler/Scheduler.h new file mode 100644 index 00000000..5df85107 --- /dev/null +++ b/dram/src/scheduler/Scheduler.h @@ -0,0 +1,27 @@ +#ifndef SCHEDULER_H +#define SCHEDULER_H +#include +#include "common/dramExtension.h" + +namespace scheduler { + +typedef tlm::tlm_generic_payload gp; + +class Scheduler +{ +public: + virtual ~Scheduler(){}; + + virtual void schedule(gp* payload) = 0; + + //TODO Rename to payload + virtual bool hasTransactionForBank(Bank bank) = 0; + virtual gp* getTransactionForBank(Bank bank) = 0; + virtual void popTransactionForBank(Bank bank) = 0; +}; + +} + + + +#endif // SCHEDULER_H diff --git a/dram/src/tlm/controllerwrapper.h b/dram/src/tlm/controllerwrapper.h index ab5db877..8249a715 100644 --- a/dram/src/tlm/controllerwrapper.h +++ b/dram/src/tlm/controllerwrapper.h @@ -14,15 +14,19 @@ #include #include #include +#include #include "common/protocol.h" #include "common/tlmDBPhaseRecorder.h" -#include "dram/core/IWrapperConnector.h" -#include "dram/core/Controller.h" +#include "../core/IWrapperConnector.h" +#include "../core/Controller.h" +#include "../scheduler/Scheduler.h" +#include "../scheduler/Fifo.h" using namespace std; using namespace tlm; using namespace core; +using namespace scheduler; template struct ControllerWrapper: public sc_module, public IWrapperConnector @@ -38,21 +42,27 @@ public: &ControllerWrapper::controllerPEQCallback), tpr(tpr) { controller = new DramController(*this); + scheduler = new Fifo(controller->getBankStates()); inputBufferDelay = controller->config.Timings.clk; iSocket.register_nb_transport_bw(this, &ControllerWrapper::nb_transport_bw); tSocket.register_nb_transport_fw(this, &ControllerWrapper::nb_transport_fw); + + for(Bank bank:controller->getBankStates().getBanks()) + bankIsFreeForRequest[bank] = true; } ~ControllerWrapper() { delete controller; + delete scheduler; } - virtual void send(const ScheduledCommand& command) + virtual void send(const ScheduledCommand& command) override { - assert(command.getStart() >= sc_time_stamp()||command.getStart()= sc_time_stamp()); sc_time delay = command.getStart() - sc_time_stamp(); tlm::tlm_phase phase; + switch (command.getCommand()) { case Read: @@ -78,7 +88,7 @@ public: dramPEQ.notify(command.getTransaction(), phase, delay); } - virtual void send(Trigger trigger, sc_time time) + virtual void send(Trigger trigger, sc_time time) override { assert(time >= sc_time_stamp()); sc_time delay = time - sc_time_stamp(); @@ -87,6 +97,9 @@ public: private: DramController* controller; + Scheduler* scheduler; + map bankIsFreeForRequest; + tlm_utils::peq_with_cb_and_phase frontendPEQ; tlm_utils::peq_with_cb_and_phase dramPEQ; tlm_utils::peq_with_cb_and_phase controllerPEQ; @@ -95,6 +108,45 @@ private: tlm::tlm_generic_payload triggerDummy; tlmDBPhaseRecorder& tpr; + + void payloadEntersSystem(tlm_generic_payload& payload) + { + //std::cout << "----------------------------------------------------------------------- " << std::endl; + //std::cout << "Transaction enters system at " << sc_time_stamp() << std::endl; + + Bank bank = DramExtension::getExtension(payload).getBank(); + scheduler->schedule(&payload); + scheduleNextPayload(bank); + } + + void scheduleNextPayload(Bank bank) + { + //std::cout << "----------------------------------------------------------------------- " << std::endl; + //std::cout << "In trigger for bank " << bank.ID() << std::endl; + + if(controller->isBusy(sc_time_stamp(), bank)) + return; + else if(scheduler->hasTransactionForBank(bank)) + { + tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank); + if(controller->schedule(sc_time_stamp(), *nextTransaction)) + { + //std::cout << "Next payload was scheduled by core " << std::endl; + scheduler->popTransactionForBank(bank); + } + else + { + //std::cout << "Next payload was not scheduled because of refresh " << std::endl; + } + } + } + + + void payloadLeavesSystem(tlm_generic_payload& payload) + { + + } + // Initiated by dram tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay) { @@ -105,57 +157,76 @@ private: // Initiated by dram frontend tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay) { - if (phase == BEGIN_REQ) - payload.acquire(); - else if (phase == END_RESP) - payload.release(); + DramExtension::getExtension(payload); + tpr.recordPhase(payload,phase,sc_time_stamp()); + + if (phase == BEGIN_REQ) + { + payload.acquire(); + frontendPEQ.notify(payload, phase, inputBufferDelay); + } + else if (phase == END_RESP) + { + payloadLeavesSystem(payload); + payload.release(); + } - frontendPEQ.notify(payload, phase, fwDelay); return TLM_ACCEPTED; } void frontendPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase) { - tpr.recordPhase(payload,phase,sc_time_stamp()); if (phase == BEGIN_REQ) { - controller->schedule(sc_time_stamp() + inputBufferDelay, payload); - frontendPEQ.notify(payload,END_REQ,inputBufferDelay); - } - else if(phase == END_REQ) - { + payloadEntersSystem(payload); payload.set_response_status(tlm::TLM_OK_RESPONSE); - sendToFrontend(payload,phase,SC_ZERO_TIME); + tpr.recordPhase(payload, END_REQ, sc_time_stamp()); + sendToFrontend(payload, END_REQ, SC_ZERO_TIME); } - else if (phase == BEGIN_RESP) - { - sendToFrontend(payload, phase, SC_ZERO_TIME); - } - else if (phase == END_RESP) - { - } - else { SC_REPORT_FATAL(0, - "Payload event queue in controller wrapper was triggered with unknown phase"); + "Frontend PEQ event queue in controller wrapper was triggered with unknown phase"); } } void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase) { tpr.recordPhase(payload,phase,sc_time_stamp()); - if (phase == BEGIN_RD || phase == BEGIN_WR || phase == BEGIN_REFA || phase == BEGIN_ACT + DramExtension *result = NULL; + payload.get_extension(result); + if(result==NULL) + { + cout << "ERROR AT TIME " << sc_time_stamp() << std::endl; + cout << "Payload " << payload.get_address() << " " << phase; + + assert(result != NULL); + } + if (phase == BEGIN_RD || phase == BEGIN_WR) + { + //std::cout << "BEGIN_RD at " <getBankStates().getBanks()) + scheduleNextPayload(bank); } else if (phase == END_RD || phase == END_WR) { - frontendPEQ.notify(payload, BEGIN_RESP, SC_ZERO_TIME); + tpr.recordPhase(payload, BEGIN_RESP, sc_time_stamp()); + sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); } - else if (phase == END_PRE || phase == END_ACT || phase == END_REFA) + else if (phase == END_PRE || phase == END_ACT) { } @@ -181,6 +252,7 @@ private: void sendToDram(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) { + DramExtension::getExtension(payload); tlm_phase TPhase = phase; sc_time TDelay = delay; iSocket->nb_transport_fw(payload, TPhase, TDelay);