Ready for debugging.

This commit is contained in:
Lukas Steiner
2019-07-22 00:23:12 +02:00
parent 9204a88a28
commit ef011ad52c
11 changed files with 437 additions and 387 deletions

View File

@@ -1,6 +1,6 @@
<simconfig>
<SimulationName value="ddr3" />
<Debug value="0" />
<Debug value="1" />
<DatabaseRecording value="1" />
<PowerAnalysis value="1" />
<EnableWindowing value = "1" />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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