Ready for debugging.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<simconfig>
|
||||
<SimulationName value="ddr3" />
|
||||
<Debug value="0" />
|
||||
<Debug value="1" />
|
||||
<DatabaseRecording value="1" />
|
||||
<PowerAnalysis value="1" />
|
||||
<EnableWindowing value = "1" />
|
||||
|
||||
@@ -1,12 +1,88 @@
|
||||
#include "BankMachine.h"
|
||||
#include "Command.h"
|
||||
#include "core/scheduling/checker/CheckerDDR3New.h"
|
||||
|
||||
BankMachine::BankMachine(ControllerNew *controller) : controller(controller)
|
||||
BankMachine::BankMachine(ControllerNew *controller, SchedulerNew *scheduler, CheckerDDR3New *checker, Bank bank)
|
||||
: controller(controller), scheduler(scheduler), checker(checker), bank(bank) {}
|
||||
|
||||
void BankMachine::setCommandFinishedTime(sc_time time)
|
||||
{
|
||||
|
||||
commandFinishedTime = time;
|
||||
}
|
||||
|
||||
void BankMachine::setResultReady(sc_time time)
|
||||
tlm_generic_payload *BankMachine::getNextStateAndResult()
|
||||
{
|
||||
resultReady = time;
|
||||
tlm_generic_payload *payloadToReturn = nullptr;
|
||||
|
||||
if (commandFinishedTime == sc_time_stamp())
|
||||
{
|
||||
if (currentState == BmState::Activating)
|
||||
currentState = BmState::Activated;
|
||||
else if (currentState == BmState::Precharging)
|
||||
currentState = BmState::Precharged;
|
||||
else if (currentState == BmState::Reading || currentState == BmState::Writing)
|
||||
{
|
||||
currentState = BmState::Activated;
|
||||
payloadToReturn = currentPayload;
|
||||
currentPayload = nullptr;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong command!");
|
||||
}
|
||||
return payloadToReturn;
|
||||
}
|
||||
|
||||
void BankMachine::startBankMachine(sc_time minDelay)
|
||||
{
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(bank);
|
||||
if (currentPayload == nullptr)
|
||||
return;
|
||||
}
|
||||
if (currentState == BmState::Precharged)
|
||||
{
|
||||
sc_time delay = max(minDelay, checker->delayToSatisfyConstraints(Command::ACT, bank));
|
||||
controller->triggerEventAfterDelay(delay);
|
||||
nextCommand = Command::ACT;
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
{
|
||||
DramExtension extension = DramExtension::getExtension(currentPayload);
|
||||
if (extension.getRow() == currentRow)
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
{
|
||||
sc_time delay = max(minDelay, checker->delayToSatisfyConstraints(Command::RD, bank));
|
||||
controller->triggerEventAfterDelay(delay);
|
||||
nextCommand = Command::RD;
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
}
|
||||
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
|
||||
{
|
||||
sc_time delay = max(minDelay, checker->delayToSatisfyConstraints(Command::WR, bank));
|
||||
controller->triggerEventAfterDelay(delay);
|
||||
nextCommand = Command::WR;
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
}
|
||||
else
|
||||
{
|
||||
sc_time delay = max(minDelay, checker->delayToSatisfyConstraints(Command::PRE, bank));
|
||||
controller->triggerEventAfterDelay(delay);
|
||||
nextCommand = Command::PRE;
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> BankMachine::getNextCommand()
|
||||
{
|
||||
if (timeToSchedule == sc_time_stamp())
|
||||
return std::pair<Command, tlm_generic_payload *>(nextCommand, currentPayload);
|
||||
else
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
}
|
||||
|
||||
@@ -5,30 +5,43 @@
|
||||
#include <tlm.h>
|
||||
#include "../common/dramExtensions.h"
|
||||
#include "Command.h"
|
||||
#include "SchedulerNew.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class ControllerNew;
|
||||
class SchedulerNew;
|
||||
class CheckerDDR3New;
|
||||
|
||||
enum class BmState
|
||||
{
|
||||
Precharged,
|
||||
Activated
|
||||
Activated,
|
||||
Precharging,
|
||||
Activating,
|
||||
Reading,
|
||||
Writing
|
||||
};
|
||||
|
||||
class BankMachine
|
||||
{
|
||||
public:
|
||||
BankMachine(ControllerNew *);
|
||||
void setResultReady(sc_time);
|
||||
BankMachine(ControllerNew *, SchedulerNew *, CheckerDDR3New*, Bank);
|
||||
void setCommandFinishedTime(sc_time);
|
||||
tlm_generic_payload *getNextStateAndResult();
|
||||
void startBankMachine(sc_time minDelay);
|
||||
std::pair<Command, tlm_generic_payload *> getNextCommand();
|
||||
private:
|
||||
tlm_generic_payload *currentPayload = nullptr;
|
||||
BmState currentState = BmState::Precharged;
|
||||
Bank bank;
|
||||
Row currentRow = Row(0);
|
||||
Command nextCommand = Command::NOP;
|
||||
sc_time timeToSchedule = SC_ZERO_TIME;
|
||||
sc_time resultReady = SC_ZERO_TIME;
|
||||
sc_time commandFinishedTime = SC_ZERO_TIME;
|
||||
ControllerNew *controller;
|
||||
SchedulerNew *scheduler;
|
||||
CheckerDDR3New *checker;
|
||||
};
|
||||
|
||||
#endif // BANKMACHINE_H
|
||||
|
||||
@@ -1,19 +1,42 @@
|
||||
#include "CommandMux.h"
|
||||
#include "core/configuration/Configuration.h"
|
||||
|
||||
CommandMux::CommandMux(ControllerNew *controller) :
|
||||
controller(controller),
|
||||
state("CommandMux", &Configuration::getInstance()),
|
||||
checker(Configuration::getInstance(), state) {}
|
||||
CommandMux::CommandMux(ControllerNew *controller, ControllerState *state, std::map<Bank, BankMachine *> &bankMachines) :
|
||||
controller(controller), state(state), bankMachines(bankMachines) {}
|
||||
|
||||
/*
|
||||
void CommandMux::compute()
|
||||
void CommandMux::insertPayload(tlm_generic_payload *payload)
|
||||
{
|
||||
// Handling of backpressure from / to arbiter!!!
|
||||
|
||||
/* END_RESP from arbiter: check for successful transaction, remove payload from response queue, numberOfPayloads--
|
||||
* END_RD / END_WR from DRAM: check for successful transaction, move payload from BM to response queue, send result to arbiter (delay??)
|
||||
* BEGIN_REQ from arbiter: check for transaction, move to scheduler map
|
||||
* Trigger by BM: get transactions from all BM, choose one, send one, change state on BM, postpone all BM to next point in time
|
||||
payloadOrder.push(payload);
|
||||
}
|
||||
|
||||
void CommandMux::selectCommand()
|
||||
{
|
||||
for (auto it : bankMachines)
|
||||
{
|
||||
std::pair<Command, tlm_generic_payload *> result = it.second->getNextCommand();
|
||||
if (result.first != Command::NOP)
|
||||
readyCommands.push_back(result);
|
||||
}
|
||||
for (auto it : readyCommands)
|
||||
{
|
||||
if (it.first == Command::ACT || it.first == Command::PRE)
|
||||
{
|
||||
controller->sendToDram(it.first, it.second);
|
||||
readyCommands.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (auto it : readyCommands)
|
||||
{
|
||||
if (it.first == Command::RD || it.first == Command::WR)
|
||||
{
|
||||
if (it.second == payloadOrder.front())
|
||||
{
|
||||
payloadOrder.pop();
|
||||
controller->sendToDram(it.first, it.second);
|
||||
readyCommands.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
#ifndef COMMANDMUX_H
|
||||
#define COMMANDMUX_H
|
||||
|
||||
#include <queue>
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "ControllerState.h"
|
||||
#include "core/scheduling/checker/CheckerDDR3New.h"
|
||||
#include "BankMachine.h"
|
||||
#include "ControllerNew.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class ControllerNew;
|
||||
class BankMachine;
|
||||
|
||||
class CommandMux
|
||||
{
|
||||
public:
|
||||
CommandMux(ControllerNew *);
|
||||
SC_HAS_PROCESS(CommandMux);
|
||||
void triggerEventAtTime(sc_time triggerTime);
|
||||
void triggerEventQueueAtTime(sc_time triggerTime);
|
||||
CommandMux(ControllerNew *, ControllerState*, std::map<Bank, BankMachine *> &);
|
||||
void insertPayload(tlm_generic_payload *);
|
||||
void selectCommand();
|
||||
private:
|
||||
ControllerState state;
|
||||
CheckerDDR3New checker;
|
||||
ControllerState *state;
|
||||
ControllerNew *controller;
|
||||
std::queue<tlm_generic_payload *> payloadOrder;
|
||||
std::map<Bank, BankMachine *> &bankMachines;
|
||||
std::vector<std::pair<Command, tlm_generic_payload *>> readyCommands;
|
||||
};
|
||||
|
||||
#endif // COMMANDMUX_H
|
||||
|
||||
@@ -3,26 +3,32 @@
|
||||
#include "scheduler/FifoStrict.h"
|
||||
#include "../common/dramExtensions.h"
|
||||
#include "../common/protocol.h"
|
||||
#include "core/scheduling/ScheduledCommand.h"
|
||||
|
||||
ControllerNew::ControllerNew(sc_module_name name, TlmRecorder *tlmRecorder) :
|
||||
sc_module(name), tlmRecorder(tlmRecorder), debugManager(&DebugManager::getInstance())
|
||||
{
|
||||
SC_METHOD(control);
|
||||
SC_METHOD(controllerMethod);
|
||||
sensitive << triggerEvent << triggerEventQueue;
|
||||
dont_initialize();
|
||||
|
||||
tSocket.register_nb_transport_fw(this, &ControllerNew::nb_transport_fw);
|
||||
tSocket.register_transport_dbg(this, &ControllerNew::transport_dbg);
|
||||
iSocket.register_nb_transport_bw(this, &ControllerNew::nb_transport_bw);
|
||||
|
||||
for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines[Bank(bankID)] = new BankMachine(this);
|
||||
commandMux = new CommandMux(this);
|
||||
state = new ControllerState("Controller", &Configuration::getInstance());
|
||||
checker = new CheckerDDR3New(Configuration::getInstance(), *state);
|
||||
scheduler = new SchedulerNew();
|
||||
for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines[Bank(bankID)] = new BankMachine(this, scheduler, checker, Bank(bankID));
|
||||
commandMux = new CommandMux(this, state, bankMachines);
|
||||
}
|
||||
|
||||
ControllerNew::~ControllerNew()
|
||||
{
|
||||
tlmRecorder->closeConnection();
|
||||
delete state;
|
||||
delete checker;
|
||||
for (auto it : bankMachines)
|
||||
delete it.second;
|
||||
delete commandMux;
|
||||
@@ -32,18 +38,20 @@ ControllerNew::~ControllerNew()
|
||||
tlm_sync_enum ControllerNew::nb_transport_fw(tlm_generic_payload &trans,
|
||||
tlm_phase &phase, sc_time &delay)
|
||||
{
|
||||
recordPhase(trans, phase, delay);
|
||||
sc_time notDelay = delay;
|
||||
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
notDelay += Configuration::getInstance().memSpec->clk;
|
||||
payloadToAcquire = &trans;
|
||||
timeToAcquire = sc_time_stamp() + notDelay;
|
||||
}
|
||||
else if (phase = END_RESP)
|
||||
{
|
||||
// FIXME: synchronization!
|
||||
notDelay += Configuration::getInstance().memSpec->clk;
|
||||
payloadToRelease = &trans;
|
||||
timeToRelease = sc_time_stamp() + notDelay;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -67,16 +75,12 @@ unsigned int ControllerNew::transport_dbg(tlm_generic_payload &trans)
|
||||
tlm_sync_enum ControllerNew::nb_transport_bw(tlm_generic_payload &trans,
|
||||
tlm_phase &phase, sc_time &delay)
|
||||
{
|
||||
// only for END_RD and END_WR
|
||||
if (phase == END_RD || phase == END_WR)
|
||||
{
|
||||
printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " +
|
||||
delay.to_string());
|
||||
Bank bank = DramExtension::getExtension(trans).getBank();
|
||||
sc_time triggerTime = sc_time_stamp() + delay;
|
||||
bankMachines[bank]->setResultReady(triggerTime);
|
||||
triggerEventQueueAtTime(triggerTime);
|
||||
}
|
||||
recordPhase(trans, phase, delay);
|
||||
printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " +
|
||||
delay.to_string());
|
||||
Bank bank = DramExtension::getExtension(trans).getBank();
|
||||
bankMachines[bank]->setCommandFinishedTime(sc_time_stamp() + delay);
|
||||
triggerEventQueue.notify(delay);
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
@@ -104,17 +108,136 @@ void ControllerNew::recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_
|
||||
tlmRecorder->recordPhase(trans, phase, recTime);
|
||||
}
|
||||
|
||||
void ControllerNew::triggerEventAtTime(sc_time triggerTime)
|
||||
void ControllerNew::triggerEventAfterDelay(sc_time delay)
|
||||
{
|
||||
triggerEvent.notify(triggerTime);
|
||||
triggerEvent.notify(delay);
|
||||
}
|
||||
|
||||
void ControllerNew::triggerEventQueueAtTime(sc_time triggerTime)
|
||||
void ControllerNew::triggerEventQueueAfterDelay(sc_time delay)
|
||||
{
|
||||
triggerEventQueue.notify(triggerTime);
|
||||
triggerEventQueue.notify(delay);
|
||||
}
|
||||
|
||||
void ControllerNew::control()
|
||||
void ControllerNew::controllerMethod()
|
||||
{
|
||||
std::cout << sc_time_stamp() << std::endl;
|
||||
releasePayload();
|
||||
acquirePayload();
|
||||
getNextBmStates();
|
||||
sendToFrontend();
|
||||
startBankMachines();
|
||||
commandMux->selectCommand();
|
||||
restartBankMachines();
|
||||
}
|
||||
|
||||
void ControllerNew::releasePayload()
|
||||
{
|
||||
if (sc_time_stamp() == timeToRelease /*&& payloadToRelease != nullptr*/)
|
||||
{
|
||||
responseQueue.pop();
|
||||
payloadToRelease->release();
|
||||
payloadToRelease = nullptr;
|
||||
numberOfPayloads--;
|
||||
// TODO: insert payload ID
|
||||
printDebugMessage("Payload ID left system.");
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerNew::acquirePayload()
|
||||
{
|
||||
if (sc_time_stamp() >= timeToAcquire && payloadToAcquire != nullptr)
|
||||
{
|
||||
if (numberOfPayloads < Configuration::getInstance().MaxNrOfTransactions)
|
||||
{
|
||||
payloadToAcquire->acquire();
|
||||
scheduler->storeRequest(payloadToAcquire);
|
||||
commandMux->insertPayload(payloadToAcquire);
|
||||
payloadToAcquire = nullptr;
|
||||
numberOfPayloads++;
|
||||
// TODO: insert payload ID
|
||||
printDebugMessage("Payload ID entered system.");
|
||||
payloadToAcquire->set_response_status(TLM_OK_RESPONSE);
|
||||
tlm_phase tPhase = END_REQ;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
recordPhase(*payloadToAcquire, tPhase, tDelay);
|
||||
tSocket->nb_transport_bw(*payloadToAcquire, tPhase, tDelay);
|
||||
}
|
||||
else
|
||||
printDebugMessage("Total number of payloads exceeded, backpressure!");
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerNew::sendToFrontend()
|
||||
{
|
||||
if (payloadToRelease == nullptr)
|
||||
{
|
||||
if (!responseQueue.empty())
|
||||
{
|
||||
payloadToRelease = responseQueue.front();
|
||||
tlm_phase tPhase = END_REQ;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
tSocket->nb_transport_bw(*payloadToRelease, tPhase, tDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerNew::getNextBmStates()
|
||||
{
|
||||
for (auto it : bankMachines)
|
||||
{
|
||||
tlm_generic_payload *result = it.second->getNextStateAndResult();
|
||||
if (result != nullptr)
|
||||
{
|
||||
responseQueue.push(result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ControllerNew::startBankMachines()
|
||||
{
|
||||
for (auto it : bankMachines)
|
||||
it.second->startBankMachine(SC_ZERO_TIME);
|
||||
}
|
||||
|
||||
void ControllerNew::restartBankMachines()
|
||||
{
|
||||
sc_time minDelay = Configuration::getInstance().memSpec->clk;
|
||||
for (auto it : bankMachines)
|
||||
it.second->startBankMachine(minDelay);
|
||||
}
|
||||
|
||||
void ControllerNew::sendToDram(Command command, tlm_generic_payload *payload)
|
||||
{
|
||||
sc_time execTime = Configuration::getInstance().memSpec->getExecutionTime(command, *payload);
|
||||
ScheduledCommand scheduledCommand(command, sc_time_stamp(), execTime, *payload);
|
||||
state->cleanUp(sc_time_stamp());
|
||||
state->change(scheduledCommand);
|
||||
|
||||
sc_time delay = SC_ZERO_TIME;
|
||||
tlm_phase phase;
|
||||
if (command == Command::ACT)
|
||||
phase = BEGIN_ACT;
|
||||
else if (command == Command::PRE)
|
||||
phase = BEGIN_PRE;
|
||||
else if (command == Command::RD)
|
||||
phase = BEGIN_RD;
|
||||
else if (command == Command::WR)
|
||||
phase = BEGIN_WR;
|
||||
else
|
||||
SC_REPORT_FATAL("ControllerNew", "Unknown phase");
|
||||
iSocket->nb_transport_fw(*payload, phase, delay);
|
||||
}
|
||||
|
||||
|
||||
//void CommandMux::compute()
|
||||
//{
|
||||
// // Handling of backpressure from / to arbiter!!!
|
||||
|
||||
// /* END_RESP from arbiter: check for successful transaction, remove payload from response queue, numberOfPayloads--
|
||||
// * END_RD / END_WR from DRAM: check for successful transaction, move payload from BM to response queue, send result to arbiter (delay??)
|
||||
// * BEGIN_REQ from arbiter: check for transaction, move to scheduler map
|
||||
// * Trigger by BM: get transactions from all BM, choose one, send one, change state on BM, postpone all BM to next point in time
|
||||
// */
|
||||
//}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include <tlm_utils/simple_initiator_socket.h>
|
||||
@@ -13,10 +14,14 @@
|
||||
#include "SchedulerNew.h"
|
||||
#include "../common/TlmRecorder.h"
|
||||
#include "../common/DebugManager.h"
|
||||
#include "core/scheduling/checker/CheckerDDR3New.h"
|
||||
#include "ControllerState.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class SchedulerNew;
|
||||
class BankMachine;
|
||||
class CommandMux;
|
||||
|
||||
class ControllerNew : public sc_module
|
||||
{
|
||||
@@ -28,8 +33,16 @@ public:
|
||||
tlm_utils::simple_target_socket<ControllerNew> tSocket;
|
||||
tlm_utils::simple_initiator_socket<ControllerNew> iSocket;
|
||||
|
||||
void triggerEventAtTime(sc_time triggerTime);
|
||||
void triggerEventQueueAtTime(sc_time triggerTime);
|
||||
void triggerEventAfterDelay(sc_time);
|
||||
void triggerEventQueueAfterDelay(sc_time);
|
||||
|
||||
ControllerState *state;
|
||||
std::map<Bank, BankMachine *> bankMachines;
|
||||
CommandMux *commandMux;
|
||||
SchedulerNew *scheduler;
|
||||
CheckerDDR3New *checker;
|
||||
|
||||
void sendToDram(Command, tlm_generic_payload *);
|
||||
|
||||
private:
|
||||
tlm_sync_enum nb_transport_fw(tlm_generic_payload &trans,
|
||||
@@ -40,19 +53,24 @@ private:
|
||||
void printDebugMessage(string message);
|
||||
void recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_time delay);
|
||||
|
||||
void releasePayload();
|
||||
void acquirePayload();
|
||||
void getNextBmStates();
|
||||
void sendToFrontend();
|
||||
void startBankMachines();
|
||||
void restartBankMachines();
|
||||
|
||||
unsigned numberOfPayloads = 0;
|
||||
tlm_generic_payload *payloadToAcquire = nullptr;
|
||||
sc_time timeToAcquire = SC_ZERO_TIME;
|
||||
tlm_generic_payload *payloadToRelease = nullptr;
|
||||
sc_time timeToRelease = SC_ZERO_TIME;
|
||||
std::queue<tlm_generic_payload *> responseQueue;
|
||||
|
||||
std::map<Bank, BankMachine *> bankMachines;
|
||||
CommandMux *commandMux;
|
||||
SchedulerNew *scheduler;
|
||||
|
||||
TlmRecorder *tlmRecorder;
|
||||
DebugManager *debugManager;
|
||||
|
||||
void control();
|
||||
void controllerMethod();
|
||||
sc_event triggerEvent;
|
||||
sc_event_queue triggerEventQueue;
|
||||
};
|
||||
|
||||
@@ -87,7 +87,7 @@ ControllerCore::ControllerCore(sc_module_name /*name*/,
|
||||
commandChecker[Command::PDXP] = commandChecker[Command::PDEA];
|
||||
commandChecker[Command::SREFEX] = commandChecker[Command::PDEA];
|
||||
|
||||
timingChecker = new CheckerDDR3New(config, *state);
|
||||
//timingChecker = new CheckerDDR3New(config, *state);
|
||||
|
||||
// if (config.RowGranularRef) {
|
||||
// refreshManager = new RGR("RGR", *this);
|
||||
@@ -127,7 +127,7 @@ ControllerCore::~ControllerCore()
|
||||
delete commandChecker[Command::WR];
|
||||
delete commandChecker[Command::REFA];
|
||||
delete commandChecker[Command::PDEA];
|
||||
delete timingChecker;
|
||||
//delete timingChecker;
|
||||
//delete refreshManager;
|
||||
//delete powerDownManager;
|
||||
delete state;
|
||||
|
||||
@@ -85,7 +85,7 @@ private:
|
||||
ScheduledCommand schedule(Command command, sc_time start,
|
||||
tlm::tlm_generic_payload &payload);
|
||||
std::map<Command, ICommandChecker *> commandChecker;
|
||||
ICommandChecker *timingChecker;
|
||||
//ICommandChecker *timingChecker;
|
||||
void printDebugMessage(string message);
|
||||
};
|
||||
|
||||
|
||||
@@ -11,365 +11,158 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
void CheckerDDR3New::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
sc_time CheckerDDR3New::delayToSatisfyConstraints(Command command, Bank bank)
|
||||
{
|
||||
ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank());
|
||||
Command LastCmd = lastCommandOnBank.getCommand();
|
||||
Command nextCmd = command.getCommand();
|
||||
ScheduledCommand lastCommand;
|
||||
|
||||
if (nextCmd == Command::ACT)
|
||||
sc_time minTimeToWait = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT)
|
||||
{
|
||||
// TODO: WRA_bank0 -> PREA -> ACT_bank0: WRA_bank0 and ACT_bank0 have TD,
|
||||
// but we only consider PREA -> ACT_bank0 TD
|
||||
// REFA -> PDEP -> PDXP -> ACT
|
||||
lastCommand = state.getLastCommand(Command::RDA, command.getBank());
|
||||
lastCommand = state.getLastCommand(Command::RDA, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP + memSpec->tRP);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WRA, command.getBank());
|
||||
lastCommand = state.getLastCommand(Command::WRA, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PRE, command.getBank());
|
||||
lastCommand = state.getLastCommand(Command::PRE, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PREA, command.getBank());
|
||||
lastCommand = state.getLastCommand(Command::PREA, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXA, command.getBank());
|
||||
lastCommand = state.getLastCommand(Command::PDXA, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXP, command.getBank());
|
||||
lastCommand = state.getLastCommand(Command::PDXP, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::REFA, command.getBank());
|
||||
lastCommand = state.getLastCommand(Command::REFA, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRFC);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRFC);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::SREFEX, command.getBank());
|
||||
lastCommand = state.getLastCommand(Command::SREFEX, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXS);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXS);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::ACT, command.getBank());
|
||||
lastCommand = state.getLastCommand(Command::ACT, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRC);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRC);
|
||||
|
||||
while (!(state.bus.isFree(command.getStart()) && satsfiesACTtoACTdifferentBank(command) && satisfiesNActivateWindow(command)))
|
||||
command.delayStart(memSpec->clk);
|
||||
}
|
||||
else if (nextCmd == Command::RD || nextCmd == Command::RDA)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::ACT, command.getBank());
|
||||
//if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRCD);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::RD, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCCD);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WR, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWTR);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::SREFEX, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXSDLL);
|
||||
|
||||
while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe_RD(command))
|
||||
command.delayStart(memSpec->clk);
|
||||
}
|
||||
else if (nextCmd == Command::WR || nextCmd == Command::WRA)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::ACT, command.getBank());
|
||||
//if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRCD);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::RD, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WR, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCCD);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::SREFEX, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXSDLL);
|
||||
|
||||
while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe_WR(command))
|
||||
command.delayStart(memSpec->clk);
|
||||
}
|
||||
else if (nextCmd == Command::PRE)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::ACT, command.getBank());
|
||||
//if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRAS);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::RD, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WR, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP);
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
else if (nextCmd == Command::PREA)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::ACT);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRAS);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::RD);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::RDA);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WR);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WRA);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::REFA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRFC);
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
else if (nextCmd == Command::PDEA)
|
||||
{
|
||||
// TODO: Remove?
|
||||
lastCommand = state.getLastCommand(Command::ACT);
|
||||
//if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::RD);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::RDA);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WR);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + 4 * memSpec->clk + memSpec->tWR);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WRA);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + 5 * memSpec->clk + memSpec->tWR);
|
||||
|
||||
// TODO: Remove?
|
||||
lastCommand = state.getLastCommand(Command::PRE);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKE);
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
else if (nextCmd == Command::PDEP)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::RD);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::RDA);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WRA);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + 5 * memSpec->clk + memSpec->tWR);
|
||||
|
||||
// TODO: Remove?
|
||||
lastCommand = state.getLastCommand(Command::PRE);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk);
|
||||
|
||||
// TODO: Remove?
|
||||
lastCommand = state.getLastCommand(Command::PREA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXP, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKE);
|
||||
|
||||
// TODO: Remove?
|
||||
lastCommand = state.getLastCommand(Command::REFA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->clk);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::SREFEX, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXS);
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
else if (nextCmd == Command::SREFEN)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::RDA);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRL + 5 * memSpec->clk);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WRA);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + 5 * memSpec->clk + memSpec->tWR);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PRE);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PREA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXP, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::SREFEX, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXS);
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
else if (nextCmd == Command::PDXA)
|
||||
{
|
||||
lastCommand = state.getLastScheduledCommand(command.getBank());
|
||||
if (lastCommand.getCommand() != Command::PDEA)
|
||||
reportFatal("CheckerDDR3New", "PDXA can not follow " + commandToString(lastCommand.getCommand()));
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKE);
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
else if (nextCmd == Command::PDXP)
|
||||
{
|
||||
lastCommand = state.getLastScheduledCommand(command.getBank());
|
||||
if (lastCommand.getCommand() != Command::PDEP)
|
||||
reportFatal("CheckerDDR3New", "PDXP can not follow " + commandToString(lastCommand.getCommand()));
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKE);
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
else if (nextCmd == Command::SREFEX)
|
||||
{
|
||||
lastCommand = state.getLastScheduledCommand(command.getBank());
|
||||
if (lastCommand.getCommand() != Command::SREFEN)
|
||||
reportFatal("CheckerDDR3New", "SREFEX can not follow " + commandToString(lastCommand.getCommand()));
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tCKESR);
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
else if (nextCmd == Command::REFA)
|
||||
{
|
||||
// TODO: Bankwise logic
|
||||
if (config.BankwiseLogic)
|
||||
for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++)
|
||||
{
|
||||
if (lastCommandOnBank.isValidCommand())
|
||||
{
|
||||
switch (LastCmd)
|
||||
{
|
||||
case Command::PRE:
|
||||
case Command::PREA:
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
memSpec->tRP_old);
|
||||
break;
|
||||
case Command::RDA:
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
memSpec->tRTP + memSpec->tRP_old);
|
||||
break;
|
||||
case Command::WRA:
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
memSpec->tWL + memSpec->getWriteAccessTime()
|
||||
+ memSpec->tWR + memSpec->tRP_old);
|
||||
break;
|
||||
case Command::REFA:
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
memSpec->tRFC_old);
|
||||
break;
|
||||
case Command::PDXP:
|
||||
case Command::PDXA:
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
memSpec->tXP);
|
||||
break;
|
||||
case Command::SREFEX:
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
memSpec->tXS);
|
||||
break;
|
||||
default:
|
||||
reportFatal("CheckerDDR3New",
|
||||
"Refresh can not follow " + commandToString(LastCmd));
|
||||
}
|
||||
}
|
||||
lastCommand = state.getLastCommand(Command::ACT, Bank(bankID));
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRRD);
|
||||
}
|
||||
else
|
||||
|
||||
if (!state.bus.isFree(sc_time_stamp()))
|
||||
minTimeToWait = max(minTimeToWait, sc_time_stamp() + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::ACT, bank);
|
||||
//if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRCD);
|
||||
|
||||
// lastCommand = state.getLastCommand(Command::RD, bank);
|
||||
// if (lastCommand.isValidCommand())
|
||||
// minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD);
|
||||
|
||||
// lastCommand = state.getLastCommand(Command::WR, bank);
|
||||
// if (lastCommand.isValidCommand())
|
||||
// minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWTR);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXA, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::SREFEX, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXSDLL);
|
||||
|
||||
if (!state.bus.isFree(sc_time_stamp()))
|
||||
minTimeToWait = max(minTimeToWait, sc_time_stamp() + memSpec->clk);
|
||||
|
||||
for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::RDA);
|
||||
lastCommand = state.getLastCommand(Command::RD, Bank(bankID));
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRTP + memSpec->tRP);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WRA);
|
||||
lastCommand = state.getLastCommand(Command::WR, Bank(bankID));
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PRE);
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PREA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXP, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::REFA, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tRFC);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::SREFEX, command.getBank());
|
||||
if (lastCommand.isValidCommand())
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(), memSpec->tXS);
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWTR);
|
||||
}
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::ACT, bank);
|
||||
//if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRCD);
|
||||
|
||||
// lastCommand = state.getLastCommand(Command::RD, bank);
|
||||
// if (lastCommand.isValidCommand())
|
||||
// minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL);
|
||||
|
||||
// lastCommand = state.getLastCommand(Command::WR, bank);
|
||||
// if (lastCommand.isValidCommand())
|
||||
// minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXA, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::SREFEX, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXSDLL);
|
||||
|
||||
if (!state.bus.isFree(sc_time_stamp()))
|
||||
minTimeToWait = max(minTimeToWait, sc_time_stamp() + memSpec->clk);
|
||||
|
||||
for (unsigned bankID = 0; bankID < Configuration::getInstance().memSpec->NumberOfBanks; bankID++)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::RD, Bank(bankID));
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WR, Bank(bankID));
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tCCD);
|
||||
}
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
lastCommand = state.getLastCommand(Command::ACT, bank);
|
||||
//if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRAS);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::RD, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tRTP);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::WR, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tWL + memSpec->tCCD + memSpec->tWR);
|
||||
|
||||
lastCommand = state.getLastCommand(Command::PDXA, bank);
|
||||
if (lastCommand.isValidCommand())
|
||||
minTimeToWait = max(minTimeToWait, lastCommand.getStart() + memSpec->tXP);
|
||||
|
||||
if (!state.bus.isFree(sc_time_stamp()))
|
||||
minTimeToWait = max(minTimeToWait, sc_time_stamp() + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerDDR3New", "Unknown command!");
|
||||
}
|
||||
return (minTimeToWait - sc_time_stamp());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "../../../ControllerState.h"
|
||||
|
||||
//Activate
|
||||
class CheckerDDR3New : public ICommandChecker
|
||||
class CheckerDDR3New
|
||||
{
|
||||
public:
|
||||
CheckerDDR3New(const Configuration &config,
|
||||
@@ -16,9 +16,9 @@ public:
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
|
||||
}
|
||||
virtual ~CheckerDDR3New() {}
|
||||
~CheckerDDR3New() {}
|
||||
|
||||
virtual void delayToSatisfyConstraints(ScheduledCommand &command) const override;
|
||||
sc_time delayToSatisfyConstraints(Command command, Bank bank);
|
||||
|
||||
private:
|
||||
MemSpecDDR3 *memSpec;
|
||||
|
||||
Reference in New Issue
Block a user