diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index e22eb7f1..6a6ca79d 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -82,22 +82,33 @@ uint64_t MemSpec::getSimMemSizeInBytes() const sc_time MemSpec::getRefreshIntervalAB() const { - SC_REPORT_FATAL("MemSpec", "All bank refresh not supported"); + SC_REPORT_FATAL("MemSpec", "All-bank refresh not supported"); return SC_ZERO_TIME; } sc_time MemSpec::getRefreshIntervalPB() const { - SC_REPORT_FATAL("MemSpec", "Per bank refresh not supported"); + SC_REPORT_FATAL("MemSpec", "Per-bank refresh not supported"); + return SC_ZERO_TIME; +} + +sc_time MemSpec::getRefreshIntervalP2B() const +{ + SC_REPORT_FATAL("MemSpec", "Per-2-bank refresh not supported"); return SC_ZERO_TIME; } sc_time MemSpec::getRefreshIntervalSB() const { - SC_REPORT_FATAL("MemSpec", "Same bank refresh not supported"); + SC_REPORT_FATAL("MemSpec", "Same-bank refresh not supported"); return SC_ZERO_TIME; } +unsigned MemSpec::getPer2BankOffset() const +{ + return 0; +} + unsigned MemSpec::getRAACDR() const { SC_REPORT_FATAL("MemSpec", "Refresh Management not supported"); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 4c6b9f9d..6e1ee9c0 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -78,8 +78,11 @@ public: virtual sc_core::sc_time getRefreshIntervalAB() const; virtual sc_core::sc_time getRefreshIntervalPB() const; + virtual sc_core::sc_time getRefreshIntervalP2B() const; virtual sc_core::sc_time getRefreshIntervalSB() const; + virtual unsigned getPer2BankOffset() const; + virtual unsigned getRAAIMT() const; virtual unsigned getRAAMMT() const; virtual unsigned getRAACDR() const; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp index 213f650e..9d6f8738 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp @@ -55,6 +55,7 @@ MemSpecGDDR6::MemSpecGDDR6(json &memspec) parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups") * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), 1), + per2BankOffset(parseUint(memspec["memarchitecturespec"], "per2BankOffset")), tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), tRC (tCK * parseUint(memspec["memtimingspec"], "RC")), @@ -80,6 +81,7 @@ MemSpecGDDR6::MemSpecGDDR6(json &memspec) tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), tREFI (tCK * parseUint(memspec["memtimingspec"], "REFI")), tREFIPB (tCK * parseUint(memspec["memtimingspec"], "REFIPB")), + tREFIP2B (tCK * parseUint(memspec["memtimingspec"], "REFIP2B")), tRFC (tCK * parseUint(memspec["memtimingspec"], "RFC")), tRFCPB (tCK * parseUint(memspec["memtimingspec"], "RFCPB")), tRREFD (tCK * parseUint(memspec["memtimingspec"], "RREFD")), @@ -122,6 +124,16 @@ sc_time MemSpecGDDR6::getRefreshIntervalPB() const return tREFIPB; } +sc_time MemSpecGDDR6::getRefreshIntervalP2B() const +{ + return tREFIP2B; +} + +unsigned MemSpecGDDR6::getPer2BankOffset() const +{ + return per2BankOffset; +} + sc_time MemSpecGDDR6::getExecutionTime(Command command, const tlm_generic_payload &payload) const { if (command == Command::PREPB || command == Command::PREAB) diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h index a28308bb..21badf4d 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h @@ -71,6 +71,7 @@ public: const sc_core::sc_time tXP; const sc_core::sc_time tREFI; const sc_core::sc_time tREFIPB; + const sc_core::sc_time tREFIP2B; const sc_core::sc_time tRFC; const sc_core::sc_time tRFCPB; const sc_core::sc_time tRREFD; @@ -90,9 +91,14 @@ public: sc_core::sc_time getRefreshIntervalAB() const override; sc_core::sc_time getRefreshIntervalPB() const override; + sc_core::sc_time getRefreshIntervalP2B() const override; + unsigned getPer2BankOffset() 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; + +private: + unsigned per2BankOffset; }; #endif // MEMSPECGDDR6_H diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 1d001427..867bdda5 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -63,7 +63,7 @@ void BankMachine::updateState(Command command) openRow = DramExtension::getRow(currentPayload); refreshManagementCounter++; break; - case Command::PREPB: case Command::PREAB: case Command::PRESB: + case Command::PREPB: case Command::PRESB: case Command::PREAB: state = State::Precharged; break; case Command::RD: case Command::WR: @@ -76,7 +76,7 @@ void BankMachine::updateState(Command command) case Command::PDEA: case Command::PDEP: case Command::SREFEN: sleeping = true; break; - case Command::REFAB: case Command::REFPB: case Command::REFSB: + case Command::REFPB: case Command::REFP2B: case Command::REFSB: case Command::REFAB: sleeping = false; blocked = false; @@ -88,7 +88,7 @@ void BankMachine::updateState(Command command) refreshManagementCounter = 0; } break; - case Command::RFMAB: case Command::RFMSB: + case Command::RFMPB: case Command::RFMP2B: case Command::RFMSB: case Command::RFMAB: sleeping = false; blocked = false; diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index 309caf59..cb9b80b5 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -125,6 +125,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, tlm_generic_paylo Bank bank = DramExtension::getBank(payload); Bank bankInGroup = Bank(logicalRank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup); unsigned burstLength = DramExtension::getBurstLength(payload); + assert(!(burstLength == 32) || (memSpec->bitWidth == 4)); sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp index b69d0643..bd9cb653 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp @@ -156,7 +156,7 @@ void PowerDownManagerStaggered::updateState(Command command) else if (controllerIdle) entryTriggered = true; break; - case Command::REFPB: + case Command::REFPB: case Command::REFP2B: case Command::REFSB: if (controllerIdle) entryTriggered = true; break; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.cpp index 4e3f9781..89e446e8 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.cpp @@ -48,16 +48,14 @@ RefreshManagerPerBank::RefreshManagerPerBank(std::vector &bankMac memSpec = config.memSpec; timeForNextTrigger = getTimeForFirstTrigger(memSpec->getRefreshIntervalPB(), rank, memSpec->numberOfRanks); - - refreshPayloads = std::vector(memSpec->banksPerRank); - for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++) + for (auto it : bankMachinesOnRank) { - setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[bankID]->getBankGroup(), - bankMachinesOnRank[bankID]->getBank()); - allBankMachines.push_back(bankMachinesOnRank[bankID]); + setUpDummy(refreshPayloads[it], 0, rank, it->getBankGroup(), it->getBank()); + allBankMachines.push_back(it); } + remainingBankMachines = allBankMachines; - currentBankMachine = *remainingBankMachines.begin(); + currentIterator = remainingBankMachines.begin(); maxPostponed = static_cast(config.refreshMaxPostponed * memSpec->banksPerRank); maxPulledin = -static_cast(config.refreshMaxPulledin * memSpec->banksPerRank); @@ -65,9 +63,7 @@ RefreshManagerPerBank::RefreshManagerPerBank(std::vector &bankMac CommandTuple::Type RefreshManagerPerBank::getNextCommand() { - return {nextCommand, - &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->banksPerRank], - std::max(timeToSchedule, sc_time_stamp())}; + return {nextCommand, &refreshPayloads[*currentIterator], std::max(timeToSchedule, sc_time_stamp())}; } sc_time RefreshManagerPerBank::start() @@ -95,14 +91,12 @@ sc_time RefreshManagerPerBank::start() if (!skipSelection) { currentIterator = remainingBankMachines.begin(); - currentBankMachine = *remainingBankMachines.begin(); for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++) { if ((*it)->isIdle()) { currentIterator = it; - currentBankMachine = *it; allBanksBusy = false; break; } @@ -117,7 +111,8 @@ sc_time RefreshManagerPerBank::start() } else { - if (currentBankMachine->isActivated()) + // TODO: bank should already be blocked for precharge and selection should be skipped + if ((*currentIterator)->isActivated()) nextCommand = Command::PREPB; else { @@ -125,13 +120,12 @@ sc_time RefreshManagerPerBank::start() if (forcedRefresh) { - currentBankMachine->block(); + (*currentIterator)->block(); skipSelection = true; } } - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, - &refreshPayloads[currentBankMachine->getBank().ID()]); + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, &refreshPayloads[*currentIterator]); return timeToSchedule; } } @@ -144,7 +138,6 @@ sc_time RefreshManagerPerBank::start() if ((*it)->isIdle()) { currentIterator = it; - currentBankMachine = *it; allBanksBusy = false; break; } @@ -158,13 +151,12 @@ sc_time RefreshManagerPerBank::start() } else { - if (currentBankMachine->isActivated()) + if ((*currentIterator)->isActivated()) nextCommand = Command::PREPB; else nextCommand = Command::REFPB; - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, - &refreshPayloads[currentBankMachine->getBank().ID()]); + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, &refreshPayloads[*currentIterator]); return timeToSchedule; } } @@ -199,6 +191,9 @@ void RefreshManagerPerBank::updateState(Command command) state = State::Regular; // TODO: check if this assignment is necessary timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalPB(); sleeping = false; + remainingBankMachines = allBankMachines; + currentIterator = remainingBankMachines.begin(); + skipSelection = false; break; case Command::PDEA: case Command::PDEP: sleeping = true; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.h b/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.h index c02a12ba..2f24dd28 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.h @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -58,7 +59,7 @@ private: enum class State {Regular, Pulledin} state = State::Regular; const MemSpec *memSpec; PowerDownManagerIF *powerDownManager; - std::vector refreshPayloads; + std::unordered_map refreshPayloads; sc_core::sc_time timeForNextTrigger = sc_core::sc_max_time(); sc_core::sc_time timeToSchedule = sc_core::sc_max_time(); CheckerIF *checker; @@ -67,7 +68,6 @@ private: std::list remainingBankMachines; std::list allBankMachines; std::list::iterator currentIterator; - BankMachine *currentBankMachine; int flexibilityCounter = 0; int maxPostponed = 0; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.cpp index 48e89ee5..dc5b0493 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.cpp @@ -146,6 +146,7 @@ sc_time RefreshManagerSameBank::start() } } + // TODO: banks should already be blocked for precharge and selection should be skipped // only check for forced refresh, also block for PRESB if (nextCommand == Command::REFSB && forcedRefresh) { @@ -312,6 +313,9 @@ void RefreshManagerSameBank::updateState(Command command) state = State::Regular; // TODO: check if this assignment is necessary timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalSB(); sleeping = false; + remainingBankMachines = allBankMachines; + currentIterator = remainingBankMachines.begin(); + skipSelection = false; break; case Command::PDEA: case Command::PDEP: sleeping = true;