First draft of RFMAB

This commit is contained in:
Matthias Jung
2021-08-27 19:54:11 +02:00
parent cbc5df18ca
commit cae54bb879
17 changed files with 115 additions and 25 deletions

View File

@@ -131,7 +131,7 @@ void TlmRecorder::recordPhase(tlm_generic_payload &trans,
if (currentTransactionsInSystem[&trans].cmd == 'X')
{
if (phase == END_REFA || phase == END_REFB || phase == END_REFSB
if (phase == END_REFA || phase == END_RFMAB || phase == END_REFB || phase == END_REFSB
|| phase == END_PDNA || phase == END_PDNP || phase == END_SREF)
removeTransactionFromSystem(trans);
}

View File

@@ -104,6 +104,12 @@ uint64_t MemSpec::getRAADEC() const
return 0;
}
uint64_t MemSpec::getRAAIMT() const
{
SC_REPORT_FATAL("MemSpec", "Refresh Management not supported");
return 0;
}
bool MemSpec::hasRasAndCasBus() const
{
return false;

View File

@@ -81,6 +81,7 @@ public:
virtual sc_core::sc_time getRefreshIntervalSB() const;
virtual uint64_t getRAADEC() const;
virtual uint64_t getRAAIMT() const;
virtual bool hasRasAndCasBus() const;

View File

@@ -196,6 +196,11 @@ uint64_t MemSpecDDR5::getRAADEC() const
return RAADEC;
}
uint64_t MemSpecDDR5::getRAAIMT() const
{
return RAAIMT;
}
// Returns the execution time for commands that have a fixed execution time
sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &payload) const
{
@@ -226,7 +231,7 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload
else
return tWL + tBURST16 + tWR + tRP + longCmdOffset;
}
else if (command == Command::REFA)
else if (command == Command::REFA || command == Command::RFMAB)
return tRFC_slr + shortCmdOffset;
else if (command == Command::REFSB)
return tRFCsb_slr + shortCmdOffset;

View File

@@ -117,6 +117,7 @@ public:
sc_core::sc_time getRefreshIntervalSB() const override;
uint64_t getRAADEC() const override;
uint64_t getRAAIMT() const override;
sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;

View File

@@ -75,7 +75,7 @@ void BankMachine::updateState(Command command)
case Command::PDEA: case Command::PDEP: case Command::SREFEN:
sleeping = true;
break;
case Command::REFA: case Command::REFB: case Command::REFSB:
case Command::REFA: case Command::REFB: case Command::REFSB: case Command::RFMAB:
sleeping = false;
blocked = false;
if(Configuration::getInstance().RFM == true) {

View File

@@ -59,6 +59,7 @@ public:
Row getOpenRow() const;
State getState() const;
bool isIdle() const;
uint64_t getRFMCounter() const;
protected:
BankMachine(SchedulerIF *, CheckerIF *, Bank);
@@ -74,6 +75,7 @@ protected:
Bank bank;
bool blocked = false;
bool sleeping = false;
uint64_t RFMCounter;
};
class BankMachineOpen final : public BankMachine

View File

@@ -165,12 +165,12 @@ MemCommand::cmds phaseToDRAMPowerCommand(tlm_phase phase)
bool phaseNeedsEnd(tlm_phase phase)
{
return (phase >= BEGIN_RD && phase <= BEGIN_REFA);
return (phase >= BEGIN_RD && phase <= BEGIN_RFMAB);
}
tlm_phase getEndPhase(tlm_phase phase)
{
assert(phase >= BEGIN_RD && phase <= BEGIN_REFA);
assert(phase >= BEGIN_RD && phase <= BEGIN_RFMAB);
return (phase + Command::Type::END_ENUM - 1);
}

View File

@@ -265,7 +265,7 @@ void Controller::controllerMethod()
readyCommands.emplace_back(commandTuple);
else
{
// (4.2) Check for refresh commands (PREA/PRE or REFA/REFB)
// (4.2) Check for refresh commands (PREA/PRE or REFA/REFB/...)
commandTuple = refreshManagers[rankID]->getNextCommand();
if (std::get<CommandTuple::Command>(commandTuple) != Command::NOP)
readyCommands.emplace_back(commandTuple);

View File

@@ -558,6 +558,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, tlm_generic_paylo
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdLengthDiff);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RFMAB][logicalRank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdLengthDiff);
// TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT?
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroup.ID()];
@@ -697,7 +701,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, tlm_generic_paylo
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
}
else if (command == Command::REFA)
else if (command == Command::REFA || command == Command::RFMAB)
{
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalRank.ID()];
if (lastCommandStart != sc_max_time())
@@ -736,6 +740,18 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, tlm_generic_paylo
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RFMAB][logicalRank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RFMAB][physicalRank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
lastCommandStart = lastScheduledByCommandAndDimmRank[Command::RFMAB][dimmRank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
// REFSB tRFCsb_slr/dlr
// PRESB tRP
}
@@ -786,6 +802,20 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, tlm_generic_paylo
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RFMAB][logicalRank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
// TODO: check this
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RFMAB][physicalRank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
// TODO: check this
lastCommandStart = lastScheduledByCommandAndDimmRank[Command::RFMAB][dimmRank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalRank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr);

View File

@@ -64,6 +64,15 @@ sc_time RefreshManagerAllBank::start()
timeToSchedule = sc_max_time();
nextCommand = Command::NOP;
bool RFMRequired = false;
for(auto bm : bankMachinesOnRank) {
if(bm->getRFMCounter() >= Configuration::getInstance().memSpec->getRAAIMT())
{
RFMRequired = true;
break;
}
}
if (sc_time_stamp() >= timeForNextTrigger)
{
powerDownManager->triggerInterruption();
@@ -137,6 +146,12 @@ sc_time RefreshManagerAllBank::start()
}
}
}
else if (RFMRequired)
{
nextCommand = Command::RFMAB;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, &refreshPayload);
return timeToSchedule;
}
else
return timeForNextTrigger;
}

View File

@@ -134,7 +134,7 @@ void Dram::reportPower()
tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &delay)
{
assert(phase >= 5 && phase <= 21);
assert(phase >= 5 && phase <= Command::Type::END_ENUM);
if (Configuration::getInstance().powerAnalysis)
{

View File

@@ -48,8 +48,10 @@ struct CommandLengths
unsigned REFB;
unsigned PRESB;
unsigned REFSB;
unsigned RFMSB;
unsigned PREA;
unsigned REFA;
unsigned RFMAB;
unsigned PDEA;
unsigned PDXA;
unsigned PDEP;
@@ -60,13 +62,14 @@ struct CommandLengths
CommandLengths(unsigned NOP, unsigned RD, unsigned WR,
unsigned RDA, unsigned WRA, unsigned ACT,
unsigned PRE, unsigned REFB, unsigned PRESB,
unsigned REFSB, unsigned PREA, unsigned REFA,
unsigned PDEA, unsigned PDXA, unsigned PDEP,
unsigned PDXP, unsigned SREFEN, unsigned SREFEX) :
unsigned REFSB, unsigned RFMSB, unsigned PREA,
unsigned REFA, unsigned RFMAB, unsigned PDEA,
unsigned PDXA, unsigned PDEP, unsigned PDXP,
unsigned SREFEN, unsigned SREFEX) :
NOP(NOP), RD(RD), WR(WR), RDA(RDA), WRA(WRA), ACT(ACT), PRE(PRE),
REFB(REFB), PRESB(PRESB), REFSB(REFSB), PREA(PREA), REFA(REFA),
PDEA(PDEA), PDXA(PDXA), PDEP(PDEP), PDXP(PDXP),
SREFEN(SREFEN), SREFEX(SREFEX) {}
REFB(REFB), PRESB(PRESB), REFSB(REFSB), RFMSB(RFMSB), PREA(PREA),
REFA(REFA), RFMAB(RFMAB), PDEA(PDEA), PDXA(PDXA), PDEP(PDEP),
PDXP(PDXP), SREFEN(SREFEN), SREFEX(SREFEX) {}
CommandLengths() {}
};

View File

@@ -365,6 +365,28 @@ protected:
}
};
class RFMAB : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
virtual QString Name() const override
{
return "RFMAB";
}
virtual Granularity getGranularity() const override
{
return Granularity::Rankwise;
}
virtual QColor getPhaseColor() const override
{
QColor phaseColor = QColor(Qt::darkRed);
phaseColor.setAlpha(130);
return phaseColor;
}
};
class REFB : public AUTO_REFRESH
{
public:

View File

@@ -73,6 +73,9 @@ shared_ptr<Phase> PhaseFactory::CreatePhase(ID id, const QString &dbPhaseName,
else if (dbPhaseName == "REFA")
return shared_ptr<Phase>(new REFA(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFA)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "RFMAB")
return shared_ptr<Phase>(new RFMAB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RFMAB)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "REFB")
return shared_ptr<Phase>(new REFB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFB)}, std::shared_ptr<Timespan>()));

View File

@@ -295,18 +295,20 @@ CommandLengths TraceDB::getCommandLengthsFromDB()
unsigned REFB = query.value(7).toInt();
unsigned PRESB = query.value(8).toInt();
unsigned REFSB = query.value(9).toInt();
unsigned PREA = query.value(10).toInt();
unsigned REFA = query.value(11).toInt();
unsigned PDEA = query.value(12).toInt();
unsigned PDXA = query.value(13).toInt();
unsigned PDEP = query.value(14).toInt();
unsigned PDXP = query.value(15).toInt();
unsigned SREFEN = query.value(16).toInt();
unsigned SREFEX = query.value(17).toInt();
unsigned RFMSB = query.value(10).toInt();
unsigned PREA = query.value(11).toInt();
unsigned REFA = query.value(12).toInt();
unsigned RFMAB = query.value(13).toInt();
unsigned PDEA = query.value(14).toInt();
unsigned PDXA = query.value(15).toInt();
unsigned PDEP = query.value(16).toInt();
unsigned PDXP = query.value(17).toInt();
unsigned SREFEN = query.value(18).toInt();
unsigned SREFEX = query.value(19).toInt();
return CommandLengths(NOP, RD, WR, RDA, WRA, ACT, PRE, REFB,
PRESB, REFSB, PREA, REFA, PDEA, PDXA,
PDEP, PDXP, SREFEN, SREFEX);
PRESB, REFSB, RFMSB, PREA, REFA, RFMAB,
PDEA, PDXA, PDEP, PDXP, SREFEN, SREFEX);
}
else
{

View File

@@ -90,7 +90,7 @@ class Granularity(enum.Enum):
def getGranularity(phase):
if phase == "PRESB" or phase == "REFSB":
return Granularity.Groupwise
elif phase == "PREA" or phase == "REFA" or phase == "PDNA" or phase == "PDNP" or phase == "SREF":
elif phase == "PREA" or phase == "REFA" or phase=="RFMAB" or phase == "PDNA" or phase == "PDNP" or phase == "SREF":
return Granularity.Rankwise
else:
return Granularity.Bankwise