diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index daff5160..8d69ad8a 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -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); } diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index 9a571168..c1db4626 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -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; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index dcafede2..a5daae71 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -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; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index 61355879..ed162d9e 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -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; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index 79bd8d84..b4f67a75 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -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; diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 5703d722..f21a82d4 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -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) { diff --git a/DRAMSys/library/src/controller/BankMachine.h b/DRAMSys/library/src/controller/BankMachine.h index 55f44340..fe26e406 100644 --- a/DRAMSys/library/src/controller/BankMachine.h +++ b/DRAMSys/library/src/controller/BankMachine.h @@ -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 diff --git a/DRAMSys/library/src/controller/Command.cpp b/DRAMSys/library/src/controller/Command.cpp index b7813666..7fbfd891 100644 --- a/DRAMSys/library/src/controller/Command.cpp +++ b/DRAMSys/library/src/controller/Command.cpp @@ -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); } diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 772b9062..7bc13b71 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -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::NOP) readyCommands.emplace_back(commandTuple); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index d2de1321..8e21de31 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -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); diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerAllBank.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerAllBank.cpp index 85ce5a45..952e932e 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerAllBank.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerAllBank.cpp @@ -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; } diff --git a/DRAMSys/library/src/simulation/dram/Dram.cpp b/DRAMSys/library/src/simulation/dram/Dram.cpp index 223e2754..ef5b206d 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.cpp +++ b/DRAMSys/library/src/simulation/dram/Dram.cpp @@ -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) { diff --git a/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h b/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h index 5db48e37..7048a0d0 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h +++ b/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h @@ -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() {} }; diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index 6dc97f9e..1b05211b 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -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: diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp index 45be28a6..5496f5b5 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp @@ -73,6 +73,9 @@ shared_ptr PhaseFactory::CreatePhase(ID id, const QString &dbPhaseName, else if (dbPhaseName == "REFA") return shared_ptr(new REFA(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.REFA)}, std::shared_ptr())); + else if (dbPhaseName == "RFMAB") + return shared_ptr(new RFMAB(id, span, clk, trans, + {Timespan(span.Begin(), span.Begin() + clk * cl.RFMAB)}, std::shared_ptr())); else if (dbPhaseName == "REFB") return shared_ptr(new REFB(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.REFB)}, std::shared_ptr())); diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index 29dcc652..7b53f16b 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -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 { diff --git a/DRAMSys/traceAnalyzer/scripts/vcdExport.py b/DRAMSys/traceAnalyzer/scripts/vcdExport.py index 70d03d32..976c94ff 100755 --- a/DRAMSys/traceAnalyzer/scripts/vcdExport.py +++ b/DRAMSys/traceAnalyzer/scripts/vcdExport.py @@ -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