Add FW and BW think delay and PHY delay.

This commit is contained in:
Lukas Steiner
2021-01-20 14:20:44 +01:00
parent 3187c59183
commit 0ab6562524
10 changed files with 150 additions and 151 deletions

View File

@@ -11,8 +11,11 @@
"RefreshMaxPulledin": 8,
"PowerDownPolicy": "NoPowerDown",
"PowerDownTimeout": 100,
"ArbitrationDelay": 0,
"ThinkDelay": 0,
"PhyDelay": 0
"ArbitrationDelayFw": 0,
"ArbitrationDelayBw": 0,
"ThinkDelayFw": 0,
"ThinkDelayBw": 0,
"PhyDelayFw": 0,
"PhyDelayBw": 0
}
}

View File

@@ -181,12 +181,18 @@ void Configuration::setParameter(std::string name, nlohmann::json value)
powerDownTimeout = value;
else if (name == "MaxActiveTransactions")
maxActiveTransactions = value;
else if (name == "ArbitrationDelay")
arbitrationDelay = memSpec->tCK * value;
else if (name == "ThinkDelay")
thinkDelay = memSpec->tCK * value;
else if (name == "PhyDelay")
phyDelay = memSpec->tCK * value;
else if (name == "ArbitrationDelayFw")
arbitrationDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK;
else if (name == "ArbitrationDelayBw")
arbitrationDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK;
else if (name == "ThinkDelayFw")
thinkDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK;
else if (name == "ThinkDelayBw")
thinkDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK;
else if (name == "PhyDelayFw")
phyDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK;
else if (name == "PhyDelayBw")
phyDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK;
//SimConfig------------------------------------------------
else if (name == "SimulationName")
simulationName = value;

View File

@@ -82,9 +82,12 @@ public:
enum class PowerDownPolicy {NoPowerDown, Staggered} powerDownPolicy;
unsigned int powerDownTimeout = 3;
unsigned int maxActiveTransactions = 64;
sc_time arbitrationDelay = SC_ZERO_TIME;
sc_time thinkDelay = SC_ZERO_TIME;
sc_time phyDelay = SC_ZERO_TIME;
sc_time arbitrationDelayFw = SC_ZERO_TIME;
sc_time arbitrationDelayBw = SC_ZERO_TIME;
sc_time thinkDelayFw = SC_ZERO_TIME;
sc_time thinkDelayBw = SC_ZERO_TIME;
sc_time phyDelayFw = SC_ZERO_TIME;
sc_time phyDelayBw = SC_ZERO_TIME;
// SimConfig
std::string simulationName = "default";

View File

@@ -126,34 +126,27 @@ sc_time BankMachineOpen::start()
timeToSchedule = sc_max_time();
nextCommand = Command::NOP;
if (sleeping)
return timeToSchedule;
currentPayload = scheduler->getNextRequest(this);
if (currentPayload == nullptr)
return timeToSchedule;
if (state == State::Precharged && !blocked) // row miss
if (!(sleeping || blocked))
{
nextCommand = Command::ACT;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
else if (state == State::Activated)
{
if (DramExtension::getRow(currentPayload) == openRow) // row hit
currentPayload = scheduler->getNextRequest(this);
if (currentPayload != nullptr)
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RD;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WR;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
else if (!blocked) // row miss
{
nextCommand = Command::PRE;
if (state == State::Precharged) // bank precharged
nextCommand = Command::ACT;
else if (state == State::Activated)
{
if (DramExtension::getRow(currentPayload) == openRow) // row hit
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RD;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WR;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
}
else // row miss
nextCommand = Command::PRE;
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
}
@@ -168,28 +161,24 @@ sc_time BankMachineClosed::start()
timeToSchedule = sc_max_time();
nextCommand = Command::NOP;
if (sleeping)
return timeToSchedule;
currentPayload = scheduler->getNextRequest(this);
if (currentPayload == nullptr)
return timeToSchedule;
if (state == State::Precharged && !blocked) // row miss
if (!(sleeping || blocked))
{
nextCommand = Command::ACT;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
else if (state == State::Activated)
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RDA;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WRA;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
currentPayload = scheduler->getNextRequest(this);
if (currentPayload != nullptr)
{
if (state == State::Precharged) // bank precharged
nextCommand = Command::ACT;
else if (state == State::Activated)
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RDA;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WRA;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
}
return timeToSchedule;
}
@@ -202,45 +191,39 @@ sc_time BankMachineOpenAdaptive::start()
timeToSchedule = sc_max_time();
nextCommand = Command::NOP;
if (sleeping)
return timeToSchedule;
currentPayload = scheduler->getNextRequest(this);
if (currentPayload == nullptr)
return timeToSchedule;
if (state == State::Precharged && !blocked) // row miss
if (!(sleeping || blocked))
{
nextCommand = Command::ACT;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
else if (state == State::Activated)
{
if (DramExtension::getRow(currentPayload) == openRow) // row hit
currentPayload = scheduler->getNextRequest(this);
if (currentPayload != nullptr)
{
if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, openRow))
if (state == State::Precharged) // bank precharged
nextCommand = Command::ACT;
else if (state == State::Activated)
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RDA;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WRA;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
if (DramExtension::getRow(currentPayload) == openRow) // row hit
{
if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, openRow))
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RDA;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WRA;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
}
else
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RD;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WR;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
}
}
else // row miss
nextCommand = Command::PRE;
}
else
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RD;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WR;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
else if (!blocked) // row miss
{
nextCommand = Command::PRE;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
}
@@ -255,48 +238,41 @@ sc_time BankMachineClosedAdaptive::start()
timeToSchedule = sc_max_time();
nextCommand = Command::NOP;
if (sleeping)
return timeToSchedule;
currentPayload = scheduler->getNextRequest(this);
if (currentPayload == nullptr)
return timeToSchedule;
if (state == State::Precharged && !blocked) // row miss
if (!(sleeping || blocked))
{
nextCommand = Command::ACT;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
else if (state == State::Activated)
{
if (DramExtension::getRow(currentPayload) == openRow) // row hit
currentPayload = scheduler->getNextRequest(this);
if (currentPayload != nullptr)
{
if (scheduler->hasFurtherRowHit(bank, openRow))
if (state == State::Precharged && !blocked) // bank precharged
nextCommand = Command::ACT;
else if (state == State::Activated)
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RD;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WR;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
}
else
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RDA;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WRA;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
if (DramExtension::getRow(currentPayload) == openRow) // row hit
{
if (scheduler->hasFurtherRowHit(bank, openRow))
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RD;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WR;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
}
else
{
if (currentPayload->get_command() == TLM_READ_COMMAND)
nextCommand = Command::RDA;
else if (currentPayload->get_command() == TLM_WRITE_COMMAND)
nextCommand = Command::WRA;
else
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
}
}
else // row miss, should never happen
SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy");
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
}
else if (!blocked) // row miss TODO: remove this, can never happen
{
nextCommand = Command::PRE;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy");
}
}
return timeToSchedule;
}

View File

@@ -72,7 +72,11 @@ Controller::Controller(sc_module_name name) :
Configuration &config = Configuration::getInstance();
memSpec = config.memSpec;
ranksNumberOfPayloads = std::vector<unsigned>(memSpec->numberOfRanks);
phyDelay = config.phyDelay;
thinkDelayFw = config.thinkDelayFw;
thinkDelayBw = config.thinkDelayBw;
phyDelayFw = config.phyDelayFw;
phyDelayBw = config.phyDelayBw;
// reserve buffer for command tuples
readyCommands.reserve(memSpec->numberOfBanks);
@@ -285,7 +289,7 @@ void Controller::controllerMethod()
bankID < memSpec->banksPerRank; bankID += memSpec->banksPerGroup)
bankMachinesOnRank[rank.ID()][bankID]->updateState(command);
}
else
else // if (isBankCommand(command))
bankMachines[bank.ID()]->updateState(command);
refreshManagers[rank.ID()]->updateState(command);
@@ -295,19 +299,21 @@ void Controller::controllerMethod()
if (isCasCommand(command))
{
scheduler->removeRequest(payload);
respQueue->insertPayload(payload, sc_time_stamp() + phyDelay
+ memSpec->getIntervalOnDataStrobe(command).end);
respQueue->insertPayload(payload, sc_time_stamp()
+ thinkDelayFw + phyDelayFw
+ memSpec->getIntervalOnDataStrobe(command).end
+ phyDelayBw + thinkDelayBw);
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
ranksNumberOfPayloads[rank.ID()]--;
ranksNumberOfPayloads[rank.ID()]--; // TODO: move to a different place?
}
if (ranksNumberOfPayloads[rank.ID()] == 0)
powerDownManagers[rank.ID()]->triggerEntry();
sendToDram(command, payload);
sendToDram(command, payload, thinkDelayFw + phyDelayFw);
}
else
readyCmdBlocked = true;
@@ -455,8 +461,8 @@ void Controller::sendToFrontend(tlm_generic_payload *payload, tlm_phase phase, s
tSocket->nb_transport_bw(*payload, phase, delay);
}
void Controller::sendToDram(Command command, tlm_generic_payload *payload)
void Controller::sendToDram(Command command, tlm_generic_payload *payload, sc_time delay)
{
tlm_phase phase = commandToPhase(command);
iSocket->nb_transport_fw(*payload, phase, phyDelay);
iSocket->nb_transport_fw(*payload, phase, delay);
}

View File

@@ -70,14 +70,17 @@ protected:
virtual unsigned int transport_dbg(tlm::tlm_generic_payload &) override;
virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase, sc_time);
virtual void sendToDram(Command, tlm::tlm_generic_payload *);
virtual void sendToDram(Command, tlm::tlm_generic_payload *, sc_time);
virtual void controllerMethod();
SchedulerIF *scheduler;
const MemSpec *memSpec;
sc_time phyDelay;
sc_time thinkDelayFw;
sc_time thinkDelayBw;
sc_time phyDelayFw;
sc_time phyDelayBw;
private:
unsigned totalNumberOfPayloads = 0;

View File

@@ -71,17 +71,17 @@ void ControllerRecordable::sendToFrontend(tlm_generic_payload *payload, tlm_phas
tSocket->nb_transport_bw(*payload, phase, delay);
}
void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payload)
void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payload, sc_time delay)
{
if (isCasCommand(command))
{
TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command);
tlmRecorder->updateDataStrobe(sc_time_stamp() + phyDelay + dataStrobe.start,
sc_time_stamp() + phyDelay + dataStrobe.end, *payload);
tlmRecorder->updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start,
sc_time_stamp() + delay + dataStrobe.end, *payload);
}
tlm_phase phase = commandToPhase(command);
iSocket->nb_transport_fw(*payload, phase, phyDelay);
iSocket->nb_transport_fw(*payload, phase, delay);
}
void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_time delay)

View File

@@ -51,7 +51,7 @@ protected:
tlm::tlm_phase &phase, sc_time &delay) override;
virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase, sc_time) override;
virtual void sendToDram(Command, tlm::tlm_generic_payload *) override;
virtual void sendToDram(Command, tlm::tlm_generic_payload *, sc_time) override;
virtual void controllerMethod() override;

View File

@@ -46,7 +46,8 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) :
sc_module(name), payloadEventQueue(this, &Arbiter::peqCallback),
maxActiveTransactions(Configuration::getInstance().maxActiveTransactions),
tCK(Configuration::getInstance().memSpec->tCK),
arbitrationDelay(Configuration::getInstance().arbitrationDelay)
arbitrationDelayFw(Configuration::getInstance().arbitrationDelayFw),
arbitrationDelayBw(Configuration::getInstance().arbitrationDelayBw)
{
iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw);
tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw);
@@ -178,7 +179,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
channelIsBusy[channelId] = true;
tlm_phase tPhase = BEGIN_REQ;
sc_time tDelay = arbitrationDelay;
sc_time tDelay = arbitrationDelayFw;
iSocket[static_cast<int>(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay);
}
else
@@ -198,7 +199,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
pendingRequests[channelId].pop();
tlm_phase tPhase = BEGIN_REQ;
// do not send two requests in the same cycle
sc_time tDelay = tCK + arbitrationDelay;
sc_time tDelay = tCK + arbitrationDelayFw;
iSocket[static_cast<int>(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay);
}
else
@@ -209,7 +210,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
if (!threadIsBusy[threadId])
{
tlm_phase tPhase = BEGIN_RESP;
sc_time tDelay = arbitrationDelay;
sc_time tDelay = arbitrationDelayBw;
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay);
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(cbPayload, tPhase, tDelay);
@@ -233,7 +234,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
pendingResponses[threadId].pop();
tlm_phase tPhase = BEGIN_RESP;
// do not send two responses in the same cycle
sc_time tDelay = tCK + arbitrationDelay;
sc_time tDelay = tCK + arbitrationDelayBw;
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(tPayload, tPhase, tDelay);

View File

@@ -90,7 +90,8 @@ protected:
unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans);
sc_time tCK;
sc_time arbitrationDelay;
sc_time arbitrationDelayFw;
sc_time arbitrationDelayBw;
};
class ArbiterSimple final : public Arbiter