From 00f95b1587cc78db39bc25ce49797345f8818470 Mon Sep 17 00:00:00 2001 From: Matthias Jung Date: Mon, 5 May 2014 23:24:36 +0200 Subject: [PATCH] timeout pdn (state: not runnning yet) --- dram/.settings/language.settings.xml | 4 +- .../configs/memconfigs/memconfig.xml | 6 +- dram/resources/scripts/metrics.py | 7 +- dram/resources/scripts/tests.py | 124 ++++++++-------- dram/resources/simulations/sim-batch.xml | 6 +- dram/src/common/protocol.h | 4 +- dram/src/core/ControllerCore.cpp | 10 +- dram/src/core/ControllerState.cpp | 17 +++ dram/src/core/ControllerState.h | 1 + dram/src/core/configuration/Configuration.cpp | 15 ++ dram/src/core/configuration/Configuration.h | 11 ++ dram/src/core/configuration/MemSpecLoader.cpp | 22 ++- dram/src/core/powerdown/IPowerDownManager.h | 7 +- dram/src/core/powerdown/PowerDownManager.cpp | 6 + dram/src/core/powerdown/PowerDownManager.h | 1 + .../powerdown/PowerDownManagerBankwise.cpp | 6 + .../core/powerdown/PowerDownManagerBankwise.h | 1 + .../powerdown/PowerDownManagerTimeout.cpp | 140 ++++++++++++++++++ .../core/powerdown/PowerDownManagerTimeout.h | 51 +++++++ dram/src/core/refresh/RefreshManager.cpp | 2 +- .../core/refresh/RefreshManagerBankwise.cpp | 2 +- dram/src/core/scheduling/Trigger.h | 2 +- dram/src/simulation/Controller.h | 51 +++++-- dram/src/simulation/main.cpp | 3 +- 24 files changed, 399 insertions(+), 100 deletions(-) create mode 100644 dram/src/core/powerdown/PowerDownManagerTimeout.cpp create mode 100644 dram/src/core/powerdown/PowerDownManagerTimeout.h diff --git a/dram/.settings/language.settings.xml b/dram/.settings/language.settings.xml index 26f9f756..ae137ce7 100644 --- a/dram/.settings/language.settings.xml +++ b/dram/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + @@ -14,7 +14,7 @@ - + diff --git a/dram/resources/configs/memconfigs/memconfig.xml b/dram/resources/configs/memconfigs/memconfig.xml index 7ace3024..97697f61 100644 --- a/dram/resources/configs/memconfigs/memconfig.xml +++ b/dram/resources/configs/memconfigs/memconfig.xml @@ -1,11 +1,13 @@ - + + + - \ No newline at end of file + diff --git a/dram/resources/scripts/metrics.py b/dram/resources/scripts/metrics.py index 0986bc73..c84734af 100644 --- a/dram/resources/scripts/metrics.py +++ b/dram/resources/scripts/metrics.py @@ -1,6 +1,5 @@ import sys import sqlite3 -import pystaggrelite3 metrics = [] threadMetrics = [] @@ -248,8 +247,8 @@ def passRatio(connection): def calculateMetrics(pathToTrace): connection = sqlite3.connect(pathToTrace) - connection.create_aggregate("median", 1, pystaggrelite3.median) - connection.create_aggregate("stdev", 1, pystaggrelite3.stdev) + #connection.create_aggregate("median", 1, pystaggrelite3.median) + #connection.create_aggregate("stdev", 1, pystaggrelite3.stdev) calculatedMetrics = [] @@ -281,4 +280,4 @@ def calculateMetrics(pathToTrace): if __name__ == "__main__": path = sys.argv[1] calculateMetrics(path) - \ No newline at end of file + diff --git a/dram/resources/scripts/tests.py b/dram/resources/scripts/tests.py index 14e3bf89..e1184e7c 100644 --- a/dram/resources/scripts/tests.py +++ b/dram/resources/scripts/tests.py @@ -1,12 +1,11 @@ import sys +import traceback import sqlite3 -import math import os import xml.etree.ElementTree as ET -from sets import Set def getPathToConfigs(): - return os.path.dirname(__file__).replace("/scripts","/configs") + return os.path.dirname(os.path.abspath(__file__).replace("/scripts","/configs")) def getValueFromConfigXML(root, id): return root.findall(".//parameter[@id='{0}']".format(id))[0].attrib['value'] @@ -192,33 +191,33 @@ def commands_are_clockaligned(connection): cursor = connection.cursor() query = "select ID,PhaseBegin,PhaseEnd from phases where phaseName NOT IN ('REQ','RESP') AND (phaseBegin%:clk!=0 OR phaseEnd%:clk!=0)" - cursor.execute(query, {"clk": dramconfig.clk}) + cursor.execute(query, {"clk": dramconfig.clk}) - result = cursor.fetchone() - - if(result != None): - return TestFailed("Command with PhaseID {0} starts at {1} and ends at. One of those times. is not aligned to system clock ({2})" - .format(result[0], formatTime(result[1]), formatTime(result[2]), formatTime(dramconfig.clk))) + result = cursor.fetchone() + + if(result != None): + return TestFailed("Command with PhaseID {0} starts at {1} and ends at. One of those times. is not aligned to system clock ({2})" + .format(result[0], formatTime(result[1]), formatTime(result[2]), formatTime(dramconfig.clk))) return TestSuceeded() @test def commandbus_slots_are_used_once(connection): """Checks that no two phases on the command bus start at the same time""" - + cursor = connection.cursor() - if dramconfig.bankwiseLogic: - excludedPhases = "('REQ','RESP','PRE_ALL')" - else: - excludedPhases = "('REQ','RESP','PRE_ALL','PDNA','PDNP','SREF','AUTO_REFRESH')" - - query = """SELECT PhaseBegin,count FROM (SELECT phaseBegin,count(phasebegin) AS count + if dramconfig.bankwiseLogic: + excludedPhases = "('REQ','RESP','PRE_ALL')" + else: + excludedPhases = "('REQ','RESP','PRE_ALL','PDNA','PDNP','SREF','AUTO_REFRESH')" + + query = """SELECT PhaseBegin,count FROM (SELECT phaseBegin,count(phasebegin) AS count FROM Phases WHERE PhaseName NOT IN """ + excludedPhases + """ AND phasebegin>0 GROUP BY phaseBegin) WHERE count>1""" cursor.execute(query) - result = cursor.fetchone() + result = cursor.fetchone() if(result != None): - return TestFailed("Slot on commandbus at time {0} is used multiple times".format(formatTime(result[0]))) + return TestFailed("Slot on commandbus at time {0} is used multiple times".format(formatTime(result[0]))) return TestSuceeded() @@ -230,42 +229,42 @@ def phase_transitions_are_valid(connection): validTransitions = {} if(dramconfig.bankwiseLogic): - validTransitions['PRE'] = Set(['ACT', 'AUTO_REFRESH']) - validTransitions['ACT'] = Set(['RD', 'RDA', 'WR', 'WRA']) + validTransitions['PRE'] = set(['ACT', 'AUTO_REFRESH']) + validTransitions['ACT'] = set(['RD', 'RDA', 'WR', 'WRA']) - validTransitions['RD'] = Set(['PRE','RD','RDA', 'WR', 'WRA', 'PDNA']) - validTransitions['WR'] = Set(['PRE', 'RD','RDA', 'WR', 'WRA', 'PDNA']) - validTransitions['RDA'] = Set(['ACT', 'AUTO_REFRESH', 'PDNP']) - validTransitions['WRA'] = Set(['ACT', 'AUTO_REFRESH', 'PDNP']) + validTransitions['RD'] = set(['PRE','RD','RDA', 'WR', 'WRA', 'PDNA']) + validTransitions['WR'] = set(['PRE', 'RD','RDA', 'WR', 'WRA', 'PDNA']) + validTransitions['RDA'] = set(['ACT', 'AUTO_REFRESH', 'PDNP']) + validTransitions['WRA'] = set(['ACT', 'AUTO_REFRESH', 'PDNP']) - validTransitions['AUTO_REFRESH'] = Set(['ACT', 'PDNP', 'SREF']) + validTransitions['AUTO_REFRESH'] = set(['ACT', 'PDNP', 'SREF']) - validTransitions['PDNA'] = Set(['PRE', 'RD','RDA', 'WR', 'WRA', 'AUTO_REFRESH']) - validTransitions['PDNP'] = Set(['ACT', 'AUTO_REFRESH']) - validTransitions['SREF'] = Set(['ACT']) + validTransitions['PDNA'] = set(['PRE', 'RD','RDA', 'WR', 'WRA', 'AUTO_REFRESH']) + validTransitions['PDNP'] = set(['ACT', 'AUTO_REFRESH']) + validTransitions['SREF'] = set(['ACT']) else: - validTransitions['PRE'] = Set(['ACT']) - validTransitions['PRE_ALL'] = Set(['AUTO_REFRESH']) - validTransitions['ACT'] = Set(['RD', 'RDA', 'WR', 'WRA']) + validTransitions['PRE'] = set(['ACT']) + validTransitions['PRE_ALL'] = set(['AUTO_REFRESH']) + validTransitions['ACT'] = set(['RD', 'RDA', 'WR', 'WRA']) - validTransitions['RD'] = Set(['PRE', 'PRE_ALL','RD','RDA', 'WR', 'WRA', 'PDNA']) - validTransitions['WR'] = Set(['PRE', 'PRE_ALL','RD','RDA', 'WR', 'WRA', 'PDNA']) - validTransitions['RDA'] = Set(['PRE_ALL', 'ACT', 'AUTO_REFRESH', 'PDNA', 'PDNP']) - validTransitions['WRA'] = Set(['PRE_ALL', 'ACT', 'AUTO_REFRESH', 'PDNA', 'PDNP']) + validTransitions['RD'] = set(['PRE', 'PRE_ALL','RD','RDA', 'WR', 'WRA', 'PDNA']) + validTransitions['WR'] = set(['PRE', 'PRE_ALL','RD','RDA', 'WR', 'WRA', 'PDNA']) + validTransitions['RDA'] = set(['PRE_ALL', 'ACT', 'AUTO_REFRESH', 'PDNA', 'PDNP']) + validTransitions['WRA'] = set(['PRE_ALL', 'ACT', 'AUTO_REFRESH', 'PDNA', 'PDNP']) - validTransitions['AUTO_REFRESH'] = Set(['PRE_ALL', 'ACT','AUTO_REFRESH', 'PDNA', 'PDNP', 'SREF']) + validTransitions['AUTO_REFRESH'] = set(['PRE_ALL', 'ACT','AUTO_REFRESH', 'PDNA', 'PDNP', 'SREF']) - validTransitions['PDNA'] = Set(['PRE','PRE_ALL','ACT', 'RD', 'RDA', 'WR', 'WRA', 'AUTO_REFRESH', 'PDNA', 'PDNP']) - validTransitions['PDNP'] = Set(['PRE_ALL', 'ACT', 'AUTO_REFRESH', 'PDNA', 'PDNP']) - validTransitions['SREF'] = Set(['PRE_ALL', 'ACT', 'AUTO_REFRESH', 'PDNA', 'PDNP']) + validTransitions['PDNA'] = set(['PRE','PRE_ALL','ACT', 'RD', 'RDA', 'WR', 'WRA', 'AUTO_REFRESH', 'PDNA', 'PDNP']) + validTransitions['PDNP'] = set(['PRE_ALL', 'ACT', 'AUTO_REFRESH', 'PDNA', 'PDNP']) + validTransitions['SREF'] = set(['PRE_ALL', 'ACT', 'AUTO_REFRESH', 'PDNA', 'PDNP']) query = """SELECT PhaseName, phases.ID FROM phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE TBank=:bank AND PhaseName NOT IN ('REQ','RESP') ORDER BY PhaseBegin""" for bankNumber in range(dramconfig.numberOfBanks): - cursor.execute(query, {"bank": bankNumber}) - lastRow = cursor.fetchone() + cursor.execute(query, {"bank": bankNumber}) + lastRow = cursor.fetchone() for currentRow in cursor: currentPhase = currentRow[0] lastPhase = lastRow[0] @@ -337,8 +336,8 @@ def timing_constraits_on_the_same_bank_hold(connection): AND PhaseName NOT IN ('REQ','RESP') ORDER BY PhaseBegin""" for bankNumber in range(dramconfig.numberOfBanks): - cursor.execute(query, {"bank": bankNumber}) - lastRow = cursor.fetchone() + cursor.execute(query, {"bank": bankNumber}) + lastRow = cursor.fetchone() for currentRow in cursor: constraint = timing_constraint(lastRow,currentRow) @@ -367,7 +366,7 @@ def row_buffer_is_used_correctly(connection): idlePhases = set(['ACT', 'PDNP', 'AUTO_REFRESH', 'SREF']) for bankNumber in range(dramconfig.numberOfBanks): - cursor.execute(query,{"bank": bankNumber}) + cursor.execute(query,{"bank": bankNumber}) rowBufferIsClosed = True @@ -417,9 +416,9 @@ def activate_to_activate_on_same_bank_holds(connection): cursor = connection.cursor() query = "SELECT Phases.ID,PhaseBegin from Phases INNER JOIN Transactions ON Phases.Transact = Transactions.ID WHERE PhaseName = 'ACT' AND TBANK = :bank ORDER BY PhaseBegin" - for bankNumber in range(dramconfig.numberOfBanks): - cursor.execute(query,{"bank": bankNumber}) - lastRow = cursor.fetchone() + for bankNumber in range(dramconfig.numberOfBanks): + cursor.execute(query,{"bank": bankNumber}) + lastRow = cursor.fetchone() for currentRow in cursor: timeBetweenActivates = currentRow[1] - lastRow[1]; @@ -502,9 +501,9 @@ def write_to_read_and_read_to_write_hold(connection): for currentRow in cursor: - if(currentRow[2] in ["RD","RDA"] and lastRow[2] in ["WR","WRA"]): - #write to read - if (currentRow[3] == lastRow[3]): + if(currentRow[2] in ["RD","RDA"] and lastRow[2] in ["WR","WRA"]): + #write to read + if (currentRow[3] == lastRow[3]): tWTR = dramconfig.tWTR_L else: tWTR = dramconfig.tWTR_S @@ -512,19 +511,19 @@ def write_to_read_and_read_to_write_hold(connection): minWriteToRead = dramconfig.tWL + dramconfig.getWriteAccessTime() + tWTR writeToRead = currentRow[1] - lastRow[1] - if(writeToRead < minWriteToRead ): - return TestFailed("Read {0} starts {1} after start of write {2}. Minimum time is {3}". + if(writeToRead < minWriteToRead ): + return TestFailed("Read {0} starts {1} after start of write {2}. Minimum time is {3}". format(currentRow[0],formatTime(writeToRead),lastRow[0], formatTime(minWriteToRead))) - elif(currentRow[2] in ["WR","WRA"] and lastRow[2] in ["RD","RDA"]): + elif(currentRow[2] in ["WR","WRA"] and lastRow[2] in ["RD","RDA"]): #read to write minReadToWrite = dramconfig.tRL + dramconfig.getReadAccessTime() - dramconfig.tWL + dramconfig.clk * 2 readToWrite = currentRow[1] - lastRow[1] if(readToWrite < minReadToWrite ): return TestFailed("Write {0} starts {1} after start of read {2}. Minimum time is {3}". - format(currentRow[0],formatTime(readToWrite),lastRow[0], formatTime(minWriteToRead))) - - lastRow = currentRow + format(currentRow[0],formatTime(readToWrite),lastRow[0], formatTime(minWriteToRead))) + + lastRow = currentRow return TestSuceeded() @@ -542,9 +541,9 @@ def read_holds_dll_constraint_after_sref(connection): cursor.execute(query,{"bank": bankNumber}) lastRow = cursor.fetchone() for currentRow in cursor: - if(currentRow[2] in ["RD","RDA"] and lastRow[2] == 'SREF'): + if(currentRow[2] in ["RD","RDA"] and lastRow[2] == 'SREF'): srefEndToRead = currentRow[1] - (lastRow[1] - dramconfig.clk) - if(srefEndToRead < dramconfig.tXSRDLL ): + if(srefEndToRead < dramconfig.tXSRDLL ): return TestFailed("Read {0} starts {1} after end of sref {2}. Minimum time is {3}". format(currentRow[0],formatTime(srefEndToRead),lastRow[0], formatTime(dramconfig.tXSRDLL))) lastRow = currentRow @@ -608,10 +607,11 @@ def runTests(pathToTrace): print("================================") connection.close() + return testResults if __name__ == "__main__": - sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) - for i in range(1,len(sys.argv)): - runTests(sys.argv[i]) - \ No newline at end of file + sys.stdout = os.fdopen(sys.stdout.fileno(), 'w') + for i in range(1,len(sys.argv)): + runTests(sys.argv[i]) + diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index c1b21891..0cbcd8e6 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -6,15 +6,13 @@ am_lowHits.xml - am_lowPara.xml - fr_fcfs.xml - fifo.xml + memconfig.xml - mediabench-fractal_32.stl + chstone-jpeg_32.stl diff --git a/dram/src/common/protocol.h b/dram/src/common/protocol.h index 08b16358..f1c8b480 100755 --- a/dram/src/common/protocol.h +++ b/dram/src/common/protocol.h @@ -42,7 +42,9 @@ DECLARE_EXTENDED_PHASE(END_SREF); //Triggers -DECLARE_EXTENDED_PHASE(REFRESH_TRIGGER); +DECLARE_EXTENDED_PHASE(REF_TRIGGER); +DECLARE_EXTENDED_PHASE(PDN_TRIGGER); + #endif diff --git a/dram/src/core/ControllerCore.cpp b/dram/src/core/ControllerCore.cpp index 0c3075c2..abf8f997 100644 --- a/dram/src/core/ControllerCore.cpp +++ b/dram/src/core/ControllerCore.cpp @@ -19,6 +19,7 @@ #include "../common/dramExtension.h" #include "../common/Utils.h" #include "powerdown/PowerDownManager.h" +#include "powerdown/PowerDownManagerTimeout.h" #include "powerdown/PowerDownManagerBankwise.h" #include "../common/DebugManager.h" @@ -55,7 +56,14 @@ ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map lastCommand.getStart()) + lastCommand = current; + } + } + + return lastCommand; +} + const ScheduledCommand ControllerState::getLastScheduledCommand(Bank bank) { ScheduledCommand lastCommand; diff --git a/dram/src/core/ControllerState.h b/dram/src/core/ControllerState.h index dd8a56ea..2b9ed6fb 100644 --- a/dram/src/core/ControllerState.h +++ b/dram/src/core/ControllerState.h @@ -33,6 +33,7 @@ public: const ScheduledCommand getLastCommand(Command command, Bank bank); const ScheduledCommand getLastCommand(Command command); const ScheduledCommand getLastScheduledCommand(Bank bank); + const ScheduledCommand getLastScheduledCommand(); void change(const ScheduledCommand& scheduledCommand); void cleanUp(sc_time time); diff --git a/dram/src/core/configuration/Configuration.cpp b/dram/src/core/configuration/Configuration.cpp index 9ba25e5a..28bb44e0 100644 --- a/dram/src/core/configuration/Configuration.cpp +++ b/dram/src/core/configuration/Configuration.cpp @@ -21,5 +21,20 @@ Configuration::Configuration() loader.loadConfiguration(*this, Configuration::memspecUri, Configuration::memconfigUri); } +const std::vector& Configuration::getBanks() const +{ + static std::vector banks; + if (banks.size() == 0) + { + for (unsigned int i = 0; i < NumberOfBanks; i++) + { + banks.push_back(Bank(i)); + } + } + + return banks; +} + + } /* namespace core */ diff --git a/dram/src/core/configuration/Configuration.h b/dram/src/core/configuration/Configuration.h index f72b9077..ce9567c2 100644 --- a/dram/src/core/configuration/Configuration.h +++ b/dram/src/core/configuration/Configuration.h @@ -15,6 +15,9 @@ namespace core{ +enum class PowerDownMode{Staggered, TimeoutPDN, TimeoutSREF}; + + struct Configuration { static std::string memspecUri; @@ -37,6 +40,10 @@ struct Configuration unsigned int DataRate; unsigned int NumberOfRows; + // Powerdown Mode + sc_time powerDownTimeout; + PowerDownMode powerDownMode; + //MemTimings TimingConfiguration Timings; @@ -49,6 +56,10 @@ struct Configuration std::string Scheduler; unsigned int Capsize; + const std::vector& getBanks() const; + + + private: Configuration(); }; diff --git a/dram/src/core/configuration/MemSpecLoader.cpp b/dram/src/core/configuration/MemSpecLoader.cpp index d281d277..e1b174ab 100644 --- a/dram/src/core/configuration/MemSpecLoader.cpp +++ b/dram/src/core/configuration/MemSpecLoader.cpp @@ -53,6 +53,22 @@ void MemSpecLoader::loadConfig(Configuration& config, XMLElement* memspec) config.MaxNrOfTransactions = queryUIntParameter(configuration, "maxNrOfTransactionsInDram"); config.Scheduler = queryStringParameter(configuration, "scheduler"); config.Capsize = queryUIntParameter(configuration, "capsize"); + + string mode = queryStringParameter(configuration, "powerDownMode"); + if (mode.compare("Staggered") == 0) + { + config.powerDownMode = PowerDownMode::Staggered; + } + else if (mode.compare("TimeoutPDN") == 0) + { + config.powerDownMode = PowerDownMode::TimeoutPDN; + } + else if (mode.compare("TimeoutSREF") == 0) + { + config.powerDownMode = PowerDownMode::TimeoutSREF; + } + + config.powerDownTimeout = queryUIntParameter(configuration, "powerDownTimeout") * config.Timings.clk; } void MemSpecLoader::loadDDR4(Configuration& config, XMLElement* memspec) @@ -101,8 +117,7 @@ void MemSpecLoader::loadDDR4(Configuration& config, XMLElement* memspec) config.Timings.refreshTimings.clear(); for (unsigned int i = 0; i < config.NumberOfBanks; ++i) { - config.Timings.refreshTimings[Bank(i)] = RefreshTiming(config.Timings.tRFC, - config.Timings.tREFI); + config.Timings.refreshTimings[Bank(i)] = RefreshTiming(config.Timings.tRFC, config.Timings.tREFI); } } @@ -152,8 +167,7 @@ void MemSpecLoader::loadWideIO(Configuration& config, XMLElement* memspec) config.Timings.refreshTimings.clear(); for (unsigned int i = 0; i < config.NumberOfBanks; ++i) { - config.Timings.refreshTimings[Bank(i)] = RefreshTiming(config.Timings.tRFC, - config.Timings.tREFI); + config.Timings.refreshTimings[Bank(i)] = RefreshTiming(config.Timings.tRFC, config.Timings.tREFI); } } diff --git a/dram/src/core/powerdown/IPowerDownManager.h b/dram/src/core/powerdown/IPowerDownManager.h index 2e9ef29b..d9647973 100644 --- a/dram/src/core/powerdown/IPowerDownManager.h +++ b/dram/src/core/powerdown/IPowerDownManager.h @@ -8,7 +8,10 @@ #ifndef IPOWERDOWNMANAGER_H_ #define IPOWERDOWNMANAGER_H_ -#include +#include +#include "../../common/dramExtension.h" +#include "../Command.h" + namespace core { @@ -23,6 +26,8 @@ public: virtual ~IPowerDownManager() {} virtual void sleep(Bank bank, sc_time time) = 0; + virtual void triggerSleep(Bank bank, sc_time time) = 0; + virtual void wakeUp(Bank bank, sc_time time) = 0; virtual void wakeUpForRefresh(Bank bank, sc_time time) = 0; diff --git a/dram/src/core/powerdown/PowerDownManager.cpp b/dram/src/core/powerdown/PowerDownManager.cpp index 2fe05836..fd38cdff 100644 --- a/dram/src/core/powerdown/PowerDownManager.cpp +++ b/dram/src/core/powerdown/PowerDownManager.cpp @@ -156,5 +156,11 @@ bool PowerDownManager::isAwakeForRefresh() return powerDownState == PowerDownState::AwakeForRefresh; } +void PowerDownManager::triggerSleep(Bank bank, sc_time time) +{ + sleep(bank, time); +} + } /* namespace core */ + diff --git a/dram/src/core/powerdown/PowerDownManager.h b/dram/src/core/powerdown/PowerDownManager.h index 82a969c6..a70e8027 100644 --- a/dram/src/core/powerdown/PowerDownManager.h +++ b/dram/src/core/powerdown/PowerDownManager.h @@ -20,6 +20,7 @@ public: PowerDownManager(ControllerCore& controller); virtual ~PowerDownManager(); + virtual void triggerSleep(Bank bank, sc_time time) override; virtual void sleep(Bank bank, sc_time time) override; virtual void wakeUp(Bank bank, sc_time time) override; virtual void wakeUpForRefresh(Bank bank, sc_time time) override; diff --git a/dram/src/core/powerdown/PowerDownManagerBankwise.cpp b/dram/src/core/powerdown/PowerDownManagerBankwise.cpp index 98d7a89a..7702a0e1 100644 --- a/dram/src/core/powerdown/PowerDownManagerBankwise.cpp +++ b/dram/src/core/powerdown/PowerDownManagerBankwise.cpp @@ -143,5 +143,11 @@ bool PowerDownManagerBankwise::canSleep(Bank bank) return controller.numberOfPayloads[bank] == 0; } +void PowerDownManagerBankwise::triggerSleep(Bank bank, sc_time time) +{ + sleep(bank, time); +} + }/* namespace core */ + diff --git a/dram/src/core/powerdown/PowerDownManagerBankwise.h b/dram/src/core/powerdown/PowerDownManagerBankwise.h index 05761beb..0cc3a2a7 100644 --- a/dram/src/core/powerdown/PowerDownManagerBankwise.h +++ b/dram/src/core/powerdown/PowerDownManagerBankwise.h @@ -28,6 +28,7 @@ public: virtual ~PowerDownManagerBankwise() { } + virtual void triggerSleep(Bank bank, sc_time time) override; virtual void sleep(Bank bank, sc_time time) override; virtual void wakeUp(Bank bank, sc_time time) override; virtual void wakeUpForRefresh(Bank bank, sc_time time) override; diff --git a/dram/src/core/powerdown/PowerDownManagerTimeout.cpp b/dram/src/core/powerdown/PowerDownManagerTimeout.cpp new file mode 100644 index 00000000..40a6bb1e --- /dev/null +++ b/dram/src/core/powerdown/PowerDownManagerTimeout.cpp @@ -0,0 +1,140 @@ +/* + * PowerDownManagerTimeout.cpp + * + * Created on: May 5, 2014 + * Author: jungma + */ + +#include "PowerDownManagerTimeout.h" +#include "../ControllerCore.h" +#include "../../common/Utils.h" + +using namespace tlm; + +namespace core { + +PowerDownManagerTimeout::PowerDownManagerTimeout(ControllerCore& controller): controller(controller) +{ + for (Bank bank : controller.getBanks()) + { + setUpDummy(powerDownPayloads[bank], bank); + } +} + +PowerDownManagerTimeout::~PowerDownManagerTimeout() +{ + // TODO Auto-generated destructor stub +} + +void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) +{ + if(canSleep() && (time - controller.state.getLastScheduledCommand().getEnd()) >= Configuration::getInstance().powerDownTimeout) + { + PowerDownState state; + if(Configuration::getInstance().powerDownMode == PowerDownMode::TimeoutPDN) + { + state = controller.state.bankStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; + } + else + { + state = PowerDownState::PDNSelfRefresh; + } + + Command cmd = IPowerDownManager::getSleepCommand(powerDownState); + ScheduledCommand pdn(cmd, time, getMinimalExecutionTime(cmd, powerDownPayloads[bank]), + DramExtension::getExtension(powerDownPayloads[bank])); + + controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + + if (controller.refreshManager->hasCollision(pdn)) + { + return; + } + else + { + setPowerDownState(state); + sendPowerDownPayloads(pdn); + } + } +} + +bool PowerDownManagerTimeout::isInPowerDown() +{ + return (powerDownState == PowerDownState::PDNActive || powerDownState == PowerDownState::PDNPrecharge + || powerDownState == PowerDownState::PDNSelfRefresh); +} + +void PowerDownManagerTimeout::setPowerDownState(PowerDownState state) +{ + powerDownState = state; + DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName, + "Is now in state " + powerDownStateToString(powerDownState) + " on all banks"); +} + +void PowerDownManagerTimeout::wakeUp(Bank bank, sc_time time) +{ + if (isInPowerDown()) //Request wakes up power down + { + Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); + ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), + DramExtension::getExtension(powerDownPayloads[bank])); + controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + + if (cmd == Command::SREFX) + controller.refreshManager->reInitialize(bank, pdn.getEnd()); + + setPowerDownState(PowerDownState::Awake); + sendPowerDownPayloads(pdn); + } +} + +void PowerDownManagerTimeout::wakeUpForRefresh(Bank bank, sc_time time) +{ + if (isInPowerDown()) + { + Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); + ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), + DramExtension::getExtension(powerDownPayloads[bank])); + + setPowerDownState(PowerDownState::AwakeForRefresh); + sendPowerDownPayloads(pdn); + } +} + +void PowerDownManagerTimeout::triggerSleep(Bank bank, sc_time time) +{ + if(canSleep()) + { + controller.wrapper.send(REFTrigger, time + controller.config.powerDownTimeout, pdn_trigger); + } +} + +bool PowerDownManagerTimeout::isInSelfRefresh(Bank bank) +{ + return powerDownState == PowerDownState::PDNSelfRefresh; +} + +bool PowerDownManagerTimeout::canSleep() +{ + for (Bank bank : controller.getBanks()) + { + if (!controller.numberOfPayloads[bank] == 0) + return false; + } + return true; +} + +void PowerDownManagerTimeout::sendPowerDownPayloads(ScheduledCommand& cmd) +{ + controller.state.bus.moveCommandToNextFreeSlot(cmd); + for (Bank bank : controller.getBanks()) + { + tlm_generic_payload& payloadToSend = powerDownPayloads[bank]; + ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(), + DramExtension::getExtension(payloadToSend)); + controller.state.change(pdnToSend); + controller.wrapper.send(pdnToSend, payloadToSend); + } +} + +} diff --git a/dram/src/core/powerdown/PowerDownManagerTimeout.h b/dram/src/core/powerdown/PowerDownManagerTimeout.h new file mode 100644 index 00000000..2f6ba16c --- /dev/null +++ b/dram/src/core/powerdown/PowerDownManagerTimeout.h @@ -0,0 +1,51 @@ +/* + * PowerDownManagerTimeout.h + * + * Created on: May 5, 2014 + * Author: jungma + */ + +#ifndef POWERDOWNMANAGERTIMEOUT_H_ +#define POWERDOWNMANAGERTIMEOUT_H_ + +#include "IPowerDownManager.h" +#include +#include "../../common/dramExtension.h" +#include +#include "../scheduling/ScheduledCommand.h" + +namespace core { +class ControllerCore; + +class PowerDownManagerTimeout: public core::IPowerDownManager +{ +public: + PowerDownManagerTimeout(ControllerCore& controller); + virtual ~PowerDownManagerTimeout(); + + virtual void triggerSleep(Bank bank, sc_time time); + virtual void sleep(Bank bank, sc_time time); + + virtual void wakeUp(Bank bank, sc_time time); + virtual void wakeUpForRefresh(Bank bank, sc_time time); + + virtual bool isInSelfRefresh(Bank bank); +private: + bool canSleep(); + ControllerCore& controller; + tlm::tlm_generic_payload pdn_trigger; + + std::map powerDownPayloads; + void sendPowerDownPayloads(ScheduledCommand& cmd); + + PowerDownState powerDownState; + void setPowerDownState(PowerDownState state); + + bool isInPowerDown(); + + +}; + +} + +#endif /* POWERDOWNMANAGERTIMEOUT_H_ */ diff --git a/dram/src/core/refresh/RefreshManager.cpp b/dram/src/core/refresh/RefreshManager.cpp index 853cadc1..5454ada2 100644 --- a/dram/src/core/refresh/RefreshManager.cpp +++ b/dram/src/core/refresh/RefreshManager.cpp @@ -76,7 +76,7 @@ void RefreshManager::sendToAllBanks(ScheduledCommand& command) void RefreshManager::planNextRefresh() { nextPlannedRefresh += timing.tREFI; - controller.wrapper.send(RefreshTrigger, nextPlannedRefresh, refreshPayloads[Bank(0)]); + controller.wrapper.send(REFTrigger, nextPlannedRefresh, refreshPayloads[Bank(0)]); } void RefreshManager::reInitialize(Bank bank, sc_time time) diff --git a/dram/src/core/refresh/RefreshManagerBankwise.cpp b/dram/src/core/refresh/RefreshManagerBankwise.cpp index 8121ccf2..dbad8403 100644 --- a/dram/src/core/refresh/RefreshManagerBankwise.cpp +++ b/dram/src/core/refresh/RefreshManagerBankwise.cpp @@ -70,7 +70,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, void RefreshManagerBankwise::planNextRefresh(Bank bank) { nextPlannedRefreshs[bank] += Configuration::getInstance().Timings.refreshTimings[bank].tREFI; - controller.wrapper.send(RefreshTrigger, nextPlannedRefreshs[bank], refreshPayloads[bank]); + controller.wrapper.send(REFTrigger, nextPlannedRefreshs[bank], refreshPayloads[bank]); } void RefreshManagerBankwise::reInitialize(Bank bank, sc_time time) diff --git a/dram/src/core/scheduling/Trigger.h b/dram/src/core/scheduling/Trigger.h index 6ab6f030..9a5827ce 100644 --- a/dram/src/core/scheduling/Trigger.h +++ b/dram/src/core/scheduling/Trigger.h @@ -10,7 +10,7 @@ namespace core { -enum Trigger {RefreshTrigger, WakeUpTrigger}; +enum Trigger {REFTrigger, PDNTrigger}; } /* namespace controller */ diff --git a/dram/src/simulation/Controller.h b/dram/src/simulation/Controller.h index 5ae57d80..4ea2c9d3 100644 --- a/dram/src/simulation/Controller.h +++ b/dram/src/simulation/Controller.h @@ -8,25 +8,40 @@ #ifndef CONTROLLERWRAPPER_H_ #define CONTROLLERWRAPPER_H_ -#include -#include -#include -#include -#include -#include +//#include +//#include +//#include +//#include +//#include #include #include +#include -#include "../common/Utils.h" +//#include +#include "/opt/systemc-2.3.0/include/systemc" +#include "/opt/systemc-2.3.0/include/tlm" +#include "/opt/systemc-2.3.0/include/tlm_utils/peq_with_cb_and_phase.h" +#include "/opt/systemc-2.3.0/include/tlm_utils/simple_initiator_socket.h" +#include "/opt/systemc-2.3.0/include/tlm_utils/simple_target_socket.h" +#include "../common/dramExtension.h" +#include "../common/DebugManager.h" #include "../common/protocol.h" #include "../common/TlmRecorder.h" -#include "../common/DebugManager.h" -#include "../core/IWrapperConnector.h" +#include "../common/Utils.h" +#include "../core/configuration/Configuration.h" +#include "../core/configuration/TimingConfiguration.h" +#include "../core/Command.h" #include "../core/ControllerCore.h" -#include "../scheduler/Scheduler.h" +#include "../core/ControllerState.h" +#include "../core/IWrapperConnector.h" +#include "../core/powerdown/IPowerDownManager.h" +#include "../core/scheduling/ScheduledCommand.h" +#include "../core/scheduling/Trigger.h" +#include "../core/TimingCalculation.h" #include "../scheduler/Fifo.h" #include "../scheduler/Fr_Fcfs.h" #include "../scheduler/PARBS.h" +//#include "../scheduler/Scheduler.h" using namespace std; using namespace tlm; @@ -156,9 +171,13 @@ public: sc_assert(time >= sc_time_stamp()); sc_time delay = time - sc_time_stamp(); - if (trigger == Trigger::RefreshTrigger) + if (trigger == Trigger::REFTrigger) { - controllerCorePEQ.notify(payload, REFRESH_TRIGGER, delay); + controllerCorePEQ.notify(payload, REF_TRIGGER, delay); + } + else if (trigger == Trigger::PDNTrigger) + { + controllerCorePEQ.notify(payload, PDN_TRIGGER, delay); } else { @@ -168,10 +187,14 @@ public: void controllerCorePEQCallback(tlm_generic_payload& payload, const tlm_phase& phase) { - if (phase == REFRESH_TRIGGER) + if (phase == REF_TRIGGER) { controller->triggerRefresh(payload, sc_time_stamp()); } + else if (phase == PDN_TRIGGER) + { + controller->powerDownManager->sleep(DramExtension::getExtension(payload).getBank(),sc_time_stamp()); + } else { Bank bank = DramExtension::getExtension(payload).getBank(); @@ -277,7 +300,7 @@ private: printDebugMessage( "Payload left system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: " + to_string(getTotalNumberOfPayloadsInSystem())); - controller->powerDownManager->sleep(bank, sc_time_stamp()); + controller->powerDownManager->triggerSleep(bank, sc_time_stamp()); } diff --git a/dram/src/simulation/main.cpp b/dram/src/simulation/main.cpp index 42cff397..b91d4672 100644 --- a/dram/src/simulation/main.cpp +++ b/dram/src/simulation/main.cpp @@ -40,13 +40,12 @@ int sc_main(int argc, char **argv) if(argc > 1) simulationToRun = argv[1]; else - simulationToRun = "first.xml"; + simulationToRun = "sim-batch.xml"; SimulationManager manager(resources); manager.loadSimulationsFromXML(resources + "/simulations/" + simulationToRun); manager.silent = false; manager.runSimulations(); - manager.startTraceAnalyzer(); return 0; }