diff --git a/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml index 5f2adc2e..61136a5c 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml @@ -9,10 +9,10 @@ - + - + @@ -40,7 +40,7 @@ - + diff --git a/DRAMSys/library/resources/configs/memspecs/rgrspec.xml b/DRAMSys/library/resources/configs/memspecs/rgrspec.xml index d3bc6990..abb7b857 100644 --- a/DRAMSys/library/resources/configs/memspecs/rgrspec.xml +++ b/DRAMSys/library/resources/configs/memspecs/rgrspec.xml @@ -1,9 +1,10 @@ - + + @@ -25,18 +26,18 @@ + + - - @@ -46,39 +47,30 @@ + + + + + + + - - - - - - - + + + + diff --git a/DRAMSys/library/src/controller/Command.cpp b/DRAMSys/library/src/controller/Command.cpp index 7b1b9d9f..4ced60b8 100644 --- a/DRAMSys/library/src/controller/Command.cpp +++ b/DRAMSys/library/src/controller/Command.cpp @@ -70,7 +70,7 @@ std::string commandToString(Command command) return "PRE_ALL"; break; case Command::AutoRefresh: - return "AUTO_REFRESH"; + return "REF"; break; case Command::PDNA: diff --git a/DRAMSys/library/src/controller/core/TimingCalculation.cpp b/DRAMSys/library/src/controller/core/TimingCalculation.cpp index 2c1f17cb..9fa99597 100644 --- a/DRAMSys/library/src/controller/core/TimingCalculation.cpp +++ b/DRAMSys/library/src/controller/core/TimingCalculation.cpp @@ -90,8 +90,12 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload) } else if (command == Command::PrechargeAll) { return config.tRP; } else if (command == Command::AutoRefresh) { - return getElementFromMap(config.refreshTimings, - DramExtension::getExtension(payload).getBank()).tRFC; + if (Configuration::getInstance().getRefMode() == 4) + return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC4; + else if (Configuration::getInstance().getRefMode() == 2) + return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC2; + else + return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC; } else if (command == Command::PDNAX || command == Command::PDNPX || command == Command::SREFX) { return config.clk; diff --git a/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp b/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp index 75049f56..c999ac23 100644 --- a/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp +++ b/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp @@ -277,12 +277,16 @@ void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *memspec) config.memSpec.tXSRDLL = clk * queryUIntParameter(timings, "XSDLL"); config.memSpec.tAL = clk * queryUIntParameter(timings, "AL"); config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC"); + config.memSpec.tRFC2 = clk * queryUIntParameter(timings, "RFC2"); + config.memSpec.tRFC4 = clk * queryUIntParameter(timings, "RFC4"); config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI"); config.memSpec.tDQSCK = clk * queryUIntParameter(timings, "DQSCK"); config.memSpec.refreshTimings.clear(); for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) { config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC, + config.memSpec.tRFC2, + config.memSpec.tRFC4, config.memSpec.tREFI); } diff --git a/DRAMSys/library/src/controller/core/configuration/MemSpec.h b/DRAMSys/library/src/controller/core/configuration/MemSpec.h index 24a0b852..7245e6d1 100644 --- a/DRAMSys/library/src/controller/core/configuration/MemSpec.h +++ b/DRAMSys/library/src/controller/core/configuration/MemSpec.h @@ -44,8 +44,11 @@ struct RefreshTiming { RefreshTiming() {} - RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tREFI(tREFI) {} + RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tRFC2(SC_ZERO_TIME), tRFC4(SC_ZERO_TIME), tREFI(tREFI) {} + RefreshTiming(sc_time tRFC, sc_time tRFC2, sc_time tRFC4, sc_time tREFI) : tRFC(tRFC), tRFC2(tRFC2), tRFC4(tRFC4), tREFI(tREFI) {} sc_time tRFC; + sc_time tRFC2; + sc_time tRFC4; sc_time tREFI; }; @@ -109,7 +112,9 @@ struct MemSpec { sc_time tAL; //additive delay (delayed execution in dram) sc_time tDQSCK; - sc_time tRFC; //min ref->act delay + sc_time tRFC; //min ref->act delay 1X mode + sc_time tRFC2; //min ref->act delay 2X mode + sc_time tRFC4; //min ref->act delay 4X mode sc_time tREFI; //auto refresh must be issued at an average periodic interval tREFI // Currents and Voltages: diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp index 14fc5a8c..4f654971 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp @@ -52,6 +52,7 @@ RefreshManager::RefreshManager(sc_module_name /*name*/, { auto m = controllerCore.config.getRefMode(); tREFIx = timing.tREFI / m; + tRFCx = m == 4 ? timing.tRFC4 : m == 2 ? timing.tRFC2 : timing.tRFC; if (controllerCore.config.ControllerCoreEnableRefPostpone) { maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd * m; } @@ -163,7 +164,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload doRefresh(payload, time); arCmdCounter++; nextState = ST_PULLIN; - nextRefTiming = timing.tRFC; + nextRefTiming = tRFCx; } else { alignValue = arCmdCounter; // Saving value to be used by ST_ALIGN nextState = ST_ALIGN; @@ -214,7 +215,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload nextRefTiming = SC_ZERO_TIME; } else { nextState = ST_BURST; - nextRefTiming = timing.tRFC; + nextRefTiming = tRFCx; } break; @@ -222,10 +223,10 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload // Align Refresh. Adjusting the timing so the next REF timing will be a in a time multiple of tREFIx if (previousState == ST_PULLIN) { - nextRefTiming = tREFIx - (timing.tRFC * (alignValue)); + nextRefTiming = tREFIx - (tRFCx * (alignValue)); nextState = ST_SKIP; } else { - nextRefTiming = tREFIx - (timing.tRFC * (alignValue - 1)); + nextRefTiming = tREFIx - (tRFCx * (alignValue - 1)); nextState = ST_REFRESH; } break; diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h index 12d891a2..8a678796 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h @@ -60,6 +60,7 @@ private: RefreshTiming &timing; sc_time nextPlannedRefresh; sc_time tREFIx; + sc_time tRFCx; std::map refreshPayloads; unsigned int maxpostpone = 0; unsigned int maxpullin = 0; diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp index 7337a436..93e9e81e 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -47,6 +47,7 @@ RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name, { auto m = controllerCore.config.getRefMode(); tREFIx = timing.tREFI / m; + tRFCx = m == 4 ? timing.tRFC4 : m == 2 ? timing.tRFC2 : timing.tRFC; if (controllerCore.config.ControllerCoreEnableRefPostpone) maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd * m; if (controllerCore.config.ControllerCoreEnableRefPullIn) @@ -147,7 +148,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, doRefresh(payload, time); arCmdCounter[bank]++; nextState[bank] = ST_PULLIN; - nextRefTiming = timing.tRFC; + nextRefTiming = tRFCx; } else { alignValue[bank] = arCmdCounter[bank]; // Saving value to be used by ST_ALIGN nextState[bank] = ST_ALIGN; @@ -206,7 +207,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, nextRefTiming = SC_ZERO_TIME; } else { nextState[bank] = ST_BURST; - nextRefTiming = timing.tRFC; + nextRefTiming = tRFCx; } break; @@ -215,10 +216,10 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, // a in a time multiple of tREFIx. if (previousState[bank] == ST_PULLIN) { - nextRefTiming = tREFIx - (timing.tRFC * (alignValue[bank])); + nextRefTiming = tREFIx - (tRFCx * (alignValue[bank])); nextState[bank] = ST_SKIP; } else { - nextRefTiming = tREFIx - (timing.tRFC * (alignValue[bank] - 1)); + nextRefTiming = tREFIx - (tRFCx * (alignValue[bank] - 1)); nextState[bank] = ST_REFRESH; } break; diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h index bc85ee97..26f56a7e 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h @@ -60,6 +60,7 @@ private: ControllerCore &controllerCore; RefreshTiming &timing; sc_time tREFIx; + sc_time tRFCx; std::map refreshPayloads; std::map nextPlannedRefreshs; unsigned int maxpostpone = 0; diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp index 841ba5a7..d3478dc9 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp @@ -62,8 +62,14 @@ void ActBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lcb.getCommand() == Command::AutoRefresh) { - cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC); - } else if (lcb.getCommand() == Command::PDNPX + auto m = Configuration::getInstance().getRefMode(); + if (m == 4) + cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC4); + else if (m == 2) + cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC2); + else + cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC); + } else if (lcb.getCommand() == Command::PDNPX || lcb.getCommand() == Command::PDNAX) { cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tXP); } else if (lcb.getCommand() == Command::SREFX) { diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp index da2b67cb..0fbdca29 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp @@ -71,8 +71,13 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand &command) const config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRFC); + auto m = Configuration::getInstance().getRefMode(); + if (m == 4) + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC4); + else if (m == 2) + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC2); + else + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC); } else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp index d4c22c36..eec65fb8 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp @@ -54,7 +54,13 @@ sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd, constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.clk; } else if (lastCmd == Command::AutoRefresh) { - constraint = config.memSpec.tRFC; + auto m = Configuration::getInstance().getRefMode(); + if (m == 4) + constraint = config.memSpec.tRFC4; + else if (m == 2) + constraint = config.memSpec.tRFC2; + else + constraint = config.memSpec.tRFC; } else if (lastCmd == Command::PDNPX || lastCmd == Command::PDNAX) { constraint = config.memSpec.tXP; } else if (lastCmd == Command::SREFX) { diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp index 12f743c9..e98ca7a7 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp @@ -70,10 +70,15 @@ const config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lastCommand.getCommand() == Command::AutoRefresh) { - command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRFC); - } else if (lastCommand.getCommand() == Command::PDNAX - || lastCommand.getCommand() == Command::PDNPX) { + auto m = Configuration::getInstance().getRefMode(); + if (m == 4) + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRFC4); + else if (m == 2) + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRFC2); + else + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRFC); + } else if (lastCommand.getCommand() == Command::PDNAX + || lastCommand.getCommand() == Command::PDNPX) { command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tXP); } else if (lastCommand.getCommand() == Command::SREFX) { diff --git a/DRAMSys/library/src/simulation/Dram.h b/DRAMSys/library/src/simulation/Dram.h index e81023a3..8d9f198c 100644 --- a/DRAMSys/library/src/simulation/Dram.h +++ b/DRAMSys/library/src/simulation/Dram.h @@ -151,7 +151,13 @@ struct Dram : sc_module { memTimingSpec.RC = Configuration::getInstance().memSpec.tRC / clk; memTimingSpec.RCD = Configuration::getInstance().memSpec.tRCD / clk; memTimingSpec.REFI = Configuration::getInstance().memSpec.tREFI / clk; - memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC / clk; + auto m = Configuration::getInstance().getRefMode(); + if (m == 4) + memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC4 / clk; + else if (m == 2) + memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC2 / clk; + else + memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC / clk; memTimingSpec.RL = Configuration::getInstance().memSpec.tRL / clk; memTimingSpec.RP = Configuration::getInstance().memSpec.tRP / clk; memTimingSpec.RRD = Configuration::getInstance().memSpec.tRRD_S / clk; diff --git a/DRAMSys/traceAnalyzer/scripts/metrics.py b/DRAMSys/traceAnalyzer/scripts/metrics.py index 64db6dd6..191f6654 100644 --- a/DRAMSys/traceAnalyzer/scripts/metrics.py +++ b/DRAMSys/traceAnalyzer/scripts/metrics.py @@ -131,7 +131,7 @@ def memory_utilisation_percent_old(connection): def refreshMissDecision(connection, calculatedMetrics): cursor = connection.cursor() - cursor.execute("""SELECT phases.ID,PhaseBegin,PhaseEnd,TBank FROM Phases INNER JOIN transactions on transactions.id = phases.transact WHERE PhaseName='AUTO_REFRESH' """) + cursor.execute("""SELECT phases.ID,PhaseBegin,PhaseEnd,TBank FROM Phases INNER JOIN transactions on transactions.id = phases.transact WHERE PhaseName IN ('REFA')' """) queryMinREQ = """SELECT id,min(PhaseBegin) FROM (SELECT transactions.id, PhaseBegin FROM transactions inner join ranges on ranges.id = transactions.range inner join phases on phases.transact = transactions.id where tthread != 0 and tbank = :bank and PhaseName = "REQ" and ranges.begin<:begin and ranges.end>:end)""" diff --git a/DRAMSys/traceAnalyzer/scripts/tests.py b/DRAMSys/traceAnalyzer/scripts/tests.py index 35d84f8b..a954693f 100755 --- a/DRAMSys/traceAnalyzer/scripts/tests.py +++ b/DRAMSys/traceAnalyzer/scripts/tests.py @@ -10,6 +10,7 @@ class DramConfig(object): memoryType = "" scheduler = "" bankwiseLogic = 0 + refMode = 1 clk = 0 unitOfTime = "" dataRate = 0 @@ -38,7 +39,9 @@ class DramConfig(object): tXSR = 0 # min delay to row access command after srefx tXSRDLL = 0 # min delay to row access command after srefx for dll commands tAL = 0 # additive delay (delayed execution in dram) - tRFC = 0 # min ref->act delay + tRFC = 0 # min ref->act delay 1X + tRFC2 = 0 # min ref->act delay 2X + tRFC4 = 0 # min ref->act delay 4X tREFI = 0 # time between REF commands def readConfigFromFiles(self, connection): @@ -52,6 +55,7 @@ class DramConfig(object): self.unitOfTime = clkWithUnit[1].lower() self.bankwiseLogic = mcconfig.getValue("BankwiseLogic") + self.refMode = mcconfig.getValue("ControllerCoreRefMode") self.scheduler = mcconfig.getValue("Scheduler") self.numberOfBanks = memspec.getIntValue("nbrOfBanks") @@ -111,6 +115,8 @@ class DramConfig(object): self.tXSRDLL = self.clk * memspec.getIntValue("XSDLL") self.tAL = self.clk * memspec.getIntValue("AL") self.tRFC = self.clk * memspec.getIntValue("RFC") + self.tRFC2 = self.clk * memspec.getIntValue("RFC2") + self.tRFC4 = self.clk * memspec.getIntValue("RFC4") self.tREFI = self.clk * memspec.getIntValue("REFI") elif (self. memoryType == "DDR3"): @@ -353,7 +359,12 @@ def timing_constraint(FirstPhase, SecondPhase): return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR + dramconfig.clk elif (FirstPhaseName == "REFA"): - return dramconfig.tRFC + if dramconfig.refMode == "4": + return dramconfig.tRFC4 + elif dramconfig.refMode == "2": + return dramconfig.tRFC2 + else: + return dramconfig.tRFC elif (FirstPhaseName in ["PDNA", "PDNP"]): # print("{0}".format(FirstPhaseName)) diff --git a/README.md b/README.md index 191d5207..4421e710 100644 --- a/README.md +++ b/README.md @@ -766,6 +766,10 @@ Below, the sub-configurations are listed and explained. - "0": normal operation (refreshes enabled) - ControllerCoreRefMode (unsigned int) - Refresh mode. 1: 1X, 2: 2X, 4: 4X. Refresh period is tREFI, tREFI/2, tREFI/4, respectively. Number of rows per refresh affected accordingly. + The default refresh mode is fixed 1X mode where Refresh commands should be issued with the normal rate, i.e., tREFI. The duration of each refresh command is the normal refresh cycle time tRFC. + In 2X mode Refresh commands are issued to the DRAM at the double frequency (tREFI/2). + In 4X mode Refresh commands are issued to the DRAM at the quadruple frequency (tREFI/4). + There is a tRFC value for each mode that comes from the memory specification. - *ControllerCoreForceMaxRefBurst* (boolean) - "1": always postpone, resulting in a ControllerCoreMaxPostponedARCmd burst - "0": normal operation