From 19673ce53a82efffffd2b7e4651f095b0b3694bd Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Fri, 13 Apr 2018 09:32:42 +0200 Subject: [PATCH 01/19] Power plot changed. --- DRAMSys/traceAnalyzer/scripts/plots.py | 69 ++++++++++++++++---------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/DRAMSys/traceAnalyzer/scripts/plots.py b/DRAMSys/traceAnalyzer/scripts/plots.py index 7576fd8a..185442d1 100755 --- a/DRAMSys/traceAnalyzer/scripts/plots.py +++ b/DRAMSys/traceAnalyzer/scripts/plots.py @@ -193,38 +193,57 @@ def memory_utilisation_window(connection, tracePath, steps): @plot def power_window(connection, tracePath, steps): + windowSize = getWindowSize(connection) + outputFile = "" cursor = connection.cursor() + cursor.execute(" SELECT * FROM Power") - result = cursor.fetchone() - if(result is not None): - time = [0] * (steps+1) - power = [0] * (steps+1) - time[0] = 0 - power[0] = 0 - #pow(10,9): seconds to nanoseconds conversion - time[1] = float(result[0])*pow(10,9) - power[1] = float(result[1]) - for i in range((steps-1)): + + power = [0] * (steps+1) + window = float(windowSize) / pow(10,12) + + for i in range(steps): + sum = 0.0 + counter = 0 + result = cursor.fetchone() + + while (result is not None): + sum += float(result[1]) + counter = counter + 1 + if(result[0] > window*i): + break result = cursor.fetchone() - time[i+2] = float(result[0])*pow(10,9) - power[i+2] = float(result[1]) - outputFileName, basename = createOutputFilename(tracePath, 'power', '', 'pdf') - outputFile = "{0}\n\t".format(outputFileName) + if(counter == 0): + break - import matplotlib.pyplot as plt - from matplotlib.backends.backend_pdf import PdfPages + sum = sum / counter + power[i] = sum + + import numpy as np + time = np.arange(0, windowSize*(steps+1)/1000/1000, windowSize/1000/1000) + + outputFileName, basename = createOutputFilename(tracePath, 'power', '', 'pdf') + outputFile = "{0}\n\t".format(outputFileName) + + import matplotlib.pyplot as plt + from matplotlib.backends.backend_pdf import PdfPages + + PowFigure = plt.figure(figsize=(10,5), dpi=300) + PowFigurePlot = PowFigure.add_subplot(111) + PowFigurePlot.set_xlabel('Time [us]') + PowFigurePlot.set_ylabel('Power [mW]') + PowFigurePlot.set_title('Power Consumption ' + str(basename)) + PowFigurePlot.grid(True) + PowFigurePlot.plot(time, power, linewidth=0.5) + + pdf = PdfPages(outputFileName) + pdf.savefig(PowFigure) + pdf.close() + PowFigurePlot.clear() + plt.close() - plt.plot(time, power) - plt.xlabel('Time [ns]') - plt.ylabel('Power [mW]') - plt.grid(True) - plt.title('Power Consumption ' + str(basename)) - pdf = PdfPages(outputFileName) - pdf.savefig() - pdf.close() - plt.close() return outputFile @plot From 805033d99b0c9542b93a8923ad28b06e8dbeb8ff Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Wed, 30 May 2018 11:02:36 +0200 Subject: [PATCH 02/19] Make static methods for instance handling private in derived classes. --- DRAMSys/library/src/common/jsonAddressDecoder.h | 3 +++ DRAMSys/library/src/common/xmlAddressdecoder.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.h b/DRAMSys/library/src/common/jsonAddressDecoder.h index 10180f21..e6838da2 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.h +++ b/DRAMSys/library/src/common/jsonAddressDecoder.h @@ -65,6 +65,9 @@ private: vector> m_vColumnBits; // This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit" + static AddressDecoder &getInstance(); + static void createInstance(Type t); + public: virtual void setConfiguration(std::string url); diff --git a/DRAMSys/library/src/common/xmlAddressdecoder.h b/DRAMSys/library/src/common/xmlAddressdecoder.h index 4178ca98..97cbd9eb 100644 --- a/DRAMSys/library/src/common/xmlAddressdecoder.h +++ b/DRAMSys/library/src/common/xmlAddressdecoder.h @@ -59,6 +59,9 @@ private: tinyxml2::XMLElement *addressmapping; + static AddressDecoder &getInstance(); + static void createInstance(Type t); + public: virtual DecodedAddress decodeAddress(sc_dt::uint64 addr); virtual sc_dt::uint64 encodeAddress(DecodedAddress n); From 534f75377076cbecb85db36a0240c41758d11f57 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 4 Jun 2018 15:06:12 +0200 Subject: [PATCH 03/19] Better way to make the static functions not accessible with the derived classes --- DRAMSys/library/src/common/jsonAddressDecoder.h | 9 +++------ DRAMSys/library/src/common/xmlAddressdecoder.h | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.h b/DRAMSys/library/src/common/jsonAddressDecoder.h index e6838da2..3ab157e1 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.h +++ b/DRAMSys/library/src/common/jsonAddressDecoder.h @@ -46,15 +46,13 @@ using std::pair; using std::map; class JSONAddressDecoder - : public AddressDecoder + : private AddressDecoder { // Friendship needed so that the AddressDecoder can access the // constructor of this class to create the object in CreateInstance. friend class AddressDecoder; private: - JSONAddressDecoder(); - vector> m_vXor; // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" // and "Second/Number of an address bit which corresponds to a row" @@ -65,10 +63,9 @@ private: vector> m_vColumnBits; // This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit" - static AddressDecoder &getInstance(); - static void createInstance(Type t); - public: + JSONAddressDecoder(); + virtual void setConfiguration(std::string url); virtual DecodedAddress decodeAddress(sc_dt::uint64 addr); diff --git a/DRAMSys/library/src/common/xmlAddressdecoder.h b/DRAMSys/library/src/common/xmlAddressdecoder.h index 97cbd9eb..063bc25e 100644 --- a/DRAMSys/library/src/common/xmlAddressdecoder.h +++ b/DRAMSys/library/src/common/xmlAddressdecoder.h @@ -45,24 +45,21 @@ #include "AddressDecoder.h" class xmlAddressDecoder - : public AddressDecoder + : private AddressDecoder { // Friendship needed so that the AddressDecoder can access the // constructor of this class to create the object in CreateInstance. friend class AddressDecoder; private: - xmlAddressDecoder(); - std::map masks; std::map shifts; tinyxml2::XMLElement *addressmapping; - static AddressDecoder &getInstance(); - static void createInstance(Type t); - public: + xmlAddressDecoder(); + virtual DecodedAddress decodeAddress(sc_dt::uint64 addr); virtual sc_dt::uint64 encodeAddress(DecodedAddress n); From 8f9751f30f797ed70b27e92b8526a793ebb1d319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Mon, 2 Jul 2018 07:50:28 +0200 Subject: [PATCH 04/19] Refresh modes 1X, 2X and 4X. --- .../resources/configs/mcconfigs/rgrmccfg.xml | 2 + .../core/configuration/Configuration.cpp | 27 ++++---- .../core/configuration/Configuration.h | 2 + .../src/controller/core/refresh/RGR.cpp | 68 +++++++++---------- .../library/src/controller/core/refresh/RGR.h | 1 + .../core/refresh/RefreshManager.cpp | 29 ++++---- .../controller/core/refresh/RefreshManager.h | 1 + .../core/refresh/RefreshManagerBankwise.cpp | 30 ++++---- .../core/refresh/RefreshManagerBankwise.h | 1 + README.md | 58 ++++++++-------- 10 files changed, 113 insertions(+), 106 deletions(-) diff --git a/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml index f6b02b27..5f2adc2e 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml @@ -9,6 +9,8 @@ + + diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp index 42f17b21..6c726065 100644 --- a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp @@ -153,8 +153,7 @@ void Configuration::setParameter(std::string name, std::string value) ". This parameter must be between 0 and 100.").c_str()); } else { SJFProbability = string2int(value); - } - else if (name == "RequestBufferSize") + } else if (name == "RequestBufferSize") RequestBufferSize = string2int(value); else if (name == "Capsize") Capsize = string2int(value); @@ -202,7 +201,12 @@ void Configuration::setParameter(std::string name, std::string value) RowGranularRef = string2bool(value); else if (name == "ControllerCoreRowGranularRefRowInc")RowInc = string2int( value); - else if (name == "ControllerCoreRowGranularRefNumAR")NumAR = string2int(value); + else if (name == "ControllerCoreRefMode") { + RefMode = string2int(value); + if (RefMode != 1 && RefMode != 2 && RefMode != 4) + SC_REPORT_FATAL("Configuration", (name + " invalid value.").c_str()); + } + else if (name == "ControllerCoreRowGranularRefNumAR")NumAR = string2int(value); else if (name == "ControllerCoreRowGranularRefB0")RGRB0 = string2bool(value); else if (name == "ControllerCoreRowGranularRefB1")RGRB1 = string2bool(value); else if (name == "ControllerCoreRowGranularRefB2")RGRB2 = string2bool(value); @@ -235,20 +239,8 @@ void Configuration::setParameter(std::string name, std::string value) ControllerCoreForceMaxRefBurst = string2bool(value); else if (name == "ControllerCoreEnableRefPostpone") { ControllerCoreEnableRefPostpone = string2bool(value); - // Refresh postpone feature available for DDR3 only in the current - // version of DRAMsys. - if (ControllerCoreEnableRefPostpone && memSpec.MemoryType != "DDR3") { - SC_REPORT_FATAL("Configuration", - (name + " requires memory type DDR3.").c_str()); - } } else if (name == "ControllerCoreEnableRefPullIn") { ControllerCoreEnableRefPullIn = string2bool(value); - // Refresh pull-in feature available for DDR3 only in the current - // version of DRAMsys. - if (ControllerCoreEnableRefPullIn && memSpec.MemoryType != "DDR3") { - SC_REPORT_FATAL("Configuration", - (name + " requires memory type DDR3.").c_str()); - } } else if (name == "ControllerCoreMaxPostponedARCmd") ControllerCoreMaxPostponedARCmd = string2int(value); else if (name == "ControllerCoreMaxPulledInARCmd") @@ -423,6 +415,11 @@ unsigned int Configuration::getRowInc(void) return RowInc; } +unsigned int Configuration::getRefMode(void) +{ + return RefMode; +} + // Changes the number of bytes depeding on the ECC Controller. This function is needed for modules which get data directly or indirectly from the ECC Controller unsigned int Configuration::adjustNumBytesAfterECC(unsigned nBytes) { diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.h b/DRAMSys/library/src/controller/core/configuration/Configuration.h index 99c9cb9e..28de22c7 100644 --- a/DRAMSys/library/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/library/src/controller/core/configuration/Configuration.h @@ -116,10 +116,12 @@ struct Configuration { bool RGRB14 = true; bool RGRB15 = true; unsigned int NumAR = 8192; + unsigned int RefMode = 1; unsigned int RowInc = 1; bool getRGRBank(unsigned int); unsigned int getNumAR(void); unsigned int getRowInc(void); + unsigned int getRefMode(void); bool ControllerCoreForceMaxRefBurst = false; bool ControllerCoreEnableRefPostpone = false; bool ControllerCoreEnableRefPullIn = false; diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.cpp b/DRAMSys/library/src/controller/core/refresh/RGR.cpp index 3be8eeee..3def058c 100644 --- a/DRAMSys/library/src/controller/core/refresh/RGR.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RGR.cpp @@ -42,18 +42,17 @@ using namespace std; RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore), timing(ctrlcore.config.memSpec.refreshTimings[ccore.getBanks()[0]]) { - if (ccore.config.ControllerCoreEnableRefPostpone) { - maxpostpone = ccore.config.ControllerCoreMaxPostponedARCmd; - } - if (ccore.config.ControllerCoreEnableRefPullIn) { - maxpullin = ccore.config.ControllerCoreMaxPulledInARCmd; - } + auto m = ccore.config.getRefMode(); + tREFIx = timing.tREFI / m; + if (ccore.config.ControllerCoreEnableRefPostpone) + maxpostpone = ccore.config.ControllerCoreMaxPostponedARCmd * m; + if (ccore.config.ControllerCoreEnableRefPullIn) + maxpullin = ccore.config.ControllerCoreMaxPulledInARCmd * m; #if 0 - if (Configuration::getInstance().BankwiseLogic) { + if (ccore.config.BankwiseLogic) { for (Bank b : ccore.getBanks()) { - sc_time refi = Configuration::getInstance().memSpec.refreshTimings[b].tREFI; - nextPlannedRefreshs[b] = b.ID() * refi / - Configuration::getInstance().memSpec.NumberOfBanks; + auto nbs = ccore.config.memSpec.NumberOfBanks; + nextPlannedRefreshs[b] = b.ID() * tREFIx / nbs; } } #endif @@ -66,12 +65,12 @@ RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore), nextState[b] = ST_REFRESH; setUpDummy(rps[b], b); } - if (Configuration::getInstance().BankwiseLogic) { + if (ccore.config.BankwiseLogic) { for (Bank b : ccore.getBanks()) { - planNextRefresh(b, timing.tREFI); + planNextRefresh(b, tREFIx); } } else { - planNextRefresh(ccore.getBanks()[0], timing.tREFI); + planNextRefresh(ccore.getBanks()[0], tREFIx); } } @@ -83,16 +82,13 @@ bool RGR::hasCollision(const ScheduledCommand __attribute__((unused)) &cmd) { #if 0 bool r = false; - nbs = Configuration::getInstance().memSpec.NumberOfBanks; + 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]) + if (cmd.getStart() < nextPlannedRefreshs[b] && cmd.getEnd() > nextPlannedRefreshs[b]) r = true; } - return r; #else return false; @@ -102,12 +98,13 @@ bool RGR::hasCollision(const ScheduledCommand __attribute__((unused)) &cmd) void RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t) { sc_assert(!isInvalidated(p, t)); - auto nr = Configuration::getInstance().memSpec.NumberOfRows; - auto nar = Configuration::getInstance().getNumAR(); - auto ri = Configuration::getInstance().getRowInc(); - assert((nr / nar) > 0); + 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 = Configuration::getInstance().BankwiseLogic; + bool bwl = ccore.config.BankwiseLogic; bool o = ccore.state->rowBufferStates->rowBufferIsOpen(b); bool ac = ccore.state->rowBufferStates->allRowBuffersAreClosed(); bool pre = !!(bwl ? o : (!ac)); @@ -123,28 +120,28 @@ void RGR::doRefresh(tlm::tlm_generic_payload &p, sc_time t) if (pre) { if (!bwl) { for (Bank b : ccore.getBanks()) { - auto rgrb = Configuration::getInstance().getRGRBank(b.ID()); + auto rgrb = ccore.config.getRGRBank(b.ID()); if (ccore.state->rowBufferStates->rowBufferIsOpen(b) && rgrb) { ccore.scheduleRequest(Command::PreB, rps[Bank(b)]); } } } else { - if (Configuration::getInstance().getRGRBank(b.ID())) { + if (ccore.config.getRGRBank(b.ID())) { ccore.scheduleRequest(Command::PreB, rps[b]); } } } - for (unsigned r = 0; r < (nr / nar); r += ri) { + for (unsigned r = 0; r < ((nr / m) / nar); r += ri) { if (!!bwl) { - if (Configuration::getInstance().getRGRBank(b.ID())) { + if (ccore.config.getRGRBank(b.ID())) { ccore.scheduleRequest(Command::ActB, rps[b]); ccore.scheduleRequest(Command::PreB, rps[b]); } DramExtension::getExtension(p).incrementRow(); } else { for (Bank b : ccore.getBanks()) { - if (Configuration::getInstance().getRGRBank(b.ID())) { + if (ccore.config.getRGRBank(b.ID())) { ccore.scheduleRequest(Command::ActB, rps[b]); ccore.scheduleRequest(Command::PreB, rps[b]); } @@ -158,7 +155,7 @@ void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) { sc_time nrt; Bank b = DramExtension::getExtension(p).getBank(); - auto bwl = Configuration::getInstance().BankwiseLogic; + 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); @@ -176,7 +173,7 @@ void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) nrt = SC_ZERO_TIME; } else { doRefresh(p, t); - nrt = timing.tREFI; + nrt = tREFIx; nextState[b] = ST_REFRESH; } break; @@ -199,7 +196,7 @@ void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) nrt = SC_ZERO_TIME; } else { nextState[b] = ST_SKIP; - nrt = timing.tREFI; + nrt = tREFIx; } break; case ST_POSTPONE: @@ -213,7 +210,7 @@ void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) } else { arCmdCounter[b]++; nextState[b] = ST_POSTPONE; - nrt = timing.tREFI; + nrt = tREFIx; } break; case ST_BURST: @@ -229,10 +226,10 @@ void RGR::scheduleRefresh(tlm::tlm_generic_payload &p, sc_time t) break; case ST_ALIGN: if (previousState[b] == ST_PULLIN) { - nrt = timing.tREFI; + nrt = tREFIx; nextState[b] = ST_SKIP; } else { - nrt = timing.tREFI; + nrt = tREFIx; nextState[b] = ST_REFRESH; } break; @@ -252,7 +249,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, timing.tREFI); + planNextRefresh(b, tREFIx); } bool RGR::isInvalidated(tlm::tlm_generic_payload &p, sc_time t) @@ -264,3 +261,4 @@ void RGR::printDebugMessage(std::string msg) { DebugManager::getInstance().printDebugMessage(this->name(), msg); } + diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.h b/DRAMSys/library/src/controller/core/refresh/RGR.h index 3cf31b10..212a0a63 100644 --- a/DRAMSys/library/src/controller/core/refresh/RGR.h +++ b/DRAMSys/library/src/controller/core/refresh/RGR.h @@ -49,6 +49,7 @@ public: void reInitialize(Bank bank, sc_time time) override; bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) override; private: + sc_time tREFIx; ControllerCore &ccore; RefreshTiming &timing; std::map rps; diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp index 78688699..4bbef8e9 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp @@ -50,16 +50,18 @@ RefreshManager::RefreshManager(sc_module_name /*name*/, timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME) { + auto m = controllerCore.config.getRefMode(); + tREFIx = timing.tREFI / m; if (controllerCore.config.ControllerCoreEnableRefPostpone) { - maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd; + maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd * m; } if (controllerCore.config.ControllerCoreEnableRefPullIn) { - maxpullin = controllerCore.config.ControllerCoreMaxPulledInARCmd; + maxpullin = controllerCore.config.ControllerCoreMaxPulledInARCmd * m; } for (Bank bank : controller.getBanks()) { setUpDummy(refreshPayloads[bank], bank); } - planNextRefresh(timing.tREFI); + planNextRefresh(tREFIx); } RefreshManager::~RefreshManager() @@ -138,9 +140,8 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload switch (currentState) { case ST_REFRESH: // Regular Refresh. It's possible to migrate from this to the flexible refresh states - - assert(arCmdCounter == - 0); // The arCmdCounter should always be equal to zero here + // The arCmdCounter should always be equal to zero here + assert(arCmdCounter == 0); if (canPostpone) { nextState = ST_POSTPONE; @@ -150,7 +151,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload nextRefTiming = SC_ZERO_TIME; // Attempt to burst pull-in } else { doRefresh(payload, time); - nextRefTiming = timing.tREFI; + nextRefTiming = tREFIx; nextState = ST_REFRESH; } break; @@ -179,7 +180,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload nextRefTiming = SC_ZERO_TIME; } else { nextState = ST_SKIP; - nextRefTiming = timing.tREFI; + nextRefTiming = tREFIx; } break; @@ -199,7 +200,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload } else { arCmdCounter++; nextState = ST_POSTPONE; - nextRefTiming = timing.tREFI; + nextRefTiming = tREFIx; } break; @@ -208,7 +209,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload arCmdCounter--; doRefresh(payload, time); - if (arCmdCounter == 0) { // All bursts issued, next state will align to tREFI + if (arCmdCounter == 0) { // All bursts issued, next state will align to tREFIx nextState = ST_ALIGN; nextRefTiming = SC_ZERO_TIME; } else { @@ -218,13 +219,13 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload break; case ST_ALIGN: - // Align Refresh. Adjusting the timing so the next REF timing will be a in a time multiple of tREFI + // Align Refresh. Adjusting the timing so the next REF timing will be a in a time multiple of tREFIx if (previousState == ST_PULLIN) { - nextRefTiming = timing.tREFI - (timing.tRFC * (alignValue)); + nextRefTiming = tREFIx - (timing.tRFC * (alignValue)); nextState = ST_SKIP; } else { - nextRefTiming = timing.tREFI - (timing.tRFC * (alignValue - 1)); + nextRefTiming = tREFIx - (timing.tRFC * (alignValue - 1)); nextState = ST_REFRESH; } break; @@ -247,7 +248,7 @@ void RefreshManager::planNextRefresh(sc_time nextRefTiming) void RefreshManager::reInitialize(Bank /*bank*/, sc_time time) { nextPlannedRefresh = clkAlign(time, Alignment::DOWN); - planNextRefresh(timing.tREFI); + planNextRefresh(tREFIx); } bool RefreshManager::isInvalidated(tlm::tlm_generic_payload &payload diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h index 2ec5792d..858d50b6 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h @@ -59,6 +59,7 @@ private: ControllerCore &controllerCore; RefreshTiming &timing; sc_time nextPlannedRefresh; + sc_time tREFIx; 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 76e69453..9e7bdd3f 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -45,12 +45,12 @@ RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name, ControllerCore &controller) : controllerCore(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]) { - if (controllerCore.config.ControllerCoreEnableRefPostpone) { - maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd; - } - if (controllerCore.config.ControllerCoreEnableRefPullIn) { - maxpullin = controllerCore.config.ControllerCoreMaxPulledInARCmd; - } + auto m = controllerCore.config.getRefMode(); + tREFIx = timing.tREFI / m; + if (controllerCore.config.ControllerCoreEnableRefPostpone) + maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd * m; + if (controllerCore.config.ControllerCoreEnableRefPullIn) + maxpullin = controllerCore.config.ControllerCoreMaxPulledInARCmd * m; for (Bank bank : controller.getBanks()) { nextPlannedRefreshs[bank] = SC_ZERO_TIME; arCmdCounter[bank] = 0; @@ -59,7 +59,7 @@ RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name, previousState[bank] = ST_REFRESH; nextState[bank] = ST_REFRESH; setUpDummy(refreshPayloads[bank], bank); - planNextRefresh(bank, timing.tREFI); + planNextRefresh(bank, tREFIx); } } @@ -134,7 +134,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, nextRefTiming = SC_ZERO_TIME; // Attempt to burst pull-in } else { doRefresh(payload, time); - nextRefTiming = timing.tREFI; + nextRefTiming = tREFIx; nextState[bank] = ST_REFRESH; } break; @@ -165,7 +165,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, nextRefTiming = SC_ZERO_TIME; } else { nextState[bank] = ST_SKIP; - nextRefTiming = timing.tREFI; + nextRefTiming = tREFIx; } break; @@ -190,7 +190,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, } else { arCmdCounter[bank]++; nextState[bank] = ST_POSTPONE; - nextRefTiming = timing.tREFI; + nextRefTiming = tREFIx; } break; @@ -201,7 +201,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, arCmdCounter[bank]--; doRefresh(payload, time); if (arCmdCounter[bank] == 0) { - // All bursts issued, next state will align to tREFI + // All bursts issued, next state will align to tREFIx nextState[bank] = ST_ALIGN; nextRefTiming = SC_ZERO_TIME; } else { @@ -212,13 +212,13 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, case ST_ALIGN: // Align Refresh. Adjusting the timing so the next REF timing will be - // a in a time multiple of tREFI. + // a in a time multiple of tREFIx. if (previousState[bank] == ST_PULLIN) { - nextRefTiming = timing.tREFI - (timing.tRFC * (alignValue[bank])); + nextRefTiming = tREFIx - (timing.tRFC * (alignValue[bank])); nextState[bank] = ST_SKIP; } else { - nextRefTiming = timing.tREFI - (timing.tRFC * (alignValue[bank] - 1)); + nextRefTiming = tREFIx - (timing.tRFC * (alignValue[bank] - 1)); nextState[bank] = ST_REFRESH; } break; @@ -241,7 +241,7 @@ void RefreshManagerBankwise::planNextRefresh(Bank bank, sc_time nextRefTiming) void RefreshManagerBankwise::reInitialize(Bank bank, sc_time time) { nextPlannedRefreshs[bank] = clkAlign(time, Alignment::DOWN); - planNextRefresh(bank, timing.tREFI); + planNextRefresh(bank, tREFIx); } bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload &payload, diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h index b5c2fc80..b7be78e4 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h @@ -59,6 +59,7 @@ public: private: ControllerCore &controllerCore; RefreshTiming &timing; + sc_time tREFIx; std::map refreshPayloads; std::map nextPlannedRefreshs; unsigned int maxpostpone = 0; diff --git a/README.md b/README.md index 73078ec6..ea30a2b2 100644 --- a/README.md +++ b/README.md @@ -689,6 +689,8 @@ Below, the sub-configurations are listed and explained. + + @@ -762,6 +764,8 @@ Below, the sub-configurations are listed and explained. - *ControllerCoreDisableRefresh* (boolean) - "1": disables refreshes - "0": normal operation (refreshes enabled) + - ControllerCoreRefMode (unsigned int) + - Refresh mode. 1: 1X, 2: 2X, 4: 4X - *ControllerCoreForceMaxRefBurst* (boolean) - "1": always postpone, resulting in a ControllerCoreMaxPostponedARCmd burst - "0": normal operation @@ -772,75 +776,75 @@ Below, the sub-configurations are listed and explained. - "1": enables the pull-in refresh feature - "0": normal operation - *ControllerCoreMaxPostponedARCmd* (unsigned int) - - Max AR commands to be postponed. + - Max AR commands to be postponed. Refresh mode affects this config (multiplier). - *ControllerCoreMaxPulledInARCmd* (unsigned int) - - Max AR commands to be pulled-in. - - *ControllerCoreRowGranularRef* (boolean) + - Max AR commands to be pulled-in. Refresh mode affects this config (multiplier). + - *ControllerCoreRowGranularRef* (boolean) - "1": enables row granular refresh feature (RGR) - "0": normal operation - - *ControllerCoreRowGranularRefNumAR* (unsigned int) + - *ControllerCoreRowGranularRefNumAR* (unsigned int) - Number of AR commands to to be issued in a refresh period tREFI - - *ControllerCoreRowGranularRefRowInc* (unsigned int) + - *ControllerCoreRowGranularRefRowInc* (unsigned int) - Row increment for each AR command (selective refresh) - - *ControllerCoreRowGranularRefB0* (boolean) + - *ControllerCoreRowGranularRefB0* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB1* (boolean) + - *ControllerCoreRowGranularRefB1* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB2* (boolean) + - *ControllerCoreRowGranularRefB2* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB3* (boolean) + - *ControllerCoreRowGranularRefB3* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB4* (boolean) + - *ControllerCoreRowGranularRefB4* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB5* (boolean) + - *ControllerCoreRowGranularRefB5* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB6* (boolean) + - *ControllerCoreRowGranularRefB6* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB7* (boolean) + - *ControllerCoreRowGranularRefB7* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB8* (boolean) + - *ControllerCoreRowGranularRefB8* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB9* (boolean) + - *ControllerCoreRowGranularRefB9* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB10* (boolean) + - *ControllerCoreRowGranularRefB10* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB11* (boolean) + - *ControllerCoreRowGranularRefB11* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB12* (boolean) + - *ControllerCoreRowGranularRefB12* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB13* (boolean) + - *ControllerCoreRowGranularRefB13* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB14* (boolean) + - *ControllerCoreRowGranularRefB14* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefB15* (boolean) + - *ControllerCoreRowGranularRefB15* (boolean) - "1": RGR this bank - "0": skip this bank - - *ControllerCoreRowGranularRefRASBInClkCycles* (unsigned int) + - *ControllerCoreRowGranularRefRASBInClkCycles* (unsigned int) - Timing can be changed to explore optimum row granular refresh (ORGR) - - *ControllerCoreRowGranularRefRRDB_LInClkCycles* (unsigned int) + - *ControllerCoreRowGranularRefRRDB_LInClkCycles* (unsigned int) - Timing can be changed to explore optimum row granular refresh (ORGR) - - *ControllerCoreRowGranularRefRRDB_SInClkCycles* (unsigned int) + - *ControllerCoreRowGranularRefRRDB_SInClkCycles* (unsigned int) - Timing can be changed to explore optimum row granular refresh (ORGR) - - *ControllerCoreRowGranularRefRPBInClkCycles* (unsigned int) + - *ControllerCoreRowGranularRefRPBInClkCycles* (unsigned int) - Timing can be changed to explore optimum row granular refresh (ORGR) - - *ControllerCoreRowGranularRefRCBInClkCycles* (unsigned int) + - *ControllerCoreRowGranularRefRCBInClkCycles* (unsigned int) - Timing can be changed to explore optimum row granular refresh (ORGR) - - *ControllerCoreRowGranularRefFAWBInClkCycles* (unsigned int) + - *ControllerCoreRowGranularRefFAWBInClkCycles* (unsigned int) - Timing can be changed to explore optimum row granular refresh (ORGR) - **Flexible Refresh** From 81914bc25f2aedfb4c01e411631a6f92e0dd8628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Mon, 2 Jul 2018 07:58:03 +0200 Subject: [PATCH 05/19] Improvement --- DRAMSys/library/resources/resources.pri | 1 + 1 file changed, 1 insertion(+) diff --git a/DRAMSys/library/resources/resources.pri b/DRAMSys/library/resources/resources.pri index 81a9c654..aed0437f 100644 --- a/DRAMSys/library/resources/resources.pri +++ b/DRAMSys/library/resources/resources.pri @@ -130,6 +130,7 @@ OTHER_FILES += resources/traces/ddr3_postpone_ref_test_1.stl OTHER_FILES += resources/traces/ddr3_postpone_ref_test_2.stl OTHER_FILES += resources/traces/ddr3_postpone_ref_test_3.stl OTHER_FILES += resources/traces/ip*.stl +OTHER_FILES += resources/traces/rgr*.stl # Memory Controller Configs OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml From 6b8a123675387c5034efe1310ada0ef0a3162ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Mon, 2 Jul 2018 07:59:22 +0200 Subject: [PATCH 06/19] coding style --- .../controller/core/configuration/Configuration.cpp | 13 +++++++------ DRAMSys/library/src/controller/core/refresh/RGR.cpp | 7 ++++--- DRAMSys/library/src/controller/core/refresh/RGR.h | 2 +- .../src/controller/core/refresh/RefreshManager.cpp | 4 ++-- .../src/controller/core/refresh/RefreshManager.h | 2 +- .../core/refresh/RefreshManagerBankwise.cpp | 2 +- .../core/refresh/RefreshManagerBankwise.h | 2 +- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp index 6c726065..d95652b0 100644 --- a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp @@ -153,7 +153,8 @@ void Configuration::setParameter(std::string name, std::string value) ". This parameter must be between 0 and 100.").c_str()); } else { SJFProbability = string2int(value); - } else if (name == "RequestBufferSize") + } + else if (name == "RequestBufferSize") RequestBufferSize = string2int(value); else if (name == "Capsize") Capsize = string2int(value); @@ -202,11 +203,11 @@ void Configuration::setParameter(std::string name, std::string value) else if (name == "ControllerCoreRowGranularRefRowInc")RowInc = string2int( value); else if (name == "ControllerCoreRefMode") { - RefMode = string2int(value); - if (RefMode != 1 && RefMode != 2 && RefMode != 4) - SC_REPORT_FATAL("Configuration", (name + " invalid value.").c_str()); - } - else if (name == "ControllerCoreRowGranularRefNumAR")NumAR = string2int(value); + RefMode = string2int(value); + if (RefMode != 1 && RefMode != 2 && RefMode != 4) + SC_REPORT_FATAL("Configuration", (name + " invalid value.").c_str()); + } else if (name == "ControllerCoreRowGranularRefNumAR")NumAR = string2int( + value); else if (name == "ControllerCoreRowGranularRefB0")RGRB0 = string2bool(value); else if (name == "ControllerCoreRowGranularRefB1")RGRB1 = string2bool(value); else if (name == "ControllerCoreRowGranularRefB2")RGRB2 = string2bool(value); diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.cpp b/DRAMSys/library/src/controller/core/refresh/RGR.cpp index 3def058c..71cdcec1 100644 --- a/DRAMSys/library/src/controller/core/refresh/RGR.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RGR.cpp @@ -43,7 +43,7 @@ RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore), timing(ctrlcore.config.memSpec.refreshTimings[ccore.getBanks()[0]]) { auto m = ccore.config.getRefMode(); - tREFIx = timing.tREFI / m; + tREFIx = timing.tREFI / m; if (ccore.config.ControllerCoreEnableRefPostpone) maxpostpone = ccore.config.ControllerCoreMaxPostponedARCmd * m; if (ccore.config.ControllerCoreEnableRefPullIn) @@ -51,7 +51,7 @@ RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore), #if 0 if (ccore.config.BankwiseLogic) { for (Bank b : ccore.getBanks()) { - auto nbs = ccore.config.memSpec.NumberOfBanks; + auto nbs = ccore.config.memSpec.NumberOfBanks; nextPlannedRefreshs[b] = b.ID() * tREFIx / nbs; } } @@ -86,7 +86,8 @@ bool RGR::hasCollision(const ScheduledCommand __attribute__((unused)) &cmd) 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]) + if (cmd.getStart() < nextPlannedRefreshs[b] + && cmd.getEnd() > nextPlannedRefreshs[b]) r = true; } return r; diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.h b/DRAMSys/library/src/controller/core/refresh/RGR.h index 212a0a63..b4dac84e 100644 --- a/DRAMSys/library/src/controller/core/refresh/RGR.h +++ b/DRAMSys/library/src/controller/core/refresh/RGR.h @@ -49,7 +49,7 @@ public: void reInitialize(Bank bank, sc_time time) override; bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) override; private: - sc_time tREFIx; + sc_time tREFIx; ControllerCore &ccore; RefreshTiming &timing; std::map rps; diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp index 4bbef8e9..14fc5a8c 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp @@ -51,7 +51,7 @@ RefreshManager::RefreshManager(sc_module_name /*name*/, nextPlannedRefresh(SC_ZERO_TIME) { auto m = controllerCore.config.getRefMode(); - tREFIx = timing.tREFI / m; + tREFIx = timing.tREFI / m; if (controllerCore.config.ControllerCoreEnableRefPostpone) { maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd * m; } @@ -140,7 +140,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload switch (currentState) { case ST_REFRESH: // Regular Refresh. It's possible to migrate from this to the flexible refresh states - // The arCmdCounter should always be equal to zero here + // The arCmdCounter should always be equal to zero here assert(arCmdCounter == 0); if (canPostpone) { diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h index 858d50b6..12d891a2 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h @@ -59,7 +59,7 @@ private: ControllerCore &controllerCore; RefreshTiming &timing; sc_time nextPlannedRefresh; - sc_time tREFIx; + sc_time tREFIx; 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 9e7bdd3f..7337a436 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -46,7 +46,7 @@ RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name, timing(controller.config.memSpec.refreshTimings[Bank(0)]) { auto m = controllerCore.config.getRefMode(); - tREFIx = timing.tREFI / m; + tREFIx = timing.tREFI / m; if (controllerCore.config.ControllerCoreEnableRefPostpone) maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd * m; if (controllerCore.config.ControllerCoreEnableRefPullIn) diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h index b7be78e4..bc85ee97 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h @@ -59,7 +59,7 @@ public: private: ControllerCore &controllerCore; RefreshTiming &timing; - sc_time tREFIx; + sc_time tREFIx; std::map refreshPayloads; std::map nextPlannedRefreshs; unsigned int maxpostpone = 0; From 88f604b7bff3d7e327ea72d38010cf82204298db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Mon, 2 Jul 2018 12:11:14 +0200 Subject: [PATCH 07/19] Doc improved --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index ea30a2b2..6c51e900 100644 --- a/README.md +++ b/README.md @@ -678,24 +678,24 @@ Below, the sub-configurations are listed and explained. ``` xml - - - - - - - - + + + + + + + + - - - - - - + + + + + + - + @@ -712,16 +712,16 @@ Below, the sub-configurations are listed and explained. - + - + - + @@ -765,7 +765,7 @@ Below, the sub-configurations are listed and explained. - "1": disables refreshes - "0": normal operation (refreshes enabled) - ControllerCoreRefMode (unsigned int) - - Refresh mode. 1: 1X, 2: 2X, 4: 4X + - Refresh mode. 1: 1X, 2: 2X, 4: 4X. Refresh period is tREFI, tREFI/2, tREFI/4, respectively. Number of rows per refresh affected accordingly. - *ControllerCoreForceMaxRefBurst* (boolean) - "1": always postpone, resulting in a ControllerCoreMaxPostponedARCmd burst - "0": normal operation From 00e57139f0297bdcb2bd6e85a0199b9c8d820a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Mon, 2 Jul 2018 12:15:56 +0200 Subject: [PATCH 08/19] indentation --- README.md | 104 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 6c51e900..191d5207 100644 --- a/README.md +++ b/README.md @@ -616,7 +616,7 @@ Below, the sub-configurations are listed and explained. - Key "Name": Name of the trace file which was used by ConGen - All items of the array "Solutions" but the first one: Alternative solution with same result. - Key "costs": Number of row misses which this configuration produces while playing the trace. - + Used data: - First item of array "Solution": - "XOR": Array of row and bank bits which are connected with an xor. Order of the bit: bank1, bank2, ..., row1, row2, ... @@ -674,58 +674,58 @@ Below, the sub-configurations are listed and explained. - **Memory Controller Configuration** - An example follows. + An example follows. ``` xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ``` - *BankwiseLogic* (boolean) @@ -847,6 +847,7 @@ Below, the sub-configurations are listed and explained. - *ControllerCoreRowGranularRefFAWBInClkCycles* (unsigned int) - Timing can be changed to explore optimum row granular refresh (ORGR) + - **Flexible Refresh** The feature can be used together with regular refresh and also with row @@ -906,6 +907,7 @@ A description of the content each directory follows. - **simulations**: main configuration files. - **traces**: pre-recorded trace files that may be used as stimuli in simulations. + #### Log Collector Script Users can profit of running multiple simulations automatically with From 3bcd0335e111c407294342bf90d920dd04a347ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 3 Jul 2018 10:57:08 +0200 Subject: [PATCH 09/19] select next refresh (analyzer) it was broken since... (?) --- DRAMSys/traceAnalyzer/data/tracedb.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index dbe3687a..7bab08ea 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -199,9 +199,7 @@ shared_ptr TraceDB::getNextPreb(ID currentTransactionId) shared_ptr TraceDB::getNextRefresh(ID currentTransactionId) { QSqlQuery query(database); - QString queryText = queryTexts.queryHead + - "WHERE TransactionID > :currentID AND PhaseName = 'AUTO_REFRESH' LIMIT 1"; - + QString queryText = queryTexts.queryHead + "WHERE TransactionID > :currentID AND PhaseName IN ('REFA') LIMIT 1"; query.prepare(queryText); query.bindValue(":currentID", currentTransactionId); executeQuery(query); From a787b7bb5b3090cd9cd98aa680630ec3f7766566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 3 Jul 2018 10:59:20 +0200 Subject: [PATCH 10/19] coding style --- DRAMSys/traceAnalyzer/data/tracedb.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index 7bab08ea..90cb8565 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -199,7 +199,8 @@ shared_ptr TraceDB::getNextPreb(ID currentTransactionId) shared_ptr TraceDB::getNextRefresh(ID currentTransactionId) { QSqlQuery query(database); - QString queryText = queryTexts.queryHead + "WHERE TransactionID > :currentID AND PhaseName IN ('REFA') LIMIT 1"; + QString queryText = queryTexts.queryHead + + "WHERE TransactionID > :currentID AND PhaseName IN ('REFA') LIMIT 1"; query.prepare(queryText); query.bindValue(":currentID", currentTransactionId); executeQuery(query); From 0ace967a67409c2b03a97d012f85e6cdac855a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 3 Jul 2018 11:24:06 +0200 Subject: [PATCH 11/19] Refresh modes 1X, 2X and 4X - tRFC --- .../resources/configs/mcconfigs/rgrmccfg.xml | 6 +-- .../resources/configs/memspecs/rgrspec.xml | 38 ++++++++----------- DRAMSys/library/src/controller/Command.cpp | 2 +- .../src/controller/core/TimingCalculation.cpp | 8 +++- .../configuration/ConfigurationLoader.cpp | 4 ++ .../controller/core/configuration/MemSpec.h | 9 ++++- .../core/refresh/RefreshManager.cpp | 9 +++-- .../controller/core/refresh/RefreshManager.h | 1 + .../core/refresh/RefreshManagerBankwise.cpp | 9 +++-- .../core/refresh/RefreshManagerBankwise.h | 1 + .../core/scheduling/checker/ActBChecker.cpp | 10 ++++- .../scheduling/checker/ActivateChecker.cpp | 9 ++++- .../scheduling/checker/PowerDownChecker.cpp | 8 +++- .../checker/PrechargeAllChecker.cpp | 13 +++++-- DRAMSys/library/src/simulation/Dram.h | 8 +++- DRAMSys/traceAnalyzer/scripts/metrics.py | 2 +- DRAMSys/traceAnalyzer/scripts/tests.py | 15 +++++++- README.md | 4 ++ 18 files changed, 104 insertions(+), 52 deletions(-) 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 From e088380a647359b3917a8b0217ebfbee5e26821e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 3 Jul 2018 11:29:21 +0200 Subject: [PATCH 12/19] coding style --- .../src/controller/core/TimingCalculation.cpp | 9 +++++--- .../controller/core/configuration/MemSpec.h | 6 ++++-- .../core/scheduling/checker/ActBChecker.cpp | 16 +++++++------- .../scheduling/checker/ActivateChecker.cpp | 17 ++++++++------- .../scheduling/checker/PowerDownChecker.cpp | 14 ++++++------- .../checker/PrechargeAllChecker.cpp | 21 +++++++++++-------- DRAMSys/library/src/simulation/Dram.h | 14 ++++++------- 7 files changed, 54 insertions(+), 43 deletions(-) diff --git a/DRAMSys/library/src/controller/core/TimingCalculation.cpp b/DRAMSys/library/src/controller/core/TimingCalculation.cpp index 9fa99597..224fd7b1 100644 --- a/DRAMSys/library/src/controller/core/TimingCalculation.cpp +++ b/DRAMSys/library/src/controller/core/TimingCalculation.cpp @@ -91,11 +91,14 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload) return config.tRP; } else if (command == Command::AutoRefresh) { if (Configuration::getInstance().getRefMode() == 4) - return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC4; + return getElementFromMap(config.refreshTimings, + DramExtension::getExtension(payload).getBank()).tRFC4; else if (Configuration::getInstance().getRefMode() == 2) - return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC2; + return getElementFromMap(config.refreshTimings, + DramExtension::getExtension(payload).getBank()).tRFC2; else - return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC; + 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/MemSpec.h b/DRAMSys/library/src/controller/core/configuration/MemSpec.h index 7245e6d1..d615866a 100644 --- a/DRAMSys/library/src/controller/core/configuration/MemSpec.h +++ b/DRAMSys/library/src/controller/core/configuration/MemSpec.h @@ -44,8 +44,10 @@ struct RefreshTiming { RefreshTiming() {} - 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) {} + 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; diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp index d3478dc9..fff23cde 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp @@ -62,14 +62,14 @@ void ActBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lcb.getCommand() == Command::AutoRefresh) { - 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 + 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 0fbdca29..86a6b0a1 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp @@ -71,13 +71,16 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand &command) const config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { - 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); + 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 eec65fb8..6e066b61 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp @@ -54,13 +54,13 @@ sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd, constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.clk; } else if (lastCmd == Command::AutoRefresh) { - 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; + 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 e98ca7a7..31b5732e 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp @@ -70,15 +70,18 @@ const config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lastCommand.getCommand() == Command::AutoRefresh) { - 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) { + 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 8d9f198c..be46ff2a 100644 --- a/DRAMSys/library/src/simulation/Dram.h +++ b/DRAMSys/library/src/simulation/Dram.h @@ -151,13 +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; - 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; + 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; From f88e88a81f23a4b7b666fd675370033885ff0b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 3 Jul 2018 13:00:34 +0200 Subject: [PATCH 13/19] improvements --- .../core/refresh/RefreshManager.cpp | 78 +++++++++---------- .../controller/core/refresh/RefreshManager.h | 1 + .../core/refresh/RefreshManagerBankwise.cpp | 14 +--- .../core/refresh/RefreshManagerBankwise.h | 1 + 4 files changed, 43 insertions(+), 51 deletions(-) diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp index 4f654971..ad16799a 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp @@ -34,6 +34,7 @@ * Matthias Jung * Felipe S. Prado * Ana Mativi + * Éder F. Zulian */ #include "RefreshManager.h" @@ -44,8 +45,7 @@ using namespace tlm; -RefreshManager::RefreshManager(sc_module_name /*name*/, - ControllerCore &controller) : +RefreshManager::RefreshManager(sc_module_name, ControllerCore &controller) : controllerCore(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME) @@ -77,20 +77,20 @@ bool RefreshManager::hasCollision(const ScheduledCommand &command) bool collisionWithNextRefStart = command.getEnd() >= nextPlannedRefresh; if (controllerCore.config.ControllerCoreEnableRefPostpone - && (arCmdCounter < - maxpostpone)) { // Flexible refresh is on and have "credits" to postpone - collisionWithNextRefStart = - false; // Then there will not be a collision with next refresh because nextPlannedRefresh will be updated + && (arCmdCounter < maxpostpone)) { + // Flexible refresh is on and have "credits" to postpone + // Then there will not be a collision with next refresh because + // nextPlannedRefresh will be updated + collisionWithNextRefStart = false; } return collisionWithPreviousRefEnd || collisionWithNextRefStart; } -void RefreshManager::doRefresh(tlm::tlm_generic_payload &payload __attribute__(( - unused)), sc_time time) +void RefreshManager::doRefresh(tlm::tlm_generic_payload &payload, sc_time time) { sc_assert(!isInvalidated(payload, time)); - - //Check if any row on all banks is activated and if so, a PrechargeAll command must be scheduled before the refresh command. + //Check if any row on all banks is activated and if so, a PrechargeAll + //command must be scheduled before the refresh command. if (!controllerCore.state->rowBufferStates->allRowBuffersAreClosed()) { ScheduledCommand prechargeAllMaster(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]), @@ -127,23 +127,22 @@ void RefreshManager::doRefresh(tlm::tlm_generic_payload &payload __attribute__(( } -void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload - __attribute__((unused)), sc_time time) +void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload, + sc_time time) { sc_time nextRefTiming; bool pendingReq = controllerCore.hasPendingRequests(); bool canPostpone = pendingReq && (arCmdCounter < maxpostpone); bool canPullIn = !pendingReq && (arCmdCounter < maxpullin); - previousState = currentState; currentState = nextState; switch (currentState) { case ST_REFRESH: - // Regular Refresh. It's possible to migrate from this to the flexible refresh states + // Regular Refresh. It's possible to migrate from this to the flexible + // refresh states // The arCmdCounter should always be equal to zero here assert(arCmdCounter == 0); - if (canPostpone) { nextState = ST_POSTPONE; nextRefTiming = SC_ZERO_TIME; @@ -156,25 +155,24 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload nextState = ST_REFRESH; } break; - case ST_PULLIN: - // Pull-In Refresh. Try to pull-in refreshes as long as the limit hasn't been reached yet and has credits - + // Pull-In Refresh. Try to pull-in refreshes as long as the limit + // hasn't been reached yet and has credits if (canPullIn) { doRefresh(payload, time); arCmdCounter++; nextState = ST_PULLIN; nextRefTiming = tRFCx; } else { - alignValue = arCmdCounter; // Saving value to be used by ST_ALIGN + // Saving value to be used by ST_ALIGN + alignValue = arCmdCounter; nextState = ST_ALIGN; nextRefTiming = SC_ZERO_TIME; } break; - case ST_SKIP: - // Skip Refresh. The arCmdCounter is used to skip the correct amount of refreshes - + // Skip Refresh. The arCmdCounter is used to skip the correct amount + // of refreshes arCmdCounter--; if (arCmdCounter == 0) { nextState = ST_REFRESH; @@ -184,18 +182,21 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload nextRefTiming = tREFIx; } break; - case ST_POSTPONE: - // Postpone Refresh. Delaying refreshes as long as there are pending requests and credits to postpone. Should be followed by a burst refresh - + // Postpone Refresh. Delaying refreshes as long as there are pending + // requests and credits to postpone. Should be followed by a burst + // refresh if ((arCmdCounter == maxpostpone) || ((!pendingReq) - && !controllerCore.config.ControllerCoreForceMaxRefBurst)) { // Burst conditions met - if (arCmdCounter < - maxpostpone) { // In case the burst was started by inactivity, need to also count the current REF + && !controllerCore.config.ControllerCoreForceMaxRefBurst)) { + // Burst conditions met + if (arCmdCounter < maxpostpone) { + // In case the burst was started by inactivity, need to also + // count the current REF arCmdCounter++; } - alignValue = - arCmdCounter; // Will start a burst next, so the value is saved to be used by ST_ALIGN + // Will start a burst next, so the value is saved to be used by + // ST_ALIGN + alignValue = arCmdCounter; nextState = ST_BURST; nextRefTiming = SC_ZERO_TIME; } else { @@ -204,13 +205,13 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload nextRefTiming = tREFIx; } break; - case ST_BURST: - // Burst Refresh. The arCmdCounter is used to issue the correct amount of refreshes - + // Burst Refresh. The arCmdCounter is used to issue the correct amount + // of refreshes arCmdCounter--; doRefresh(payload, time); - if (arCmdCounter == 0) { // All bursts issued, next state will align to tREFIx + if (arCmdCounter == 0) { + // All bursts issued, next state will align to tREFIx nextState = ST_ALIGN; nextRefTiming = SC_ZERO_TIME; } else { @@ -218,10 +219,9 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload nextRefTiming = tRFCx; } break; - case ST_ALIGN: - // Align Refresh. Adjusting the timing so the next REF timing will be a in a time multiple of tREFIx - + // 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 - (tRFCx * (alignValue)); nextState = ST_SKIP; @@ -230,12 +230,10 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload nextState = ST_REFRESH; } break; - default: SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop."); break; } - planNextRefresh(nextRefTiming); } @@ -246,7 +244,7 @@ void RefreshManager::planNextRefresh(sc_time nextRefTiming) refreshPayloads[Bank(0)]); } -void RefreshManager::reInitialize(Bank /*bank*/, sc_time time) +void RefreshManager::reInitialize(Bank, sc_time time) { nextPlannedRefresh = clkAlign(time, Alignment::DOWN); planNextRefresh(tREFIx); diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h index 8a678796..33ec9861 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h @@ -32,6 +32,7 @@ * Authors: * Robert Gernhardt * Matthias Jung + * Éder F. Zulian */ #ifndef REFRESHMANAGER_H_ diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp index 93e9e81e..bd9e44f4 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -32,6 +32,7 @@ * Authors: * Janik Schlemminger * Matthias Jung + * Éder F. Zulian */ #include "RefreshManagerBankwise.h" @@ -116,7 +117,6 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, bool pendingReq = controllerCore.hasPendingRequests(bank); bool canPostpone = pendingReq && (arCmdCounter[bank] < maxpostpone); bool canPullIn = !pendingReq && (arCmdCounter[bank] < maxpullin); - previousState[bank] = currentState[bank]; currentState[bank] = nextState[bank]; @@ -139,7 +139,6 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, nextState[bank] = ST_REFRESH; } break; - case ST_PULLIN: // Pull-In Refresh. Try to pull-in refreshes as long as the limit // hasn't been reached yet and has credits @@ -150,16 +149,15 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, nextState[bank] = ST_PULLIN; nextRefTiming = tRFCx; } else { - alignValue[bank] = arCmdCounter[bank]; // Saving value to be used by ST_ALIGN + // Saving value to be used by ST_ALIGN + alignValue[bank] = arCmdCounter[bank]; nextState[bank] = ST_ALIGN; nextRefTiming = SC_ZERO_TIME; } break; - case ST_SKIP: // Skip Refresh. The arCmdCounter[bank] is used to skip the correct // amount of refreshes - arCmdCounter[bank]--; if (arCmdCounter[bank] == 0) { nextState[bank] = ST_REFRESH; @@ -169,12 +167,10 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, nextRefTiming = tREFIx; } break; - case ST_POSTPONE: // Postpone Refresh. Delaying refreshes as long as there are pending // requests and credits to postpone. Should be followed by a burst // refresh. - if ((arCmdCounter[bank] == maxpostpone) || ((!pendingReq) && !controllerCore.config.ControllerCoreForceMaxRefBurst)) { // Burst conditions met @@ -198,7 +194,6 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, case ST_BURST: // Burst Refresh. The arCmdCounter[bank] is used to issue the correct // amount of refreshes - arCmdCounter[bank]--; doRefresh(payload, time); if (arCmdCounter[bank] == 0) { @@ -210,11 +205,9 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, nextRefTiming = tRFCx; } break; - case ST_ALIGN: // Align Refresh. Adjusting the timing so the next REF timing will be // a in a time multiple of tREFIx. - if (previousState[bank] == ST_PULLIN) { nextRefTiming = tREFIx - (tRFCx * (alignValue[bank])); nextState[bank] = ST_SKIP; @@ -223,7 +216,6 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, nextState[bank] = ST_REFRESH; } break; - default: SC_REPORT_FATAL(this->name(), "Invalid State in Flexible Refresh FSM. Stop."); break; diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h index 26f56a7e..c5959616 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h @@ -32,6 +32,7 @@ * Authors: * Janik Schlemminger * Matthias Jung + * Éder F. Zulian */ #ifndef BANKWISEREFRESHMANAGER_H_ From 6c5c49179ae8bb672f869e6997708523c50c7092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 3 Jul 2018 15:03:36 +0200 Subject: [PATCH 14/19] Commit of the following: Changed stlPlayer to template class. Integrated the relative stl player. --- DRAMSys/library/library.pro | 1 - DRAMSys/library/src/simulation/StlPlayer.cpp | 168 ------------------ DRAMSys/library/src/simulation/StlPlayer.h | 133 +++++++++++++- DRAMSys/library/src/simulation/TraceSetup.cpp | 32 +++- DRAMSys/library/src/simulation/TraceSetup.h | 2 +- DRAMSys/simulator/main.cpp | 2 +- README.md | 31 +++- 7 files changed, 185 insertions(+), 184 deletions(-) delete mode 100644 DRAMSys/library/src/simulation/StlPlayer.cpp diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index c4cef29a..d2e26c1f 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -112,7 +112,6 @@ SOURCES += \ src/error/errormodel.cpp \ src/controller/Controller.cpp \ src/simulation/TracePlayer.cpp \ - src/simulation/StlPlayer.cpp \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \ src/simulation/TraceSetup.cpp \ src/simulation/DRAMSys.cpp \ diff --git a/DRAMSys/library/src/simulation/StlPlayer.cpp b/DRAMSys/library/src/simulation/StlPlayer.cpp deleted file mode 100644 index e38c3405..00000000 --- a/DRAMSys/library/src/simulation/StlPlayer.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - * Éder F. Zulian - * Felipe S. Prado - */ - -#include "StlPlayer.h" - -StlPlayer::StlPlayer(sc_module_name, - string pathToTrace, - sc_time playerClk, - TracePlayerListener *listener) : - TracePlayer(listener), - file(pathToTrace) -{ - if (!file.is_open()) - SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); - - this->playerClk = playerClk; - this->burstlength = Configuration::getInstance().memSpec.BurstLength; - this->dataLength = Configuration::getInstance().getBytesPerBurst(); - this->lineCnt = 0; -} - -void StlPlayer::nextPayload() -{ - std::string line; - while (line.empty() && file) { - // Get a new line from the input file. - std::getline(file, line); - lineCnt++; - // If the line starts with '#' (commented lines) the transaction is ignored. - if (!line.empty() && line.at(0) == '#') - line.clear(); - } - - if (!file) { - // The file is empty. Nothing more to do. - this->finish(); - return; - } else { - numberOfTransactions++; - } - - // Allocate a generic payload for this request. - gp *payload = this->allocatePayload(); - - // Allocate a data buffer and initialize it with zeroes. It may be - // overwritten with data from the trace file depending on the storage - // mode. - unsigned char *data = new unsigned char[dataLength]; - std::fill(data, data + dataLength, 0); - - // Trace files MUST provide timestamp, command and address for every - // transaction. The data information depends on the storage mode - // configuration. - string time; - string command; - string address; - string dataStr; - - std::istringstream iss(line); - - // Get the timestamp for the transaction. - iss >> time; - if (time.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Timestamp could not be found (line " + to_string( - lineCnt) + ").").c_str()); - sc_time sendingTime = std::stoull(time.c_str()) * playerClk; - - // Get the command. - iss >> command; - if (command.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Command could not be found (line " + to_string( - lineCnt) + ").").c_str()); - enum tlm_command cmd; - if (command == "read") { - cmd = TLM_READ_COMMAND; - } else if (command == "write") { - cmd = TLM_WRITE_COMMAND; - } else { - SC_REPORT_FATAL("StlPlayer", - (string("Corrupted tracefile, command ") + command + - string(" unknown")).c_str()); - } - - // Get the address. - iss >> address; - if (address.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Address could not be found (line " + to_string( - lineCnt) + ").").c_str()); - unsigned long long addr = std::stoull(address.c_str(), 0, 16); - - // Get the data if necessary. - if (Configuration::getInstance().StoreMode != StorageMode::NoStorage - && cmd != TLM_READ_COMMAND) { - // The input trace file must provide the data to be stored into the memory. - iss >> dataStr; - if (dataStr.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Data information could not be found (line " + to_string( - lineCnt) + ").").c_str()); - - // Check if data length in the trace file is correct. We need two characters to represent 1 byte in hexadecimal. - if (dataStr.length() != (dataLength * 2)) - SC_REPORT_FATAL("StlPlayer", - ("Data in the trace file has an invalid length (line " + to_string( - lineCnt) + ").").c_str()); - - // Set data - for (unsigned i = 0; i < dataLength; i++) - data[i] = (unsigned char)std::stoi(dataStr.substr(i * 2, 2).c_str(), 0, 16); - } - - // Fill up the payload. - payload->set_address(addr); - payload->set_response_status(TLM_INCOMPLETE_RESPONSE); - payload->set_dmi_allowed(false); - payload->set_byte_enable_length(0); - payload->set_streaming_width(burstlength); - payload->set_data_length(dataLength); - payload->set_data_ptr(data); - payload->set_command(cmd); - - // Send the transaction directly or schedule it to be sent in the future. - if (sendingTime <= sc_time_stamp()) - this->payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); - else - this->payloadEventQueue.notify(*payload, BEGIN_REQ, - sendingTime - sc_time_stamp()); -} - diff --git a/DRAMSys/library/src/simulation/StlPlayer.h b/DRAMSys/library/src/simulation/StlPlayer.h index 4400c58c..8e36b54b 100644 --- a/DRAMSys/library/src/simulation/StlPlayer.h +++ b/DRAMSys/library/src/simulation/StlPlayer.h @@ -46,14 +46,141 @@ using namespace std; using namespace tlm; -struct StlPlayer: public TracePlayer { +template class StlPlayer: public TracePlayer +{ public: StlPlayer(sc_module_name /*name*/, string pathToTrace, sc_time playerClk, - TracePlayerListener *listener); + TracePlayerListener *listener) : + TracePlayer(listener), + file(pathToTrace) + { + if (!file.is_open()) + SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); - void nextPayload(); + this->playerClk = playerClk; + this->burstlength = Configuration::getInstance().memSpec.BurstLength; + this->dataLength = Configuration::getInstance().getBytesPerBurst(); + this->lineCnt = 0; + } + + + + void nextPayload() + { + std::string line; + while (line.empty() && file) { + // Get a new line from the input file. + std::getline(file, line); + lineCnt++; + // If the line starts with '#' (commented lines) the transaction is ignored. + if (!line.empty() && line.at(0) == '#') + line.clear(); + } + + if (!file) { + // The file is empty. Nothing more to do. + this->finish(); + return; + } else { + numberOfTransactions++; + } + + // Allocate a generic payload for this request. + gp *payload = this->allocatePayload(); + + // Allocate a data buffer and initialize it with zeroes. It may be + // overwritten with data from the trace file depending on the storage + // mode. + unsigned char *data = new unsigned char[dataLength]; + std::fill(data, data + dataLength, 0); + + // Trace files MUST provide timestamp, command and address for every + // transaction. The data information depends on the storage mode + // configuration. + string time; + string command; + string address; + string dataStr; + + std::istringstream iss(line); + + // Get the timestamp for the transaction. + iss >> time; + if (time.empty()) + SC_REPORT_FATAL("StlPlayer", + ("Malformed trace file. Timestamp could not be found (line " + to_string( + lineCnt) + ").").c_str()); + sc_time sendingTime = std::stoull(time.c_str()) * playerClk; + + // Get the command. + iss >> command; + if (command.empty()) + SC_REPORT_FATAL("StlPlayer", + ("Malformed trace file. Command could not be found (line " + to_string( + lineCnt) + ").").c_str()); + enum tlm_command cmd; + if (command == "read") { + cmd = TLM_READ_COMMAND; + } else if (command == "write") { + cmd = TLM_WRITE_COMMAND; + } else { + SC_REPORT_FATAL("StlPlayer", + (string("Corrupted tracefile, command ") + command + + string(" unknown")).c_str()); + } + + // Get the address. + iss >> address; + if (address.empty()) + SC_REPORT_FATAL("StlPlayer", + ("Malformed trace file. Address could not be found (line " + to_string( + lineCnt) + ").").c_str()); + unsigned long long addr = std::stoull(address.c_str(), 0, 16); + + // Get the data if necessary. + if (Configuration::getInstance().StoreMode != StorageMode::NoStorage + && cmd != TLM_READ_COMMAND) { + // The input trace file must provide the data to be stored into the memory. + iss >> dataStr; + if (dataStr.empty()) + SC_REPORT_FATAL("StlPlayer", + ("Malformed trace file. Data information could not be found (line " + to_string( + lineCnt) + ").").c_str()); + + // Check if data length in the trace file is correct. We need two characters to represent 1 byte in hexadecimal. + if (dataStr.length() != (dataLength * 2)) + SC_REPORT_FATAL("StlPlayer", + ("Data in the trace file has an invalid length (line " + to_string( + lineCnt) + ").").c_str()); + + // Set data + for (unsigned i = 0; i < dataLength; i++) + data[i] = (unsigned char)std::stoi(dataStr.substr(i * 2, 2).c_str(), 0, 16); + } + + // Fill up the payload. + payload->set_address(addr); + payload->set_response_status(TLM_INCOMPLETE_RESPONSE); + payload->set_dmi_allowed(false); + payload->set_byte_enable_length(0); + payload->set_streaming_width(burstlength); + payload->set_data_length(dataLength); + payload->set_data_ptr(data); + payload->set_command(cmd); + + if (relative == false) { + // Send the transaction directly or schedule it to be sent in the future. + if (sendingTime <= sc_time_stamp()) + this->payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); + else + this->payloadEventQueue.notify(*payload, BEGIN_REQ, + sendingTime - sc_time_stamp()); + } else { + payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime); + } + } private: ifstream file; diff --git a/DRAMSys/library/src/simulation/TraceSetup.cpp b/DRAMSys/library/src/simulation/TraceSetup.cpp index 21152069..b0fd3390 100644 --- a/DRAMSys/library/src/simulation/TraceSetup.cpp +++ b/DRAMSys/library/src/simulation/TraceSetup.cpp @@ -37,7 +37,7 @@ traceSetup::traceSetup(std::string uri, std::string pathToResources, - std::vector *devices) + std::vector * devices) { // Load Simulation: tinyxml2::XMLDocument simulationdoc; @@ -69,17 +69,37 @@ traceSetup::traceSetup(std::string uri, } std::string name = device->GetText(); + + int pos = name.rfind('.'); + if(pos == std::string::npos) + { + throw std::runtime_error("Name of the trace file does not contain a valid extension."); + } + + // Get the extension and make it lower case + std::string ext = name.substr(pos+1); + std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); + std::string stlFile = pathToResources + string("traces/") + name; std::string moduleName = name; // replace all '.' to '_' std::replace( moduleName.begin(), moduleName.end(), '.', '_'); - StlPlayer *player = new StlPlayer(moduleName.c_str(), - stlFile, - playerClk, - this); - + TracePlayer * player; + if(strcmp(ext.c_str(), "stl") == 0) + { + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); + } + else if(strcmp(ext.c_str(), "rstl") == 0) + { + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); + } + else + { + std::string error = "Unsupported file extension in " + name; + throw std::runtime_error(error); + } devices->push_back(player); if (Configuration::getInstance().SimulationProgressBar) { diff --git a/DRAMSys/library/src/simulation/TraceSetup.h b/DRAMSys/library/src/simulation/TraceSetup.h index 2287d052..2d0596c9 100644 --- a/DRAMSys/library/src/simulation/TraceSetup.h +++ b/DRAMSys/library/src/simulation/TraceSetup.h @@ -49,7 +49,7 @@ class traceSetup : public TracePlayerListener public: traceSetup(std::string uri, std::string pathToResources, - std::vector *devices); + std::vector * devices); virtual void tracePlayerTerminates() override; virtual void transactionFinished() override; diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 39fb82d7..8c71aaeb 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) SimulationXML = resources + "simulations/ddr3-example.xml"; } - std::vector players; + std::vector players; // Instantiate DRAMSys: DRAMSys *dramSys = new DRAMSys("DRAMSys", SimulationXML, resources); diff --git a/README.md b/README.md index 4421e710..ed4b1a61 100644 --- a/README.md +++ b/README.md @@ -381,11 +381,22 @@ configuration structure. The **device** configuration consists of two parameters - clkMhz (operation frequency for this device) - and a **trace file**. +#### Trace files + A **trace file** is a pre-recorded file containing memory transactions. Each memory transaction has a timestamp that tells the simulator when it shall happen, a transaction type (read or write) and a memory address given in hexadecimal. +There are two different kinds of trace files. They differ in their timing behaviour and are distingushed by their file extension. + +##### STL Trace (.stl) + +The timestamp corresponds to the time the request is to be issued and it is +given in cycles of the bus master device. Example: the device is a FPGA with +frequency 200 MHz (clock period of 5 ns). If the timestamp is 10 it means that +the request is to be issued when time is 50 ns. + Here is an example syntax: ``` @@ -397,10 +408,22 @@ Here is an example syntax: 81: read 0x400180 ``` -The timestamp corresponds to the time the request is to be issued and it is -given in cycles of the bus master device. Example: the device is a FPGA with -frequency 200 MHz (clock period of 5 ns). If the timestamp is 10 it means that -the request is to be issued when time is 50 ns. +##### Relative STL Traces (.rstl) + +The timestamp corresponds to the time the request is to be issued relative to the end of the transaction before or the beginning of the trace. This results in a simulation in which the **trace player** is able to react to possible delays due to DRAM bottlenecks. + +Here is an example syntax: + +``` +# Comment lines begin with # +# [clock-cyle]: [write|read] [hex-address] +31: read 0x400140 +2: read 0x400160 +23: write 0x7fff8000 +25: read 0x400180 +``` + +#### Trace player A **trace player** is **equivalent** to a bus master **device** (processor, FPGA, etc.). It reads an input trace file and translates each line into From 2cc7127317b915c881fa016063180f190977ca7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 3 Jul 2018 15:10:39 +0200 Subject: [PATCH 15/19] coding style --- DRAMSys/library/src/simulation/TraceSetup.cpp | 20 +++++++------------ DRAMSys/library/src/simulation/TraceSetup.h | 2 +- DRAMSys/simulator/main.cpp | 2 +- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/DRAMSys/library/src/simulation/TraceSetup.cpp b/DRAMSys/library/src/simulation/TraceSetup.cpp index b0fd3390..faaa37f8 100644 --- a/DRAMSys/library/src/simulation/TraceSetup.cpp +++ b/DRAMSys/library/src/simulation/TraceSetup.cpp @@ -37,7 +37,7 @@ traceSetup::traceSetup(std::string uri, std::string pathToResources, - std::vector * devices) + std::vector *devices) { // Load Simulation: tinyxml2::XMLDocument simulationdoc; @@ -71,13 +71,12 @@ traceSetup::traceSetup(std::string uri, std::string name = device->GetText(); int pos = name.rfind('.'); - if(pos == std::string::npos) - { + if (pos == std::string::npos) { throw std::runtime_error("Name of the trace file does not contain a valid extension."); } // Get the extension and make it lower case - std::string ext = name.substr(pos+1); + std::string ext = name.substr(pos + 1); std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); std::string stlFile = pathToResources + string("traces/") + name; @@ -86,17 +85,12 @@ traceSetup::traceSetup(std::string uri, // replace all '.' to '_' std::replace( moduleName.begin(), moduleName.end(), '.', '_'); - TracePlayer * player; - if(strcmp(ext.c_str(), "stl") == 0) - { + TracePlayer *player; + if (strcmp(ext.c_str(), "stl") == 0) { player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); - } - else if(strcmp(ext.c_str(), "rstl") == 0) - { + } else if (strcmp(ext.c_str(), "rstl") == 0) { player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); - } - else - { + } else { std::string error = "Unsupported file extension in " + name; throw std::runtime_error(error); } diff --git a/DRAMSys/library/src/simulation/TraceSetup.h b/DRAMSys/library/src/simulation/TraceSetup.h index 2d0596c9..901b6756 100644 --- a/DRAMSys/library/src/simulation/TraceSetup.h +++ b/DRAMSys/library/src/simulation/TraceSetup.h @@ -49,7 +49,7 @@ class traceSetup : public TracePlayerListener public: traceSetup(std::string uri, std::string pathToResources, - std::vector * devices); + std::vector *devices); virtual void tracePlayerTerminates() override; virtual void transactionFinished() override; diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 8c71aaeb..f6a6bda9 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) SimulationXML = resources + "simulations/ddr3-example.xml"; } - std::vector players; + std::vector players; // Instantiate DRAMSys: DRAMSys *dramSys = new DRAMSys("DRAMSys", SimulationXML, resources); From 2e307d00e89cf1e52fa65a3c2de539ee147cf42f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 5 Jul 2018 08:09:36 +0200 Subject: [PATCH 16/19] Doc improved --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ed4b1a61..74a1cde4 100644 --- a/README.md +++ b/README.md @@ -887,18 +887,19 @@ the memory is in an idle state. Therefore, in order to prepare for possible accesses that might happen in the future, a burst of REF commands is initiated. If, at any point, requests start coming in, the burst is interrupted, meaning that the maximum amount of time, considering the worst -case scenario (a request arrives at the same time a REF was issued), is tRFC. -The advantage of pulling-in refreshes is that they will not issued in the -near future (in their actual times), allowing for more efficient accesses to -the memory. +case scenario (a request arrives at the same time a REF was issued), is a +refresh cycle time (tRFC). The advantage of pulling-in refreshes is that they +will not issued in the near future (in their actual times), allowing for more +efficient accesses to the memory. **Postpone Refresh** Similarly, the decision to postpone a refresh is done if there are pending requests on the buffer. Given that having requests might mean a hit, we want -to postpone the refresh to minimize the PREA commands needed. If the memory -enters an idle state, a burst is issued for the same number of REF commands -that were postponed. +to postpone the refresh to avoid breaking row hit sequences and reducing the +number of commands (e.g., ACT, PRE) to carry out the memory accesses. If the +memory enters an idle state, a burst is issued for the same number of REF +commands that were postponed. **The Flexible Refresh FSM** From d579060e8eeb4a23d780269466147424f57658ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 5 Jul 2018 08:19:31 +0200 Subject: [PATCH 17/19] Doc improved --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 74a1cde4..cf8df867 100644 --- a/README.md +++ b/README.md @@ -895,11 +895,11 @@ efficient accesses to the memory. **Postpone Refresh** Similarly, the decision to postpone a refresh is done if there are pending -requests on the buffer. Given that having requests might mean a hit, we want -to postpone the refresh to avoid breaking row hit sequences and reducing the -number of commands (e.g., ACT, PRE) to carry out the memory accesses. If the -memory enters an idle state, a burst is issued for the same number of REF -commands that were postponed. +requests on the buffer. Buffered requests may generate row-hits, so postponing +refreshes may be beneficial for it avoids breaking row-hit sequences what +reduces the number of commands (e.g., ACT, PRE) to carry out the memory +accesses. If the memory enters an idle state, a burst is issued for the same +number of REF commands that were postponed. **The Flexible Refresh FSM** From 9b237be228f0ef45cbee53c1503b756aeac5a1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 5 Jul 2018 11:39:04 +0200 Subject: [PATCH 18/19] RecordableController and RecordableDram --- DRAMSys/library/library.pro | 3 + DRAMSys/library/src/common/TlmRecorder.cpp | 129 ++++++------ DRAMSys/library/src/common/TlmRecorder.h | 3 +- DRAMSys/library/src/controller/Controller.cpp | 199 ++++++------------ DRAMSys/library/src/controller/Controller.h | 20 +- .../src/controller/RecordableController.cpp | 92 ++++++++ .../src/controller/RecordableController.h | 64 ++++++ .../src/controller/core/ControllerCore.cpp | 6 +- .../src/controller/core/ControllerCore.h | 2 +- .../core/powerdown/PowerDownManager.cpp | 1 - .../core/scheduling/ScheduledCommand.cpp | 1 - .../core/scheduling/ScheduledCommand.h | 1 - .../library/src/controller/scheduler/Fifo.cpp | 2 +- .../library/src/controller/scheduler/Fifo.h | 2 +- .../src/controller/scheduler/FifoStrict.cpp | 2 +- .../src/controller/scheduler/FifoStrict.h | 2 +- .../src/controller/scheduler/Fr_Fcfs.cpp | 3 +- .../src/controller/scheduler/Fr_Fcfs.h | 2 +- .../src/controller/scheduler/IScheduler.h | 2 +- .../library/src/controller/scheduler/SMS.cpp | 2 +- .../library/src/controller/scheduler/SMS.h | 2 +- DRAMSys/library/src/simulation/Arbiter.h | 25 +-- DRAMSys/library/src/simulation/DRAMSys.cpp | 22 +- DRAMSys/library/src/simulation/DRAMSys.h | 4 +- DRAMSys/library/src/simulation/Dram.h | 93 +------- .../library/src/simulation/RecordableDram.h | 152 +++++++++++++ 26 files changed, 487 insertions(+), 349 deletions(-) create mode 100644 DRAMSys/library/src/controller/RecordableController.cpp create mode 100644 DRAMSys/library/src/controller/RecordableController.h create mode 100644 DRAMSys/library/src/simulation/RecordableDram.h diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index d2e26c1f..f9c718f7 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -123,6 +123,7 @@ SOURCES += \ src/error/ecchamming.cpp \ src/controller/scheduler/Fr_Fcfs_read_priority.cpp \ src/controller/scheduler/Fr_Fcfs_grouper.cpp \ + src/controller/RecordableController.cpp \ src/common/AddressDecoder.cpp \ src/common/jsonAddressDecoder.cpp @@ -201,6 +202,8 @@ HEADERS += \ src/controller/scheduler/Fr_Fcfs_grouper.h \ src/simulation/IArbiter.h \ src/simulation/SimpleArbiter.h \ + src/controller/RecordableController.h \ + src/simulation/RecordableDram.h \ src/common/AddressDecoder.h \ src/common/jsonAddressDecoder.h #src/common/third_party/json/include/nlohmann/json.hpp \ diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 9cc03443..0fae8cd7 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -48,90 +48,90 @@ using namespace std; -TlmRecorder::TlmRecorder(sc_module_name /*name*/, string uri, string dbname, - bool recenable) : sqlScriptURI(uri), dbName(dbname), - recordingEnabled(recenable), totalNumTransactions(1), + +TlmRecorder::TlmRecorder(sc_module_name /*name*/, string uri, + string dbname) : sqlScriptURI(uri), dbName(dbname), totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME) { - if (TlmRecorder::recordingEnabled == true) { - recordedData.reserve(transactionCommitRate); - setUpTransactionTerminatingPhases(); - openDB(TlmRecorder::dbName.c_str()); - char *sErrMsg; - sqlite3_exec(db, "PRAGMA main.page_size = 4096", NULL, NULL, &sErrMsg); - sqlite3_exec(db, "PRAGMA main.cache_size=10000", NULL, NULL, &sErrMsg); - sqlite3_exec(db, "PRAGMA main.locking_mode=EXCLUSIVE", NULL, NULL, &sErrMsg); - sqlite3_exec(db, "PRAGMA main.synchronous=OFF", NULL, NULL, &sErrMsg); - sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &sErrMsg); + recordedData.reserve(transactionCommitRate); + setUpTransactionTerminatingPhases(); + openDB(TlmRecorder::dbName.c_str()); + char *sErrMsg; + sqlite3_exec(db, "PRAGMA main.page_size = 4096", NULL, NULL, &sErrMsg); + sqlite3_exec(db, "PRAGMA main.cache_size=10000", NULL, NULL, &sErrMsg); + sqlite3_exec(db, "PRAGMA main.locking_mode=EXCLUSIVE", NULL, NULL, &sErrMsg); + sqlite3_exec(db, "PRAGMA main.synchronous=OFF", NULL, NULL, &sErrMsg); + sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &sErrMsg); - createTables(TlmRecorder::sqlScriptURI); - prepareSqlStatements(); + createTables(TlmRecorder::sqlScriptURI); + prepareSqlStatements(); - printDebugMessage("Starting new database transaction"); - } + printDebugMessage("Starting new database transaction"); } TlmRecorder::~TlmRecorder() { if (db) closeConnection(); + sqlite3_finalize(insertTransactionStatement); + sqlite3_finalize(insertRangeStatement); + sqlite3_finalize(updateRangeStatement); + sqlite3_finalize(insertPhaseStatement); + sqlite3_finalize(updatePhaseStatement); + sqlite3_finalize(insertGeneralInfoStatement); + sqlite3_finalize(insertDebugMessageStatement); + sqlite3_finalize(updateDataStrobeStatement); + sqlite3_finalize(insertPowerStatement); } void TlmRecorder::recordPower(double timeInSeconds, double averagePower) { - if (TlmRecorder::recordingEnabled) { - sqlite3_bind_double(insertPowerStatement, 1, timeInSeconds); - sqlite3_bind_double(insertPowerStatement, 2, averagePower); - executeSqlStatement(insertPowerStatement); - } + sqlite3_bind_double(insertPowerStatement, 1, timeInSeconds); + sqlite3_bind_double(insertPowerStatement, 2, averagePower); + executeSqlStatement(insertPowerStatement); } void TlmRecorder::recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time) { - if (TlmRecorder::recordingEnabled) { - if (currentTransactionsInSystem.count(&trans) == 0) - introduceTransactionSystem(trans); + if (currentTransactionsInSystem.count(&trans) == 0) + introduceTransactionSystem(trans); - string phaseName = phaseNameToString(phase); - string phaseBeginPrefix = "BEGIN_"; - string phaseEndPrefix = "END_"; + string phaseName = phaseNameToString(phase); + string phaseBeginPrefix = "BEGIN_"; + string phaseEndPrefix = "END_"; - if (phaseName.find(phaseBeginPrefix) != string::npos) { - phaseName.erase(0, phaseBeginPrefix.length()); - assert(currentTransactionsInSystem.count(&trans) != 0); - currentTransactionsInSystem[&trans].insertPhase(phaseName, time); - } else { - phaseName.erase(0, phaseEndPrefix.length()); - assert(currentTransactionsInSystem.count(&trans) != 0); - currentTransactionsInSystem[&trans].setPhaseEnd(phaseName, time); - } - - bool phaseTerminatesTransaction = count(transactionTerminatingPhases.begin(), - transactionTerminatingPhases.end(), phase) == 1; - if (phaseTerminatesTransaction) - removeTransactionFromSystem(trans); - - simulationTimeCoveredByRecording = time; + if (phaseName.find(phaseBeginPrefix) != string::npos) { + phaseName.erase(0, phaseBeginPrefix.length()); + assert(currentTransactionsInSystem.count(&trans) != 0); + currentTransactionsInSystem[&trans].insertPhase(phaseName, time); + } else { + phaseName.erase(0, phaseEndPrefix.length()); + assert(currentTransactionsInSystem.count(&trans) != 0); + currentTransactionsInSystem[&trans].setPhaseEnd(phaseName, time); } + + bool phaseTerminatesTransaction = count(transactionTerminatingPhases.begin(), + transactionTerminatingPhases.end(), phase) == 1; + if (phaseTerminatesTransaction) + removeTransactionFromSystem(trans); + + simulationTimeCoveredByRecording = time; } void TlmRecorder::updateDataStrobe(const sc_time &begin, const sc_time &end, tlm::tlm_generic_payload &trans) { - if (TlmRecorder::recordingEnabled) { - assert(currentTransactionsInSystem.count(&trans) != 0); - currentTransactionsInSystem[&trans].timeOnDataStrobe.start = begin; - currentTransactionsInSystem[&trans].timeOnDataStrobe.end = end; - } + assert(currentTransactionsInSystem.count(&trans) != 0); + currentTransactionsInSystem[&trans].timeOnDataStrobe.start = begin; + currentTransactionsInSystem[&trans].timeOnDataStrobe.end = end; } void TlmRecorder::recordDebugMessage(std::string message, sc_time time) { - if (TlmRecorder::recordingEnabled) - insertDebugMessageInDB(message, time); + insertDebugMessageInDB(message, time); } @@ -434,24 +434,13 @@ void TlmRecorder::printDebugMessage(std::string message) void TlmRecorder::closeConnection() { - if (TlmRecorder::recordingEnabled) { - commitRecordedDataToDB(); - insertGeneralInfo(); - printDebugMessage( - "Number of transactions written to DB: " + std::to_string( - totalNumTransactions - 1)); - printDebugMessage("tlmPhaseRecorder:\tEnd Recording"); - sqlite3_finalize(insertTransactionStatement); - sqlite3_finalize(insertRangeStatement); - sqlite3_finalize(updateRangeStatement); - sqlite3_finalize(insertPhaseStatement); - sqlite3_finalize(updatePhaseStatement); - sqlite3_finalize(insertGeneralInfoStatement); - sqlite3_finalize(insertDebugMessageStatement); - sqlite3_finalize(updateDataStrobeStatement); - sqlite3_finalize(insertPowerStatement); - sqlite3_close(db); - db = NULL; - } + commitRecordedDataToDB(); + insertGeneralInfo(); + printDebugMessage( + "Number of transactions written to DB: " + std::to_string( + totalNumTransactions - 1)); + printDebugMessage("tlmPhaseRecorder:\tEnd Recording"); + sqlite3_close(db); + db = NULL; } diff --git a/DRAMSys/library/src/common/TlmRecorder.h b/DRAMSys/library/src/common/TlmRecorder.h index f984dc4a..31deb14d 100644 --- a/DRAMSys/library/src/common/TlmRecorder.h +++ b/DRAMSys/library/src/common/TlmRecorder.h @@ -60,9 +60,8 @@ class TlmRecorder : public sc_module public: std::string sqlScriptURI; std::string dbName; - bool recordingEnabled; - TlmRecorder(sc_module_name /*name*/, string uri, string dbname, bool recenable); + TlmRecorder(sc_module_name /*name*/, string uri, string dbname); ~TlmRecorder(); void recordMCconfig(string mcconfig) diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index e7bb8af2..ad4879a3 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -75,114 +75,83 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payload) { sc_assert(command.getStart() >= sc_time_stamp()); - TimeInterval dataStrobe; + + tlm_phase phase; switch (command.getCommand()) { //TODO: refactor tlm recorder case Command::Read: - dataStrobe = command.getIntervalOnDataStrobe(); - tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_RD, - command.getStart() - sc_time_stamp()); + phase = BEGIN_RD; break; case Command::ReadA: - dataStrobe = command.getIntervalOnDataStrobe(); - tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_RDA, - command.getStart() - sc_time_stamp()); + phase = BEGIN_RDA; break; case Command::Write: - dataStrobe = command.getIntervalOnDataStrobe(); - tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_WR, - command.getStart() - sc_time_stamp()); + phase = BEGIN_WR; break; case Command::WriteA: - dataStrobe = command.getIntervalOnDataStrobe(); - tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_WRA, - command.getStart() - sc_time_stamp()); + phase = BEGIN_WRA; break; case Command::AutoRefresh: if (!Configuration::getInstance().BankwiseLogic) { - controllerCorePEQ.notify(payload, BEGIN_REFA, - command.getStart() - sc_time_stamp()); + phase = BEGIN_REFA; } else - controllerCorePEQ.notify(payload, BEGIN_REFB, - command.getStart() - sc_time_stamp()); - break; - case Command::ActB: - controllerCorePEQ.notify(payload, BEGIN_ACTB, - command.getStart() - sc_time_stamp()); + phase = BEGIN_REFB; break; case Command::Activate: - controllerCorePEQ.notify(payload, BEGIN_ACT, - command.getStart() - sc_time_stamp()); - break; - case Command::PreB: - controllerCorePEQ.notify(payload, BEGIN_PREB, - command.getStart() - sc_time_stamp()); + phase = BEGIN_ACT; break; case Command::Precharge: - controllerCorePEQ.notify(payload, BEGIN_PRE, - command.getStart() - sc_time_stamp()); + phase = BEGIN_PRE; break; case Command::PrechargeAll: - controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, - command.getStart() - sc_time_stamp()); + phase = BEGIN_PRE_ALL; break; case Command::PDNA: if (!Configuration::getInstance().BankwiseLogic) { - controllerCorePEQ.notify(payload, BEGIN_PDNA, - command.getStart() - sc_time_stamp()); + phase = BEGIN_PDNA; } else - controllerCorePEQ.notify(payload, BEGIN_PDNAB, - command.getStart() - sc_time_stamp()); + phase = BEGIN_PDNAB; break; case Command::PDNAX: if (!Configuration::getInstance().BankwiseLogic) { - controllerCorePEQ.notify(payload, END_PDNA, - command.getStart() - sc_time_stamp()); + phase = END_PDNA; } else - controllerCorePEQ.notify(payload, END_PDNAB, - command.getStart() - sc_time_stamp()); + phase = END_PDNAB; break; case Command::PDNP: if (!Configuration::getInstance().BankwiseLogic) { - controllerCorePEQ.notify(payload, BEGIN_PDNP, - command.getStart() - sc_time_stamp()); + phase = BEGIN_PDNP; } else - controllerCorePEQ.notify(payload, BEGIN_PDNPB, - command.getStart() - sc_time_stamp()); + phase = BEGIN_PDNPB; break; case Command::PDNPX: if (!Configuration::getInstance().BankwiseLogic) { - controllerCorePEQ.notify(payload, END_PDNP, - command.getStart() - sc_time_stamp()); + phase = END_PDNP; } else - controllerCorePEQ.notify(payload, END_PDNPB, - command.getStart() - sc_time_stamp()); + phase = END_PDNPB; break; case Command::SREF: if (!Configuration::getInstance().BankwiseLogic) { - controllerCorePEQ.notify(payload, BEGIN_SREF, - command.getStart() - sc_time_stamp()); + phase = BEGIN_SREF; } else - controllerCorePEQ.notify(payload, BEGIN_SREFB, - command.getStart() - sc_time_stamp()); + phase = BEGIN_SREFB; break; case Command::SREFX: if (!Configuration::getInstance().BankwiseLogic) { - controllerCorePEQ.notify(payload, END_SREF, - command.getStart() - sc_time_stamp()); + phase = END_SREF; } else - controllerCorePEQ.notify(payload, END_SREFB, - command.getStart() - sc_time_stamp()); + phase = END_SREFB; break; default: SC_REPORT_FATAL(0, "unsupported command was sent by controller"); break; } + + sc_time notDelay = command.getStart() - sc_time_stamp(); + printDebugMessage(phaseNameToString(phase) + " notification in " + + notDelay.to_string()); + controllerCorePEQ.notify(payload, phase, notDelay); } //Trigger the next planned refresh or the power down mode on the DRAM @@ -191,14 +160,20 @@ void Controller::send(Trigger trigger, sc_time time, { sc_assert(time >= sc_time_stamp()); - sc_time delay = time - sc_time_stamp(); + tlm_phase phase; + if (trigger == Trigger::REFTrigger) { - controllerCorePEQ.notify(payload, REF_TRIGGER, delay); + phase = REF_TRIGGER; } else if (trigger == Trigger::PDNTrigger) { - controllerCorePEQ.notify(payload, PDN_TRIGGER, delay); + phase = PDN_TRIGGER; } else { SC_REPORT_FATAL("controller wrapper", "unknown trigger"); } + + sc_time delay = time - sc_time_stamp(); + printDebugMessage(phaseNameToString(phase) + " notification in " + + delay.to_string()); + controllerCorePEQ.notify(payload, phase, delay); } void Controller::controllerCorePEQCallback(tlm_generic_payload &payload, @@ -237,63 +212,33 @@ void Controller::controllerCorePEQCallback(tlm_generic_payload &payload, } else SC_REPORT_FATAL(0, - "refreshTriggerPEQCallback queue in controller wrapper was triggered with unsupported phase"); + "Controller Core PEQ in controller wrapper was triggered with unsupported phase"); } } tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) { - sc_time recTime; - sc_time notDelay; - - unsigned int thr = DramExtension::getExtension(payload).getThread().ID(); - unsigned int ch = DramExtension::getExtension(payload).getChannel().ID(); - unsigned int bg = DramExtension::getExtension(payload).getBankGroup().ID(); - unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); - unsigned int row = DramExtension::getExtension(payload).getRow().ID(); - unsigned int col = DramExtension::getExtension(payload).getColumn().ID(); + sc_time notDelay = fwDelay; if (phase == BEGIN_REQ) { - recTime = fwDelay + sc_time_stamp(); - notDelay = clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay) + - Configuration::getInstance().memSpec.clk; - - printDebugMessage("[fw] Recording " + phaseNameToString( - phase) + " thread " + to_string(thr) + " channel " + to_string( - ch) + " bank group " + to_string(bg) + " bank " + to_string( - bank) + " row " + to_string(row) + " column " + to_string( - col) + " at " + recTime.to_string() + " notification in " + - notDelay.to_string()); - - tlmRecorder->recordPhase(payload, phase, recTime); - frontendPEQ.notify(payload, phase, notDelay); + notDelay += Configuration::getInstance().memSpec.clk; //Bandwidth IDLE if ((getTotalNumberOfPayloadsInSystem() == 0) && idleState) { endBandwidthIdleCollector(); } } else if (phase == END_RESP) { - - recTime = fwDelay + sc_time_stamp() + Configuration::getInstance().memSpec.clk; - notDelay = clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay); - - printDebugMessage("[fw] Recording " + phaseNameToString( - phase) + " thread " + to_string(thr) + " channel " + to_string( - ch) + " bank group " + to_string(bg) + " bank " + to_string( - bank) + " row " + to_string(row) + " column " + to_string( - col) + " at " + recTime.to_string() + " notification in " + - notDelay.to_string()); - // Badnwith IDLE if (getTotalNumberOfPayloadsInSystem() == 1) { startBandwidthIdleCollector(); } - - tlmRecorder->recordPhase(payload, phase, recTime); - frontendPEQ.notify(payload, phase, notDelay); - } + + printDebugMessage("[fw] " + phaseNameToString(phase) + " notification in " + + notDelay.to_string()); + frontendPEQ.notify(payload, phase, notDelay); + return TLM_ACCEPTED; } @@ -319,7 +264,7 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload, payload.set_response_status(tlm::TLM_OK_RESPONSE); sendToFrontend(payload, END_REQ, SC_ZERO_TIME); - scheduler->schedule(&payload); + scheduler->storeRequest(&payload); scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); } else if (phase == PendingRequest) { // Schedule a pending request. @@ -330,7 +275,7 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload, backpressure->set_response_status(tlm::TLM_OK_RESPONSE); sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME); - scheduler->schedule(backpressure); + scheduler->storeRequest(backpressure); scheduleNextFromScheduler(DramExtension::getExtension(backpressure).getBank()); backpressure = NULL; } @@ -339,7 +284,7 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload, payload.release(); } else { SC_REPORT_FATAL(0, - "Frontend PEQ event queue in controller wrapper was triggered with unknown phase"); + "Front-end PEQ in controller wrapper was triggered with unknown phase"); } } @@ -381,7 +326,6 @@ unsigned int Controller::getTotalNumberOfPayloadsInSystem() void Controller::scheduleNextFromScheduler(Bank bank) { - if (controllerCore->bankIsBusy(bank)) { return; } @@ -390,11 +334,7 @@ void Controller::scheduleNextFromScheduler(Bank bank) pair nextRequest = scheduler->getNextRequest(bank); if (nextRequest.second != NULL) { - controllerCore->powerDownManager->wakeUp(DramExtension::getExtension( - nextRequest.second).getBank(), sc_time_stamp()); - controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second); - printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString( - nextRequest.first) + "]"); + schedule(nextRequest.first, *nextRequest.second); } else { gp *pendingRequest = scheduler->getPendingRequest(bank); if (pendingRequest != NULL) { @@ -412,11 +352,7 @@ void Controller::scheduleNextFromScheduler(Bank bank) pair nextRequest = scheduler->getNextRequest(bank); if (nextRequest.second != NULL) { - controllerCore->powerDownManager->wakeUp(DramExtension::getExtension( - nextRequest.second).getBank(), sc_time_stamp()); - controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second); - printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString( - nextRequest.first) + "] (unblocked)"); + schedule(nextRequest.first, *nextRequest.second); } else { gp *pendingRequest = scheduler->getPendingRequest(bank); if (pendingRequest != NULL) { @@ -433,6 +369,16 @@ void Controller::scheduleNextFromScheduler(Bank bank) blockedRequests = blocked; } +void Controller::schedule(Command command, gp &payload) +{ + controllerCore->powerDownManager->wakeUp(DramExtension::getBank(payload), + sc_time_stamp()); + if (controllerCore->scheduleRequest(command, payload)) { + printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString( + command) + "] (unblocked)"); + } +} + void Controller::sendToFrontend(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) { @@ -444,26 +390,9 @@ void Controller::sendToFrontend(tlm_generic_payload &payload, tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) { - sc_time recTime = bwDelay + sc_time_stamp(); - sc_time notDelay = bwDelay; - - unsigned int thr = DramExtension::getExtension(payload).getThread().ID(); - unsigned int ch = DramExtension::getExtension(payload).getChannel().ID(); - unsigned int bg = DramExtension::getExtension(payload).getBankGroup().ID(); - unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); - unsigned int row = DramExtension::getExtension(payload).getRow().ID(); - unsigned int col = DramExtension::getExtension(payload).getColumn().ID(); - - printDebugMessage("[bw] Recording " + phaseNameToString( - phase) + " thread " + to_string(thr) + " channel " + to_string( - ch) + " bank group " + to_string(bg) + " bank " + to_string( - bank) + " row " + to_string(row) + " column " + to_string( - col) + " at " + recTime.to_string() + " notification in " + - notDelay.to_string()); - - dramPEQ.notify(payload, phase, notDelay); - tlmRecorder->recordPhase(payload, phase, recTime); - + printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " + + bwDelay.to_string()); + dramPEQ.notify(payload, phase, bwDelay); return TLM_ACCEPTED; } @@ -510,7 +439,7 @@ void Controller::dramPEQCallback(tlm_generic_payload &payload, // scheduler implementation) } else { string str = - string("dramPEQCallback queue in controller wrapper was triggered with unsupported phase ") + string("DRAM PEQ in controller wrapper was triggered with unsupported phase ") + phaseNameToString(phase); SC_REPORT_FATAL(0, str.c_str()); } diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index 90c787f3..f09fedfa 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -80,11 +80,11 @@ DECLARE_EXTENDED_PHASE(PendingRequest); class Controller: public sc_module, public IController { public: - Controller(sc_module_name /*name*/, TlmRecorder *rec) : + Controller(sc_module_name /*name*/) : frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ(this, &Controller::controllerCorePEQCallback), - debugManager(DebugManager::getInstance()), tlmRecorder(rec) + debugManager(DebugManager::getInstance()) { controllerCore = new ControllerCore("core", *this, numberOfPayloadsInSystem); buildScheduler(); @@ -121,27 +121,28 @@ public: return controllerThreadId; } -private: +protected: void buildScheduler(); void payloadEntersSystem(tlm_generic_payload &payload); void payloadLeavesSystem(tlm_generic_payload &payload); // --- FRONTEND ------ - tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload, tlm_phase &phase, - sc_time &fwDelay); + virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &fwDelay); virtual unsigned int transport_dbg(tlm::tlm_generic_payload &trans); void frontendPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase); - void sendToFrontend(tlm_generic_payload &payload, const tlm_phase &phase, - const sc_time &delay); + virtual void sendToFrontend(tlm_generic_payload &payload, + const tlm_phase &phase, const sc_time &delay); // --- DRAM ------ - tlm_sync_enum nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, - sc_time &bwDelay); + virtual tlm_sync_enum nb_transport_bw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &bwDelay); void dramPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase); void sendToDram(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay); // ------- CONTROLLER CORE --------- + virtual void schedule(Command command, gp &payload); void controllerCorePEQCallback(tlm_generic_payload &payload, const tlm_phase &phase); @@ -161,7 +162,6 @@ private: tlm_utils::peq_with_cb_and_phase controllerCorePEQ; DebugManager &debugManager; - TlmRecorder *tlmRecorder; // Bandwidth realted: sc_time idleStart; diff --git a/DRAMSys/library/src/controller/RecordableController.cpp b/DRAMSys/library/src/controller/RecordableController.cpp new file mode 100644 index 00000000..51ff4f21 --- /dev/null +++ b/DRAMSys/library/src/controller/RecordableController.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2018, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Felipe S. Prado + * Matthias Jung + */ + +#include "RecordableController.h" + +tlm_sync_enum RecordableController::nb_transport_fw(tlm_generic_payload + &payload, tlm_phase &phase, sc_time &fwDelay) +{ + recordPhase(payload, phase, fwDelay); + + return Controller::nb_transport_fw(payload, phase, fwDelay); +} + +void RecordableController::sendToFrontend(tlm_generic_payload &payload, + const tlm_phase &phase, const sc_time &delay) +{ + recordPhase(payload, phase, delay); + + Controller::sendToFrontend(payload, phase, delay); +} + +tlm_sync_enum RecordableController::nb_transport_bw(tlm_generic_payload + &payload, tlm_phase &phase, sc_time &bwDelay) +{ + recordPhase(payload, phase, bwDelay); + + return Controller::nb_transport_bw(payload, phase, bwDelay); +} + +void RecordableController::recordPhase(tlm::tlm_generic_payload &trans, + tlm::tlm_phase phase, sc_time delay) +{ + sc_time recTime = delay + sc_time_stamp(); + + unsigned int thr = DramExtension::getExtension(trans).getThread().ID(); + unsigned int ch = DramExtension::getExtension(trans).getChannel().ID(); + unsigned int bg = DramExtension::getExtension(trans).getBankGroup().ID(); + unsigned int bank = DramExtension::getExtension(trans).getBank().ID(); + unsigned int row = DramExtension::getExtension(trans).getRow().ID(); + unsigned int col = DramExtension::getExtension(trans).getColumn().ID(); + + printDebugMessage("Recording " + phaseNameToString(phase) + " thread " + + to_string(thr) + " channel " + to_string(ch) + " bank group " + to_string( + bg) + " bank " + to_string(bank) + " row " + to_string(row) + " column " + + to_string(col) + " at " + recTime.to_string()); + + tlmRecorder->recordPhase(trans, phase, recTime); +} + +void RecordableController::schedule(Command command, gp &payload) +{ + Controller::schedule(command, payload); + if (commandIsIn(command, {Command::Read, Command::ReadA, Command::Write, Command::WriteA})) { + ScheduledCommand scheduledCommand = controllerCore->state->getLastCommand( + command, DramExtension::getBank(payload)); + TimeInterval dataStrobe = scheduledCommand.getIntervalOnDataStrobe(); + tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); + } +} diff --git a/DRAMSys/library/src/controller/RecordableController.h b/DRAMSys/library/src/controller/RecordableController.h new file mode 100644 index 00000000..3f37870c --- /dev/null +++ b/DRAMSys/library/src/controller/RecordableController.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Felipe S. Prado + * Matthias Jung + */ + +#ifndef RECORDABLECONTROLLER_H +#define RECORDABLECONTROLLER_H + +#include "Controller.h" + +struct RecordableController: public Controller { +public: + RecordableController(sc_module_name name, TlmRecorder *rec) : + Controller(name), tlmRecorder(rec) + { + } + +protected: + TlmRecorder *tlmRecorder; + + virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &fwDelay) override; + virtual tlm_sync_enum nb_transport_bw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &bwDelay) override; + virtual void sendToFrontend(tlm_generic_payload &payload, + const tlm_phase &phase, const sc_time &delay) override; + virtual void schedule(Command command, tlm_generic_payload &payload) override; + + void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, + sc_time delay); +}; + +#endif // RECORDABLECONTROLLER_H diff --git a/DRAMSys/library/src/controller/core/ControllerCore.cpp b/DRAMSys/library/src/controller/core/ControllerCore.cpp index 0a9f434a..fd278bb6 100644 --- a/DRAMSys/library/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/library/src/controller/core/ControllerCore.cpp @@ -166,7 +166,7 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload &payload) } } -void ControllerCore::scheduleRequest(Command command, +bool ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload &payload) { sc_time start = clkAlign(sc_time_stamp()); @@ -175,13 +175,16 @@ void ControllerCore::scheduleRequest(Command command, if (config.ControllerCoreDisableRefresh == true) { state->change(scheduledCommand); controller.send(scheduledCommand, payload); + return true; } else { if (!((command == Command::Precharge || command == Command::Activate) && refreshManager->hasCollision(scheduledCommand))) { state->change(scheduledCommand); controller.send(scheduledCommand, payload); + return true; } } + return false; } ScheduledCommand ControllerCore::schedule(Command command, sc_time start, @@ -236,7 +239,6 @@ bool ControllerCore::bankIsBusy(Bank bank) SC_REPORT_FATAL("Core", "Last command unkown"); return false; } - } const std::vector &ControllerCore::getBanks() diff --git a/DRAMSys/library/src/controller/core/ControllerCore.h b/DRAMSys/library/src/controller/core/ControllerCore.h index 7a3818ef..7b00f1ea 100644 --- a/DRAMSys/library/src/controller/core/ControllerCore.h +++ b/DRAMSys/library/src/controller/core/ControllerCore.h @@ -58,7 +58,7 @@ public: std::map &numberOfPayloads); virtual ~ControllerCore(); - void scheduleRequest(Command command, tlm::tlm_generic_payload &payload); + bool scheduleRequest(Command command, tlm::tlm_generic_payload &payload); void triggerRefresh(tlm::tlm_generic_payload &payload); const std::vector &getBanks(); diff --git a/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.cpp b/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.cpp index 45923fdd..93cab1a6 100644 --- a/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.cpp +++ b/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.cpp @@ -172,7 +172,6 @@ void PowerDownManager::sendPowerDownPayload(ScheduledCommand &pdnToSend) pdnToSend.getCommand()) + " on bank " + to_string(pdnToSend.getBank().ID()) + " start time " + pdnToSend.getStart().to_string() + " end time " + pdnToSend.getEnd().to_string()); - } void PowerDownManager::setPowerDownState(PowerDownState state) diff --git a/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.cpp b/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.cpp index 34ed336e..3b367eda 100644 --- a/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.cpp @@ -45,7 +45,6 @@ bool ScheduledCommand::isNoCommand() const && executionTime == SC_ZERO_TIME && end == SC_ZERO_TIME); } - bool ScheduledCommand::isValidCommand() const { return !isNoCommand(); diff --git a/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.h b/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.h index 8bb57653..c2a5a2fc 100644 --- a/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.h +++ b/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.h @@ -62,7 +62,6 @@ public: { } - ScheduledCommand() : command(Command::NOP), start(SC_ZERO_TIME), executionTime(SC_ZERO_TIME), end(SC_ZERO_TIME), extension() diff --git a/DRAMSys/library/src/controller/scheduler/Fifo.cpp b/DRAMSys/library/src/controller/scheduler/Fifo.cpp index fe041319..6eb46aa8 100644 --- a/DRAMSys/library/src/controller/scheduler/Fifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/Fifo.cpp @@ -38,7 +38,7 @@ using namespace std; -void Fifo::schedule(gp *payload) +void Fifo::storeRequest(gp *payload) { buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); } diff --git a/DRAMSys/library/src/controller/scheduler/Fifo.h b/DRAMSys/library/src/controller/scheduler/Fifo.h index 7194fad6..912570d2 100644 --- a/DRAMSys/library/src/controller/scheduler/Fifo.h +++ b/DRAMSys/library/src/controller/scheduler/Fifo.h @@ -50,7 +50,7 @@ public: Fifo(ControllerCore &controllerCore) : IScheduler(controllerCore) {} virtual ~Fifo() {} - void schedule(gp *payload) override; + void storeRequest(gp *payload) override; std::pair getNextRequest( Bank bank) override; virtual gp *getPendingRequest(Bank bank) override; diff --git a/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp b/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp index 035031d0..9b3f8ec3 100644 --- a/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp +++ b/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp @@ -38,7 +38,7 @@ #include "FifoStrict.h" -void FifoStrict::schedule(tlm::tlm_generic_payload *payload) +void FifoStrict::storeRequest(tlm::tlm_generic_payload *payload) { Bank bank = DramExtension::getExtension(payload).getBank(); buffer.push_back(std::pair(bank, payload)); diff --git a/DRAMSys/library/src/controller/scheduler/FifoStrict.h b/DRAMSys/library/src/controller/scheduler/FifoStrict.h index 74e85b2e..acd22086 100644 --- a/DRAMSys/library/src/controller/scheduler/FifoStrict.h +++ b/DRAMSys/library/src/controller/scheduler/FifoStrict.h @@ -56,7 +56,7 @@ public: controller(controller) {} virtual ~FifoStrict() {} - void schedule(gp *payload) override; + void storeRequest(gp *payload) override; std::pair getNextRequest( Bank bank) override; virtual gp *getPendingRequest(Bank bank) override; diff --git a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp b/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp index a50212e6..05a4e745 100644 --- a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp @@ -58,9 +58,8 @@ using namespace std; // Bank6: OOOOO0XX // Bank7: XXXXXXXX -void FR_FCFS::schedule(gp *payload) +void FR_FCFS::storeRequest(gp *payload) { - // FIXME: Question: what if the buffer is full? IMHO the schedule function // should provide a true or false when the placement into the buffer worked // out or not (?). diff --git a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.h b/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.h index 02b46ca0..983c664a 100644 --- a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.h +++ b/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.h @@ -51,7 +51,7 @@ public: FR_FCFS(ControllerCore &controllerCore) : IScheduler(controllerCore) {} virtual ~FR_FCFS() {} - void schedule(gp *payload) override; + void storeRequest(gp *payload) override; std::pair getNextRequest( Bank bank) override; virtual gp *getPendingRequest(Bank bank) override; diff --git a/DRAMSys/library/src/controller/scheduler/IScheduler.h b/DRAMSys/library/src/controller/scheduler/IScheduler.h index 7d7837a6..0b0cf0f5 100644 --- a/DRAMSys/library/src/controller/scheduler/IScheduler.h +++ b/DRAMSys/library/src/controller/scheduler/IScheduler.h @@ -52,7 +52,7 @@ public: virtual ~IScheduler() {} IScheduler(ControllerCore &controllerCore) : controllerCore(controllerCore) {} - virtual void schedule(gp *payload) = 0; + virtual void storeRequest(gp *payload) = 0; virtual std::pair getNextRequest(Bank bank) = 0; virtual gp *getPendingRequest(Bank bank) = 0; static std::string sendername; diff --git a/DRAMSys/library/src/controller/scheduler/SMS.cpp b/DRAMSys/library/src/controller/scheduler/SMS.cpp index 9406237a..0f407775 100644 --- a/DRAMSys/library/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/library/src/controller/scheduler/SMS.cpp @@ -3,7 +3,7 @@ using namespace std; -void SMS::schedule(gp *payload) +void SMS::storeRequest(gp *payload) { Thread thread = DramExtension::getExtension(payload).getThread(); bool wasEmpty = isRequestBuffersEmpty(); diff --git a/DRAMSys/library/src/controller/scheduler/SMS.h b/DRAMSys/library/src/controller/scheduler/SMS.h index 0cb18882..d60c033a 100644 --- a/DRAMSys/library/src/controller/scheduler/SMS.h +++ b/DRAMSys/library/src/controller/scheduler/SMS.h @@ -46,7 +46,7 @@ public: { } - virtual void schedule(gp *payload) override; + virtual void storeRequest(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; virtual gp *getPendingRequest(Bank bank) override; diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 027184d2..7f60913d 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -79,11 +79,6 @@ public: tSocket.register_transport_dbg(this, &Arbiter::transport_dbg); } - void setTlmRecorders(std::vector recorders) - { - tlmRecorders = recorders; - } - private: tlm_utils::peq_with_cb_and_phase payloadEventQueue; @@ -96,8 +91,6 @@ private: // This is a queue of responses comming from the memory side. The phase of these transactions is BEGIN_RESP. std::map> receivedResponses; - std::vector tlmRecorders; - //used to map the transaction from devices to the arbiter's target socket ID. std::map routeMap; @@ -111,15 +104,10 @@ private: payload).getChannel().ID()) { SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted"); } - sc_time recTime = bwDelay + sc_time_stamp(); - sc_time notDelay = bwDelay; - printDebugMessage("[bw] Recording " + phaseNameToString( - phase) + " at " + recTime.to_string() + " notification in " + - notDelay.to_string()); - - tlmRecorders[channelId]->recordPhase(payload, phase, recTime); - payloadEventQueue.notify(payload, phase, notDelay); + printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " + + bwDelay.to_string()); + payloadEventQueue.notify(payload, phase, bwDelay); return TLM_ACCEPTED; } @@ -128,6 +116,8 @@ private: tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) { + sc_time notDelay = clkAlign(sc_time_stamp() + fwDelay) - + (sc_time_stamp() + fwDelay); if (phase == BEGIN_REQ) { // adjust address offset: payload.set_address(payload.get_address() - @@ -141,12 +131,15 @@ private: appendDramExtension(id, payload); payload.acquire(); } else if (phase == END_RESP) { + notDelay += Configuration::getInstance().memSpec.clk; // Erase before the payload is released. routeMap.erase(&payload); payload.release(); } - payloadEventQueue.notify(payload, phase, fwDelay); + printDebugMessage("[fw] " + phaseNameToString(phase) + " notification in " + + notDelay.to_string()); + payloadEventQueue.notify(payload, phase, notDelay); return TLM_ACCEPTED; } diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 031e4bc4..a1b48a58 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -198,8 +198,7 @@ void DRAMSys::setupTlmRecorders(const string &traceName, TlmRecorder *tlmRecorder = new TlmRecorder(recorderName.c_str(), sqlScriptURI.c_str(), - dbName.c_str(), - Configuration::getInstance().DatabaseRecording); + dbName.c_str()); tlmRecorder->recordMCconfig(Configuration::getInstance().mcconfigUri); tlmRecorder->recordMemspec(Configuration::getInstance().memspecUri); @@ -219,7 +218,9 @@ void DRAMSys::instantiateModules(const string &traceName, // Create and properly initialize TLM recorders. // They need to be ready before creating some modules. - setupTlmRecorders(traceName, pathToResources); + bool recordingEnabled = Configuration::getInstance().DatabaseRecording; + if (recordingEnabled) + setupTlmRecorders(traceName, pathToResources); // Create new ECC Controller switch (Configuration::getInstance().ECCMode) { @@ -236,19 +237,26 @@ void DRAMSys::instantiateModules(const string &traceName, // Create arbiter arbiter = new Arbiter("arbiter"); - arbiter->setTlmRecorders(tlmRecorders); // Create DRAM for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) { std::string str = "controller" + std::to_string(i); - Controller *controller = new Controller(str.c_str(), tlmRecorders[i]); + + Controller *controller; + if (recordingEnabled) + controller = new RecordableController(str.c_str(), tlmRecorders[i]); + else + controller = new Controller(str.c_str()); controllers.push_back(controller); str = "dram" + std::to_string(i); - Dram *dram = new Dram(str.c_str()); - dram->setTlmRecorder(tlmRecorders[i]); + Dram *dram; + if (recordingEnabled) + dram = new RecordableDram(str.c_str(), tlmRecorders[i]); + else + dram = new Dram(str.c_str()); dram->setDramController(controllers[i]); drams.push_back(dram); diff --git a/DRAMSys/library/src/simulation/DRAMSys.h b/DRAMSys/library/src/simulation/DRAMSys.h index 0a3c2337..25bf4bad 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.h +++ b/DRAMSys/library/src/simulation/DRAMSys.h @@ -42,13 +42,13 @@ #include #include -#include "Dram.h" +#include "RecordableDram.h" #include "Arbiter.h" #include "TraceGenerator.h" #include "ReorderBuffer.h" #include #include -#include "../controller/Controller.h" +#include "../controller/RecordableController.h" #include "../common/third_party/tinyxml2/tinyxml2.h" #include "../common/tlm2_base_protocol_checker.h" #include "../error/eccbaseclass.h" diff --git a/DRAMSys/library/src/simulation/Dram.h b/DRAMSys/library/src/simulation/Dram.h index be46ff2a..566f9b83 100644 --- a/DRAMSys/library/src/simulation/Dram.h +++ b/DRAMSys/library/src/simulation/Dram.h @@ -56,7 +56,6 @@ #include "../controller/core/configuration/Configuration.h" #include "../common/protocol.h" #include "../common/Utils.h" -#include "../common/TlmRecorder.h" #include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" #include "../error/errormodel.h" @@ -72,8 +71,6 @@ struct Dram : sc_module { // Power Model related bool powerAnalysis = Configuration::getInstance().PowerAnalysis; - sc_time powerWindowSize = Configuration::getInstance().memSpec.clk * - Configuration::getInstance().WindowSize; libDRAMPower *DRAMPower; // Bandwidth realted: @@ -88,7 +85,6 @@ struct Dram : sc_module { // Data Storage: unsigned char *memory; - TlmRecorder *tlmRecorder; Controller *dramController; SC_CTOR(Dram) : tSocket("socket") @@ -97,7 +93,6 @@ struct Dram : sc_module { bytesPerBurst = Configuration::getInstance().adjustNumBytesAfterECC( bytesPerBurst); dramController = NULL; - tlmRecorder = NULL; std::uint64_t memorySize = Configuration::getInstance().getSimMemSizeInBytes(); // allocate and model storage of one DRAM channel using memory map @@ -209,11 +204,6 @@ struct Dram : sc_module { memSpec.memArchSpec = memArchSpec; DRAMPower = new libDRAMPower( memSpec, 0 ); - - // Create a thread that is triggered every $powerWindowSize - // to generate a Power over Time plot in the Trace analyzer: - if (Configuration::getInstance().EnableWindowing) - SC_THREAD(powerWindow); } // Bandwidth Calculation: @@ -244,13 +234,8 @@ struct Dram : sc_module { ~Dram() { if (powerAnalysis == true) { - // Obtain the residual energy which was not covered by - // previous windows - DRAMPower->calcEnergy(); - - tlmRecorder->recordPower(sc_time_stamp().to_seconds(), - DRAMPower->getPower().window_average_power - * Configuration::getInstance().NumberOfDevicesOnDIMM); + if (!Configuration::getInstance().DatabaseRecording) + DRAMPower->calcEnergy(); // Print the final total energy and the average power for // the simulation: @@ -313,88 +298,18 @@ struct Dram : sc_module { for (auto e : ememory) { delete e; } - - tlmRecorder->closeConnection(); - } - - // When working with floats, we have to decide ourselves what is an - // acceptable definition for "equal". Here the number is compared with a - // suitable error margin (0.00001). - bool is_equal(double a, double b, const double epsilon = 1e-05) - { - return std::fabs(a - b) < epsilon; - } - - // This Thread is only triggered when Power Simulation is enabled. - // It estimates the current average power which will be stored in the trace database for visualization purposes. - void powerWindow() - { - unsigned long long clk_cycles = 0; - - do { - // At the very beginning (zero clock cycles) the energy is 0, so we wait first - wait(powerWindowSize); - - clk_cycles = sc_time_stamp().value() / - Configuration::getInstance().memSpec.clk.value(); - - DRAMPower->calcWindowEnergy(clk_cycles); - - // During operation the energy should never be zero since the device is always consuming - assert(!is_equal(DRAMPower->getEnergy().window_energy, 0.0)); - - // Store the time (in seconds) and the current average power (in mW) into the database - tlmRecorder->recordPower(sc_time_stamp().to_seconds(), - DRAMPower->getPower().window_average_power * - Configuration::getInstance().NumberOfDevicesOnDIMM); - - // Here considering that DRAMPower provides the energy in pJ and the power in mW - printDebugMessage(string("\tWindow Energy: \t") + to_string( - DRAMPower->getEnergy().window_energy * - Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[pJ]")); - printDebugMessage(string("\tWindow Average Power: \t") + to_string( - DRAMPower->getPower().window_average_power * - Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[mW]")); - - } while (true); } virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &delay) { - // Recording time used by the traceAnalyzer - sc_time recTime = sc_time_stamp() + delay; - if (numberOfTransactionsServed == 0) { firstAccess = sc_time_stamp(); } else { lastAccess = sc_time_stamp(); } - - // These are terminating phases recorded by the DRAM. The execution - // time of the related command must be taken into consideration. - if (phase == END_PDNA || phase == END_PDNAB) { - recTime += getExecutionTime(Command::PDNAX, payload); - } else if (phase == END_PDNP || phase == END_PDNPB) { - recTime += getExecutionTime(Command::PDNPX, payload); - } else if (phase == END_SREF || phase == END_SREFB) { - recTime += getExecutionTime(Command::SREFX, payload); - } - - unsigned int thr = DramExtension::getExtension(payload).getThread().ID(); - unsigned int ch = DramExtension::getExtension(payload).getChannel().ID(); - unsigned int bg = DramExtension::getExtension(payload).getBankGroup().ID(); unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); - unsigned int row = DramExtension::getExtension(payload).getRow().ID(); - unsigned int col = DramExtension::getExtension(payload).getColumn().ID(); - - printDebugMessage("[fw] Recording " + phaseNameToString( - phase) + " thread " + to_string(thr) + " channel " + to_string( - ch) + " bank group " + to_string(bg) + " bank " + to_string( - bank) + " row " + to_string(row) + " column " + to_string( - col) + " at " + recTime.to_string()); - tlmRecorder->recordPhase(payload, phase, recTime); // This is only needed for power simulation: unsigned long long cycle = 0; @@ -650,10 +565,6 @@ struct Dram : sc_module { DebugManager::getInstance().printDebugMessage(name(), message); } - void setTlmRecorder(TlmRecorder *rec) - { - tlmRecorder = rec; - } void setDramController(Controller *contr) { dramController = contr; diff --git a/DRAMSys/library/src/simulation/RecordableDram.h b/DRAMSys/library/src/simulation/RecordableDram.h new file mode 100644 index 00000000..00a2d073 --- /dev/null +++ b/DRAMSys/library/src/simulation/RecordableDram.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2018, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Felipe S. Prado + * Matthias Jung + */ + +#ifndef RECORDABLEDRAM_H_ +#define RECORDABLEDRAM_H_ + +#include "Dram.h" +#include "../common/TlmRecorder.h" + +struct RecordableDram : public Dram { + SC_HAS_PROCESS(RecordableDram); + RecordableDram(sc_module_name name, TlmRecorder *tlmRecorder): + Dram(name), tlmRecorder(tlmRecorder) + { + // Create a thread that is triggered every $powerWindowSize + // to generate a Power over Time plot in the Trace analyzer: + if (Configuration::getInstance().PowerAnalysis + && Configuration::getInstance().EnableWindowing) + SC_THREAD(powerWindow); + } + + ~RecordableDram() + { + if (Configuration::getInstance().PowerAnalysis) { + // Obtain the residual energy which was not covered by + // previous windows + DRAMPower->calcEnergy(); + recordPower(); + } + tlmRecorder->closeConnection(); + } + + TlmRecorder *tlmRecorder; + sc_time powerWindowSize = Configuration::getInstance().memSpec.clk * + Configuration::getInstance().WindowSize; + + virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, sc_time &delay) + { + // Recording time used by the traceAnalyzer + sc_time recTime = sc_time_stamp() + delay; + + // These are terminating phases recorded by the DRAM. The execution + // time of the related command must be taken into consideration. + if (phase == END_PDNA || phase == END_PDNAB) { + recTime += getExecutionTime(Command::PDNAX, payload); + } else if (phase == END_PDNP || phase == END_PDNPB) { + recTime += getExecutionTime(Command::PDNPX, payload); + } else if (phase == END_SREF || phase == END_SREFB) { + recTime += getExecutionTime(Command::SREFX, payload); + } + + unsigned int thr = DramExtension::getExtension(payload).getThread().ID(); + unsigned int ch = DramExtension::getExtension(payload).getChannel().ID(); + unsigned int bg = DramExtension::getExtension(payload).getBankGroup().ID(); + unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); + unsigned int row = DramExtension::getExtension(payload).getRow().ID(); + unsigned int col = DramExtension::getExtension(payload).getColumn().ID(); + + printDebugMessage("Recording " + phaseNameToString(phase) + " thread " + + to_string(thr) + " channel " + to_string(ch) + " bank group " + to_string( + bg) + " bank " + to_string(bank) + " row " + to_string(row) + " column " + + to_string(col) + " at " + recTime.to_string()); + + tlmRecorder->recordPhase(payload, phase, recTime); + + return Dram::nb_transport_fw(payload, phase, delay); + } + + // When working with floats, we have to decide ourselves what is an + // acceptable definition for "equal". Here the number is compared with a + // suitable error margin (0.00001). + bool is_equal(double a, double b, const double epsilon = 1e-05) + { + return std::fabs(a - b) < epsilon; + } + + // This Thread is only triggered when Power Simulation is enabled. + // It estimates the current average power which will be stored in the trace database for visualization purposes. + void powerWindow() + { + unsigned long long clk_cycles = 0; + + do { + // At the very beginning (zero clock cycles) the energy is 0, so we wait first + wait(powerWindowSize); + + clk_cycles = sc_time_stamp().value() / + Configuration::getInstance().memSpec.clk.value(); + + DRAMPower->calcWindowEnergy(clk_cycles); + + // During operation the energy should never be zero since the device is always consuming + assert(!is_equal(DRAMPower->getEnergy().window_energy, 0.0)); + + // Store the time (in seconds) and the current average power (in mW) into the database + recordPower(); + + // Here considering that DRAMPower provides the energy in pJ and the power in mW + printDebugMessage(string("\tWindow Energy: \t") + to_string( + DRAMPower->getEnergy().window_energy * + Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[pJ]")); + printDebugMessage(string("\tWindow Average Power: \t") + to_string( + DRAMPower->getPower().window_average_power * + Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[mW]")); + + } while (true); + } + + void recordPower() + { + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), + DRAMPower->getPower().window_average_power + * Configuration::getInstance().NumberOfDevicesOnDIMM); + } +}; + +#endif /* RECORDABLEDRAM_H_ */ + From 7ca63967660e8faf882c5e37c0ee918a05a6f245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 5 Jul 2018 13:12:39 +0200 Subject: [PATCH 19/19] Doc improved --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cf8df867..b14bbbd6 100644 --- a/README.md +++ b/README.md @@ -889,7 +889,7 @@ initiated. If, at any point, requests start coming in, the burst is interrupted, meaning that the maximum amount of time, considering the worst case scenario (a request arrives at the same time a REF was issued), is a refresh cycle time (tRFC). The advantage of pulling-in refreshes is that they -will not issued in the near future (in their actual times), allowing for more +will not be issued in the near future (in their actual times), allowing for more efficient accesses to the memory. **Postpone Refresh** @@ -899,7 +899,9 @@ requests on the buffer. Buffered requests may generate row-hits, so postponing refreshes may be beneficial for it avoids breaking row-hit sequences what reduces the number of commands (e.g., ACT, PRE) to carry out the memory accesses. If the memory enters an idle state, a burst is issued for the same -number of REF commands that were postponed. +number of REF commands that were postponed. When the maximum allowed +number of postponed refreshes is reached a burst is issued in the next +refresh interval despite the memory state (busy or idle). **The Flexible Refresh FSM**