diff --git a/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml index 61136a5c..35d14181 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml @@ -12,7 +12,7 @@ - + @@ -41,7 +41,7 @@ - + diff --git a/DRAMSys/library/resources/configs/memspecs/rgrspec.xml b/DRAMSys/library/resources/configs/memspecs/rgrspec.xml index abb7b857..f1ddefd8 100644 --- a/DRAMSys/library/resources/configs/memspecs/rgrspec.xml +++ b/DRAMSys/library/resources/configs/memspecs/rgrspec.xml @@ -15,7 +15,7 @@ --> - + @@ -40,14 +40,12 @@ - - @@ -68,7 +66,6 @@ - diff --git a/DRAMSys/library/resources/simulations/rgrsim.xml b/DRAMSys/library/resources/simulations/rgrsim.xml index fa6201b4..d9546fe3 100644 --- a/DRAMSys/library/resources/simulations/rgrsim.xml +++ b/DRAMSys/library/resources/simulations/rgrsim.xml @@ -14,10 +14,11 @@ - rgr_postpone_test.stl + rgr_pullin_test.stl diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.cpp b/DRAMSys/library/src/controller/core/refresh/RGR.cpp index 71cdcec1..de92f6ce 100644 --- a/DRAMSys/library/src/controller/core/refresh/RGR.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RGR.cpp @@ -32,6 +32,8 @@ * Author: Éder F. Zulian */ +#include + #include "RGR.h" #include "../ControllerCore.h" #include "../TimingCalculation.h" @@ -42,14 +44,23 @@ using namespace std; RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore), timing(ctrlcore.config.memSpec.refreshTimings[ccore.getBanks()[0]]) { + fmb = ccore.config.ControllerCoreForceMaxRefBurst; + bwl = ccore.config.BankwiseLogic; + ri = ccore.config.getRowInc(); + auto nr = ccore.config.memSpec.NumberOfRows; + auto nar = ccore.config.getNumAR(); auto m = ccore.config.getRefMode(); + rpr = (nr / m) / nar; + assert(rpr > 0); tREFIx = timing.tREFI / m; - if (ccore.config.ControllerCoreEnableRefPostpone) - maxpostpone = ccore.config.ControllerCoreMaxPostponedARCmd * m; - if (ccore.config.ControllerCoreEnableRefPullIn) - maxpullin = ccore.config.ControllerCoreMaxPulledInARCmd * m; + trp = ccore.config.getTrpb(); + trcd = ccore.config.memSpec.tRCD; + postponeEnabled = ccore.config.ControllerCoreEnableRefPostpone; + pullInEnabled = ccore.config.ControllerCoreEnableRefPullIn; + maxpostpone = ccore.config.ControllerCoreMaxPostponedARCmd * m; + maxpullin = ccore.config.ControllerCoreMaxPulledInARCmd * m; #if 0 - if (ccore.config.BankwiseLogic) { + if (bwl) { for (Bank b : ccore.getBanks()) { auto nbs = ccore.config.memSpec.NumberOfBanks; nextPlannedRefreshs[b] = b.ID() * tREFIx / nbs; @@ -57,20 +68,20 @@ RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore), } #endif for (Bank b : ccore.getBanks()) { - nextPlannedRefreshs[b] = SC_ZERO_TIME; - arCmdCounter[b] = 0; - alignValue[b] = 0; + pulledin[b] = 0; + postponed[b] = 0; currentState[b] = ST_REFRESH; previousState[b] = ST_REFRESH; nextState[b] = ST_REFRESH; setUpDummy(rps[b], b); + nextPlannedRefreshs[b] = SC_ZERO_TIME; } if (ccore.config.BankwiseLogic) { for (Bank b : ccore.getBanks()) { - planNextRefresh(b, tREFIx); + planNextRefresh(b, tREFIx, false); } } else { - planNextRefresh(ccore.getBanks()[0], tREFIx); + planNextRefresh(ccore.getBanks()[0], tREFIx, false); } } @@ -80,35 +91,17 @@ RGR::~RGR() bool RGR::hasCollision(const ScheduledCommand __attribute__((unused)) &cmd) { -#if 0 - bool r = false; - nbs = ccore.config.memSpec.NumberOfBanks; - for (unsigned b = 0; b < nbs; b++) { - if (cmd.getStart() < currentRefresh[b] && cmd.getEnd() > currentRefresh[b]) - r = true; - if (cmd.getStart() < nextPlannedRefreshs[b] - && cmd.getEnd() > nextPlannedRefreshs[b]) - r = true; - } - return r; -#else return false; -#endif } -void RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t) +sc_time RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t) { sc_assert(!isInvalidated(p, t)); - auto nr = ccore.config.memSpec.NumberOfRows; - auto nar = ccore.config.getNumAR(); - auto ri = ccore.config.getRowInc(); - auto m = ccore.config.getRefMode(); - assert(((nr / m) / nar) > 0); Bank b = DramExtension::getExtension(p).getBank(); - bool bwl = ccore.config.BankwiseLogic; - bool o = ccore.state->rowBufferStates->rowBufferIsOpen(b); - bool ac = ccore.state->rowBufferStates->allRowBuffersAreClosed(); - bool pre = !!(bwl ? o : (!ac)); + bool openBank = ccore.state->rowBufferStates->rowBufferIsOpen(b); + bool allClosed = ccore.state->rowBufferStates->allRowBuffersAreClosed(); + bool pre = bwl ? openBank : !allClosed; + sc_time trfcx = SC_ZERO_TIME; if (!bwl) { for (Bank b : ccore.getBanks()) { @@ -119,22 +112,24 @@ void RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t) } if (pre) { - if (!bwl) { + trfcx += trp; + if (bwl) { + if (ccore.config.getRGRBank(b.ID())) { + ccore.scheduleRequest(Command::PreB, rps[b]); + } + } else { for (Bank b : ccore.getBanks()) { auto rgrb = ccore.config.getRGRBank(b.ID()); if (ccore.state->rowBufferStates->rowBufferIsOpen(b) && rgrb) { ccore.scheduleRequest(Command::PreB, rps[Bank(b)]); } } - } else { - if (ccore.config.getRGRBank(b.ID())) { - ccore.scheduleRequest(Command::PreB, rps[b]); - } } } - for (unsigned r = 0; r < ((nr / m) / nar); r += ri) { - if (!!bwl) { + for (unsigned r = 0; r < rpr; r += ri) { + trfcx += trcd + trp; + if (bwl) { if (ccore.config.getRGRBank(b.ID())) { ccore.scheduleRequest(Command::ActB, rps[b]); ccore.scheduleRequest(Command::PreB, rps[b]); @@ -150,28 +145,32 @@ void RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t) } } } + + return trfcx; } void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) { sc_time nrt; + sc_time trfcx; Bank b = DramExtension::getExtension(p).getBank(); - auto bwl = ccore.config.BankwiseLogic; bool preq = bwl ? ccore.hasPendingRequests(b) : ccore.hasPendingRequests(); - bool canPostpone = preq && (arCmdCounter[b] < maxpostpone); - bool canPullIn = !preq && (arCmdCounter[b] < maxpullin); - bool fmb = !!ccore.config.ControllerCoreForceMaxRefBurst; + bool postpone = postponeEnabled && preq && (postponed[b] < maxpostpone); + bool pullIn = pullInEnabled && !preq && (pulledin[b] < maxpullin); previousState[b] = currentState[b]; currentState[b] = nextState[b]; + bool align = false; + switch (currentState[b]) { case ST_REFRESH: - assert(arCmdCounter[b] == 0); - if (canPostpone) { + assert(pulledin[b] == 0 && postponed[b] == 0); + if (postpone) { + nrt = SC_ZERO_TIME; nextState[b] = ST_POSTPONE; - nrt = SC_ZERO_TIME; - } else if (canPullIn) { + } else if (pullIn) { + trfcx = doRefresh(p, t); + nrt = trfcx; nextState[b] = ST_PULLIN; - nrt = SC_ZERO_TIME; } else { doRefresh(p, t); nrt = tREFIx; @@ -179,70 +178,69 @@ void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) } break; case ST_PULLIN: - if (canPullIn) { - doRefresh(p, t); - arCmdCounter[b]++; + if (pullIn) { + trfcx = doRefresh(p, t); + pulledin[b]++; + nrt = trfcx; nextState[b] = ST_PULLIN; - nrt = SC_ZERO_TIME; } else { - alignValue[b] = arCmdCounter[b]; - nextState[b] = ST_ALIGN; nrt = SC_ZERO_TIME; + nextState[b] = ST_ALIGN; } break; case ST_SKIP: - arCmdCounter[b]--; - if (arCmdCounter[b] == 0) { - nextState[b] = ST_REFRESH; + if (pulledin[b] == 0) { nrt = SC_ZERO_TIME; + nextState[b] = ST_REFRESH; } else { - nextState[b] = ST_SKIP; + pulledin[b]--; nrt = tREFIx; + nextState[b] = ST_SKIP; } break; case ST_POSTPONE: - if ((arCmdCounter[b] == maxpostpone) || ((!preq) && !fmb)) { - if (arCmdCounter[b] < maxpostpone) { - arCmdCounter[b]++; - } - alignValue[b] = arCmdCounter[b]; - nextState[b] = ST_BURST; + postponed[b]++; + if ((postponed[b] > maxpostpone) || (!preq && !fmb)) { + // Burst triggered by inactivity or max postpone value reached. nrt = SC_ZERO_TIME; + nextState[b] = ST_BURST; } else { - arCmdCounter[b]++; - nextState[b] = ST_POSTPONE; nrt = tREFIx; + nextState[b] = ST_POSTPONE; } break; case ST_BURST: - arCmdCounter[b]--; doRefresh(p, t); - if (arCmdCounter[b] == 0) { + postponed[b]--; + if (postponed[b] == 0) { + nrt = SC_ZERO_TIME; nextState[b] = ST_ALIGN; - nrt = SC_ZERO_TIME; } else { - nextState[b] = ST_BURST; nrt = SC_ZERO_TIME; + nextState[b] = ST_BURST; } break; case ST_ALIGN: + nrt = tREFIx; + align = true; if (previousState[b] == ST_PULLIN) { - nrt = tREFIx; nextState[b] = ST_SKIP; } else { - nrt = tREFIx; nextState[b] = ST_REFRESH; } break; default: - SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop."); + SC_REPORT_FATAL(this->name(), "Invalid state in RGR flexible refresh FSM. Stop."); break; } - planNextRefresh(!bwl ? ccore.getBanks()[0] : b, nrt); + planNextRefresh(bwl ? b : ccore.getBanks()[0], nrt, align); } -void RGR::planNextRefresh(Bank b, sc_time t) +void RGR::planNextRefresh(Bank b, sc_time t, bool align) { + if (align) { + nextPlannedRefreshs[b] = trunc(nextPlannedRefreshs[b].to_double() / tREFIx.to_double()) * tREFIx; + } nextPlannedRefreshs[b] += t; ccore.controller.send(REFTrigger, nextPlannedRefreshs[b], rps[b]); } @@ -250,7 +248,7 @@ void RGR::planNextRefresh(Bank b, sc_time t) void RGR::reInitialize(Bank b, sc_time t) { nextPlannedRefreshs[b] = clkAlign(t, Alignment::DOWN); - planNextRefresh(b, tREFIx); + planNextRefresh(b, tREFIx, true); } bool RGR::isInvalidated(tlm::tlm_generic_payload &p, sc_time t) diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.h b/DRAMSys/library/src/controller/core/refresh/RGR.h index b4dac84e..96ad8cdb 100644 --- a/DRAMSys/library/src/controller/core/refresh/RGR.h +++ b/DRAMSys/library/src/controller/core/refresh/RGR.h @@ -43,27 +43,34 @@ class RGR : public IRefreshManager, public sc_module public: RGR(sc_module_name, ControllerCore &ctrlcore); virtual ~RGR(); - virtual bool hasCollision(const ScheduledCommand __attribute__(( - unused)) &command) override; + virtual bool hasCollision(const ScheduledCommand &cmd) override; virtual void scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) override; void reInitialize(Bank bank, sc_time time) override; bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) override; private: + bool fmb; + bool bwl; + unsigned int ri; + unsigned int rpr; + sc_time trp; + sc_time trcd; sc_time tREFIx; ControllerCore &ccore; RefreshTiming &timing; std::map rps; std::map nextPlannedRefreshs; std::map currentRefresh; - unsigned int maxpostpone = 0; - unsigned int maxpullin = 0; - std::map arCmdCounter; - std::map alignValue; + bool postponeEnabled; + bool pullInEnabled; + unsigned int maxpostpone; + unsigned int maxpullin; + std::map pulledin; + std::map postponed; std::map currentState; std::map previousState; std::map nextState; - void doRefresh(tlm::tlm_generic_payload &p, sc_time t); - void planNextRefresh(Bank b, sc_time t); + sc_time doRefresh(tlm::tlm_generic_payload &p, sc_time t); + void planNextRefresh(Bank b, sc_time t, bool align); void printDebugMessage(std::string message); }; #endif /* RGR_MANAGER_H_ */ diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp index ad16799a..73f944fe 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp @@ -231,7 +231,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload, } break; default: - SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop."); + SC_REPORT_FATAL(this->name(), "Invalid state in flexible refresh FSM. Stop."); break; } planNextRefresh(nextRefTiming); diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp index bd9e44f4..f917d2b8 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -217,7 +217,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, } break; default: - SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop."); + SC_REPORT_FATAL(this->name(), "Invalid state in bankwise flexible refresh FSM. Stop."); break; } diff --git a/DRAMSys/library/src/simulation/TraceSetup.cpp b/DRAMSys/library/src/simulation/TraceSetup.cpp index faaa37f8..c64eac3d 100644 --- a/DRAMSys/library/src/simulation/TraceSetup.cpp +++ b/DRAMSys/library/src/simulation/TraceSetup.cpp @@ -70,7 +70,7 @@ traceSetup::traceSetup(std::string uri, std::string name = device->GetText(); - int pos = name.rfind('.'); + size_t pos = name.rfind('.'); if (pos == std::string::npos) { throw std::runtime_error("Name of the trace file does not contain a valid extension."); }