From f11adf51dcdf026d350691ce02537bc6216e3466 Mon Sep 17 00:00:00 2001 From: gernhard2 Date: Mon, 16 Feb 2015 08:21:27 +0100 Subject: [PATCH] Relocated the python scripts. They now live in the analyzer directory and are deployed to the output folder when building the analyzer. Major change to simulation logic in dramSys: Commands in a transaction are now scheduled one at a time, instead of scheduling a whole transaction at once. Since single commands (e.g. Pre or Act) are not that long, refreshes are allowed to be delayed to allow a command to finsh. Consequently, the whole loop in the ControllerCore about trying to scheduleding a transaction and aborting it when it collides with a refresh could be ommitted. Lastly, Fifo_Strict has been added, which is a Fifo Scheduler that forces the read and write transactions, even between different banks to be executed in order. Fifo and FR_FCFS have been modified to fit into the new scheduling logic. --- .../analyzer/businessObjects/pythoncaller.cpp | 5 +- .../analyzer/businessObjects/pythoncaller.h | 4 +- analyzer/analyzer/evaluationtool.cpp | 8 +- .../analyzer}/scripts/metrics.py | 0 analyzer/analyzer/scripts/tests.py | 617 ++++++++++++++++++ analyzer/analyzer/traceAnalyzer.pro | 11 +- dram/dramSys/dramSys.pro | 31 +- dram/resources/configs/memconfigs/fifo.xml | 6 +- dram/resources/configs/memconfigs/fr_fcfs.xml | 4 +- dram/resources/scripts/sampleStlGeneration.py | 17 - dram/resources/scripts/stlGenerator.py | 123 ---- dram/resources/scripts/tests.py | 617 ------------------ dram/resources/simulations/datasizes.xml | 22 - dram/resources/simulations/sim-batch.xml | 22 +- dram/src/common/DebugManager.cpp | 16 +- dram/src/common/DebugManager.h | 4 - dram/src/common/TlmRecorder.cpp | 11 +- dram/src/common/dramExtension.cpp | 22 +- dram/src/common/dramExtension.h | 13 + dram/src/common/third_party/DRAMPower | 2 +- dram/src/common/xmlAddressdecoder.cpp | 4 +- dram/src/controller/Command.cpp | 78 +++ dram/src/controller/{core => }/Command.h | 8 +- dram/src/controller/Controller.h | 185 +++--- .../controller/{core => }/ControllerState.cpp | 5 +- .../controller/{core => }/ControllerState.h | 8 +- dram/src/controller/IController.h | 23 + .../controller/{core => }/RowBufferStates.cpp | 10 +- .../controller/{core => }/RowBufferStates.h | 7 +- dram/src/controller/core/Command.cpp | 71 -- dram/src/controller/core/ControllerCore.cpp | 63 +- dram/src/controller/core/ControllerCore.h | 27 +- dram/src/controller/core/IWrapperConnector.h | 28 - dram/src/controller/core/Slots.cpp | 2 - dram/src/controller/core/Slots.h | 2 - .../src/controller/core/TimingCalculation.cpp | 2 - dram/src/controller/core/TimingCalculation.h | 6 +- .../core/configuration/Configuration.cpp | 7 - .../core/configuration/Configuration.h | 6 - .../configuration/ConfigurationLoader.cpp | 47 +- .../core/configuration/ConfigurationLoader.h | 3 - .../controller/core/configuration/MemSpec.h | 2 - .../core/powerdown/IPowerDownManager.h | 5 +- .../controller/core/powerdown/NoPowerDown.cpp | 10 +- .../controller/core/powerdown/NoPowerDown.h | 3 +- .../core/powerdown/PowerDownManager.cpp | 33 +- .../core/powerdown/PowerDownManager.h | 6 +- .../powerdown/PowerDownManagerBankwise.cpp | 28 +- .../core/powerdown/PowerDownManagerBankwise.h | 8 +- .../powerdown/PowerDownManagerTimeout.cpp | 30 +- .../core/powerdown/PowerDownManagerTimeout.h | 9 +- .../controller/core/refresh/IRefreshManager.h | 5 +- .../core/refresh/RefreshManager.cpp | 71 +- .../controller/core/refresh/RefreshManager.h | 11 +- .../core/refresh/RefreshManagerBankwise.cpp | 30 +- .../core/refresh/RefreshManagerBankwise.h | 10 +- .../core/scheduling/CommandSchedule.h | 67 -- .../scheduling/CommandSequenceGenerator.cpp | 88 --- .../scheduling/CommandSequenceGenerator.h | 37 -- .../scheduling/CommandSequenceScheduler.cpp | 37 -- .../scheduling/CommandSequenceScheduler.h | 31 - .../core/scheduling/ScheduledCommand.cpp | 10 +- .../core/scheduling/ScheduledCommand.h | 11 +- dram/src/controller/core/scheduling/Trigger.h | 2 - .../scheduling/checker/ActivateChecker.cpp | 20 +- .../core/scheduling/checker/ActivateChecker.h | 6 +- .../core/scheduling/checker/ICommandChecker.h | 2 - .../scheduling/checker/PowerDownChecker.cpp | 21 +- .../scheduling/checker/PowerDownChecker.h | 4 +- .../checker/PrechargeAllChecker.cpp | 29 +- .../scheduling/checker/PrechargeAllChecker.h | 6 +- .../scheduling/checker/PrechargeChecker.cpp | 24 +- .../scheduling/checker/PrechargeChecker.h | 6 +- .../core/scheduling/checker/ReadChecker.cpp | 31 +- .../core/scheduling/checker/ReadChecker.h | 6 +- .../scheduling/checker/RefreshChecker.cpp | 12 +- .../core/scheduling/checker/RefreshChecker.h | 4 +- .../core/scheduling/checker/WriteChecker.cpp | 26 +- .../core/scheduling/checker/WriteChecker.h | 6 +- dram/src/controller/scheduler/Fifo.cpp | 37 +- dram/src/controller/scheduler/Fifo.h | 23 +- dram/src/controller/scheduler/FifoStrict.cpp | 89 +++ dram/src/controller/scheduler/FifoStrict.h | 32 + dram/src/controller/scheduler/Fr_Fcfs.cpp | 136 +--- dram/src/controller/scheduler/Fr_Fcfs.h | 32 +- dram/src/controller/scheduler/IScheduler.cpp | 58 ++ dram/src/controller/scheduler/IScheduler.h | 33 + dram/src/controller/scheduler/PARBS.cpp | 183 +++--- dram/src/controller/scheduler/PARBS.h | 62 +- dram/src/controller/scheduler/Scheduler.cpp | 16 - dram/src/controller/scheduler/Scheduler.h | 28 - dram/src/controller/scheduler/ThreadLoad.cpp | 118 ++-- dram/src/controller/scheduler/ThreadLoad.h | 66 +- .../controller/scheduler/readwritegrouper.cpp | 266 ++++---- .../controller/scheduler/readwritegrouper.h | 64 +- dram/src/simulation/Dram.h | 5 +- dram/src/simulation/MemoryManager.cpp | 6 +- dram/src/simulation/Simulation.cpp | 18 - dram/src/simulation/SimulationManager.cpp | 14 +- dram/src/simulation/StlPlayer.h | 6 +- dram/src/simulation/TraceGenerator.h | 6 +- 101 files changed, 1814 insertions(+), 2378 deletions(-) rename {dram/resources => analyzer/analyzer}/scripts/metrics.py (100%) create mode 100644 analyzer/analyzer/scripts/tests.py delete mode 100644 dram/resources/scripts/sampleStlGeneration.py delete mode 100755 dram/resources/scripts/stlGenerator.py delete mode 100644 dram/resources/scripts/tests.py delete mode 100644 dram/resources/simulations/datasizes.xml create mode 100644 dram/src/controller/Command.cpp rename dram/src/controller/{core => }/Command.h (80%) rename dram/src/controller/{core => }/ControllerState.cpp (97%) rename dram/src/controller/{core => }/ControllerState.h (89%) create mode 100644 dram/src/controller/IController.h rename dram/src/controller/{core => }/RowBufferStates.cpp (92%) rename dram/src/controller/{core => }/RowBufferStates.h (90%) delete mode 100644 dram/src/controller/core/Command.cpp delete mode 100644 dram/src/controller/core/IWrapperConnector.h delete mode 100644 dram/src/controller/core/scheduling/CommandSchedule.h delete mode 100644 dram/src/controller/core/scheduling/CommandSequenceGenerator.cpp delete mode 100644 dram/src/controller/core/scheduling/CommandSequenceGenerator.h delete mode 100644 dram/src/controller/core/scheduling/CommandSequenceScheduler.cpp delete mode 100644 dram/src/controller/core/scheduling/CommandSequenceScheduler.h create mode 100644 dram/src/controller/scheduler/FifoStrict.cpp create mode 100644 dram/src/controller/scheduler/FifoStrict.h create mode 100644 dram/src/controller/scheduler/IScheduler.cpp create mode 100644 dram/src/controller/scheduler/IScheduler.h delete mode 100644 dram/src/controller/scheduler/Scheduler.cpp delete mode 100644 dram/src/controller/scheduler/Scheduler.h diff --git a/analyzer/analyzer/businessObjects/pythoncaller.cpp b/analyzer/analyzer/businessObjects/pythoncaller.cpp index 014bd2e9..da477e79 100644 --- a/analyzer/analyzer/businessObjects/pythoncaller.cpp +++ b/analyzer/analyzer/businessObjects/pythoncaller.cpp @@ -4,11 +4,12 @@ #include #include #include +#include using namespace std; -PythonCaller::PythonCaller(const QString& pathToScripts) : - testModuleName("tests"), testFunctionName("runTests"), metricModuleName("metrics"), metricFunctionName("calculateMetrics"), pathToScripts(pathToScripts.toStdString()) +PythonCaller::PythonCaller() : + testModuleName("tests"), testFunctionName("runTests"), metricModuleName("metrics"), metricFunctionName("calculateMetrics"), pathToScripts(QApplication::applicationDirPath().toStdString() +"/scripts") { Py_Initialize(); PyObject *sysPath = PySys_GetObject((char*)"path"); diff --git a/analyzer/analyzer/businessObjects/pythoncaller.h b/analyzer/analyzer/businessObjects/pythoncaller.h index 370f9756..fe203c0d 100644 --- a/analyzer/analyzer/businessObjects/pythoncaller.h +++ b/analyzer/analyzer/businessObjects/pythoncaller.h @@ -9,7 +9,7 @@ class PythonCaller { public: - PythonCaller(const QString& pathToScripts); + PythonCaller(); ~PythonCaller(); TraceTestResults runTestsOnTrace(QString pathToTrace); TraceCalculatedMetrics calculateMetricsOnTrace(QString pathToTrace); @@ -18,7 +18,7 @@ private: PyObject *pRunTestsFunction, *pCalculateMetricsFunction; PyObject* loadFunctionFromModule(std::string moduleName, std::string functionName); std::string testModuleName, testFunctionName, metricModuleName, metricFunctionName, pathToScripts; - PyObject *callFunctionWithStringArgument(PyObject *function, QString argument); + PyObject *callFunctionWithStringArgument(PyObject *function, QString argument); }; #endif // PYTHONCALLER_H diff --git a/analyzer/analyzer/evaluationtool.cpp b/analyzer/analyzer/evaluationtool.cpp index 5b9ec6d3..030b15f9 100644 --- a/analyzer/analyzer/evaluationtool.cpp +++ b/analyzer/analyzer/evaluationtool.cpp @@ -83,9 +83,7 @@ void EvaluationTool::on_btn_test_clicked() void EvaluationTool::runTests() { - QString resourcesAbsPath = QApplication::applicationDirPath() + this->resourcesRelPath; - qDebug() << resourcesAbsPath; - PythonCaller pythonCaller(resourcesAbsPath); + PythonCaller pythonCaller; ui->traceTestTreeWidget->clear(); ui->testLight->setGray(); @@ -118,9 +116,7 @@ void EvaluationTool::on_btn_calculateMetrics_clicked() void EvaluationTool::calculateMetrics() { - QString resourcesAbsPath = QApplication::applicationDirPath() + this->resourcesRelPath; - qDebug() << resourcesAbsPath; - PythonCaller pythonCaller(resourcesAbsPath); + PythonCaller pythonCaller; ui->traceMetricTreeWidget->clear(); for(int row = 0; row < traceFilesModel->rowCount(); ++row) { diff --git a/dram/resources/scripts/metrics.py b/analyzer/analyzer/scripts/metrics.py similarity index 100% rename from dram/resources/scripts/metrics.py rename to analyzer/analyzer/scripts/metrics.py diff --git a/analyzer/analyzer/scripts/tests.py b/analyzer/analyzer/scripts/tests.py new file mode 100644 index 00000000..c42617c2 --- /dev/null +++ b/analyzer/analyzer/scripts/tests.py @@ -0,0 +1,617 @@ +import sys +import traceback +import sqlite3 +import os +import xml.etree.ElementTree as ET + +def getPathToConfigs(): + 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'] + +def getIntValueFromConfigXML(root, id): + return int(root.findall(".//parameter[@id='{0}']".format(id))[0].attrib['value']) + +def getMemconfig(connection): + cursor = connection.cursor() + cursor.execute("SELECT Memconfig FROM GeneralInfo") + result = cursor.fetchone() + memconfig = result[0] + return ET.parse(memconfig) + +def getMemspec(connection): + cursor = connection.cursor() + cursor.execute("SELECT Memspec FROM GeneralInfo") + result = cursor.fetchone() + memspec = result[0] + return ET.parse(memspec) + +def getClock(connection): + cursor = connection.cursor() + cursor.execute("SELECT clk, UnitOfTime FROM GeneralInfo") + result = cursor.fetchone() + return (result[0],result[1]) + +class DramConfig(object): + memoryType = "" + bankwiseLogic = 0 + clk = 0 + unitOfTime = "" + dataRate = 0 + nActivateWindow = numberOfBanks = 0 + + clk = 0 + tRP = 0 #precharge-time (pre -> act same bank) + tRAS = 0 #active-time (act -> pre same bank) + tRC = 0 #RAS-cycle-time (min time bw 2 succesive ACT to same bank) + tCCD_S = 0 #TODO: relevant? max(bl, tCCD) + tCCD_L = 0 + tRTP = 0 #Read to precharge + tRRD_S = 0 #min time bw 2 succesive ACT to different banks (different bank group) + tRRD_L = 0 #.. (same bank group) + tRCD = 0 #act -> read/write + tNAW = 0 #n activate window + tRL = 0 #read latency (read command start to data strobe) + tWL = 0 #write latency + tWR = 0 #write recovery (write to precharge) + tWTR_S = 0 #write to read (different bank group) + tWTR_L = 0 #.. (same bank group) + tCKESR = 0 #min time in sref + tCKE = 0 #min time in pdna or pdnp + tXP = 0 #min delay to row access command after pdnpx pdnax + tXPDLL = 0 #min delay to row access command after pdnpx pdnax for dll commands + 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 + + + def readConfigFromFiles(self, connection): + print("Parsing dram configuration") + memspec = getMemspec(connection) + + clkWithUnit = getClock(connection) + self.clk = clkWithUnit[0] + self.unitOfTime = clkWithUnit[1].lower() + + print(getMemconfig(connection)) + self.bankwiseLogic = getMemconfig(connection).findall("BankwiseLogic")[0].attrib['value'] + self.numberOfBanks = getIntValueFromConfigXML(memspec, "nbrOfBanks") + self.burstLength = getIntValueFromConfigXML(memspec, "burstLength") + self.memoryType = getValueFromConfigXML(memspec, "memoryType") + self.dataRate = getIntValueFromConfigXML(memspec, "dataRate") + + if(self.memoryType == "WIDEIO_SDR"): + self.nActivateWindow = 2; + self.tRP = self.clk * getIntValueFromConfigXML(memspec, "RP") + self.tRAS = self.clk * getIntValueFromConfigXML(memspec, "RAS") + self.tRC = self.clk * getIntValueFromConfigXML(memspec, "RC") + self.tRRD_S = self.clk * getIntValueFromConfigXML(memspec, "RRD") + self.tRRD_L = self.tRRD_S + self.tCCD_S = self.clk * getIntValueFromConfigXML(memspec, "CCD") + self.tCCD_L = self.tCCD_S + self.tRCD = self.clk * getIntValueFromConfigXML(memspec, "RCD") + self.tNAW = self.clk * getIntValueFromConfigXML(memspec, "TAW") + self.tRL = self.clk * getIntValueFromConfigXML(memspec, "RL") + self.tWL = self.clk * getIntValueFromConfigXML(memspec, "WL") + self.tWR = self.clk * getIntValueFromConfigXML(memspec, "WR") + self.tWTR_S = self.clk * getIntValueFromConfigXML(memspec, "WTR") + self.tWTR_L = self.tWTR_S + self.tRTP = self.clk * getIntValueFromConfigXML(memspec, "RTP"); + self.tCKESR = self.clk * getIntValueFromConfigXML(memspec, "CKESR") + self.tCKE = self.clk * getIntValueFromConfigXML(memspec, "CKE") + self.tXP = self.clk * getIntValueFromConfigXML(memspec, "XP") + self.tXPDLL = self.tXP + self.tXSR = self.clk * getIntValueFromConfigXML(memspec, "XS") + self.tXSRDLL = self.tXSR + self.tAL = self.clk * getIntValueFromConfigXML(memspec, "AL") + self.tRFC = self.clk * getIntValueFromConfigXML(memspec, "RFC") + + elif(self. memoryType == "DDR4"): + self.nActivateWindow = 4; + self.tRP = self.clk * getIntValueFromConfigXML(memspec, "RP"); + self.tRAS = self.clk * getIntValueFromConfigXML(memspec, "RAS"); + self.tRC = self.clk * getIntValueFromConfigXML(memspec, "RC"); + self.tRTP = self.clk * getIntValueFromConfigXML(memspec, "RTP"); + self.tRRD_S = self.clk * getIntValueFromConfigXML(memspec, "RRD_S"); + self.tRRD_L = self.clk * getIntValueFromConfigXML(memspec, "RRD_L"); + self.tCCD_S = self.clk * getIntValueFromConfigXML(memspec, "CCD_S"); + self.tCCD_L = self.clk * getIntValueFromConfigXML(memspec, "CCD_L"); + self.tRCD = self.clk * getIntValueFromConfigXML(memspec, "RCD"); + self.tNAW = self.clk * getIntValueFromConfigXML(memspec, "FAW"); + self.tRL = self.clk * getIntValueFromConfigXML(memspec, "RL"); + self.tWL = self.clk * getIntValueFromConfigXML(memspec, "WL"); + self.tWR = self.clk * getIntValueFromConfigXML(memspec, "WR"); + self.tWTR_S = self.clk * getIntValueFromConfigXML(memspec, "WTR_S"); + self.tWTR_L = self.clk * getIntValueFromConfigXML(memspec, "WTR_L"); + self.tCKESR = self.clk * getIntValueFromConfigXML(memspec, "CKESR"); + self.tCKE = self.clk * getIntValueFromConfigXML(memspec, "CKE"); + self.tXP = self.clk * getIntValueFromConfigXML(memspec, "XP"); + self.tXPDLL = self.clk * getIntValueFromConfigXML(memspec, "XPDLL"); + self.tXSR = self.clk * getIntValueFromConfigXML(memspec, "XS"); + self.tXSRDLL = self.clk * getIntValueFromConfigXML(memspec, "XSDLL"); + self.tAL = self.clk * getIntValueFromConfigXML(memspec, "AL"); + self.tRFC = self.clk * getIntValueFromConfigXML(memspec, "RFC"); + else: + raise Exception("MemoryType not supported yet. Insert a coin into the coin machine and try again") + + def clkAlign(self, value): + return math.ceil(1.0*value/self.clk)*self.clk + + def getWriteAccessTime(self): + if(self.dataRate == 1): + return self.clk*(self.burstLength - 1) + elif (self.memoryType == "DDR4"): + return self.clk*self.burstLength/self.dataRate + + def getReadAccessTime(self): + return self.burstLength/self.dataRate * dramconfig.clk + + + def __init__(self): + pass + +dramconfig = DramConfig() + +def calculateReadLength(burstLength): + return dramconfig.tRL + burstLength * dramconfig.clk + +def calculateWriteLength(burstLength): + return dramconfig.tWL + burstLength * dramconfig.clk + +# ----------- test utils --------------------------------------- + +tests = [] + +def test(function): + tests.append(function) + return function + +class TestResult(object): + passed = True + message = '' + def __init__(self, passed = True, message = ''): + self.passed = passed + self.message = message + +def TestSuceeded(): + return TestResult() + +def TestFailed(message): + return TestResult(False,message); + +def formatTime(time): + return ('{0} {1}'.format(time, dramconfig.unitOfTime)) + +# ----------- checks --------------------------------------- + +@test +def commands_are_clockaligned(connection): + """Checks that all commands on the command bus are aligned to the system clock""" + + 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}) + + 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 + FROM Phases WHERE PhaseName NOT IN """ + excludedPhases + """ AND phasebegin>0 GROUP BY phaseBegin) WHERE count>1""" + + cursor.execute(query) + result = cursor.fetchone() + if(result != None): + return TestFailed("Slot on commandbus at time {0} is used multiple times".format(formatTime(result[0]))) + return TestSuceeded() + + +@test +def phase_transitions_are_valid(connection): + """Checks that all transition of two consequtive phases on the same bank are valid""" + + cursor = connection.cursor() + validTransitions = {} + + if(dramconfig.bankwiseLogic): + validTransitions['PRE'] = set(['ACT', 'AUTO_REFRESH']) + validTransitions['ACT'] = set(['RD', 'RDA', 'WR', 'WRA', 'PRE', 'PRE_ALL']) + + 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['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', 'PRE_ALl']) + + 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['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() + for currentRow in cursor: + currentPhase = currentRow[0] + lastPhase = lastRow[0] + if(currentPhase not in validTransitions[lastPhase]): + return TestFailed("Phase {0}({1}) is not allowed to follow phase {2}({3})".format(currentRow[1],currentPhase,lastRow[1],lastPhase)) + lastRow = currentRow + + return TestSuceeded() + + +def timing_constraint(FirstPhase, SecondPhase): + FirstPhaseName = FirstPhase[0] + SecondPhaseName = SecondPhase[0] + + if(FirstPhaseName == "PRE" or FirstPhaseName == "PRE_ALL"): + return dramconfig.tRP + + elif(FirstPhaseName == "ACT"): + return dramconfig.tRCD + + elif(FirstPhaseName == "RD"): + if(SecondPhaseName in ["PRE, PRE_ALL"]): + return dramconfig.tRTP + elif(SecondPhaseName in ["RD, RDA"]): + return max(dramconfig.tCCD_L, getReadAccessTime()) + elif(SecondPhase in ["WR","WRA"]): + return dramconfig.tRL + getReadAccessTime() - dramconfig.tWL + 2*dramconfig.clk + elif(SecondPhase == "PDNA" ): + return dramconfig.tRL + getReadAccessTime() + dramconfig.clk + + elif(FirstPhaseName == "WR"): + if(SecondPhaseName in ["PRE, PRE_ALL", "PDNA"]): + return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR + elif(SecondPhaseName in ["RD, RDA"]): + return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWTR_L + elif(SecondPhaseName in ["WR, WRA"]): + return max(dramconfig.tCCD_L, burstlength/dramconfig.dataRate) + + elif(FirstPhaseName == "RDA"): + if(SecondPhaseName in ["ACT", "PRE_ALL", "AUTO_REFRESH"]): + return dramconfig.tRTP + dramconfig.tRP + elif(SecondPhaseName in ["PDNA","PDNP"]): + return dramconfig.tRL + getReadAccessTime() + dramconfig.clk + + elif(FirstPhaseName == "WRA"): + if(SecondPhaseName in ["ACT", "PRE_ALL", "AUTO_REFRESH"]): + return dramconfig.tWL + getWriteAccessTime() + dramconfig.tWR + dramconfig.tRP + elif(SecondPhaseName in ["PDNA","PDNP"]): + return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR + dramconfig.clk + + elif(FirstPhaseName == "AUTO_REFRESH"): + return dramconfig.tRFC + + elif(FirstPhaseName in ["PDNA","PDNP"]): + return (FirstPhase[3] - FirstPhase[2]) + dramconfig.tXP - dramconfig.clk + + elif(FirstPhaseName == "SREF"): + return (FirstPhase[3] - FirstPhase[2]) + dramconfig.tXSR - dramconfig.clk + + return 0 + +@test +def timing_constraits_on_the_same_bank_hold(connection): + """Checks that all transitions of two consequtive phases on the same bank meet their timing constraints""" + cursor = connection.cursor() + validTransitions = {} + + query = """SELECT PhaseName, phases.ID,PhaseBegin,PhaseEnd 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() + + for currentRow in cursor: + constraint = timing_constraint(lastRow,currentRow) + if(currentRow[2] - lastRow[2] + constraint < 0): + return TestFailed("Phase {0}({1}) starts {2} after Start of Phase {3}({4}). Minimal time is {5}".format( + currentRow[1],currentRow[0],formatTime(currentRow[2]-lastRow[2]),lastRow[1],lastRow[0], formatTime(constraint))) + lastRow = currentRow + return TestSuceeded() + +@test +def row_buffer_is_used_correctly(connection): + """Checks that each bank's row buffer is used correctly""" + + cursor = connection.cursor() + 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""" + + + #phases that precharge the bank and close the rowbuffer + prechargingPhases = set(['PRE','PRE_ALL','RDA','WRA']) + + #phases that require the bank to be in active state and the rowbuffer to be opened + accessingPhases = set(['RD','RDA', 'WR', 'WRA', 'PRE']) + + #phases that require the bank to be in precharged state and the robuffer to be closed + idlePhases = set(['ACT', 'PDNP', 'AUTO_REFRESH', 'SREF']) + + for bankNumber in range(dramconfig.numberOfBanks): + cursor.execute(query,{"bank": bankNumber}) + + rowBufferIsClosed = True + + + + for currentRow in cursor: + if(currentRow[0] in accessingPhases and rowBufferIsClosed == True): + return TestFailed("Phase {0}({1}) acesses a closed rowbuffer".format(currentRow[1], currentRow[0])) + + if(currentRow[0] in idlePhases and rowBufferIsClosed == False): + return TestFailed("Phase {0}({1}) needs a closed rowbuffer".format(currentRow[1], currentRow[0])) + + if(currentRow[0] == 'ACT'): + rowBufferIsClosed = False + + if(currentRow[0] in prechargingPhases): + rowBufferIsClosed = True + + return TestSuceeded() + +#----------- activate checks --------------------------------------- +@test +def activate_to_activate_holds(connection): + """Checks that all activates are far enough apart(JESD229 229, P. 27)""" + cursor = connection.cursor() + cursor.execute("SELECT phases.ID,PhaseBegin,TBankGroup FROM Phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE PhaseName = 'ACT' ORDER BY PhaseBegin") + lastRow = cursor.fetchone() + + for currentRow in cursor: + timeBetweenActivates = currentRow[1] - lastRow[1] + if (currentRow[2] == lastRow[2]): + minTime = dramconfig.tRRD_L + else: + minTime = dramconfig.tRRD_S + if(timeBetweenActivates < minTime): + return TestFailed("Activates with PhaseIDs {0} and {1} are {2} apart. Minimum time between two activates is {3}". + format(currentRow[0], lastRow[0],formatTime(timeBetweenActivates), formatTime(minTime))) + + lastRow = currentRow + + return TestSuceeded() + + +@test +def activate_to_activate_on_same_bank_holds(connection): + """Checks that all activates on the same bank are far enough apart (JEDEC 229, P. 27)""" + 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 currentRow in cursor: + timeBetweenActivates = currentRow[1] - lastRow[1]; + if(timeBetweenActivates < dramconfig.tRC): + return TestFailed("Activates with PhaseIDs {0} and {1} are {2} apart. Minimum time between two activates is {3}, since they are on the same bank({4})". + format(currentRow[0], lastRow[0],formatTime(timeBetweenActivates), dramconfig.tRC)) + else: + lastRow = currentRow + + return TestSuceeded() + +@test +def n_activate_window_holds(connection): + """Checks that the n-Activate constraint is met everywhere(JEDEC 229, P. 27)""" + cursor = connection.cursor() + cursor.execute("SELECT ID,PhaseBegin from Phases WHERE PhaseName = 'ACT' ORDER BY PhaseBegin") + activateWindow = [] + + for currentRow in cursor: + activateWindow.append(currentRow[1]) + if(len(activateWindow) > dramconfig.nActivateWindow + 1): + activateWindow.pop(0) + if(activateWindow[dramconfig.nActivateWindow] - activateWindow[0] < dramconfig.tNAW): + return TestFailed("Activate with PhaseID {0} and the {1} preceeding activates violate the '{1} activate window' constraint." + " No more than {1} activates should be in rolling time window of {2}".format(currentRow[0], dramconfig.nActivateWindow,formatTime(dramconfig.tNAW))) + return TestSuceeded() + + + # ----------- read/write checks --------------------------------------- +@test +def read_to_read_holds(connection): + """Check that the read operations do not intefere with each other on the data bus""" + cursor = connection.cursor() + cursor.execute("SELECT phases.ID,PhaseBegin,TBankGroup FROM Phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE PhaseName IN ('RD','RDA') ORDER BY PhaseBegin") + lastRow = cursor.fetchone() + + for currentRow in cursor: + timeBetweenReads = currentRow[1] - lastRow[1] + if (currentRow[2] == lastRow[2]): + minTime = max(dramconfig.tCCD_L,dramconfig.getReadAccessTime()) + else: + minTime = max(dramconfig.tCCD_S,dramconfig.getReadAccessTime()) + if(timeBetweenReads < minTime): + return TestFailed("Reads with PhaseIDs {0} and {1} are {2} apart. Minimum time between two reads is {3}".format(currentRow[0], lastRow[0],formatTime(timeBetweenReads), minTime)) + lastRow = currentRow + + return TestSuceeded() + + +@test +def write_to_write_holds(connection): + """Check that the write operations do not intefere with each other on the data bus""" + + cursor = connection.cursor() + cursor.execute("SELECT phases.ID,PhaseBegin,TBankGroup FROM Phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE PhaseName IN ('WR','WRA') ORDER BY PhaseBegin") + lastRow = cursor.fetchone() + + for currentRow in cursor: + timeBetweenWrites = currentRow[1] - lastRow[1] + if (currentRow[2] == lastRow[2]): + minTime = max(dramconfig.tCCD_L,dramconfig.getWriteAccessTime()) + else: + minTime = max(dramconfig.tCCD_S,dramconfig.getWriteAccessTime()) + if(timeBetweenWrites < minTime): + return TestFailed("Writes with PhaseIDs {0} and {1} are {2} apart. Minimum time between two writes is {3}".format(currentRow[0], lastRow[0],formatTime(timeBetweenWrites), minTime)) + lastRow = currentRow + return TestSuceeded() + +@test +def write_to_read_and_read_to_write_hold(connection): + """Checks that read and write operation do not interfere with each other on the data bus + and that the write-to-read constraint is met""" + + cursor = connection.cursor() + query = """SELECT Phases.ID,PhaseBegin,PhaseName,TBankGroup from Phases INNER JOIN Transactions ON Phases.Transact = Transactions.ID + WHERE PhaseName IN ('RD','WR','RDA','WRA') ORDER BY PhaseBegin""" + + cursor.execute(query) + lastRow = cursor.fetchone() + + for currentRow in cursor: + + 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 + + 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}". + format(currentRow[0],formatTime(writeToRead),lastRow[0], formatTime(minWriteToRead))) + + 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 + + return TestSuceeded() + + +@test +def read_holds_dll_constraint_after_sref(connection): + """Checks that all read operations are delayed long enough after the end of the self refresh powerdown state""" + + cursor = connection.cursor() + query = """SELECT Phases.ID,PhaseBegin,PhaseName,TBankGroup from Phases INNER JOIN Transactions ON Phases.Transact = Transactions.ID AND TBank = :bank + WHERE PhaseName IN ('RD', 'RDA', 'SREF') ORDER BY PhaseBegin""" + + + for bankNumber in range(dramconfig.numberOfBanks): + cursor.execute(query,{"bank": bankNumber}) + lastRow = cursor.fetchone() + for currentRow in cursor: + if(currentRow[2] in ["RD","RDA"] and lastRow[2] == 'SREF'): + srefEndToRead = currentRow[1] - (lastRow[1] - dramconfig.clk) + 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 + return TestSuceeded() + + # ----------- powerdown checks --------------------------------------- + +# @test +# def sref_active_for_minimal_time(connection): +# """Checks that after entering self refresh powerndown state, the state is active for a minimal time (JEDEC 229, P. 41)""" +# +# cursor = connection.cursor() +# cursor.execute("SELECT ID, PhaseEnd-clk-PhaseBegin FROM Phases, GeneralInfo WHERE PhaseName = 'SREF'") +# for currentRow in cursor: +# if(currentRow[1] < dramconfig.tCKESR): +# return TestFailed("SREF with ID {0} is {1} long. Minimal time in SREF is {2}".format(currentRow[0], formatTime(currentRow[1]), dramconfig.tCKESR)) +# return TestSuceeded() + +# @test +# def pdna_pdnp_active_for_minimal_time(connection): +# """Checks that after entering active/precharged powerdown, the state is active for a minimal time (JEDEC 229, P. 41)""" +# +# cursor = connection.cursor() +# cursor.execute("SELECT ID,PhaseName, PhaseEnd-PhaseBegin FROM Phases, GeneralInfo WHERE PhaseName IN ('PDNA', 'PDNP') ") +# for currentRow in cursor: +# if(currentRow[2] < dramconfig.tCKE): +# return TestFailed("{0} with ID {1} is {2} long. Minimal time in SREF is {3}".format(currentRow[1], currentRow[0], formatTime(currentRow[2]), dramconfig.tCKE)) +# return TestSuceeded() + +# -------------------------- interface methods -------------------- + +def runTests(pathToTrace): + connection = sqlite3.connect(pathToTrace) + dramconfig.readConfigFromFiles(connection) + + testResults = [] + numberOfFailedTest = 0 + print("================================") + print("RUNNING TEST ON {0}".format(pathToTrace)) + + print("-----------------------------\n") + + for test in tests: + testResult = test(connection) + testName = test.__name__.replace("_"," ") + testResults.append((testName, testResult.passed,testResult.message)) + + if(testResult.passed): + print("[passed] {0}".format(testName)) + else: + print("[failed] {0} failed. Message: {1}".format(testName, testResult.message)) + numberOfFailedTest = numberOfFailedTest + 1 + + print("\n-----------------------------") + + if(numberOfFailedTest == 0): + print("All tests passed") + else: + print("{0} of {1} tests passed".format(len(tests) - numberOfFailedTest,len(tests))) + + print("================================") + connection.close() + + return testResults + +if __name__ == "__main__": + sys.stdout = os.fdopen(sys.stdout.fileno(), 'w') + for i in range(1,len(sys.argv)): + runTests(sys.argv[i]) + diff --git a/analyzer/analyzer/traceAnalyzer.pro b/analyzer/analyzer/traceAnalyzer.pro index 0c58af9a..bccb9571 100644 --- a/analyzer/analyzer/traceAnalyzer.pro +++ b/analyzer/analyzer/traceAnalyzer.pro @@ -16,6 +16,11 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = traceAnalyzer TEMPLATE = app +#copy python scripts +config.path = $${OUT_PWD}/scripts +config.files = scripts/* +INSTALLS += config + SOURCES += main.cpp\ businessObjects/transaction.cpp \ businessObjects/timespan.cpp \ @@ -95,7 +100,11 @@ FORMS += \ evaluationtool.ui OTHER_FILES += \ - common/static/createTraceDB.sql + common/static/createTraceDB.sql \ + tests.py \ + metrics.py \ + scripts/metrics.py \ + scripts/tests.py QMAKE_CXXFLAGS += -std=c++11 QMAKE_CXXFLAGS += -Xlinker -export-dynamic diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index 7aee4613..d4ccf183 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -57,22 +57,22 @@ SOURCES += \ ../src/controller/core/scheduling/checker/PowerDownChecker.cpp \ ../src/controller/core/scheduling/checker/ActivateChecker.cpp \ ../src/controller/core/scheduling/ScheduledCommand.cpp \ - ../src/controller/core/scheduling/CommandSequenceScheduler.cpp \ - ../src/controller/core/scheduling/CommandSequenceGenerator.cpp \ ../src/controller/core/TimingCalculation.cpp \ ../src/controller/core/Slots.cpp \ - ../src/controller/core/ControllerState.cpp \ ../src/controller/core/ControllerCore.cpp \ - ../src/controller/core/Command.cpp \ ../src/simulation/SimulationManager.cpp \ ../src/simulation/Simulation.cpp \ ../src/simulation/MemoryManager.cpp \ ../src/simulation/main.cpp \ - ../src/controller/core/RowBufferStates.cpp \ - ../src/controller/scheduler/Scheduler.cpp \ ../src/controller/scheduler/readwritegrouper.cpp \ ../src/controller/core/configuration/ConfigurationLoader.cpp \ - ../src/controller/core/powerdown/NoPowerDown.cpp + ../src/controller/core/powerdown/NoPowerDown.cpp \ + ../src/controller/Command.cpp \ + ../src/controller/Controller.cpp \ + ../src/controller/ControllerState.cpp \ + ../src/controller/RowBufferStates.cpp \ + ../src/controller/scheduler/IScheduler.cpp \ + ../src/controller/scheduler/FifoStrict.cpp HEADERS += \ ../src/common/third_party/tinyxml2.h \ @@ -88,7 +88,6 @@ HEADERS += \ ../src/controller/core/powerdown/PowerDownManagerBankwise.h \ ../src/controller/core/powerdown/PowerDownManager.h \ ../src/controller/scheduler/ThreadLoad.h \ - ../src/controller/scheduler/Scheduler.h \ ../src/controller/scheduler/PARBS.h \ ../src/controller/scheduler/Fr_Fcfs.h \ ../src/controller/scheduler/Fifo.h \ @@ -106,15 +105,9 @@ HEADERS += \ ../src/controller/core/scheduling/checker/ActivateChecker.h \ ../src/controller/core/scheduling/Trigger.h \ ../src/controller/core/scheduling/ScheduledCommand.h \ - ../src/controller/core/scheduling/CommandSequenceScheduler.h \ - ../src/controller/core/scheduling/CommandSequenceGenerator.h \ - ../src/controller/core/scheduling/CommandSchedule.h \ ../src/controller/core/TimingCalculation.h \ ../src/controller/core/Slots.h \ - ../src/controller/core/IWrapperConnector.h \ - ../src/controller/core/ControllerState.h \ ../src/controller/core/ControllerCore.h \ - ../src/controller/core/Command.h \ ../src/simulation/TracePlayer.h \ ../src/simulation/SimulationManager.h \ ../src/simulation/Simulation.h \ @@ -122,13 +115,19 @@ HEADERS += \ ../src/simulation/Dram.h \ ../src/simulation/Arbiter.h \ ../src/common/libDRAMPower.h \ - ../src/controller/core/RowBufferStates.h \ ../src/controller/scheduler/readwritegrouper.h \ ../src/simulation/ReorderBuffer.h \ ../src/controller/core/configuration/MemSpec.h \ ../src/simulation/StlPlayer.h \ ../src/simulation/TracePlayerListener.h \ ../src/simulation/TraceGenerator.h \ - ../src/controller/core/powerdown/NoPowerDown.h + ../src/controller/core/powerdown/NoPowerDown.h \ + ../src/controller/Command.h \ + ../src/controller/RowBufferStates.h \ + ../src/controller/ControllerState.h \ + ../src/controller/core/powerdown/IPowerDownManager.h \ + ../src/controller/scheduler/IScheduler.h \ + ../src/controller/scheduler/FifoStrict.h \ + ../src/controller/IController.h ../src/controller/core/configuration/ConfigurationLoader.h diff --git a/dram/resources/configs/memconfigs/fifo.xml b/dram/resources/configs/memconfigs/fifo.xml index eff47892..5cbb790e 100644 --- a/dram/resources/configs/memconfigs/fifo.xml +++ b/dram/resources/configs/memconfigs/fifo.xml @@ -1,11 +1,9 @@ - - - + - \ No newline at end of file + diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml index f890dc93..d2605c7e 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs.xml @@ -1,12 +1,10 @@ - - - + '.format(filename)) -# print(result) -# print( -# '<---------------------- End generated stl ---------------------->'.format(filename)) - -# def __generateAdress(self, channel, bank, row): -# if(channel > self.__dramConfigReader.maxValues['channel']): -# raise(BaseException('Channel argument out of range')) -# if(bank > self.__dramConfigReader.maxValues['bank']): -# raise(BaseException('Bank argument out of range')) -# if(row > self.__dramConfigReader.maxValues['row']): -# raise(BaseException('Row argument out of range')) -# return (channel << self.__dramConfigReader.startBits['channel']) | (bank << self.__dramConfigReader.startBits['bank']) | (row << self.__dramConfigReader.startBits['row']) - -# def __init__(self): -# pass - - -if __name__ == '__main__': - if(len(sys.argv) > 1): - stlReader = StlReader() - for line in sys.argv[1:]: - stlReader.printStlPretty(line) diff --git a/dram/resources/scripts/tests.py b/dram/resources/scripts/tests.py deleted file mode 100644 index e1184e7c..00000000 --- a/dram/resources/scripts/tests.py +++ /dev/null @@ -1,617 +0,0 @@ -import sys -import traceback -import sqlite3 -import os -import xml.etree.ElementTree as ET - -def getPathToConfigs(): - 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'] - -def getIntValueFromConfigXML(root, id): - return int(root.findall(".//parameter[@id='{0}']".format(id))[0].attrib['value']) - -def getMemconfig(connection): - cursor = connection.cursor() - cursor.execute("SELECT Memconfig FROM GeneralInfo") - result = cursor.fetchone() - memconfig = getPathToConfigs() + "/memconfigs/" + result[0] - return ET.parse(memconfig) - -def getMemspec(connection): - cursor = connection.cursor() - cursor.execute("SELECT Memspec FROM GeneralInfo") - result = cursor.fetchone() - memspec = getPathToConfigs() + "/memspecs/" + result[0] - return ET.parse(memspec) - -def getClock(connection): - cursor = connection.cursor() - cursor.execute("SELECT clk, UnitOfTime FROM GeneralInfo") - result = cursor.fetchone() - return (result[0],result[1]) - -class DramConfig(object): - memoryType = "" - bankwiseLogic = 0 - clk = 0 - unitOfTime = "" - dataRate = 0 - nActivateWindow = numberOfBanks = 0 - - clk = 0 - tRP = 0 #precharge-time (pre -> act same bank) - tRAS = 0 #active-time (act -> pre same bank) - tRC = 0 #RAS-cycle-time (min time bw 2 succesive ACT to same bank) - tCCD_S = 0 #TODO: relevant? max(bl, tCCD) - tCCD_L = 0 - tRTP = 0 #Read to precharge - tRRD_S = 0 #min time bw 2 succesive ACT to different banks (different bank group) - tRRD_L = 0 #.. (same bank group) - tRCD = 0 #act -> read/write - tNAW = 0 #n activate window - tRL = 0 #read latency (read command start to data strobe) - tWL = 0 #write latency - tWR = 0 #write recovery (write to precharge) - tWTR_S = 0 #write to read (different bank group) - tWTR_L = 0 #.. (same bank group) - tCKESR = 0 #min time in sref - tCKE = 0 #min time in pdna or pdnp - tXP = 0 #min delay to row access command after pdnpx pdnax - tXPDLL = 0 #min delay to row access command after pdnpx pdnax for dll commands - 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 - - - def readConfigFromFiles(self, connection): - print("Parsing dram configuration") - memspec = getMemspec(connection) - - clkWithUnit = getClock(connection) - self.clk = clkWithUnit[0] - self.unitOfTime = clkWithUnit[1].lower() - - self.bankwiseLogic = getIntValueFromConfigXML(getMemconfig(connection), "bankwiseLogic") - self.numberOfBanks = getIntValueFromConfigXML(memspec, "nbrOfBanks") - self.burstLength = getIntValueFromConfigXML(memspec, "burstLength") - self.memoryType = getValueFromConfigXML(memspec, "memoryType") - self.dataRate = getIntValueFromConfigXML(memspec, "dataRate") - - if(self.memoryType == "WIDEIO_SDR"): - self.nActivateWindow = 2; - self.tRP = self.clk * getIntValueFromConfigXML(memspec, "RP") - self.tRAS = self.clk * getIntValueFromConfigXML(memspec, "RAS") - self.tRC = self.clk * getIntValueFromConfigXML(memspec, "RC") - self.tRRD_S = self.clk * getIntValueFromConfigXML(memspec, "RRD") - self.tRRD_L = self.tRRD_S - self.tCCD_S = self.clk * getIntValueFromConfigXML(memspec, "CCD") - self.tCCD_L = self.tCCD_S - self.tRCD = self.clk * getIntValueFromConfigXML(memspec, "RCD") - self.tNAW = self.clk * getIntValueFromConfigXML(memspec, "TAW") - self.tRL = self.clk * getIntValueFromConfigXML(memspec, "RL") - self.tWL = self.clk * getIntValueFromConfigXML(memspec, "WL") - self.tWR = self.clk * getIntValueFromConfigXML(memspec, "WR") - self.tWTR_S = self.clk * getIntValueFromConfigXML(memspec, "WTR") - self.tWTR_L = self.tWTR_S - self.tRTP = self.clk * getIntValueFromConfigXML(memspec, "RTP"); - self.tCKESR = self.clk * getIntValueFromConfigXML(memspec, "CKESR") - self.tCKE = self.clk * getIntValueFromConfigXML(memspec, "CKE") - self.tXP = self.clk * getIntValueFromConfigXML(memspec, "XP") - self.tXPDLL = self.tXP - self.tXSR = self.clk * getIntValueFromConfigXML(memspec, "XS") - self.tXSRDLL = self.tXSR - self.tAL = self.clk * getIntValueFromConfigXML(memspec, "AL") - self.tRFC = self.clk * getIntValueFromConfigXML(memspec, "RFC") - - elif(self. memoryType == "DDR4"): - self.nActivateWindow = 4; - self.tRP = self.clk * getIntValueFromConfigXML(memspec, "RP"); - self.tRAS = self.clk * getIntValueFromConfigXML(memspec, "RAS"); - self.tRC = self.clk * getIntValueFromConfigXML(memspec, "RC"); - self.tRTP = self.clk * getIntValueFromConfigXML(memspec, "RTP"); - self.tRRD_S = self.clk * getIntValueFromConfigXML(memspec, "RRD_S"); - self.tRRD_L = self.clk * getIntValueFromConfigXML(memspec, "RRD_L"); - self.tCCD_S = self.clk * getIntValueFromConfigXML(memspec, "CCD_S"); - self.tCCD_L = self.clk * getIntValueFromConfigXML(memspec, "CCD_L"); - self.tRCD = self.clk * getIntValueFromConfigXML(memspec, "RCD"); - self.tNAW = self.clk * getIntValueFromConfigXML(memspec, "FAW"); - self.tRL = self.clk * getIntValueFromConfigXML(memspec, "RL"); - self.tWL = self.clk * getIntValueFromConfigXML(memspec, "WL"); - self.tWR = self.clk * getIntValueFromConfigXML(memspec, "WR"); - self.tWTR_S = self.clk * getIntValueFromConfigXML(memspec, "WTR_S"); - self.tWTR_L = self.clk * getIntValueFromConfigXML(memspec, "WTR_L"); - self.tCKESR = self.clk * getIntValueFromConfigXML(memspec, "CKESR"); - self.tCKE = self.clk * getIntValueFromConfigXML(memspec, "CKE"); - self.tXP = self.clk * getIntValueFromConfigXML(memspec, "XP"); - self.tXPDLL = self.clk * getIntValueFromConfigXML(memspec, "XPDLL"); - self.tXSR = self.clk * getIntValueFromConfigXML(memspec, "XS"); - self.tXSRDLL = self.clk * getIntValueFromConfigXML(memspec, "XSDLL"); - self.tAL = self.clk * getIntValueFromConfigXML(memspec, "AL"); - self.tRFC = self.clk * getIntValueFromConfigXML(memspec, "RFC"); - else: - raise Exception("MemoryType not supported yet. Insert a coin into the coin machine and try again") - - def clkAlign(self, value): - return math.ceil(1.0*value/self.clk)*self.clk - - def getWriteAccessTime(self): - if(self.dataRate == 1): - return self.clk*(self.burstLength - 1) - elif (self.memoryType == "DDR4"): - return self.clk*self.burstLength/self.dataRate - - def getReadAccessTime(self): - return self.burstLength/self.dataRate * dramconfig.clk - - - def __init__(self): - pass - -dramconfig = DramConfig() - -def calculateReadLength(burstLength): - return dramconfig.tRL + burstLength * dramconfig.clk - -def calculateWriteLength(burstLength): - return dramconfig.tWL + burstLength * dramconfig.clk - -# ----------- test utils --------------------------------------- - -tests = [] - -def test(function): - tests.append(function) - return function - -class TestResult(object): - passed = True - message = '' - def __init__(self, passed = True, message = ''): - self.passed = passed - self.message = message - -def TestSuceeded(): - return TestResult() - -def TestFailed(message): - return TestResult(False,message); - -def formatTime(time): - return ('{0} {1}'.format(time, dramconfig.unitOfTime)) - -# ----------- checks --------------------------------------- - -@test -def commands_are_clockaligned(connection): - """Checks that all commands on the command bus are aligned to the system clock""" - - 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}) - - 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 - FROM Phases WHERE PhaseName NOT IN """ + excludedPhases + """ AND phasebegin>0 GROUP BY phaseBegin) WHERE count>1""" - - cursor.execute(query) - result = cursor.fetchone() - if(result != None): - return TestFailed("Slot on commandbus at time {0} is used multiple times".format(formatTime(result[0]))) - return TestSuceeded() - - -@test -def phase_transitions_are_valid(connection): - """Checks that all transition of two consequtive phases on the same bank are valid""" - - cursor = connection.cursor() - validTransitions = {} - - if(dramconfig.bankwiseLogic): - 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['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']) - else: - 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['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']) - - - 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() - for currentRow in cursor: - currentPhase = currentRow[0] - lastPhase = lastRow[0] - if(currentPhase not in validTransitions[lastPhase]): - return TestFailed("Phase {0}({1}) is not allowed to follow phase {2}({3})".format(currentRow[1],currentPhase,lastRow[1],lastPhase)) - lastRow = currentRow - - return TestSuceeded() - - -def timing_constraint(FirstPhase, SecondPhase): - FirstPhaseName = FirstPhase[0] - SecondPhaseName = SecondPhase[0] - - if(FirstPhaseName == "PRE" or FirstPhaseName == "PRE_ALL"): - return dramconfig.tRP - - elif(FirstPhaseName == "ACT"): - return dramconfig.tRCD - - elif(FirstPhaseName == "RD"): - if(SecondPhaseName in ["PRE, PRE_ALL"]): - return dramconfig.tRTP - elif(SecondPhaseName in ["RD, RDA"]): - return max(dramconfig.tCCD_L, getReadAccessTime()) - elif(SecondPhase in ["WR","WRA"]): - return dramconfig.tRL + getReadAccessTime() - dramconfig.tWL + 2*dramconfig.clk - elif(SecondPhase == "PDNA" ): - return dramconfig.tRL + getReadAccessTime() + dramconfig.clk - - elif(FirstPhaseName == "WR"): - if(SecondPhaseName in ["PRE, PRE_ALL", "PDNA"]): - return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR - elif(SecondPhaseName in ["RD, RDA"]): - return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWTR_L - elif(SecondPhaseName in ["WR, WRA"]): - return max(dramconfig.tCCD_L, burstlength/dramconfig.dataRate) - - elif(FirstPhaseName == "RDA"): - if(SecondPhaseName in ["ACT", "PRE_ALL", "AUTO_REFRESH"]): - return dramconfig.tRTP + dramconfig.tRP - elif(SecondPhaseName in ["PDNA","PDNP"]): - return dramconfig.tRL + getReadAccessTime() + dramconfig.clk - - elif(FirstPhaseName == "WRA"): - if(SecondPhaseName in ["ACT", "PRE_ALL", "AUTO_REFRESH"]): - return dramconfig.tWL + getWriteAccessTime() + dramconfig.tWR + dramconfig.tRP - elif(SecondPhaseName in ["PDNA","PDNP"]): - return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR + dramconfig.clk - - elif(FirstPhaseName == "AUTO_REFRESH"): - return dramconfig.tRFC - - elif(FirstPhaseName in ["PDNA","PDNP"]): - return (FirstPhase[3] - FirstPhase[2]) + dramconfig.tXP - dramconfig.clk - - elif(FirstPhaseName == "SREF"): - return (FirstPhase[3] - FirstPhase[2]) + dramconfig.tXSR - dramconfig.clk - - return 0 - -@test -def timing_constraits_on_the_same_bank_hold(connection): - """Checks that all transitions of two consequtive phases on the same bank meet their timing constraints""" - cursor = connection.cursor() - validTransitions = {} - - query = """SELECT PhaseName, phases.ID,PhaseBegin,PhaseEnd 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() - - for currentRow in cursor: - constraint = timing_constraint(lastRow,currentRow) - if(currentRow[2] - lastRow[2] + constraint < 0): - return TestFailed("Phase {0}({1}) starts {2} after Start of Phase {3}({4}). Minimal time is {5}".format( - currentRow[1],currentRow[0],formatTime(currentRow[2]-lastRow[2]),lastRow[1],lastRow[0], formatTime(constraint))) - lastRow = currentRow - return TestSuceeded() - -@test -def row_buffer_is_used_correctly(connection): - """Checks that each bank's row buffer is used correctly""" - - cursor = connection.cursor() - 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""" - - - #phases that precharge the bank and close the rowbuffer - prechargingPhases = set(['PRE','PRE_ALL','RDA','WRA']) - - #phases that require the bank to be in active state and the rowbuffer to be opened - accessingPhases = set(['RD','RDA', 'WR', 'WRA', 'PRE']) - - #phases that require the bank to be in precharged state and the robuffer to be closed - idlePhases = set(['ACT', 'PDNP', 'AUTO_REFRESH', 'SREF']) - - for bankNumber in range(dramconfig.numberOfBanks): - cursor.execute(query,{"bank": bankNumber}) - - rowBufferIsClosed = True - - - - for currentRow in cursor: - if(currentRow[0] in accessingPhases and rowBufferIsClosed == True): - return TestFailed("Phase {0}({1}) acesses a closed rowbuffer".format(currentRow[1], currentRow[0])) - - if(currentRow[0] in idlePhases and rowBufferIsClosed == False): - return TestFailed("Phase {0}({1}) needs a closed rowbuffer".format(currentRow[1], currentRow[0])) - - if(currentRow[0] == 'ACT'): - rowBufferIsClosed = False - - if(currentRow[0] in prechargingPhases): - rowBufferIsClosed = True - - return TestSuceeded() - -#----------- activate checks --------------------------------------- -@test -def activate_to_activate_holds(connection): - """Checks that all activates are far enough apart(JESD229 229, P. 27)""" - cursor = connection.cursor() - cursor.execute("SELECT phases.ID,PhaseBegin,TBankGroup FROM Phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE PhaseName = 'ACT' ORDER BY PhaseBegin") - lastRow = cursor.fetchone() - - for currentRow in cursor: - timeBetweenActivates = currentRow[1] - lastRow[1] - if (currentRow[2] == lastRow[2]): - minTime = dramconfig.tRRD_L - else: - minTime = dramconfig.tRRD_S - if(timeBetweenActivates < minTime): - return TestFailed("Activates with PhaseIDs {0} and {1} are {2} apart. Minimum time between two activates is {3}". - format(currentRow[0], lastRow[0],formatTime(timeBetweenActivates), formatTime(minTime))) - - lastRow = currentRow - - return TestSuceeded() - - -@test -def activate_to_activate_on_same_bank_holds(connection): - """Checks that all activates on the same bank are far enough apart (JEDEC 229, P. 27)""" - 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 currentRow in cursor: - timeBetweenActivates = currentRow[1] - lastRow[1]; - if(timeBetweenActivates < dramconfig.tRC): - return TestFailed("Activates with PhaseIDs {0} and {1} are {2} apart. Minimum time between two activates is {3}, since they are on the same bank({4})". - format(currentRow[0], lastRow[0],formatTime(timeBetweenActivates), dramconfig.tRC)) - else: - lastRow = currentRow - - return TestSuceeded() - -@test -def n_activate_window_holds(connection): - """Checks that the n-Activate constraint is met everywhere(JEDEC 229, P. 27)""" - cursor = connection.cursor() - cursor.execute("SELECT ID,PhaseBegin from Phases WHERE PhaseName = 'ACT' ORDER BY PhaseBegin") - activateWindow = [] - - for currentRow in cursor: - activateWindow.append(currentRow[1]) - if(len(activateWindow) > dramconfig.nActivateWindow + 1): - activateWindow.pop(0) - if(activateWindow[dramconfig.nActivateWindow] - activateWindow[0] < dramconfig.tNAW): - return TestFailed("Activate with PhaseID {0} and the {1} preceeding activates violate the '{1} activate window' constraint." - " No more than {1} activates should be in rolling time window of {2}".format(currentRow[0], dramconfig.nActivateWindow,formatTime(dramconfig.tNAW))) - return TestSuceeded() - - - # ----------- read/write checks --------------------------------------- -@test -def read_to_read_holds(connection): - """Check that the read operations do not intefere with each other on the data bus""" - cursor = connection.cursor() - cursor.execute("SELECT phases.ID,PhaseBegin,TBankGroup FROM Phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE PhaseName IN ('RD','RDA') ORDER BY PhaseBegin") - lastRow = cursor.fetchone() - - for currentRow in cursor: - timeBetweenReads = currentRow[1] - lastRow[1] - if (currentRow[2] == lastRow[2]): - minTime = max(dramconfig.tCCD_L,dramconfig.getReadAccessTime()) - else: - minTime = max(dramconfig.tCCD_S,dramconfig.getReadAccessTime()) - if(timeBetweenReads < minTime): - return TestFailed("Reads with PhaseIDs {0} and {1} are {2} apart. Minimum time between two reads is {3}".format(currentRow[0], lastRow[0],formatTime(timeBetweenReads), minTime)) - lastRow = currentRow - - return TestSuceeded() - - -@test -def write_to_write_holds(connection): - """Check that the write operations do not intefere with each other on the data bus""" - - cursor = connection.cursor() - cursor.execute("SELECT phases.ID,PhaseBegin,TBankGroup FROM Phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE PhaseName IN ('WR','WRA') ORDER BY PhaseBegin") - lastRow = cursor.fetchone() - - for currentRow in cursor: - timeBetweenWrites = currentRow[1] - lastRow[1] - if (currentRow[2] == lastRow[2]): - minTime = max(dramconfig.tCCD_L,dramconfig.getWriteAccessTime()) - else: - minTime = max(dramconfig.tCCD_S,dramconfig.getWriteAccessTime()) - if(timeBetweenWrites < minTime): - return TestFailed("Writes with PhaseIDs {0} and {1} are {2} apart. Minimum time between two writes is {3}".format(currentRow[0], lastRow[0],formatTime(timeBetweenWrites), minTime)) - lastRow = currentRow - return TestSuceeded() - -@test -def write_to_read_and_read_to_write_hold(connection): - """Checks that read and write operation do not interfere with each other on the data bus - and that the write-to-read constraint is met""" - - cursor = connection.cursor() - query = """SELECT Phases.ID,PhaseBegin,PhaseName,TBankGroup from Phases INNER JOIN Transactions ON Phases.Transact = Transactions.ID - WHERE PhaseName IN ('RD','WR','RDA','WRA') ORDER BY PhaseBegin""" - - cursor.execute(query) - lastRow = cursor.fetchone() - - for currentRow in cursor: - - 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 - - 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}". - format(currentRow[0],formatTime(writeToRead),lastRow[0], formatTime(minWriteToRead))) - - 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 - - return TestSuceeded() - - -@test -def read_holds_dll_constraint_after_sref(connection): - """Checks that all read operations are delayed long enough after the end of the self refresh powerdown state""" - - cursor = connection.cursor() - query = """SELECT Phases.ID,PhaseBegin,PhaseName,TBankGroup from Phases INNER JOIN Transactions ON Phases.Transact = Transactions.ID AND TBank = :bank - WHERE PhaseName IN ('RD', 'RDA', 'SREF') ORDER BY PhaseBegin""" - - - for bankNumber in range(dramconfig.numberOfBanks): - cursor.execute(query,{"bank": bankNumber}) - lastRow = cursor.fetchone() - for currentRow in cursor: - if(currentRow[2] in ["RD","RDA"] and lastRow[2] == 'SREF'): - srefEndToRead = currentRow[1] - (lastRow[1] - dramconfig.clk) - 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 - return TestSuceeded() - - # ----------- powerdown checks --------------------------------------- - -# @test -# def sref_active_for_minimal_time(connection): -# """Checks that after entering self refresh powerndown state, the state is active for a minimal time (JEDEC 229, P. 41)""" -# -# cursor = connection.cursor() -# cursor.execute("SELECT ID, PhaseEnd-clk-PhaseBegin FROM Phases, GeneralInfo WHERE PhaseName = 'SREF'") -# for currentRow in cursor: -# if(currentRow[1] < dramconfig.tCKESR): -# return TestFailed("SREF with ID {0} is {1} long. Minimal time in SREF is {2}".format(currentRow[0], formatTime(currentRow[1]), dramconfig.tCKESR)) -# return TestSuceeded() - -# @test -# def pdna_pdnp_active_for_minimal_time(connection): -# """Checks that after entering active/precharged powerdown, the state is active for a minimal time (JEDEC 229, P. 41)""" -# -# cursor = connection.cursor() -# cursor.execute("SELECT ID,PhaseName, PhaseEnd-PhaseBegin FROM Phases, GeneralInfo WHERE PhaseName IN ('PDNA', 'PDNP') ") -# for currentRow in cursor: -# if(currentRow[2] < dramconfig.tCKE): -# return TestFailed("{0} with ID {1} is {2} long. Minimal time in SREF is {3}".format(currentRow[1], currentRow[0], formatTime(currentRow[2]), dramconfig.tCKE)) -# return TestSuceeded() - -# -------------------------- interface methods -------------------- - -def runTests(pathToTrace): - print(pathToTrace) - connection = sqlite3.connect(pathToTrace) - dramconfig.readConfigFromFiles(connection) - - testResults = [] - numberOfFailedTest = 0 - print("================================") - print("RUNNING TEST ON {0}".format(pathToTrace)) - - print("-----------------------------\n") - - for test in tests: - testResult = test(connection) - testName = test.__name__.replace("_"," ") - testResults.append((testName, testResult.passed,testResult.message)) - - if(testResult.passed): - print("[passed] {0}".format(testName)) - else: - print("[failed] {0} failed. Message: {1}".format(testName, testResult.message)) - numberOfFailedTest = numberOfFailedTest + 1 - - print("\n-----------------------------") - - if(numberOfFailedTest == 0): - print("All tests passed") - else: - print("{0} of {1} tests passed".format(len(tests) - numberOfFailedTest,len(tests))) - - print("================================") - connection.close() - - return testResults - -if __name__ == "__main__": - 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/datasizes.xml b/dram/resources/simulations/datasizes.xml deleted file mode 100644 index c014fcfa..00000000 --- a/dram/resources/simulations/datasizes.xml +++ /dev/null @@ -1,22 +0,0 @@ - - JEDEC_256Mb_WIDEIO_SDR-266_128bit.xml - am_wideioFourBanks.xml - - fr_fcfs_unaware.xml - - - - - chstone-aes_32.stl - chstone-motion_32.stl - - - - chstone-motion_32.stl - chstone-jpeg_32.stl - - - - - - diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index 4d4d7562..bed17c6a 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -1,25 +1,25 @@ - + + + - + - + - - + + - - - - - small.stl + + + + mediabench-epic_32.stl - diff --git a/dram/src/common/DebugManager.cpp b/dram/src/common/DebugManager.cpp index 0ee8dcf2..0b6fe1f4 100644 --- a/dram/src/common/DebugManager.cpp +++ b/dram/src/common/DebugManager.cpp @@ -6,12 +6,12 @@ */ #include "DebugManager.h" +#include "../controller/core/configuration/Configuration.h" using namespace std; void DebugManager::printDebugMessage(string sender, string message) { -#ifndef NDEBUG - if (whiteList.count(sender)) + if(Configuration::getInstance().Debug) { if (writeToConsole) cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message << endl; @@ -19,7 +19,6 @@ void DebugManager::printDebugMessage(string sender, string message) if (writeToFile && debugFile) debugFile << " at " << sc_time_stamp() << " in " << sender << "\t: " << message << "\n"; } -#endif } void DebugManager::openDebugFile(string filename) @@ -29,17 +28,6 @@ void DebugManager::openDebugFile(string filename) debugFile.open(filename); } -void DebugManager::addToWhiteList(string sender) -{ - whiteList.insert(sender); -} - -void DebugManager::addToWhiteList(vector senders) -{ - for (string sender : senders) - addToWhiteList(sender); -} - DebugManager::DebugManager() : writeToConsole(true), writeToFile(true) { diff --git a/dram/src/common/DebugManager.h b/dram/src/common/DebugManager.h index 4bcd5fdf..8987b24a 100644 --- a/dram/src/common/DebugManager.h +++ b/dram/src/common/DebugManager.h @@ -28,15 +28,11 @@ public: void printDebugMessage(std::string sender, std::string message); void openDebugFile(std::string filename); - void addToWhiteList(std::string sender); - void addToWhiteList(std::vector senders); - private: DebugManager(); DebugManager(const DebugManager&){} ofstream debugFile; - std::set whiteList; }; #endif /* DEBUGMANAGER_H_ */ diff --git a/dram/src/common/TlmRecorder.cpp b/dram/src/common/TlmRecorder.cpp index d1ebd6ba..e5123a1d 100644 --- a/dram/src/common/TlmRecorder.cpp +++ b/dram/src/common/TlmRecorder.cpp @@ -158,12 +158,17 @@ void TlmRecorder::Transaction::insertPhase(string name, sc_time begin) void TlmRecorder::Transaction::setPhaseEnd(string name, sc_time end) { - for(Phase& data: recordedPhases) + // Find the latest recorder phase for that transaction with a matching name and update it + // Note: Transaction have the same phase multiple times (e.g. PRE->ACT->REF->ACT->RD) only update the latest + // one that has been recorder + for(int i = recordedPhases.size() - 1; i >= 0;i--) { + Phase& data = recordedPhases[i]; if(data.name == name) { data.interval.end = end; return; + } } SC_REPORT_FATAL("Recording Error", "While trying to set phase end: phaseBegin has not been recorded"); @@ -240,8 +245,8 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_int64(insertGeneralInfoStatement, 1, totalNumTransactions - 1); sqlite3_bind_int64(insertGeneralInfoStatement, 2, simulationTimeCoveredByRecording.value()); sqlite3_bind_int(insertGeneralInfoStatement, 3, - core::Configuration::getInstance().memSpec.NumberOfBanks); - sqlite3_bind_int(insertGeneralInfoStatement, 4, core::Configuration::getInstance().memSpec.clk.value()); + Configuration::getInstance().memSpec.NumberOfBanks); + sqlite3_bind_int(insertGeneralInfoStatement, 4, Configuration::getInstance().memSpec.clk.value()); sqlite3_bind_text(insertGeneralInfoStatement, 5, "PS", 2, NULL); sqlite3_bind_text(insertGeneralInfoStatement, 6, memconfig.c_str(), memconfig.length(), NULL); sqlite3_bind_text(insertGeneralInfoStatement, 7, memspec.c_str(), memspec.length(), NULL); diff --git a/dram/src/common/dramExtension.cpp b/dram/src/common/dramExtension.cpp index ca2dce48..76e77330 100644 --- a/dram/src/common/dramExtension.cpp +++ b/dram/src/common/dramExtension.cpp @@ -35,6 +35,26 @@ DramExtension& DramExtension::getExtension(const tlm_generic_payload &payload) return DramExtension::getExtension(&payload); } +Bank DramExtension::getBank(const tlm_generic_payload *payload) +{ + return DramExtension::getExtension(payload).getBank(); +} + +Bank DramExtension::getBank(const tlm_generic_payload &payload) +{ + return DramExtension::getBank(&payload); +} + +Row DramExtension::getRow(const tlm_generic_payload *payload) +{ + return DramExtension::getExtension(payload).getRow(); +} + +Row DramExtension::getRow(const tlm_generic_payload &payload) +{ + return DramExtension::getRow(&payload); +} + tlm_extension_base* DramExtension::clone() const { @@ -184,7 +204,7 @@ bool operator !=(const Row& lhs, const Row& rhs) const Row Row::operator ++() { - id = (id + 1) % core::Configuration::getInstance().memSpec.NumberOfRows; + id = (id + 1) % Configuration::getInstance().memSpec.NumberOfRows; return *this; } diff --git a/dram/src/common/dramExtension.h b/dram/src/common/dramExtension.h index e0307be5..25d9e839 100644 --- a/dram/src/common/dramExtension.h +++ b/dram/src/common/dramExtension.h @@ -76,6 +76,12 @@ public: return 0; } + std::string toString() + { + return std::to_string(id); + } + + private: unsigned int id; }; @@ -135,9 +141,16 @@ public: virtual tlm_extension_base* clone() const; virtual void copy_from(const tlm_extension_base& ext); + static DramExtension& getExtension(const tlm::tlm_generic_payload *payload); static DramExtension& getExtension(const tlm::tlm_generic_payload &payload); + // Used for convience, caller could also use getExtension(..) to access these field + static Bank getBank(const tlm::tlm_generic_payload *payload); + static Bank getBank(const tlm::tlm_generic_payload &payload); + static Row getRow(const tlm::tlm_generic_payload *payload); + static Row getRow(const tlm::tlm_generic_payload &payload); + Thread getThread() const; Channel getChannel() const; Bank getBank() const; diff --git a/dram/src/common/third_party/DRAMPower b/dram/src/common/third_party/DRAMPower index 7723662d..e39b6d66 160000 --- a/dram/src/common/third_party/DRAMPower +++ b/dram/src/common/third_party/DRAMPower @@ -1 +1 @@ -Subproject commit 7723662db4edd6b8ccd7424edd17073fbfbff601 +Subproject commit e39b6d6668fed4ddbc3c9150dce1dd1bfc7a8be2 diff --git a/dram/src/common/xmlAddressdecoder.cpp b/dram/src/common/xmlAddressdecoder.cpp index a8b9752b..7cb20b4a 100644 --- a/dram/src/common/xmlAddressdecoder.cpp +++ b/dram/src/common/xmlAddressdecoder.cpp @@ -52,8 +52,8 @@ DecodedAddress xmlAddressDecoder::decodeAddress(sc_dt::uint64 addr) //result.rank = (addr & masks["rank"]) >> shifts["rank"]; //result.bankgroup = (addr & masks["bankgroup"]) >> shifts["bankgroup"]; result.bank = (addr & masks["bank"]) >> shifts["bank"]; - result.bankgroup = result.bank % core::Configuration::getInstance().memSpec.NumberOfBankGroups; - result.rank = result.bank % core::Configuration::getInstance().memSpec.NumberOfRanks; + result.bankgroup = result.bank % Configuration::getInstance().memSpec.NumberOfBankGroups; + result.rank = result.bank % Configuration::getInstance().memSpec.NumberOfRanks; result.row = (addr & masks["row"]) >> shifts["row"]; result.column = (addr & masks["column"]) >> shifts["column"]; result.bytes = (addr & masks["bytes"]) >> shifts["bytes"]; diff --git a/dram/src/controller/Command.cpp b/dram/src/controller/Command.cpp new file mode 100644 index 00000000..2f1bee11 --- /dev/null +++ b/dram/src/controller/Command.cpp @@ -0,0 +1,78 @@ +#include "Command.h" +#include + + +std::string commandToString(Command command) +{ + switch (command) + { + case Command::Read: + return "RD"; + break; + case Command::ReadA: + return "RDA"; + break; + case Command::Write: + return "WR"; + break; + case Command::WriteA: + return "WRA"; + break; + case Command::Precharge: + return "PRE"; + break; + case Command::Activate: + return "ACT"; + break; + case Command::PrechargeAll: + return "PRE_ALL"; + break; + case Command::AutoRefresh: + return "AUTO_REFRESH"; + break; + + case Command::PDNA: + return "PDNA"; + break; + case Command::PDNAX: + return "PDNAX"; + break; + case Command::PDNP: + return "PDNP"; + break; + case Command::PDNPX: + return "PDNPX"; + break; + case Command::SREF: + return "SREF"; + break; + case Command::SREFX: + return "SREFX"; + break; + + default: + SC_REPORT_FATAL("command", "commandToString was called with unknown command"); + break; + } + + return ""; +} + +const std::vector& getAllCommands() +{ + static std::vector allCommands( { Command::Precharge, Command::PrechargeAll, + Command::Activate, Command::Read, Command::Write, Command::ReadA, Command::WriteA, + Command::AutoRefresh, Command::PDNA, Command::PDNAX, Command::PDNP, Command::PDNPX, + Command::SREF, Command::SREFX }); + return allCommands; +} + +bool commandIsIn(Command command, std::vector commands) +{ + for (Command c : commands) + { + if (c == command) + return true; + } + return false; +} diff --git a/dram/src/controller/core/Command.h b/dram/src/controller/Command.h similarity index 80% rename from dram/src/controller/core/Command.h rename to dram/src/controller/Command.h index db88ca12..e844e01a 100644 --- a/dram/src/controller/core/Command.h +++ b/dram/src/controller/Command.h @@ -10,16 +10,10 @@ #include #include -namespace core { enum class Command {NOP, Precharge, PrechargeAll, Activate, Read, Write, ReadA, WriteA, AutoRefresh, PDNA, PDNAX, PDNP, PDNPX, SREF, SREFX}; std::string commandToString(Command command); - const std::vector& getAllCommands(); - - -typedef std::vector CommandSequence; - -} /* namespace controller */ +bool commandIsIn(Command command, std::vector commands); #endif /* COMMAND_H_ */ diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h index 05142081..7b708b02 100644 --- a/dram/src/controller/Controller.h +++ b/dram/src/controller/Controller.h @@ -25,26 +25,24 @@ #include "../common/Utils.h" #include "core/configuration/Configuration.h" #include "core/configuration/MemSpec.h" -#include "core/Command.h" +#include "Command.h" #include "core/ControllerCore.h" -#include "core/ControllerState.h" -#include "core/IWrapperConnector.h" +#include "ControllerState.h" +#include "IController.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/FifoStrict.h" #include "scheduler/Fr_Fcfs.h" -#include "scheduler/PARBS.h" -#include "scheduler/readwritegrouper.h" +#include "scheduler/IScheduler.h" using namespace std; using namespace tlm; -using namespace core; -using namespace scheduler; template -struct Controller: public sc_module, public IWrapperConnector +struct Controller: public sc_module, public IController { public: Controller(sc_module_name /*name*/) : @@ -59,7 +57,7 @@ public: ~Controller() { - delete controllerCore; + delete controllerCore; delete scheduler; } @@ -69,7 +67,6 @@ public: virtual void send(const ScheduledCommand& command, tlm_generic_payload& payload) override; virtual void send(Trigger trigger, sc_time time, tlm_generic_payload& payload) override; - tlm_utils::simple_initiator_socket iSocket; tlm_utils::simple_target_socket tSocket; @@ -78,10 +75,7 @@ private: void payloadEntersSystem(tlm_generic_payload& payload); void payloadLeavesSystem(tlm_generic_payload& payload); unsigned int getTotalNumberOfPayloadsInSystem(); - void scheduleNextFromScheduler(); - //FIFO HACK - void scheduleDirectly(gp* payload); - + void scheduleNextFromScheduler(Bank bank); // --- FRONTEND ------ tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay); @@ -96,12 +90,13 @@ private: // ------- CONTROLLER CORE --------- void controllerCorePEQCallback(tlm_generic_payload& payload, const tlm_phase& phase); - //Helpers TODO move them + // Helpers TODO move them void printDebugMessage(string message); bool containsPhase(tlm_phase phase, std::vector phases); ControllerCore* controllerCore; - Scheduler* scheduler; + //Scheduler* scheduler; + IScheduler* scheduler; std::map numberOfPayloadsInSystem; std::vector refreshCollisionRequets; tlm::tlm_generic_payload* backpressure = NULL; @@ -123,23 +118,27 @@ void Controller::buildScheduler() { string selectedScheduler = Configuration::getInstance().Scheduler; - if (selectedScheduler == "FR_FCFS") + if (selectedScheduler == "FIFO") { - scheduler = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling,Configuration::getInstance().AdaptiveOpenPagePolicy); + scheduler = new Fifo(*controllerCore); } - else if (selectedScheduler == "PAR_BS") + else if (selectedScheduler == "FIFO_STRICT") { - scheduler = new PAR_BS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, - Configuration::getInstance().Capsize); + scheduler = new FifoStrict(*this, *controllerCore); } - else if (selectedScheduler == "FIFO") + else if (selectedScheduler == "FR_FCFS") { - scheduler = new Fifo(*controllerCore); - } - else if (selectedScheduler == "Grouper") - { - scheduler = new ReadWriteGrouper(*controllerCore); + scheduler = new FR_FCFS(*controllerCore); } +// else if (selectedScheduler == "PAR_BS") +// { +// scheduler = new PAR_BS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, +// Configuration::getInstance().Capsize); +// } +// else if (selectedScheduler == "Grouper") +// { +// scheduler = new ReadWriteGrouper(*controllerCore); +// } else reportFatal(name(), "unsupported scheduler: " + selectedScheduler); } @@ -152,6 +151,7 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_pay switch (command.getCommand()) { + //TODO: refactor tlm recorder case Command::Read: dataStrobe = command.getIntervalOnDataStrobe(); TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); @@ -284,11 +284,22 @@ void Controller::controllerCorePEQCallback(tlm_generic_payload &payloa } else { - Bank bank = DramExtension::getExtension(payload).getBank(); + Bank bank = DramExtension::getBank(payload); sendToDram(payload, phase, SC_ZERO_TIME); if (phase == BEGIN_RD || phase == BEGIN_WR) - scheduleNextFromScheduler(); + { + if(Configuration::getInstance().Scheduler == "FIFO_STRICT") + { + // special case for the Fifo_strict scheduler, because it may have to unblock + // the current front element + dynamic_cast(scheduler)->NotifyBeginRD(); + } + else + { + scheduleNextFromScheduler(DramExtension::getBank(payload)); + } + } else if (phase == BEGIN_REFB) printDebugMessage("Entering REFB on bank " + to_string(bank.ID())); else if (phase == BEGIN_REFA) @@ -343,17 +354,13 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload, con payload.set_response_status(tlm::TLM_OK_RESPONSE); sendToFrontend(payload, END_REQ, SC_ZERO_TIME); - //FIFO HACK - if(Configuration::getInstance().Scheduler == "FIFO") - { - scheduleDirectly(&payload); - } - //Original - else - { - scheduler->schedule(&payload); - scheduleNextFromScheduler(); - } + scheduler->schedule(&payload); + + // Since we are triggering the scheduling of the next action on the bank + // because of an incoming transaction, we have to check if the bank + // is still busy. If it is, we let the end of the command which is currently in + // progress trigger the next scheduling + scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); } else if (phase == END_RESP) { @@ -363,15 +370,14 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload, con backpressure->set_response_status(tlm::TLM_OK_RESPONSE); sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME); - //FIFO HACK - if(Configuration::getInstance().Scheduler == "FIFO") + scheduler->schedule(backpressure); + // Since we are triggering the scheduling of the next action on the bank + // because of an incoming transaction, we have to check if the bank + // is still busy. If it is, we let the end of the command which is currently in + // progress trigger the next scheduling + if(!controllerCore->bankIsBusy(DramExtension::getBank(payload))) { - scheduleDirectly(backpressure); - } - else - { - scheduler->schedule(backpressure); - scheduleNextFromScheduler(); + scheduleNextFromScheduler(DramExtension::getExtension(backpressure).getBank()); } backpressure = NULL; } @@ -417,33 +423,19 @@ unsigned int Controller::getTotalNumberOfPayloadsInSystem() return sum; } - -//FIFO HACK! template -void Controller::scheduleDirectly(gp* payload) +void Controller::scheduleNextFromScheduler(Bank bank) { - if(!controllerCore->scheduleRequest(*payload)) + if(controllerCore->bankIsBusy(bank)) { - refreshCollisionRequets.push_back(payload); + return; } -} - -template -void Controller::scheduleNextFromScheduler() -{ - if(scheduler->hasPayloads()) + pair nextRequest = scheduler->getNextRequest(bank); + if(nextRequest.second != NULL) { - tlm_generic_payload* payload = scheduler->getNextPayload(); - if(payload != NULL) - { - controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), sc_time_stamp()); - bool wasScheduledByCore = controllerCore->scheduleRequest(*payload); - if (wasScheduledByCore) - { - scheduler->removePayload(payload); - printDebugMessage("\t-> Next payload was scheduled by core"); - } - } + 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"); } } @@ -469,44 +461,53 @@ void Controller::dramPEQCallback(tlm_generic_payload &payload, const t Bank bank = DramExtension::getExtension(payload).getBank(); printDebugMessage("Received " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()) + " from DRAM"); - if (phase == BEGIN_RD || phase == BEGIN_WR) - { - scheduleNextFromScheduler(); - sendToDram(payload, phase, SC_ZERO_TIME); - } - else if (phase == END_RD || phase == END_WR) + if (phase == END_RD || phase == END_WR) { sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); } else if (phase == END_RDA || phase == END_WRA) { sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); - scheduleNextFromScheduler(); + scheduleNextFromScheduler(bank); } - else if (phase == END_REFA || phase == END_REFB) + else if (phase == END_REFA) { - printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); + printDebugMessage("Finished auto refresh on all banks "); - if(numberOfPayloadsInSystem[bank] == 0) - controllerCore->powerDownManager->sleep(bank,sc_time_stamp()); - //FIFO HACK - if(Configuration::getInstance().Scheduler == "FIFO") + for(Bank bank : controllerCore->getBanks()) { - std::vector collidedReq = this->refreshCollisionRequets; - refreshCollisionRequets.clear(); - for(gp* payload : collidedReq) + if(numberOfPayloadsInSystem[bank] == 0) { - scheduleDirectly(payload); + controllerCore->powerDownManager->sleep(bank,sc_time_stamp()); + } + else + { + scheduleNextFromScheduler(bank); } } - else - { - scheduleNextFromScheduler(); - } } - else if (containsPhase(phase, { END_PRE, END_PRE_ALL, END_ACT })) + else if(phase == END_REFB) { + printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); + if(numberOfPayloadsInSystem[bank] == 0) + { + controllerCore->powerDownManager->sleep(bank,sc_time_stamp()); + } + else + { + scheduleNextFromScheduler(bank); + } + scheduleNextFromScheduler(bank); + } + else if (containsPhase(phase, { END_PRE, END_ACT })) + { + scheduleNextFromScheduler(bank); + } + else if(phase == END_PRE_ALL) + { + // No need to trigger anything for a END_PRE_ALL. It is followed by a AUTO_REFRESH anyway (in our current + // scheduler implementation) } else { diff --git a/dram/src/controller/core/ControllerState.cpp b/dram/src/controller/ControllerState.cpp similarity index 97% rename from dram/src/controller/core/ControllerState.cpp rename to dram/src/controller/ControllerState.cpp index 95816fd5..6c3b8ab5 100644 --- a/dram/src/controller/core/ControllerState.cpp +++ b/dram/src/controller/ControllerState.cpp @@ -7,9 +7,8 @@ #include "ControllerState.h" #include -#include "TimingCalculation.h" +#include "core/TimingCalculation.h" -namespace core { const ScheduledCommand ControllerState::getLastCommand(Command command, Bank bank) //TODO const reference? and make const { @@ -116,5 +115,3 @@ void ControllerState::cleanUp(sc_time time) if(time >= config->memSpec.tActHistory()) lastActivates.erase(lastActivates.begin(), lastActivates.lower_bound(time - config->memSpec.tActHistory())); } - -} /* namespace controller */ diff --git a/dram/src/controller/core/ControllerState.h b/dram/src/controller/ControllerState.h similarity index 89% rename from dram/src/controller/core/ControllerState.h rename to dram/src/controller/ControllerState.h index 83702d50..fe1162a1 100644 --- a/dram/src/controller/core/ControllerState.h +++ b/dram/src/controller/ControllerState.h @@ -10,15 +10,12 @@ #include #include "RowBufferStates.h" -#include "scheduling/ScheduledCommand.h" -#include "Slots.h" -#include "configuration/Configuration.h" +#include "core/Slots.h" +#include "core/configuration/Configuration.h" #include #include #include -namespace core { - class ControllerState { public: @@ -54,6 +51,5 @@ private: Configuration* config; }; -} /* namespace controller */ #endif /* CONTROLLER_STATE_H_ */ diff --git a/dram/src/controller/IController.h b/dram/src/controller/IController.h new file mode 100644 index 00000000..0358a4ad --- /dev/null +++ b/dram/src/controller/IController.h @@ -0,0 +1,23 @@ +#ifndef ICONTROLLER_H +#define ICONTROLLER_H + + +#include +#include "core/scheduling/ScheduledCommand.h" +#include "core/scheduling/Trigger.h" + + +// Utiliy class to pass around the Controller class to the controller Core and various schedulers, without having to propagate the template defintions +// throughout all classes +class IController +{ +public: + virtual ~IController() {} + virtual void send(const ScheduledCommand& command,tlm::tlm_generic_payload& payload) = 0; + virtual void send(Trigger trigger, sc_time time, tlm::tlm_generic_payload& payload) = 0; + virtual void scheduleNextFromScheduler(Bank bank) = 0; + +}; + + +#endif // ICONTROLLER_H diff --git a/dram/src/controller/core/RowBufferStates.cpp b/dram/src/controller/RowBufferStates.cpp similarity index 92% rename from dram/src/controller/core/RowBufferStates.cpp rename to dram/src/controller/RowBufferStates.cpp index d77186db..279e6eb5 100644 --- a/dram/src/controller/core/RowBufferStates.cpp +++ b/dram/src/controller/RowBufferStates.cpp @@ -6,15 +6,12 @@ */ #include "RowBufferStates.h" -#include "ControllerCore.h" -#include "../../common/DebugManager.h" -#include "../../common/Utils.h" +#include "core/ControllerCore.h" +#include "../common/DebugManager.h" +#include "../common/Utils.h" using namespace std; -namespace core -{ - RowBufferState::RowBufferState() { closeAllRowBuffers(); @@ -64,5 +61,4 @@ void RowBufferState::closeAllRowBuffers() } } -} diff --git a/dram/src/controller/core/RowBufferStates.h b/dram/src/controller/RowBufferStates.h similarity index 90% rename from dram/src/controller/core/RowBufferStates.h rename to dram/src/controller/RowBufferStates.h index f496ed97..3885ab42 100644 --- a/dram/src/controller/core/RowBufferStates.h +++ b/dram/src/controller/RowBufferStates.h @@ -8,10 +8,7 @@ #ifndef ROWBUFFERSTATES_H_ #define ROWBUFFERSTATES_H_ #include -#include "../../common/dramExtension.h" - -namespace core -{ +#include "../common/dramExtension.h" class RowBufferState { public: @@ -30,6 +27,4 @@ private: std::map rowsInRowBuffers; }; -} - #endif /* BANKSTATES_H_ */ diff --git a/dram/src/controller/core/Command.cpp b/dram/src/controller/core/Command.cpp deleted file mode 100644 index 53310152..00000000 --- a/dram/src/controller/core/Command.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "Command.h" -#include - -namespace core { - -std::string commandToString(Command command) -{ - switch (command) - { - case Command::Read: - return "RD"; - break; - case Command::ReadA: - return "RDA"; - break; - case Command::Write: - return "WR"; - break; - case Command::WriteA: - return "WRA"; - break; - case Command::Precharge: - return "PRE"; - break; - case Command::Activate: - return "ACT"; - break; - case Command::PrechargeAll: - return "PRE_ALL"; - break; - case Command::AutoRefresh: - return "AUTO_REFRESH"; - break; - - case Command::PDNA: - return "PDNA"; - break; - case Command::PDNAX: - return "PDNAX"; - break; - case Command::PDNP: - return "PDNP"; - break; - case Command::PDNPX: - return "PDNPX"; - break; - case Command::SREF: - return "SREF"; - break; - case Command::SREFX: - return "SREFX"; - break; - - default: - SC_REPORT_FATAL("command", "commandToString was called with unknown command"); - break; - } - - return ""; -} - -const std::vector& getAllCommands() -{ - static std::vector allCommands( { Command::Precharge, Command::PrechargeAll, - Command::Activate, Command::Read, Command::Write, Command::ReadA, Command::WriteA, - Command::AutoRefresh, Command::PDNA, Command::PDNAX, Command::PDNP, Command::PDNPX, - Command::SREF, Command::SREFX }); - return allCommands; -} -} - diff --git a/dram/src/controller/core/ControllerCore.cpp b/dram/src/controller/core/ControllerCore.cpp index df0e3067..9dc96e52 100644 --- a/dram/src/controller/core/ControllerCore.cpp +++ b/dram/src/controller/core/ControllerCore.cpp @@ -27,13 +27,12 @@ #include "../../common/DebugManager.h" -namespace core { std::string ControllerCore::senderName = "Controller Core"; -ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map& numberOfPayloads) : - config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), numberOfPayloads( - numberOfPayloads), commandChecker(), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(*this) +ControllerCore::ControllerCore(IController& wrapperConnector, std::map& numberOfPayloads) : + config(Configuration::getInstance()), state(&config), controller(wrapperConnector), numberOfPayloads( + numberOfPayloads), commandChecker() { commandChecker[Command::Activate] = new ActivateChecker(config, state); @@ -92,16 +91,6 @@ ControllerCore::~ControllerCore() delete powerDownManager; } -void ControllerCore::saveState() -{ - savedState = state; -} - -void ControllerCore::resetState() -{ - state = savedState; -} - void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload) { sc_time time = sc_time_stamp(); @@ -117,28 +106,28 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload) } } -bool ControllerCore::scheduleRequest(tlm::tlm_generic_payload& payload) +void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload &payload) { sc_time start = clkAlign(sc_time_stamp()); state.cleanUp(start); - saveState(); - - CommandSequence sequence = commandSequenceGenerator.generateCommandSequence(payload); - CommandSchedule schedule = commandSequenceScheduler.schedule(sequence, start, payload); - - if (refreshManager->hasCollision(schedule)) - { - resetState(); - return false; - } - else - { - send(schedule, payload); - return true; - } + ScheduledCommand scheduledCommand = schedule(command, start, payload); + state.change(scheduledCommand); + controller.send(scheduledCommand, payload); } +ScheduledCommand ControllerCore::schedule(Command command, sc_time start, + tlm::tlm_generic_payload& payload) +{ + ControllerCore::printDebugMessage("Scheduling command " + commandToString(command) + " on " + DramExtension::getBank(payload).toString()); + ICommandChecker& checker = getCommandChecker(command); + sc_time executionTime = getExecutionTime(command, payload); + ScheduledCommand scheduledCommand(command, start, executionTime, DramExtension::getExtension(payload)); + checker.delayToSatisfyConstraints(scheduledCommand); + return scheduledCommand; +} + + bool ControllerCore::bankIsBusy(Bank bank) { sc_time time = sc_time_stamp(); @@ -148,9 +137,10 @@ bool ControllerCore::bankIsBusy(Bank bank) return false; else if (lastScheduledCommand.commandIsIn( { Command::Write, Command::Read })) { + // Read and writes can overlap, so the bank should not be busy during a rd/wr return (time < lastScheduledCommand.getStart()); } - else if (lastScheduledCommand.commandIsIn( { Command::WriteA, Command::ReadA })) + else if (lastScheduledCommand.commandIsIn( { Command::WriteA, Command::ReadA, Command::Precharge, Command::PrechargeAll, Command::Activate })) { return (time < lastScheduledCommand.getEnd()); } @@ -165,7 +155,7 @@ bool ControllerCore::bankIsBusy(Bank bank) } else { - SC_REPORT_FATAL("Core", "Last command in command sequence was activate or precharge. This really doesn't make sense :D."); + SC_REPORT_FATAL("Core", "Last command unkown"); return false; } @@ -197,14 +187,6 @@ std::vector ControllerCore::getFreeBanks() return freeBanks; } -void ControllerCore::send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const -{ - for (const ScheduledCommand& cmd : schedule.getScheduledCommands()) - { - wrapper.send(cmd, payload); - } -} - ICommandChecker& ControllerCore::getCommandChecker(Command command) { return *getElementFromMap(commandChecker, command); @@ -215,5 +197,4 @@ void ControllerCore::printDebugMessage(string message) DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, message); } -} /* namespace controller */ diff --git a/dram/src/controller/core/ControllerCore.h b/dram/src/controller/core/ControllerCore.h index 7f4b7f52..75e8dd89 100644 --- a/dram/src/controller/core/ControllerCore.h +++ b/dram/src/controller/core/ControllerCore.h @@ -10,53 +10,46 @@ #include #include -#include "IWrapperConnector.h" +#include +#include "../IController.h" #include "configuration/Configuration.h" #include "powerdown/PowerDownManager.h" #include "refresh/IRefreshManager.h" -#include "scheduling/CommandSequenceGenerator.h" #include "scheduling/checker/ICommandChecker.h" -#include "scheduling/CommandSequenceScheduler.h" #include "../../common/TlmRecorder.h" +#include "../RowBufferStates.h" +#include "../ControllerState.h" -namespace core { class ControllerCore { public: - ControllerCore(IWrapperConnector& wrapper, std::map& numberOfPayloads); + ControllerCore(IController& controller, std::map& numberOfPayloads); virtual ~ControllerCore() ; - bool scheduleRequest(tlm::tlm_generic_payload& payload); + void scheduleRequest(Command command, tlm::tlm_generic_payload& payload); void triggerRefresh(tlm::tlm_generic_payload& payload); const std::vector& getBanks(); std::vector getFreeBanks(); const RowBufferState& getRowBufferStates(){return state.rowBufferStates;} + bool bankIsBusy(Bank bank); - ICommandChecker& getCommandChecker(Command command); - static void printDebugMessage(string message); + ICommandChecker& getCommandChecker(Command command); static void printDebugMessage(string message); Configuration config; ControllerState state; - IWrapperConnector& wrapper; + IController& controller; IPowerDownManager* powerDownManager; IRefreshManager* refreshManager; std::map& numberOfPayloads; static std::string senderName; private: - void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const; - bool bankIsBusy(Bank bank); - void saveState(); - void resetState(); + ScheduledCommand schedule(Command command, sc_time start, tlm::tlm_generic_payload &payload); std::map commandChecker; - ControllerState savedState; - CommandSequenceGenerator commandSequenceGenerator; - CommandSequenceScheduler commandSequenceScheduler; }; -} /* namespace controller */ #endif /* CONTROLLER_H_ */ diff --git a/dram/src/controller/core/IWrapperConnector.h b/dram/src/controller/core/IWrapperConnector.h deleted file mode 100644 index 65501ffa..00000000 --- a/dram/src/controller/core/IWrapperConnector.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * IInternalScheduler.h - * - * Created on: Mar 13, 2014 - * Author: jonny - */ - -#ifndef IINTERNALSCHEDULER_H_ -#define IINTERNALSCHEDULER_H_ - -#include -#include "scheduling/ScheduledCommand.h" -#include "scheduling/Trigger.h" - -namespace core -{ - -class IWrapperConnector -{ -public: - virtual ~IWrapperConnector() {} - virtual void send(const core::ScheduledCommand& command,tlm::tlm_generic_payload& payload) = 0; - virtual void send(Trigger trigger, sc_time time, tlm::tlm_generic_payload& payload) = 0; -}; - -} - -#endif /* IINTERNALSCHEDULER_H_ */ diff --git a/dram/src/controller/core/Slots.cpp b/dram/src/controller/core/Slots.cpp index 8e1cacc4..510f6454 100644 --- a/dram/src/controller/core/Slots.cpp +++ b/dram/src/controller/core/Slots.cpp @@ -8,7 +8,6 @@ #include "Slots.h" #include "TimingCalculation.h" -namespace core { Slots::Slots(sc_time clk) : clk(clk) @@ -60,4 +59,3 @@ void Slots::blockSlots(sc_time begin, sc_time end, bool excludeBorders) } -} /* namespace core */ diff --git a/dram/src/controller/core/Slots.h b/dram/src/controller/core/Slots.h index abd810da..cbd83999 100644 --- a/dram/src/controller/core/Slots.h +++ b/dram/src/controller/core/Slots.h @@ -11,7 +11,6 @@ #include #include "scheduling/ScheduledCommand.h" -namespace core { class Slots { @@ -30,6 +29,5 @@ private: }; -} /* namespace core */ #endif /* SLOTS_H_ */ diff --git a/dram/src/controller/core/TimingCalculation.cpp b/dram/src/controller/core/TimingCalculation.cpp index f1c25060..3e616c8d 100644 --- a/dram/src/controller/core/TimingCalculation.cpp +++ b/dram/src/controller/core/TimingCalculation.cpp @@ -12,7 +12,6 @@ #include "configuration/Configuration.h" #include "../../common/Utils.h" -namespace core { sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint) @@ -129,5 +128,4 @@ sc_time getWriteAccessTime() } } -} diff --git a/dram/src/controller/core/TimingCalculation.h b/dram/src/controller/core/TimingCalculation.h index 9b513f69..9539da78 100644 --- a/dram/src/controller/core/TimingCalculation.h +++ b/dram/src/controller/core/TimingCalculation.h @@ -11,10 +11,8 @@ #include #include #include "../../common/dramExtension.h" -#include "Command.h" +#include "../Command.h" -namespace core -{ sc_time getMinExecutionTimeForPowerDownCmd(Command command); sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload); @@ -28,6 +26,4 @@ const sc_time clkAlign(sc_time time, Alignment alignment = UP); bool isClkAligned(sc_time time, sc_time clk); const sc_time FrequencyToClk(double frequencyMhz); - -} #endif /* UTILS_H_ */ diff --git a/dram/src/controller/core/configuration/Configuration.cpp b/dram/src/controller/core/configuration/Configuration.cpp index bc85232d..5d46c639 100644 --- a/dram/src/controller/core/configuration/Configuration.cpp +++ b/dram/src/controller/core/configuration/Configuration.cpp @@ -11,8 +11,6 @@ using namespace std; -namespace core{ - string Configuration::memspecUri = ""; string Configuration::memconfigUri = ""; @@ -66,10 +64,6 @@ void Configuration::setParameter(std::string name, std::string value) BankwiseLogic = string2bool(value); else if(name == "OpenPagePolicy") OpenPagePolicy = string2bool(value); - else if(name == "AdaptiveOpenPagePolicy") - AdaptiveOpenPagePolicy = string2bool(value); - else if(name == "RefreshAwareScheduling") - RefreshAwareScheduling = string2bool(value); else if(name == "MaxNrOfTransactions") MaxNrOfTransactions = string2int(value); else if(name == "Scheduler") @@ -113,5 +107,4 @@ void Configuration::setParameters(std::map parameterMa } } -} /* namespace core */ diff --git a/dram/src/controller/core/configuration/Configuration.h b/dram/src/controller/core/configuration/Configuration.h index 90b1d3d1..5383dbdb 100644 --- a/dram/src/controller/core/configuration/Configuration.h +++ b/dram/src/controller/core/configuration/Configuration.h @@ -12,8 +12,6 @@ #include #include "MemSpec.h" -namespace core{ - enum class EPowerDownMode{NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF}; @@ -31,8 +29,6 @@ struct Configuration //MemConfig bool BankwiseLogic = false; bool OpenPagePolicy = true; - bool AdaptiveOpenPagePolicy = false; - bool RefreshAwareScheduling = false; unsigned int MaxNrOfTransactions = 50; std::string Scheduler; unsigned int Capsize = 5; @@ -60,7 +56,5 @@ private: unsigned int powerDownTimeoutInClk = 3; }; -} /* namespace core */ - #endif /* CONFIGURATION_H_ */ diff --git a/dram/src/controller/core/configuration/ConfigurationLoader.cpp b/dram/src/controller/core/configuration/ConfigurationLoader.cpp index d8bf7caa..aaa4e4aa 100644 --- a/dram/src/controller/core/configuration/ConfigurationLoader.cpp +++ b/dram/src/controller/core/configuration/ConfigurationLoader.cpp @@ -12,8 +12,6 @@ using namespace tinyxml2; using namespace std; -namespace core { - void ConfigurationLoader::loadSimConfig(Configuration& config, string simconfigUri) { tinyxml2::XMLDocument doc; @@ -23,28 +21,6 @@ void ConfigurationLoader::loadSimConfig(Configuration& config, string simconfigU loadConfig(config, simconfig); } - -void ConfigurationLoader::loadMemConfig(Configuration& config, string memconfigUri) -{ - tinyxml2::XMLDocument doc; - - loadXML(memconfigUri, doc); - XMLElement* memconfig = doc.FirstChildElement("memconfig"); - loadConfig(config, memconfig); -} - -void ConfigurationLoader::loadMemConfig(Configuration& config, XMLElement* memconfig) -{ - if(memconfig->Attribute("src")) - { - XMLDocument doc; - string src(memconfig->Attribute("src")); - loadXML(src, doc); - loadMemConfig(config, doc.FirstChildElement("memconfig")); - } - loadConfig(config, memconfig); -} - void ConfigurationLoader::loadSimConfig(Configuration& config, XMLElement* simconfig) { if(simconfig->Attribute("src")) @@ -103,6 +79,28 @@ void ConfigurationLoader::loadMemSpec(Configuration& config, XMLElement* memspec } } +void ConfigurationLoader::loadMemConfig(Configuration& config, string memconfigUri) +{ + tinyxml2::XMLDocument doc; + + loadXML(memconfigUri, doc); + XMLElement* memconfig = doc.FirstChildElement("memconfig"); + loadConfig(config, memconfig); +} + +void ConfigurationLoader::loadMemConfig(Configuration& config, XMLElement* memconfig) +{ + if(memconfig->Attribute("src")) + { + XMLDocument doc; + string src(memconfig->Attribute("src")); + config.memconfigUri = src; + loadXML(src, doc); + loadMemConfig(config, doc.FirstChildElement("memconfig")); + } + loadConfig(config, memconfig); +} + void ConfigurationLoader::loadDDR4(Configuration& config, XMLElement* memspec) { //MemArchitecture @@ -207,4 +205,3 @@ void ConfigurationLoader::loadWideIO(Configuration& config, XMLElement* memspec) } -} /* namespace core */ diff --git a/dram/src/controller/core/configuration/ConfigurationLoader.h b/dram/src/controller/core/configuration/ConfigurationLoader.h index f0089633..258e6763 100644 --- a/dram/src/controller/core/configuration/ConfigurationLoader.h +++ b/dram/src/controller/core/configuration/ConfigurationLoader.h @@ -13,8 +13,6 @@ #include "../../../common/Utils.h" #include "Configuration.h" -namespace core { - class ConfigurationLoader { public: @@ -35,6 +33,5 @@ private: static void loadWideIO(Configuration& config, tinyxml2::XMLElement* memspec); }; -} /* namespace core */ #endif /* CONFIGURATIONLOADER_H_ */ diff --git a/dram/src/controller/core/configuration/MemSpec.h b/dram/src/controller/core/configuration/MemSpec.h index 80890d9c..ddbfc9b6 100644 --- a/dram/src/controller/core/configuration/MemSpec.h +++ b/dram/src/controller/core/configuration/MemSpec.h @@ -12,7 +12,6 @@ #include #include "../../../common/dramExtension.h" -namespace core{ struct RefreshTiming { @@ -89,7 +88,6 @@ struct MemSpec sc_time tDataStrobeHistory(){return tWTR_L;} }; -} /* namespace core */ #endif /* MemSpec_H_ */ diff --git a/dram/src/controller/core/powerdown/IPowerDownManager.h b/dram/src/controller/core/powerdown/IPowerDownManager.h index d6e48c89..5f315eaf 100644 --- a/dram/src/controller/core/powerdown/IPowerDownManager.h +++ b/dram/src/controller/core/powerdown/IPowerDownManager.h @@ -10,11 +10,9 @@ #include #include "../../../common/dramExtension.h" -#include "../Command.h" +#include "../../Command.h" -namespace core { - enum class PowerDownState { Awake, AwakeForRefresh, PDNActive, PDNPrecharge, PDNSelfRefresh @@ -99,6 +97,5 @@ inline std::string powerDownStateToString(PowerDownState powerDownState) } } -} /* namespace core */ #endif /* IPOWERDOWNMANAGER_H_ */ diff --git a/dram/src/controller/core/powerdown/NoPowerDown.cpp b/dram/src/controller/core/powerdown/NoPowerDown.cpp index 17599ca1..046a99b8 100644 --- a/dram/src/controller/core/powerdown/NoPowerDown.cpp +++ b/dram/src/controller/core/powerdown/NoPowerDown.cpp @@ -1,26 +1,26 @@ #include "NoPowerDown.h" -void core::NoPowerDown::triggerSleep(Bank /*bank*/, sc_time /*time*/) +void NoPowerDown::triggerSleep(Bank /*bank*/, sc_time /*time*/) { return; } -void core::NoPowerDown::sleep(Bank /*bank*/, sc_time /*time*/) +void NoPowerDown::sleep(Bank /*bank*/, sc_time /*time*/) { return; } -void core::NoPowerDown::wakeUp(Bank /*bank*/, sc_time /*time*/) +void NoPowerDown::wakeUp(Bank /*bank*/, sc_time /*time*/) { return; } -void core::NoPowerDown::wakeUpForRefresh(Bank /*bank*/, sc_time /*time*/) +void NoPowerDown::wakeUpForRefresh(Bank /*bank*/, sc_time /*time*/) { return; } -bool core::NoPowerDown::isInSelfRefresh(Bank /*bank*/) +bool NoPowerDown::isInSelfRefresh(Bank /*bank*/) { return false; } diff --git a/dram/src/controller/core/powerdown/NoPowerDown.h b/dram/src/controller/core/powerdown/NoPowerDown.h index 6cf52e25..a4e36426 100644 --- a/dram/src/controller/core/powerdown/NoPowerDown.h +++ b/dram/src/controller/core/powerdown/NoPowerDown.h @@ -15,7 +15,6 @@ #include "../scheduling/ScheduledCommand.h" -namespace core { class NoPowerDown: public IPowerDownManager { @@ -32,6 +31,6 @@ public: virtual bool isInSelfRefresh(Bank bank) override; }; -} + #endif // NOPOWERDOWN_H diff --git a/dram/src/controller/core/powerdown/PowerDownManager.cpp b/dram/src/controller/core/powerdown/PowerDownManager.cpp index 978c72cf..32d40113 100644 --- a/dram/src/controller/core/powerdown/PowerDownManager.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManager.cpp @@ -17,10 +17,9 @@ using namespace tlm; using namespace std; -namespace core { PowerDownManager::PowerDownManager(ControllerCore& controller) : - controller(controller) + controllerCore(controller) { powerDownState = PowerDownState::Awake; for (Bank bank : controller.getBanks()) @@ -43,14 +42,14 @@ void PowerDownManager::sleep(Bank bank, sc_time time) if (state == PowerDownState::Awake) //coming from active { - state = controller.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; + state = controllerCore.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; } else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down { - sc_assert(controller.state.rowBufferStates.allRowBuffersAreClosed()); + sc_assert(controllerCore.state.rowBufferStates.allRowBuffersAreClosed()); - if (controller.state.getLastCommand(Command::PDNA).getStart() - >= controller.state.getLastCommand(Command::PDNP).getStart()) + if (controllerCore.state.getLastCommand(Command::PDNA).getStart() + >= controllerCore.state.getLastCommand(Command::PDNP).getStart()) state = PowerDownState::PDNPrecharge; else { @@ -62,9 +61,9 @@ void PowerDownManager::sleep(Bank bank, sc_time time) ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd), DramExtension::getExtension(powerDownPayloads[bank])); - controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); - if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn)) + if (state != PowerDownState::PDNSelfRefresh && controllerCore.refreshManager->hasCollision(pdn)) { return; } @@ -86,10 +85,10 @@ void PowerDownManager::wakeUp(Bank bank, sc_time time) Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); - controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); if (cmd == Command::SREFX) - controller.refreshManager->reInitialize(bank, pdn.getEnd()); + controllerCore.refreshManager->reInitialize(bank, pdn.getEnd()); setPowerDownState(PowerDownState::Awake); sendPowerDownPayloads(pdn); @@ -111,14 +110,15 @@ void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time) void PowerDownManager::sendPowerDownPayloads(ScheduledCommand& cmd) { - controller.state.bus.moveCommandToNextFreeSlot(cmd); - for (Bank bank : controller.getBanks()) + controllerCore.state.bus.moveCommandToNextFreeSlot(cmd); + for (Bank bank : controllerCore.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); + controllerCore.state.change(pdnToSend); + controllerCore.controller.send(pdnToSend, payloadToSend); } } @@ -137,9 +137,9 @@ bool PowerDownManager::isInPowerDown() bool PowerDownManager::canSleep() { - for (Bank bank : controller.getBanks()) + for (Bank bank : controllerCore.getBanks()) { - if (!controller.numberOfPayloads[bank] == 0) + if (!controllerCore.numberOfPayloads[bank] == 0) return false; } return true; @@ -160,6 +160,5 @@ void PowerDownManager::triggerSleep(Bank bank, sc_time time) sleep(bank, time); } -} /* namespace core */ diff --git a/dram/src/controller/core/powerdown/PowerDownManager.h b/dram/src/controller/core/powerdown/PowerDownManager.h index 2b1dad8f..3ddd20ff 100644 --- a/dram/src/controller/core/powerdown/PowerDownManager.h +++ b/dram/src/controller/core/powerdown/PowerDownManager.h @@ -10,14 +10,13 @@ #include "PowerDownManagerBankwise.h" -namespace core { class ControllerCore; class PowerDownManager: public IPowerDownManager { public: - PowerDownManager(ControllerCore& controller); + PowerDownManager(ControllerCore& controllerCore); virtual ~PowerDownManager(); virtual void triggerSleep(Bank bank, sc_time time) override; @@ -35,9 +34,8 @@ private: PowerDownState powerDownState; std::map powerDownPayloads; - ControllerCore& controller; + ControllerCore& controllerCore; }; -} /* namespace core */ #endif /* POWERDOWNMANAGER_H_ */ diff --git a/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp b/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp index 92c6aa0c..f445da86 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp @@ -12,12 +12,11 @@ using namespace tlm; -namespace core { std::string PowerDownManagerBankwise::senderName = "pdn manager"; PowerDownManagerBankwise::PowerDownManagerBankwise(ControllerCore& controller) : - controller(controller) + controllerCore(controller) { for (Bank bank : controller.getBanks()) { @@ -36,14 +35,14 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) PowerDownState state = powerDownStates[bank]; if (state == PowerDownState::Awake) //coming from active { - state = controller.state.rowBufferStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; + state = controllerCore.state.rowBufferStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; } else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down { - sc_assert(!controller.state.rowBufferStates.rowBufferIsOpen(bank)); + sc_assert(!controllerCore.state.rowBufferStates.rowBufferIsOpen(bank)); - if (controller.state.getLastCommand(Command::PDNA, bank).getStart() - >= controller.state.getLastCommand(Command::PDNP, bank).getStart()) + if (controllerCore.state.getLastCommand(Command::PDNA, bank).getStart() + >= controllerCore.state.getLastCommand(Command::PDNP, bank).getStart()) state = PowerDownState::PDNPrecharge; else { @@ -53,9 +52,9 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) Command cmd = IPowerDownManager::getSleepCommand(state); ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd), DramExtension::getExtension(payload)); - controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); - if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn)) + if (state != PowerDownState::PDNSelfRefresh && controllerCore.refreshManager->hasCollision(pdn)) { return; } @@ -78,10 +77,10 @@ void PowerDownManagerBankwise::wakeUp(Bank bank, sc_time time) Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); - controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); if (cmd == Command::SREFX) - controller.refreshManager->reInitialize(bank, pdn.getEnd()); + controllerCore.refreshManager->reInitialize(bank, pdn.getEnd()); setState(PowerDownState::Awake, bank); sendPowerDownPayload(pdn); @@ -133,14 +132,14 @@ void PowerDownManagerBankwise::setState(PowerDownState state, Bank bank) void PowerDownManagerBankwise::sendPowerDownPayload(ScheduledCommand& pdn) { - controller.state.bus.moveCommandToNextFreeSlot(pdn); - controller.state.change(pdn); - controller.wrapper.send(pdn, powerDownPayloads[pdn.getBank()]); + controllerCore.state.bus.moveCommandToNextFreeSlot(pdn); + controllerCore.state.change(pdn); + controllerCore.controller.send(pdn, powerDownPayloads[pdn.getBank()]); } bool PowerDownManagerBankwise::canSleep(Bank bank) { - return controller.numberOfPayloads[bank] == 0; + return controllerCore.numberOfPayloads[bank] == 0; } void PowerDownManagerBankwise::triggerSleep(Bank bank, sc_time time) @@ -148,6 +147,5 @@ void PowerDownManagerBankwise::triggerSleep(Bank bank, sc_time time) sleep(bank, time); } -}/* namespace core */ diff --git a/dram/src/controller/core/powerdown/PowerDownManagerBankwise.h b/dram/src/controller/core/powerdown/PowerDownManagerBankwise.h index 60204f15..984a3cd5 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerBankwise.h +++ b/dram/src/controller/core/powerdown/PowerDownManagerBankwise.h @@ -12,19 +12,18 @@ #include #include #include -#include "../Command.h" +#include "../../Command.h" #include "../../../common/dramExtension.h" #include "../scheduling/ScheduledCommand.h" #include "IPowerDownManager.h" -namespace core { class ControllerCore; class PowerDownManagerBankwise: public IPowerDownManager { public: - PowerDownManagerBankwise(ControllerCore& controller); + PowerDownManagerBankwise(ControllerCore& controllerCore); virtual ~PowerDownManagerBankwise() { } @@ -41,7 +40,7 @@ private: virtual bool isAwake(Bank bank); virtual bool isAwakeForRefresh(Bank bank); - ControllerCore& controller; + ControllerCore& controllerCore; std::map powerDownPayloads; std::map powerDownStates; @@ -55,6 +54,5 @@ private: void sendPowerDownPayload(ScheduledCommand& pdn); }; -}/* namespace core */ #endif /* POWERDOWNMANAGERBANKWISE_H_ */ diff --git a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp index 61ebf3f0..76b2c27d 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp @@ -12,9 +12,8 @@ using namespace tlm; -namespace core { -PowerDownManagerTimeout::PowerDownManagerTimeout(ControllerCore& controller): controller(controller) +PowerDownManagerTimeout::PowerDownManagerTimeout(ControllerCore& controller): controllerCore(controller) { for (Bank bank : controller.getBanks()) { @@ -29,12 +28,12 @@ PowerDownManagerTimeout::~PowerDownManagerTimeout() void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) { - if(canSleep() && !isInPowerDown() && (time - controller.state.getLastScheduledCommand().getEnd()) >= Configuration::getInstance().getPowerDownTimeout()) + if(canSleep() && !isInPowerDown() && (time - controllerCore.state.getLastScheduledCommand().getEnd()) >= Configuration::getInstance().getPowerDownTimeout()) { PowerDownState newState; if(Configuration::getInstance().PowerDownMode == EPowerDownMode::TimeoutPDN) { - newState = controller.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; + newState = controllerCore.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; } else { @@ -45,9 +44,9 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd), DramExtension::getExtension(powerDownPayloads[bank])); - controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); - if (controller.refreshManager->hasCollision(pdn)) + if (controllerCore.refreshManager->hasCollision(pdn)) { return; } @@ -79,10 +78,10 @@ void PowerDownManagerTimeout::wakeUp(Bank bank, sc_time time) Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); - controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); if (cmd == Command::SREFX) - controller.refreshManager->reInitialize(bank, pdn.getEnd()); + controllerCore.refreshManager->reInitialize(bank, pdn.getEnd()); setPowerDownState(PowerDownState::Awake); sendPowerDownPayloads(pdn); @@ -106,7 +105,7 @@ void PowerDownManagerTimeout::triggerSleep(Bank /*bank*/, sc_time time) { if(canSleep() && !isInPowerDown()) { - controller.wrapper.send(PDNTrigger, time + controller.config.getPowerDownTimeout(), powerDownPayloads[Bank(0)]); + controllerCore.controller.send(PDNTrigger, time + controllerCore.config.getPowerDownTimeout(), powerDownPayloads[Bank(0)]); } } @@ -117,9 +116,9 @@ bool PowerDownManagerTimeout::isInSelfRefresh(Bank /*bank*/) bool PowerDownManagerTimeout::canSleep() { - for (Bank bank : controller.getBanks()) + for (Bank bank : controllerCore.getBanks()) { - if (!controller.numberOfPayloads[bank] == 0) + if (!controllerCore.numberOfPayloads[bank] == 0) return false; } return true; @@ -127,15 +126,14 @@ bool PowerDownManagerTimeout::canSleep() void PowerDownManagerTimeout::sendPowerDownPayloads(ScheduledCommand& cmd) { - controller.state.bus.moveCommandToNextFreeSlot(cmd); - for (Bank bank : controller.getBanks()) + controllerCore.state.bus.moveCommandToNextFreeSlot(cmd); + for (Bank bank : controllerCore.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); + controllerCore.state.change(pdnToSend); + controllerCore.controller.send(pdnToSend, payloadToSend); } } -} diff --git a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.h b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.h index fc2539a0..c6e41c69 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.h +++ b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.h @@ -14,13 +14,12 @@ #include "../scheduling/ScheduledCommand.h" #include -namespace core { class ControllerCore; -class PowerDownManagerTimeout: public core::IPowerDownManager +class PowerDownManagerTimeout: public IPowerDownManager { public: - PowerDownManagerTimeout(ControllerCore& controller); + PowerDownManagerTimeout(ControllerCore& controllerCore); virtual ~PowerDownManagerTimeout(); virtual void triggerSleep(Bank bank, sc_time time); @@ -32,7 +31,7 @@ public: virtual bool isInSelfRefresh(Bank bank); private: bool canSleep(); - ControllerCore& controller; + ControllerCore& controllerCore; std::map powerDownPayloads; void sendPowerDownPayloads(ScheduledCommand& cmd); @@ -42,6 +41,6 @@ private: bool isInPowerDown(); }; -} + #endif /* POWERDOWNMANAGERTIMEOUT_H_ */ diff --git a/dram/src/controller/core/refresh/IRefreshManager.h b/dram/src/controller/core/refresh/IRefreshManager.h index b924f566..fcf34a12 100644 --- a/dram/src/controller/core/refresh/IRefreshManager.h +++ b/dram/src/controller/core/refresh/IRefreshManager.h @@ -2,15 +2,13 @@ #define IREFRESHMANAGER_H_ #include -#include "../scheduling/CommandSchedule.h" +#include "../scheduling/ScheduledCommand.h" -namespace core { class IRefreshManager { public: virtual ~IRefreshManager(){}; - virtual bool hasCollision(const CommandSchedule& schedule) = 0; virtual bool hasCollision(const ScheduledCommand& command) = 0; virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) = 0; virtual void reInitialize(Bank bank, sc_time time) = 0; @@ -19,6 +17,5 @@ public: virtual bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) = 0; }; -} // namespace core #endif diff --git a/dram/src/controller/core/refresh/RefreshManager.cpp b/dram/src/controller/core/refresh/RefreshManager.cpp index af4c1b91..98ddfb2e 100644 --- a/dram/src/controller/core/refresh/RefreshManager.cpp +++ b/dram/src/controller/core/refresh/RefreshManager.cpp @@ -12,12 +12,14 @@ #include "../TimingCalculation.h" using namespace tlm; -namespace core { RefreshManager::RefreshManager(ControllerCore& controller) : - controller(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME) + controllerCore(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME) { - setupTransactions(); + for (Bank bank : controller.getBanks()) + { + setUpDummy(refreshPayloads[bank], bank); + } planNextRefresh(); } @@ -25,58 +27,48 @@ RefreshManager::~RefreshManager() { } -bool RefreshManager::hasCollision(const CommandSchedule& schedule) -{ - return schedule.getStart() < controller.state.getLastCommand(Command::AutoRefresh).getEnd() || schedule.getEnd() > nextPlannedRefresh; -} - bool RefreshManager::hasCollision(const ScheduledCommand& command) { - - return command.getStart() < controller.state.getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh; + return command.getStart() < controllerCore.state.getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh; } void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) { sc_assert(!isInvalidated(payload, time)); - if (!controller.state.rowBufferStates.allRowBuffersAreClosed()) + if (!controllerCore.state.rowBufferStates.allRowBuffersAreClosed()) { - ScheduledCommand precharge(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]), - DramExtension::getExtension(refreshPayloads[Bank(0)])); - controller.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(precharge); - sendToAllBanks(precharge); + ScheduledCommand prechargeAllMaster(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]), + refreshPayloads[Bank(0)]); + controllerCore.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(prechargeAllMaster); + + for (Bank bank : controllerCore.getBanks()) + { + ScheduledCommand prechargeAll(Command::PrechargeAll, prechargeAllMaster.getStart(), prechargeAllMaster.getExecutionTime(), + refreshPayloads[bank]); + controllerCore.state.change(prechargeAll); + controllerCore.controller.send(prechargeAll, refreshPayloads[bank]); + } } - ScheduledCommand nextRefresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayloads[Bank(0)]), - DramExtension::getExtension(refreshPayloads[Bank(0)])); - controller.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(nextRefresh); - sendToAllBanks(nextRefresh); - - for (Bank bank : controller.getBanks()) + for (Bank bank : controllerCore.getBanks()) { + ScheduledCommand refresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayloads[bank]), + DramExtension::getExtension(refreshPayloads[bank])); + controllerCore.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(refresh); + controllerCore.state.change(refresh); + controllerCore.controller.send(refresh, refreshPayloads[bank]); + DramExtension::getExtension(refreshPayloads[bank]).incrementRow(); } planNextRefresh(); } -void RefreshManager::sendToAllBanks(ScheduledCommand& command) -{ - for (Bank bank : controller.getBanks()) - { - tlm_generic_payload& payload = refreshPayloads[bank]; - DramExtension extension = DramExtension::getExtension(payload); - ScheduledCommand cmd(command.getCommand(), command.getStart(), command.getExecutionTime(), extension); - controller.state.change(cmd); - controller.wrapper.send(cmd, payload); - } -} - void RefreshManager::planNextRefresh() { nextPlannedRefresh += timing.tREFI; - controller.wrapper.send(REFTrigger, nextPlannedRefresh, refreshPayloads[Bank(0)]); + controllerCore.controller.send(REFTrigger, nextPlannedRefresh, refreshPayloads[Bank(0)]); } void RefreshManager::reInitialize(Bank /*bank*/, sc_time time) @@ -85,17 +77,8 @@ void RefreshManager::reInitialize(Bank /*bank*/, sc_time time) planNextRefresh(); } -bool core::RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) +bool RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) { return nextPlannedRefresh > time; } -void RefreshManager::setupTransactions() -{ - for (Bank bank : controller.getBanks()) - { - setUpDummy(refreshPayloads[bank], bank); - } -} - -} /* namespace core */ diff --git a/dram/src/controller/core/refresh/RefreshManager.h b/dram/src/controller/core/refresh/RefreshManager.h index 6d1d325a..ced0fa9a 100644 --- a/dram/src/controller/core/refresh/RefreshManager.h +++ b/dram/src/controller/core/refresh/RefreshManager.h @@ -11,35 +11,28 @@ #include "IRefreshManager.h" #include "../configuration/MemSpec.h" -namespace core { class ControllerCore; class RefreshManager : public IRefreshManager { public: - RefreshManager(ControllerCore& controller); + RefreshManager(ControllerCore& controllerCore); virtual ~RefreshManager(); - virtual bool hasCollision(const CommandSchedule& schedule) override; virtual bool hasCollision(const ScheduledCommand& command) override; - virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override; void reInitialize(Bank bank, sc_time time) override; virtual bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) override; private: - ControllerCore& controller; + ControllerCore& controllerCore; RefreshTiming& timing; sc_time nextPlannedRefresh; std::map refreshPayloads; void planNextRefresh(); - - void sendToAllBanks(ScheduledCommand& command); - void setupTransactions(); }; -} /* namespace core */ #endif /* REFRESHMANAGER_H_ */ diff --git a/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp b/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp index 590d39af..3a643adf 100644 --- a/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -12,10 +12,9 @@ using namespace std; -namespace core { RefreshManagerBankwise::RefreshManagerBankwise(ControllerCore& controller) : - controller(controller) + controllerCore(controller) { for (Bank bank : controller.getBanks()) { @@ -28,15 +27,9 @@ RefreshManagerBankwise::~RefreshManagerBankwise() { } -bool RefreshManagerBankwise::hasCollision(const CommandSchedule& schedule) -{ - return schedule.getStart() < controller.state.getLastCommand(Command::AutoRefresh, schedule.getBank()).getEnd() - || schedule.getEnd() > nextPlannedRefreshs[schedule.getBank()]; -} - bool RefreshManagerBankwise::hasCollision(const ScheduledCommand& command) { - return command.getStart() < controller.state.getLastCommand(Command::AutoRefresh, command.getBank()).getEnd() + return command.getStart() < controllerCore.state.getLastCommand(Command::AutoRefresh, command.getBank()).getEnd() || command.getEnd() > nextPlannedRefreshs[command.getBank()];} void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) @@ -47,19 +40,19 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, DramExtension& extension = DramExtension::getExtension(refreshPayload); - if (controller.state.rowBufferStates.rowBufferIsOpen(extension.getBank())) + if (controllerCore.state.rowBufferStates.rowBufferIsOpen(extension.getBank())) { ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, refreshPayload), extension); - controller.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge); - controller.state.change(precharge); - controller.wrapper.send(precharge, refreshPayload); + controllerCore.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge); + controllerCore.state.change(precharge); + controllerCore.controller.send(precharge, refreshPayload); } - ScheduledCommand nextRefresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayload), extension); - controller.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(nextRefresh); - controller.state.change(nextRefresh); - controller.wrapper.send(nextRefresh, refreshPayload); + ScheduledCommand refresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayload), extension); + controllerCore.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(refresh); + controllerCore.state.change(refresh); + controllerCore.controller.send(refresh, refreshPayload); extension.incrementRow(); planNextRefresh(extension.getBank()); @@ -68,7 +61,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, void RefreshManagerBankwise::planNextRefresh(Bank bank) { nextPlannedRefreshs[bank] += Configuration::getInstance().memSpec.refreshTimings[bank].tREFI; - controller.wrapper.send(REFTrigger, nextPlannedRefreshs[bank], refreshPayloads[bank]); + controllerCore.controller.send(REFTrigger, nextPlannedRefreshs[bank], refreshPayloads[bank]); } void RefreshManagerBankwise::reInitialize(Bank bank, sc_time time) @@ -82,5 +75,4 @@ bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload& payload, sc return nextPlannedRefreshs[DramExtension::getExtension(payload).getBank()] > time; } -} /* namespace core */ diff --git a/dram/src/controller/core/refresh/RefreshManagerBankwise.h b/dram/src/controller/core/refresh/RefreshManagerBankwise.h index b52a3d02..7e1f2337 100644 --- a/dram/src/controller/core/refresh/RefreshManagerBankwise.h +++ b/dram/src/controller/core/refresh/RefreshManagerBankwise.h @@ -8,23 +8,20 @@ #ifndef BANKWISEREFRESHMANAGER_H_ #define BANKWISEREFRESHMANAGER_H_ -#include "../scheduling/CommandSchedule.h" #include "../../../common/dramExtension.h" #include "../configuration/MemSpec.h" #include "IRefreshManager.h" -namespace core { class ControllerCore; class RefreshManagerBankwise : public IRefreshManager { public: - RefreshManagerBankwise(ControllerCore& controller); + RefreshManagerBankwise(ControllerCore& controllerCore); virtual ~RefreshManagerBankwise(); - virtual bool hasCollision(const CommandSchedule& schedule) override; - virtual bool hasCollision(const ScheduledCommand& command) override; + virtual bool hasCollision(const ScheduledCommand& command) override; virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override; void reInitialize(Bank bank, sc_time time) override; @@ -33,7 +30,7 @@ public: private: - ControllerCore& controller; + ControllerCore& controllerCore; std::map refreshPayloads; std::map nextPlannedRefreshs; @@ -41,6 +38,5 @@ private: void planNextRefresh(Bank bank); }; -} /* namespace controller */ #endif /* BANKWISEREFRESHMANAGER_H_ */ diff --git a/dram/src/controller/core/scheduling/CommandSchedule.h b/dram/src/controller/core/scheduling/CommandSchedule.h deleted file mode 100644 index f3cedf85..00000000 --- a/dram/src/controller/core/scheduling/CommandSchedule.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * CommandSchedule.h - * - * Created on: Mar 5, 2014 - * Author: jonny - */ - -#ifndef COMMANDSCHEDULE_H_ -#define COMMANDSCHEDULE_H_ - -#include -#include "../../../common/dramExtension.h" -#include "../../../common/TlmRecorder.h" -#include "ScheduledCommand.h" -namespace core { - -class CommandSchedule -{ -public: - CommandSchedule(tlm::tlm_generic_payload& transaction) : - extension(DramExtension::getExtension(&transaction)) - { - } - - virtual ~CommandSchedule() - { - } - - ScheduledCommand& add(Command command, sc_time start, sc_time executionTime) - { - scheduledCommands.push_back(ScheduledCommand(command, start, executionTime, extension)); - return scheduledCommands.back(); - } - - const std::vector& getScheduledCommands() const - { - return scheduledCommands; - } - - sc_time getStart() const - { - return scheduledCommands.front().getStart(); - } - - sc_time getEnd() const - { - return scheduledCommands.back().getEnd(); - } - - sc_time getExecutionTime() const - { - return scheduledCommands.back().getEnd() - scheduledCommands.front().getStart(); - } - - Bank getBank() const - { - return extension.getBank(); - } - -private: - std::vector scheduledCommands; - DramExtension extension; -}; - -} /* namespace controller */ - -#endif /* COMMANDSCHEDULE_H_ */ diff --git a/dram/src/controller/core/scheduling/CommandSequenceGenerator.cpp b/dram/src/controller/core/scheduling/CommandSequenceGenerator.cpp deleted file mode 100644 index b4800f7d..00000000 --- a/dram/src/controller/core/scheduling/CommandSequenceGenerator.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * CommandSequenceGenerator.cpp - * - * Created on: Mar 5, 2014 - * Author: jonny - */ - -#include "CommandSequenceGenerator.h" -#include "../../../common/dramExtension.h" -#include "../configuration/Configuration.h" - -using namespace std; - -namespace core { - -CommandSequence CommandSequenceGenerator::generateCommandSequence(tlm::tlm_generic_payload& transaction) -{ - const DramExtension& extension = DramExtension::getExtension(&transaction); - Bank bank = extension.getBank(); - Row row = extension.getRow(); - - CommandSequence result; - - if (!controllerState.rowBufferStates.rowBufferIsOpen(bank)) - { - return getBankMissCommandSequence(transaction); - } - else if (controllerState.rowBufferStates.getRowInRowBuffer(bank) != row) - { - return getRowMissCommandSequence(transaction); - } - else - { - return getRowHitCommandSequence(transaction); - } -} - -CommandSequence CommandSequenceGenerator::generateCommandSequence( - tlm::tlm_generic_payload* transaction) -{ - return generateCommandSequence(*transaction); -} - -CommandSequence CommandSequenceGenerator::getBankMissCommandSequence(tlm::tlm_generic_payload& transaction) -{ - vector result; - result.push_back(Command::Activate); - result.push_back(getReadWriteCommand(transaction)); - return result; -} - -CommandSequence CommandSequenceGenerator::getRowMissCommandSequence(tlm::tlm_generic_payload& transaction) -{ - vector result; - result.push_back(Command::Precharge); - result.push_back(Command::Activate); - result.push_back(getReadWriteCommand(transaction)); - return result; -} - -CommandSequence CommandSequenceGenerator::getRowHitCommandSequence(tlm::tlm_generic_payload& transaction) -{ - vector result; - result.push_back(getReadWriteCommand(transaction)); - return result; -} - -Command CommandSequenceGenerator::getReadWriteCommand(tlm::tlm_generic_payload& transaction) -{ - - if (transaction.get_command() == tlm::TLM_READ_COMMAND) - { - if(Configuration::getInstance().OpenPagePolicy) - return Command::Read; - else - return Command::ReadA; - } - else - { - if(Configuration::getInstance().OpenPagePolicy) - return Command::Write; - else - return Command::WriteA; - } -} - -} /* namespace controller */ - diff --git a/dram/src/controller/core/scheduling/CommandSequenceGenerator.h b/dram/src/controller/core/scheduling/CommandSequenceGenerator.h deleted file mode 100644 index df8516e0..00000000 --- a/dram/src/controller/core/scheduling/CommandSequenceGenerator.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CommandGenerator.h - * - * Created on: Mar 5, 2014 - * Author: jonny - */ - -#ifndef COMMANDGENERATOR_H_ -#define COMMANDGENERATOR_H_ - -#include -#include -#include "../ControllerState.h" -#include "../Command.h" - -namespace core { - -class CommandSequenceGenerator { -public: - CommandSequenceGenerator(const ControllerState& controllerState) : controllerState(controllerState) {} - virtual ~CommandSequenceGenerator() {} - - CommandSequence generateCommandSequence(tlm::tlm_generic_payload& transaction); - CommandSequence generateCommandSequence(tlm::tlm_generic_payload* transaction); - -private: - const ControllerState& controllerState; - - Command getReadWriteCommand(tlm::tlm_generic_payload& transaction); - CommandSequence getBankMissCommandSequence(tlm::tlm_generic_payload& transaction); - CommandSequence getRowMissCommandSequence(tlm::tlm_generic_payload& transaction); - CommandSequence getRowHitCommandSequence(tlm::tlm_generic_payload& transaction); -}; - -} /* namespace controller */ - -#endif /* COMMANDGENERATOR_H_ */ diff --git a/dram/src/controller/core/scheduling/CommandSequenceScheduler.cpp b/dram/src/controller/core/scheduling/CommandSequenceScheduler.cpp deleted file mode 100644 index 0f254563..00000000 --- a/dram/src/controller/core/scheduling/CommandSequenceScheduler.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CommandSequenceScheduler.cpp - * - * Created on: Mar 9, 2014 - * Author: jonny - */ - -#include "CommandSequenceScheduler.h" -#include "../ControllerCore.h" -#include "../../../common/DebugManager.h" -#include "../TimingCalculation.h" - -namespace core { - -CommandSchedule CommandSequenceScheduler::schedule(CommandSequence commands, sc_time start, - tlm::tlm_generic_payload& transaction) -{ - CommandSchedule schedule(transaction); - - for (Command cmd : commands) - { - ControllerCore::printDebugMessage("Scheduling command " + commandToString(cmd)); - - ICommandChecker& checker = controller.getCommandChecker(cmd); - - sc_time executionTime = getExecutionTime(cmd,transaction); - ScheduledCommand& scheduledCommand = schedule.add(cmd, start, executionTime); - checker.delayToSatisfyConstraints(scheduledCommand); - - sc_assert(scheduledCommand.getStart()>=start && scheduledCommand.getStart() < scheduledCommand.getEnd()); - controller.state.change(scheduledCommand); - } - - return schedule; -} - -} /* namespace controller */ diff --git a/dram/src/controller/core/scheduling/CommandSequenceScheduler.h b/dram/src/controller/core/scheduling/CommandSequenceScheduler.h deleted file mode 100644 index 39800ef6..00000000 --- a/dram/src/controller/core/scheduling/CommandSequenceScheduler.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * CommandSequenceScheduler.h - * - * Created on: Mar 9, 2014 - * Author: jonny - */ - -#ifndef COMMANDSEQUENCESCHEDULER_H_ -#define COMMANDSEQUENCESCHEDULER_H_ - -#include "CommandSchedule.h" - -namespace core { - -class ControllerCore; - -class CommandSequenceScheduler -{ -public: - CommandSequenceScheduler(ControllerCore& controller) : controller(controller){} - virtual ~CommandSequenceScheduler(){} - - CommandSchedule schedule(CommandSequence commands, sc_time start, tlm::tlm_generic_payload& transaction); - -private: - ControllerCore& controller; -}; - -} /* namespace controller */ - -#endif /* COMMANDSEQUENCESCHEDULER_H_ */ diff --git a/dram/src/controller/core/scheduling/ScheduledCommand.cpp b/dram/src/controller/core/scheduling/ScheduledCommand.cpp index a6b7e65d..d7d50875 100644 --- a/dram/src/controller/core/scheduling/ScheduledCommand.cpp +++ b/dram/src/controller/core/scheduling/ScheduledCommand.cpp @@ -9,8 +9,6 @@ #include "../../../common/Utils.h" #include "../configuration/Configuration.h" -namespace core { - bool ScheduledCommand::isNoCommand() const { return (command == Command::NOP && start == SC_ZERO_TIME && executionTime == SC_ZERO_TIME && end == SC_ZERO_TIME); @@ -38,7 +36,9 @@ void ScheduledCommand::delayStart(sc_time delay) setStart(start+delay); } -void ScheduledCommand::delayToMeetConstraint(sc_time previous, sc_time constraint) +// Delays the command so that its start is at least value(constraint) from timepoint previous apart. +// If passed a constraint of 0ns, method will make sure that command starts no earlier than at timepoint previous +void ScheduledCommand::establishMinDistanceFromStart(sc_time previous, sc_time constraint) { delayStart(getDelayToMeetConstraint(previous, start, constraint)); } @@ -106,7 +106,3 @@ TimeInterval ScheduledCommand::getIntervalOnDataStrobe() const return TimeInterval(getStart() + timings.tWL - timings.clk / 2, getStart() + timings.tWL + getWriteAccessTime() - timings.clk / 2); } } - - - -} diff --git a/dram/src/controller/core/scheduling/ScheduledCommand.h b/dram/src/controller/core/scheduling/ScheduledCommand.h index 50b3ad1b..60a18975 100644 --- a/dram/src/controller/core/scheduling/ScheduledCommand.h +++ b/dram/src/controller/core/scheduling/ScheduledCommand.h @@ -10,12 +10,11 @@ #include #include -#include "../Command.h" +#include "../../Command.h" #include "../../../common/dramExtension.h" #include "../../../common/TlmRecorder.h" #include "../../../common/Utils.h" -namespace core { class ScheduledCommand { @@ -27,6 +26,11 @@ public: { } + ScheduledCommand(Command command, sc_time start, sc_time executionTime, const tlm::tlm_generic_payload& payload) : + ScheduledCommand(command, start, executionTime, DramExtension::getExtension(payload)) + { + } + ScheduledCommand() : command(Command::NOP), start(SC_ZERO_TIME), executionTime(SC_ZERO_TIME), end(SC_ZERO_TIME), extension() @@ -39,7 +43,7 @@ public: const sc_time getStart() const; void setStart(sc_time newStart); void delayStart(sc_time delay); - void delayToMeetConstraint(sc_time previous, sc_time constraint); + void establishMinDistanceFromStart(sc_time previous, sc_time constraint); sc_time getEnd() const; Command getCommand() const; @@ -63,6 +67,5 @@ private: sc_time end; DramExtension extension; }; -} /* namespace controller */ #endif /* SCHEDULEDCOMMAND_H_ */ diff --git a/dram/src/controller/core/scheduling/Trigger.h b/dram/src/controller/core/scheduling/Trigger.h index 9a5827ce..f41b46b9 100644 --- a/dram/src/controller/core/scheduling/Trigger.h +++ b/dram/src/controller/core/scheduling/Trigger.h @@ -8,10 +8,8 @@ #ifndef TRIGGER_H_ #define TRIGGER_H_ -namespace core { enum Trigger {REFTrigger, PDNTrigger}; -} /* namespace controller */ #endif /* TRIGGER_H_ */ diff --git a/dram/src/controller/core/scheduling/checker/ActivateChecker.cpp b/dram/src/controller/core/scheduling/checker/ActivateChecker.cpp index f5ce84f9..b3840800 100644 --- a/dram/src/controller/core/scheduling/checker/ActivateChecker.cpp +++ b/dram/src/controller/core/scheduling/checker/ActivateChecker.cpp @@ -10,12 +10,10 @@ #include "ActivateChecker.h" #include "../../TimingCalculation.h" #include "../../../../common/DebugManager.h" -#include "../../Command.h" +#include "../../../Command.h" #include "../../../../common/Utils.h" #include -namespace core { - void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { sc_assert(command.getCommand() == Command::Activate); @@ -25,28 +23,28 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { if (lastCommandOnBank.getCommand() == Command::Precharge) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tRP); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::ReadA) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tRTP + config.memSpec.tRP); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRTP + config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::WriteA) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tRFC); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC); } else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tXP); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP); } else if (lastCommandOnBank.getCommand() == Command::SREFX) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tXSR); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR); } else reportFatal("Activate Checker", "Activate can not follow " + commandToString(lastCommandOnBank.getCommand())); @@ -67,7 +65,7 @@ void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank(ScheduledComm ScheduledCommand lastActivateOnBank = state.getLastCommand(Command::Activate, command.getBank()); if (lastActivateOnBank.isValidCommand()) { - command.delayToMeetConstraint(lastActivateOnBank.getStart(), config.memSpec.tRC); + command.establishMinDistanceFromStart(lastActivateOnBank.getStart(), config.memSpec.tRC); } } @@ -111,5 +109,3 @@ bool ActivateChecker::satisfies_nActivateWindow(ScheduledCommand& command) const return true; } - -} /* namespace controller */ diff --git a/dram/src/controller/core/scheduling/checker/ActivateChecker.h b/dram/src/controller/core/scheduling/checker/ActivateChecker.h index 2a31407c..df3ce72d 100644 --- a/dram/src/controller/core/scheduling/checker/ActivateChecker.h +++ b/dram/src/controller/core/scheduling/checker/ActivateChecker.h @@ -11,9 +11,7 @@ #include #include "ICommandChecker.h" #include "../../configuration/Configuration.h" -#include "../../ControllerState.h" - -namespace core { +#include "../../../ControllerState.h" class ActivateChecker: public ICommandChecker { @@ -31,6 +29,4 @@ private: bool satisfies_nActivateWindow(ScheduledCommand& command) const; }; -} /* namespace controller */ - #endif /* ACTIVATESCHEDULER_H_ */ diff --git a/dram/src/controller/core/scheduling/checker/ICommandChecker.h b/dram/src/controller/core/scheduling/checker/ICommandChecker.h index ae73c5b1..6e14c8c8 100644 --- a/dram/src/controller/core/scheduling/checker/ICommandChecker.h +++ b/dram/src/controller/core/scheduling/checker/ICommandChecker.h @@ -11,7 +11,6 @@ #include #include "../ScheduledCommand.h" -namespace core { class ICommandChecker { @@ -20,7 +19,6 @@ public: virtual void delayToSatisfyConstraints(ScheduledCommand& command) const = 0; }; -} /* namespace controller */ #endif /* ICOMMANDSCHEDULER_H_ */ diff --git a/dram/src/controller/core/scheduling/checker/PowerDownChecker.cpp b/dram/src/controller/core/scheduling/checker/PowerDownChecker.cpp index 58c5281d..8688d5e3 100644 --- a/dram/src/controller/core/scheduling/checker/PowerDownChecker.cpp +++ b/dram/src/controller/core/scheduling/checker/PowerDownChecker.cpp @@ -8,7 +8,6 @@ #include "PowerDownChecker.h" #include "../../TimingCalculation.h" -namespace core { void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { sc_assert( @@ -23,31 +22,31 @@ void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons { if (lastCommandOnBank.getCommand() == Command::Read || lastCommandOnBank.getCommand() == Command::ReadA) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRL + getReadAccessTime() + config.memSpec.clk); } else if (lastCommandOnBank.getCommand() == Command::Write) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); } else if (lastCommandOnBank.getCommand() == Command::WriteA) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.clk); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tRFC); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC); } else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tXP); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP); } else if (lastCommandOnBank.getCommand() == Command::SREFX) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tXSR); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR); } else @@ -59,19 +58,17 @@ void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons else if (command.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(state.getLastCommand(Command::PDNA).getStart(), config.memSpec.tCKE); + command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNA).getStart(), config.memSpec.tCKE); } else if (command.getCommand() == Command::PDNPX) { - command.delayToMeetConstraint(state.getLastCommand(Command::PDNP).getStart(), config.memSpec.tCKE); + command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNP).getStart(), config.memSpec.tCKE); } else if (command.getCommand() == Command::SREFX) { - command.delayToMeetConstraint(state.getLastCommand(Command::SREF).getStart(), config.memSpec.tCKESR); + command.establishMinDistanceFromStart(state.getLastCommand(Command::SREF).getStart(), config.memSpec.tCKESR); } state.bus.moveCommandToNextFreeSlot(command); } -} /* namespace core */ - diff --git a/dram/src/controller/core/scheduling/checker/PowerDownChecker.h b/dram/src/controller/core/scheduling/checker/PowerDownChecker.h index 24784d13..dcabc5d9 100644 --- a/dram/src/controller/core/scheduling/checker/PowerDownChecker.h +++ b/dram/src/controller/core/scheduling/checker/PowerDownChecker.h @@ -8,12 +8,11 @@ #ifndef POWERDOWNCHECKER_H_ #define POWERDOWNCHECKER_H_ -#include "../../ControllerState.h" +#include "../../../ControllerState.h" #include "../../configuration/Configuration.h" #include "ICommandChecker.h" #include -namespace core { class PowerDownChecker : public ICommandChecker { @@ -33,6 +32,5 @@ private: ControllerState& state; }; -} /* namespace core */ #endif /* POWERDOWNCHECKER_H_ */ diff --git a/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp b/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp index 42fd85f1..a67f126c 100644 --- a/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp +++ b/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp @@ -8,44 +8,52 @@ #include "PrechargeAllChecker.h" #include "../../TimingCalculation.h" -namespace core { void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { sc_assert(command.getCommand() == Command::PrechargeAll); + // Consider all banks for the constraints, since precharge all command is supposed to happen at the same time on all banks for (unsigned int bank = 0; bank < config.memSpec.NumberOfBanks; ++bank) { ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank)); if (lastCommand.isValidCommand()) { - if (lastCommand.getCommand() == Command::Read) + if(lastCommand.getCommand() == Command::Precharge) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tRTP); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRP); + } + else if(lastCommand.getCommand() == Command::Activate) + { + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); + } + else if (lastCommand.getCommand() == Command::Read) + { + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRTP); } else if (lastCommand.getCommand() == Command::ReadA) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tRTP + config.memSpec.tRP); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRTP + config.memSpec.tRP); } else if (lastCommand.getCommand() == Command::Write) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); } else if(lastCommand.getCommand() == Command::WriteA) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lastCommand.getCommand() == Command::AutoRefresh) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tRFC); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRFC); } else if (lastCommand.getCommand() == Command::PDNAX || lastCommand.getCommand() == Command::PDNPX) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tXP); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tXP); } else if (lastCommand.getCommand() == Command::SREFX) { - command.delayToMeetConstraint(lastCommand.getEnd(), config.memSpec.tXSR); + command.establishMinDistanceFromStart(lastCommand.getEnd(), config.memSpec.tXSR); } else reportFatal("Precharge All Checker", @@ -56,10 +64,9 @@ void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand& command) c ScheduledCommand lastActivate = state.getLastCommand(Command::Activate, command.getBank()); if (lastActivate.isValidCommand()) { - command.delayToMeetConstraint(lastActivate.getStart(), config.memSpec.tRAS); + command.establishMinDistanceFromStart(lastActivate.getStart(), config.memSpec.tRAS); } state.bus.moveCommandToNextFreeSlot(command); } -} /* namespace core */ diff --git a/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.h b/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.h index f536a1a2..97a23c90 100644 --- a/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.h +++ b/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.h @@ -10,11 +10,10 @@ #include "ICommandChecker.h" #include "../../configuration/Configuration.h" -#include "../../ControllerState.h" +#include "../../../ControllerState.h" -namespace core { -class PrechargeAllChecker: public core::ICommandChecker +class PrechargeAllChecker: public ICommandChecker { public: PrechargeAllChecker(const Configuration& config, ControllerState& state) : @@ -32,6 +31,5 @@ private: ControllerState& state; }; -} /* namespace core */ #endif /* PRECHARGEALLCHECKER_H_ */ diff --git a/dram/src/controller/core/scheduling/checker/PrechargeChecker.cpp b/dram/src/controller/core/scheduling/checker/PrechargeChecker.cpp index de0d315e..2b654389 100644 --- a/dram/src/controller/core/scheduling/checker/PrechargeChecker.cpp +++ b/dram/src/controller/core/scheduling/checker/PrechargeChecker.cpp @@ -8,7 +8,6 @@ #include "PrechargeChecker.h" #include "../../TimingCalculation.h" -namespace core { void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { @@ -19,18 +18,29 @@ void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons if (lastCommand.isValidCommand()) { - if (lastCommand.getCommand() == Command::Read) + // the first two cases happen when a resfresh interrups the command sequence of a transaction + // (e.g. commands to process transaction are PRE-ACT-RD and refresh happens after the PRE or after the ACT) + if(lastCommand.getCommand() == Command::Precharge) { - command.delayToMeetConstraint(lastCommand.getStart(),config.memSpec.tRTP); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRP); + } + else if(lastCommand.getCommand() == Command::Activate) + { + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); + } + + else if (lastCommand.getCommand() == Command::Read) + { + command.establishMinDistanceFromStart(lastCommand.getStart(),config.memSpec.tRTP); } else if (lastCommand.getCommand() == Command::Write) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); } else if (lastCommand.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tXP); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tXP); } else reportFatal("Precharge Checker", "Precharge can not follow " + commandToString(lastCommand.getCommand())); @@ -39,11 +49,9 @@ void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) cons ScheduledCommand lastActivate = state.getLastCommand(Command::Activate, command.getBank()); if (lastActivate.isValidCommand()) { - command.delayToMeetConstraint(lastActivate.getStart(), config.memSpec.tRAS); + command.establishMinDistanceFromStart(lastActivate.getStart(), config.memSpec.tRAS); } - state.bus.moveCommandToNextFreeSlot(command); } -} /* namespace controller */ diff --git a/dram/src/controller/core/scheduling/checker/PrechargeChecker.h b/dram/src/controller/core/scheduling/checker/PrechargeChecker.h index e93d4b73..c5177bfd 100644 --- a/dram/src/controller/core/scheduling/checker/PrechargeChecker.h +++ b/dram/src/controller/core/scheduling/checker/PrechargeChecker.h @@ -10,11 +10,10 @@ #include "ICommandChecker.h" #include "../../configuration/Configuration.h" -#include "../../ControllerState.h" +#include "../../../ControllerState.h" -namespace core { -class PrechargeChecker: public core::ICommandChecker +class PrechargeChecker: public ICommandChecker { public: PrechargeChecker(const Configuration& config, ControllerState& state) : config(config), state(state) {} @@ -26,6 +25,5 @@ private: ControllerState& state; }; -} /* namespace controller */ #endif /* PRECHARGECHECKER_H_ */ diff --git a/dram/src/controller/core/scheduling/checker/ReadChecker.cpp b/dram/src/controller/core/scheduling/checker/ReadChecker.cpp index 7288701a..2b53fe0b 100644 --- a/dram/src/controller/core/scheduling/checker/ReadChecker.cpp +++ b/dram/src/controller/core/scheduling/checker/ReadChecker.cpp @@ -10,49 +10,29 @@ #include "../../../../common/Utils.h" #include "WriteChecker.h" -namespace core { - void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { sc_assert(command.getCommand() == Command::Read || command.getCommand() == Command::ReadA); - delayToSatisfyDLL(command); - ScheduledCommand lastCommand = state.getLastScheduledCommand(command.getBank()); - //fifo patch - if(config.Scheduler == "FIFO") - { - - //no access can accelerate other access - ScheduledCommand lastread = state.getLastCommand(Command::Read); - ScheduledCommand lastwrite = state.getLastCommand(Command::Write); - ScheduledCommand lastreada = state.getLastCommand(Command::ReadA); - ScheduledCommand lastwritea = state.getLastCommand(Command::WriteA); - - command.delayToMeetConstraint(lastread.getStart(), SC_ZERO_TIME); - command.delayToMeetConstraint(lastreada.getStart(), SC_ZERO_TIME); - command.delayToMeetConstraint(lastwrite.getStart(), SC_ZERO_TIME); - command.delayToMeetConstraint(lastwritea.getStart(), SC_ZERO_TIME); - } - if (lastCommand.isValidCommand()) { if (lastCommand.getCommand() == Command::Activate) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tRCD); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); } else if (lastCommand.getCommand() == Command::Read) { - command.delayToMeetConstraint(lastCommand.getStart(), ReadChecker::readToRead(lastCommand,command)); + command.establishMinDistanceFromStart(lastCommand.getStart(), ReadChecker::readToRead(lastCommand,command)); } else if (lastCommand.getCommand() == Command::Write) { - command.delayToMeetConstraint(lastCommand.getStart(), ReadChecker::writeToRead(lastCommand, command)); + command.establishMinDistanceFromStart(lastCommand.getStart(), ReadChecker::writeToRead(lastCommand, command)); } else if (lastCommand.getCommand() == Command::PDNPX || lastCommand.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tXP); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tXP); } else reportFatal("Read Checker", "Read can not follow " + commandToString(lastCommand.getCommand())); @@ -100,7 +80,7 @@ void ReadChecker::delayToSatisfyDLL(ScheduledCommand& read) const { ScheduledCommand lastSREFX = state.getLastCommand(Command::SREFX, read.getBank()); if (lastSREFX.isValidCommand()) - read.delayToMeetConstraint(lastSREFX.getStart(), config.memSpec.tXSRDLL); + read.establishMinDistanceFromStart(lastSREFX.getStart(), config.memSpec.tXSRDLL); } sc_time ReadChecker::readToRead(ScheduledCommand& firstRead, ScheduledCommand& secondRead) @@ -123,5 +103,4 @@ sc_time ReadChecker::writeToRead(ScheduledCommand& write, ScheduledCommand& read return config.tWL + getWriteAccessTime() + tWTR; } -} /* namespace controller */ diff --git a/dram/src/controller/core/scheduling/checker/ReadChecker.h b/dram/src/controller/core/scheduling/checker/ReadChecker.h index 3f1fae9d..5955473d 100644 --- a/dram/src/controller/core/scheduling/checker/ReadChecker.h +++ b/dram/src/controller/core/scheduling/checker/ReadChecker.h @@ -10,11 +10,10 @@ #include "ICommandChecker.h" #include "../../configuration/Configuration.h" -#include "../../ControllerState.h" +#include "../../../ControllerState.h" -namespace core { -class ReadChecker: public core::ICommandChecker +class ReadChecker: public ICommandChecker { public: ReadChecker(Configuration& config, ControllerState& state) : config(config), state(state) {} @@ -34,6 +33,5 @@ private: bool collidesWithStrobeCommand(ScheduledCommand& read, ScheduledCommand& strobeCommand) const; }; -} /* namespace controller */ #endif /* READCHECKER_H_ */ diff --git a/dram/src/controller/core/scheduling/checker/RefreshChecker.cpp b/dram/src/controller/core/scheduling/checker/RefreshChecker.cpp index d9e09ee2..dafba7e5 100644 --- a/dram/src/controller/core/scheduling/checker/RefreshChecker.cpp +++ b/dram/src/controller/core/scheduling/checker/RefreshChecker.cpp @@ -9,7 +9,6 @@ #include "../../TimingCalculation.h" -namespace core { void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { @@ -21,24 +20,24 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { if (lastCommandOnBank.getCommand() == Command::Precharge || lastCommandOnBank.getCommand() == Command::PrechargeAll) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tRP); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::ReadA) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tRTP + config.memSpec.tRP); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRTP + config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::WriteA) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tXP); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP); } else if (lastCommandOnBank.getCommand() == Command::SREFX) { - command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.memSpec.tXSR); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { @@ -50,5 +49,4 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const state.bus.moveCommandToNextFreeSlot(command); } -} /* namespace core */ diff --git a/dram/src/controller/core/scheduling/checker/RefreshChecker.h b/dram/src/controller/core/scheduling/checker/RefreshChecker.h index fca86dc3..92949ec1 100644 --- a/dram/src/controller/core/scheduling/checker/RefreshChecker.h +++ b/dram/src/controller/core/scheduling/checker/RefreshChecker.h @@ -9,11 +9,10 @@ #define REFRESHCHECKER_H_ #include "ICommandChecker.h" -#include "../../ControllerState.h" +#include "../../../ControllerState.h" #include "../../configuration/Configuration.h" #include -namespace core { class RefreshChecker: public ICommandChecker { @@ -34,6 +33,5 @@ private: }; -} /* namespace core */ #endif /* REFRESHCHECKER_H_ */ diff --git a/dram/src/controller/core/scheduling/checker/WriteChecker.cpp b/dram/src/controller/core/scheduling/checker/WriteChecker.cpp index dac9a578..1d5321af 100644 --- a/dram/src/controller/core/scheduling/checker/WriteChecker.cpp +++ b/dram/src/controller/core/scheduling/checker/WriteChecker.cpp @@ -10,7 +10,6 @@ #include "../../../../common/Utils.h" #include "ReadChecker.h" -namespace core { void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { @@ -18,39 +17,23 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const ScheduledCommand lastCommand = state.getLastScheduledCommand(command.getBank()); - //fifo patch - if(config.Scheduler == "FIFO") - { - - //no access can accelerate other access - ScheduledCommand lastread = state.getLastCommand(Command::Read); - ScheduledCommand lastwrite = state.getLastCommand(Command::Write); - ScheduledCommand lastreada = state.getLastCommand(Command::ReadA); - ScheduledCommand lastwritea = state.getLastCommand(Command::WriteA); - - command.delayToMeetConstraint(lastread.getStart(), SC_ZERO_TIME); - command.delayToMeetConstraint(lastreada.getStart(), SC_ZERO_TIME); - command.delayToMeetConstraint(lastwrite.getStart(), SC_ZERO_TIME); - command.delayToMeetConstraint(lastwritea.getStart(), SC_ZERO_TIME); - } - if (lastCommand.isValidCommand()) { if (lastCommand.getCommand() == Command::Activate) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tRCD); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); } else if (lastCommand.getCommand() == Command::Read) { - command.delayToMeetConstraint(lastCommand.getStart(), WriteChecker::readToWrite(lastCommand, command)); + command.establishMinDistanceFromStart(lastCommand.getStart(), WriteChecker::readToWrite(lastCommand, command)); } else if (lastCommand.getCommand() == Command::Write) { - command.delayToMeetConstraint(lastCommand.getStart(), WriteChecker::writeToWrite(lastCommand, command)); + command.establishMinDistanceFromStart(lastCommand.getStart(), WriteChecker::writeToWrite(lastCommand, command)); } else if (lastCommand.getCommand() == Command::PDNPX || lastCommand.getCommand() == Command::PDNAX) { - command.delayToMeetConstraint(lastCommand.getStart(), config.memSpec.tXP); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tXP); } else reportFatal("Write Checker", "Write can not follow " + commandToString(lastCommand.getCommand())); @@ -113,4 +96,3 @@ sc_time WriteChecker::readToWrite(ScheduledCommand& read, ScheduledCommand& writ return config.tRL + getReadAccessTime() - config.tWL + config.clk * 2; } -} /* namespace controller */ diff --git a/dram/src/controller/core/scheduling/checker/WriteChecker.h b/dram/src/controller/core/scheduling/checker/WriteChecker.h index 28ba61d5..1fa1d735 100644 --- a/dram/src/controller/core/scheduling/checker/WriteChecker.h +++ b/dram/src/controller/core/scheduling/checker/WriteChecker.h @@ -10,11 +10,10 @@ #include "ICommandChecker.h" #include "../../configuration/Configuration.h" -#include "../../ControllerState.h" +#include "../../../ControllerState.h" -namespace core { -class WriteChecker: public core::ICommandChecker +class WriteChecker: public ICommandChecker { public: WriteChecker(const Configuration& config, ControllerState& state) : config(config), state(state) {} @@ -31,6 +30,5 @@ private: ControllerState& state; }; -} /* namespace controller */ #endif /* WRITECHECKER_H_ */ diff --git a/dram/src/controller/scheduler/Fifo.cpp b/dram/src/controller/scheduler/Fifo.cpp index fa9a7fe1..f6c4a83e 100644 --- a/dram/src/controller/scheduler/Fifo.cpp +++ b/dram/src/controller/scheduler/Fifo.cpp @@ -7,43 +7,28 @@ #include "Fifo.h" - -namespace scheduler { - -bool Fifo::hasPayloads() -{ - return getNumberOfQueuedPayloads() > 0; -} +using namespace std; void Fifo::schedule(gp* payload) { - buffer.push_back(payload); + buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); } -gp* Fifo::getNextPayload() +pair Fifo::getNextRequest(Bank bank) { - if(!buffer.empty()) + if(!buffer[bank].empty()) { - DramExtension& frontRequest = DramExtension::getExtension(buffer.front()); - vector freeBanks = controllerCore.getFreeBanks(); - if(std::find(freeBanks.begin(),freeBanks.end(),frontRequest.getBank()) != freeBanks.end()) + gp* payload = buffer[bank].front(); + Command command = IScheduler::getNextCommand(*payload); + if(command == Command::Read || command == Command::ReadA || command == Command::Write || command == Command::WriteA) { - return buffer.front(); + buffer[bank].pop_front(); } + + return pair(command, payload); } - return NULL; + return pair(Command::NOP, NULL); } -void Fifo::removePayload(gp* /*payload*/) -{ - buffer.pop_front(); -} - -unsigned int Fifo::getNumberOfQueuedPayloads() -{ - return buffer.size(); -} - -} /* namespace scheduler */ diff --git a/dram/src/controller/scheduler/Fifo.h b/dram/src/controller/scheduler/Fifo.h index 51e54337..e8986a5f 100644 --- a/dram/src/controller/scheduler/Fifo.h +++ b/dram/src/controller/scheduler/Fifo.h @@ -8,33 +8,26 @@ #ifndef FIFO_H_ #define FIFO_H_ -#include "Scheduler.h" #include "../core/ControllerCore.h" +#include "../Command.h" +#include "IScheduler.h" #include #include +#include - -namespace scheduler { - -class Fifo : public Scheduler +class Fifo : public IScheduler { public: - Fifo(core::ControllerCore &controllerCore) : controllerCore(controllerCore) + Fifo(ControllerCore &controllerCore) : IScheduler(controllerCore) {} virtual ~Fifo() {} - virtual bool hasPayloads() override; - virtual void schedule(gp* payload) override; - virtual gp* getNextPayload() override; - virtual void removePayload(gp* payload) override; + void schedule(gp* payload) override; + std::pair getNextRequest(Bank bank) override; private: - std::deque buffer; - core::ControllerCore &controllerCore; - unsigned int getNumberOfQueuedPayloads(); + std::map> buffer; }; -} /* namespace scheduler */ - #endif /* FIFO_H_ */ diff --git a/dram/src/controller/scheduler/FifoStrict.cpp b/dram/src/controller/scheduler/FifoStrict.cpp new file mode 100644 index 00000000..8699500f --- /dev/null +++ b/dram/src/controller/scheduler/FifoStrict.cpp @@ -0,0 +1,89 @@ +#include "FifoStrict.h" + +void FifoStrict::schedule(gp *payload) +{ + buffer.push_back(payload); + printDebugMessage("New payload scheduled. Total number " + std::to_string(buffer.size()) + "\n"); +} + +void FifoStrict::printFrontElementState() +{ + if(buffer.size() > 0) + { + printDebugMessage("Front element state - Bank: " + DramExtension::getBank(buffer.front()).toString() + " Operation: " + + commandToString(getNextCommand(*buffer.front())) + "\n"); + } + else + { + printDebugMessage("No fron element. Buffer is empty \n "); + } +} + +void FifoStrict::NotifyBeginRD() +{ + Bank oldFrontElementBank = DramExtension::getBank(buffer.front()); + buffer.erase(buffer.begin()); + printDebugMessage("Front element finished. New front Element: "); + printFrontElementState(); + + if(buffer.size() > 0) + { + // If the new front element was orginally blocked, because it had to wait on the preceeding fron element, we have to unblock it. + // We only have to unblock if the new fron element is waiting for a RD/WR operation + if(commandIsIn(getNextCommand(*buffer.front()), {Command::Read, Command::Write, Command::ReadA, Command::WriteA}) + && !controllerCore.bankIsBusy(DramExtension::getBank(buffer.front()))) + { + printDebugMessage("Unblocking front element.\n"); + controller.scheduleNextFromScheduler(DramExtension::getBank(buffer.front())); + } + // If the new front element is on the same bank as the old one, we have let it make progress, even when the next command is not a RD/WR + // because we are not calling scheduleNextFromScheduler from the calling side + else if(oldFrontElementBank == DramExtension::getBank(*buffer.front())) + { + controller.scheduleNextFromScheduler(DramExtension::getBank(buffer.front())); + } + } + +} + +std::pair FifoStrict::getNextRequest(Bank bank) +{ + if(buffer.empty()) + { + return pair(Command::NOP, NULL); + } + + else if(DramExtension::getBank(buffer.front()) == bank) + { + Command command = getNextCommand(*buffer.front()); + pair result(command, buffer.front()); + printDebugMessage("Operation for front Element scheduled. "); + printFrontElementState(); + + return result; + } + else + { + for(unsigned int i = 1; i < buffer.size(); ++i) + { + if(DramExtension::getBank(buffer[i]) == bank) + { + Command command = getNextCommand(*buffer[i]); + + // RD/WR operations have to be strictly in order across banks, so only allow progress on commands + // other than RD/WR commands. + if(commandIsIn(command, {Command::Read, Command::Write, Command::ReadA, Command::WriteA})) + { + printDebugMessage("Current queue element " + std::to_string(i) + " blocked. Waiting for earlier rd/wr to finish\n"); + return pair(Command::NOP, NULL); + } + else + { + return pair(command, buffer[i]); + } + } + } + + return pair(Command::NOP, NULL); + } +} diff --git a/dram/src/controller/scheduler/FifoStrict.h b/dram/src/controller/scheduler/FifoStrict.h new file mode 100644 index 00000000..8bd975b7 --- /dev/null +++ b/dram/src/controller/scheduler/FifoStrict.h @@ -0,0 +1,32 @@ +#ifndef FIFOSTRICT_H +#define FIFOSTRICT_H + +#include "../core/ControllerCore.h" +#include "../Command.h" +#include "../../common/dramExtension.h" +#include "IScheduler.h" +#include +#include +#include + +class FifoStrict : public IScheduler +{ +public: + FifoStrict(IController &controller,ControllerCore &controllerCore) : + IScheduler(controllerCore), controller(controller) + {} + virtual ~FifoStrict() + {} + + void schedule(gp* payload) override; + std::pair getNextRequest(Bank bank) override; + void NotifyBeginRD(); + +private: + std::vector buffer; + IController &controller; + void printFrontElementState(); +}; + + +#endif // FIFOSTRICT_H diff --git a/dram/src/controller/scheduler/Fr_Fcfs.cpp b/dram/src/controller/scheduler/Fr_Fcfs.cpp index b0b6c159..ea22eb56 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.cpp +++ b/dram/src/controller/scheduler/Fr_Fcfs.cpp @@ -4,133 +4,47 @@ #include using namespace std; -using namespace core; - -namespace scheduler { - -FR_FCFS::FR_FCFS(core::ControllerCore& controllerCore, bool useExternalStates, bool adaptiveOpenPage) : - controllerCore(controllerCore), useExternalStates(useExternalStates), adaptiveOpenPage( - adaptiveOpenPage) -{ -} - -FR_FCFS::~FR_FCFS() -{ -} - -bool FR_FCFS::hasPayloads() -{ - return getNumberOfQueuedPayloads() > 0; -} -void FR_FCFS::schedule(gp* payload) + +void FR_FCFS::schedule(gp *payload) { buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); } - -void FR_FCFS::schedule(std::vector payloads) -{ - for(gp* payload: payloads) - schedule(payload); -} - -gp* FR_FCFS::getNextPayload() -{ - for(Bank bank: controllerCore.getFreeBanks()) - { - if(!buffer[bank].empty()) - { - Row openRowOnBank = (useExternalStates) ? controllerCore.getRowBufferStates().getRowInRowBuffer(bank) : internalBankstates.getRowInRowBuffer(bank); - auto rowHits = findRowHits(bank, openRowOnBank); - gp* result = rowHits.empty() ? buffer[bank].front() : rowHits.front(); - - if (!adaptiveOpenPage) - { - return result; - } - else - { - rowHits = findRowHits(bank, DramExtension::getExtension(result).getRow()); - //other row hits are still in buffer, leave page open - if (rowHits.size() > 1) - Configuration::getInstance().OpenPagePolicy = true; - else - Configuration::getInstance().OpenPagePolicy = false; - - //other row hits are still in buffer, leave page open - if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() > 1) - Configuration::getInstance().OpenPagePolicy = true; - else - Configuration::getInstance().OpenPagePolicy = false; - - //no other hit in buffer, but row miss is waiting - if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() == 1 && buffer[bank].size() > 2 ) - Configuration::getInstance().OpenPagePolicy = false; - else - Configuration::getInstance().OpenPagePolicy = true; - return result; - } - - } - } - return NULL; -} - -gp* FR_FCFS::popOldest(Bank bank) +std::pair FR_FCFS::getNextRequest(Bank bank) { if(buffer[bank].empty()) - return NULL; - gp* result = buffer[bank].front(); - buffer[bank].pop_front(); - return result; -} - -unsigned int FR_FCFS::getNumberOfQueuedPayloads() -{ - unsigned int numberOfQueuedPaylods = 0; - for(auto& bufferElement : buffer) { - numberOfQueuedPaylods += bufferElement.second.size(); + return pair(Command::NOP, NULL); } - return numberOfQueuedPaylods; -} -bool FR_FCFS::containsPayloadTragetingSameAddress(gp *payload) -{ - Bank bank = DramExtension::getExtension(payload).getBank(); - Row row = DramExtension::getExtension(payload).getRow(); - - for(gp* bufferedPayload: buffer[bank]) + deque::iterator it = FindRowHit(bank); + if(it != buffer[bank].end()) { - if(DramExtension::getExtension(bufferedPayload).getRow() == row) - return true; + gp* payload = *it; + buffer[bank].erase(it); + return pair(getReadWriteCommand(*payload), payload); } - return false; + + return pair(getNextCommand(buffer[bank].front()), buffer[bank].front()); } -std::vector FR_FCFS::findRowHits(Bank bank, Row row) +deque::iterator FR_FCFS::FindRowHit(Bank bank) { - vector found; - for (gp* payload : buffer[bank]) + deque &queue = buffer[bank]; + + if(!controllerCore.getRowBufferStates().rowBufferIsOpen(bank)) + return queue.end(); + + for(auto it = queue.begin(); it!=queue.end(); it++) { - if (DramExtension::getExtension(payload).getRow() == row) - found.push_back(payload); + gp* payload = *it; + //Found row-hit + if(DramExtension::getRow(payload) == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) + { + return it; + } } - return found; + return queue.end(); } - -void FR_FCFS::removePayload(gp* payload) -{ - Bank bank = DramExtension::getExtension(payload).getBank(); - buffer[bank].remove(payload); - - if (!useExternalStates) - { - internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow()); - } -} - -} - diff --git a/dram/src/controller/scheduler/Fr_Fcfs.h b/dram/src/controller/scheduler/Fr_Fcfs.h index 39446120..1d309c20 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.h +++ b/dram/src/controller/scheduler/Fr_Fcfs.h @@ -1,41 +1,27 @@ #ifndef FR_FCFS_H_ #define FR_FCFS_H_ -#include "Scheduler.h" +#include "IScheduler.h" #include "../core/ControllerCore.h" #include #include #include -namespace scheduler { -class FR_FCFS : public Scheduler +class FR_FCFS : public IScheduler { public: - FR_FCFS(core::ControllerCore& controllerCore, bool refreshAware, bool adaptiveOpenPage); - virtual ~FR_FCFS(); + FR_FCFS(ControllerCore &controllerCore) : IScheduler(controllerCore){} + virtual ~FR_FCFS(){} - virtual bool hasPayloads() override; - virtual void schedule(gp* payload) override; - virtual gp* getNextPayload() override; - virtual void removePayload(gp* payload) override; + void schedule(gp* payload) override; + std::pair getNextRequest(Bank bank) override; - //used by PAR_BS - void schedule(std::vector payloads); - gp* popOldest(Bank bank); - unsigned int getNumberOfQueuedPayloads(); - - //used by read/write grouper - bool containsPayloadTragetingSameAddress(gp* payload); private: - std::vector findRowHits(Bank bank, Row row); - std::map> buffer; - core::ControllerCore& controllerCore; - core::RowBufferState internalBankstates; - bool useExternalStates; - bool adaptiveOpenPage; + std::map> buffer; + std::deque::iterator FindRowHit(Bank bank); + }; -} /* namespace scheduler */ #endif diff --git a/dram/src/controller/scheduler/IScheduler.cpp b/dram/src/controller/scheduler/IScheduler.cpp new file mode 100644 index 00000000..ba158f1d --- /dev/null +++ b/dram/src/controller/scheduler/IScheduler.cpp @@ -0,0 +1,58 @@ +#include "IScheduler.h" +#include "../../common/DebugManager.h" +#include "../core/configuration/Configuration.h" + +std::string IScheduler::sendername = "scheduler"; + +void IScheduler::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(IScheduler::sendername, message); +} + +// Get the next command that is necessary to process the request representend by the payload +Command IScheduler::getNextCommand(gp& payload) +{ + Bank bank = DramExtension::getBank(payload); + if(!controllerCore.getRowBufferStates().rowBufferIsOpen(bank)) + { + return Command::Activate; + } + else if(controllerCore.getRowBufferStates().rowBufferIsOpen(bank) && + controllerCore.getRowBufferStates().getRowInRowBuffer(bank) != DramExtension::getRow(payload)) + { + return Command::Precharge; + } + else + { + return getReadWriteCommand(payload); + } +} + +Command IScheduler::getNextCommand(gp *payload) +{ + return getNextCommand(*payload); +} + +Command IScheduler::getReadWriteCommand(gp& payload) +{ + + if (payload.get_command() == tlm::TLM_READ_COMMAND) + { + if(Configuration::getInstance().OpenPagePolicy) + return Command::Read; + else + return Command::ReadA; + } + else + { + if(Configuration::getInstance().OpenPagePolicy) + return Command::Write; + else + return Command::WriteA; + } +} + +Command IScheduler::getReadWriteCommand(gp *payload) +{ + return getReadWriteCommand(*payload); +} diff --git a/dram/src/controller/scheduler/IScheduler.h b/dram/src/controller/scheduler/IScheduler.h new file mode 100644 index 00000000..243b1575 --- /dev/null +++ b/dram/src/controller/scheduler/IScheduler.h @@ -0,0 +1,33 @@ +#ifndef ISCHEDULER_H +#define ISCHEDULER_H + + +#include +#include "../../common/dramExtension.h" +#include "../Command.h" +#include "../core/ControllerCore.h" + +typedef tlm::tlm_generic_payload gp; + +class IScheduler +{ +public: + virtual ~IScheduler(){} + IScheduler(ControllerCore &controllerCore) : controllerCore(controllerCore){} + + virtual void schedule(gp* payload) = 0; + virtual std::pair getNextRequest(Bank bank) = 0; + static std::string sendername; + +protected: + void printDebugMessage(std::string message); + Command getNextCommand(gp &payload); + Command getNextCommand(gp *payload); + + Command getReadWriteCommand(gp &payload); + Command getReadWriteCommand(gp *payload); + + ControllerCore &controllerCore; +}; + +#endif // ISCHEDULER_H diff --git a/dram/src/controller/scheduler/PARBS.cpp b/dram/src/controller/scheduler/PARBS.cpp index f871b68c..0ba21b7a 100644 --- a/dram/src/controller/scheduler/PARBS.cpp +++ b/dram/src/controller/scheduler/PARBS.cpp @@ -1,113 +1,112 @@ -// * PARBS.cpp -// * -// * Created on: Apr 9, 2014 -// * Author: robert -// */ +//// * PARBS.cpp +//// * +//// * Created on: Apr 9, 2014 +//// * Author: robert +//// */ -#include "PARBS.h" -#include "../core/configuration/Configuration.h" -#include "../../common/dramExtension.h" -#include "map" -#include "ThreadLoad.h" -#include +//#include "PARBS.h" +//#include "../core/configuration/Configuration.h" +//#include "../../common/dramExtension.h" +//#include "map" +//#include "ThreadLoad.h" +//#include -namespace scheduler { +//namespace scheduler { -using namespace std; -using namespace core; +//using namespace std; -PAR_BS::PAR_BS(core::ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize) : - controllerCore(controllerCore), useExternalBankstates(useExternalBankstates), capsize(capsize) -{ - if (useExternalBankstates) - { - batch = new FR_FCFS(controllerCore, true, false); - buffer = new FR_FCFS(controllerCore, true, false); - } - else - { - batch = new FR_FCFS(controllerCore, true, false); - buffer = new FR_FCFS(controllerCore, true, false); - } -} +//PAR_BS::PAR_BS(ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize) : +// controllerCore(controllerCore), useExternalBankstates(useExternalBankstates), capsize(capsize) +//{ +// if (useExternalBankstates) +// { +// batch = new FR_FCFS(controllerCore, true, false); +// buffer = new FR_FCFS(controllerCore, true, false); +// } +// else +// { +// batch = new FR_FCFS(controllerCore, true, false); +// buffer = new FR_FCFS(controllerCore, true, false); +// } +//} -PAR_BS::~PAR_BS() -{ +//PAR_BS::~PAR_BS() +//{ -} +//} -bool PAR_BS::hasPayloads() -{ - return batch->hasPayloads() || buffer->hasPayloads(); -} +//bool PAR_BS::hasPayloads() +//{ +// return batch->hasPayloads() || buffer->hasPayloads(); +//} -void PAR_BS::schedule(gp* payload) -{ - printDebugMessage("hello!"); - buffer->schedule(payload); -} +//void PAR_BS::schedule(gp* payload) +//{ +// printDebugMessage("hello!"); +// buffer->schedule(payload); +//} -gp* PAR_BS::getNextPayload() -{ - if (!batch->hasPayloads()) - { - stringstream s; - s << "In batch: " << batch->getNumberOfQueuedPayloads() << "\t" << "in buffer: " << buffer->getNumberOfQueuedPayloads() << endl; - formBatch(); - s<< "Formed new batch" << endl; - s << "In batch: " << batch->getNumberOfQueuedPayloads() << "\t" << "in buffer: " << buffer->getNumberOfQueuedPayloads() << endl; - printDebugMessage(s.str()); - sc_assert(batch->hasPayloads()); - } +//gp* PAR_BS::getNextPayload() +//{ +// if (!batch->hasPayloads()) +// { +// stringstream s; +// s << "In batch: " << batch->getNumberOfQueuedPayloads() << "\t" << "in buffer: " << buffer->getNumberOfQueuedPayloads() << endl; +// formBatch(); +// s<< "Formed new batch" << endl; +// s << "In batch: " << batch->getNumberOfQueuedPayloads() << "\t" << "in buffer: " << buffer->getNumberOfQueuedPayloads() << endl; +// printDebugMessage(s.str()); +// sc_assert(batch->hasPayloads()); +// } - gp* result = batch->getNextPayload(); - if(result == NULL) - result = buffer->getNextPayload(); - return result; -} +// gp* result = batch->getNextPayload(); +// if(result == NULL) +// result = buffer->getNextPayload(); +// return result; +//} -void PAR_BS::removePayload(gp* payload) -{ - buffer->removePayload(payload); - batch->removePayload(payload); +//void PAR_BS::removePayload(gp* payload) +//{ +// buffer->removePayload(payload); +// batch->removePayload(payload); - if (!useExternalBankstates) - { - DramExtension& extension = DramExtension::getExtension(payload); - internalBankstates.openRowInRowBuffer(extension.getBank(), extension.getRow()); - } +// if (!useExternalBankstates) +// { +// DramExtension& extension = DramExtension::getExtension(payload); +// internalBankstates.openRowInRowBuffer(extension.getBank(), extension.getRow()); +// } -} +//} -void PAR_BS::formBatch() -{ - map loads; +//void PAR_BS::formBatch() +//{ +// map loads; - for (Bank bank : controllerCore.getBanks()) - { - for (unsigned int i = 0; i < capsize; i++) - { - gp* payload = buffer->popOldest(bank); - if(payload == NULL) - break; - loads[DramExtension::getExtension(payload).getThread()].addTransaction(payload); - } - } +// for (Bank bank : controllerCore.getBanks()) +// { +// for (unsigned int i = 0; i < capsize; i++) +// { +// gp* payload = buffer->popOldest(bank); +// if(payload == NULL) +// break; +// loads[DramExtension::getExtension(payload).getThread()].addTransaction(payload); +// } +// } - vector sortedLoads; - for (auto& threadLoadPair : loads) - { - sortedLoads.push_back(&threadLoadPair.second); - } +// vector sortedLoads; +// for (auto& threadLoadPair : loads) +// { +// sortedLoads.push_back(&threadLoadPair.second); +// } - sort(sortedLoads.begin(), sortedLoads.end(), LoadPointerComparer()); +// sort(sortedLoads.begin(), sortedLoads.end(), LoadPointerComparer()); - for (auto& load : sortedLoads) - { - batch->schedule(load->getTransactions()); - } +// for (auto& load : sortedLoads) +// { +// batch->schedule(load->getTransactions()); +// } -} +//} -} +//} diff --git a/dram/src/controller/scheduler/PARBS.h b/dram/src/controller/scheduler/PARBS.h index 3d472011..ff07f89c 100644 --- a/dram/src/controller/scheduler/PARBS.h +++ b/dram/src/controller/scheduler/PARBS.h @@ -1,40 +1,40 @@ -// * PARBS.h -// * -// * Created on: Apr 9, 2014 -// * Author: robert -// * +//// * PARBS.h +//// * +//// * Created on: Apr 9, 2014 +//// * Author: robert +//// * -#ifndef PARBS_H_ -#define PARBS_H_ -#include "Scheduler.h" -#include "../core/ControllerCore.h" -#include "Fr_Fcfs.h" +//#ifndef PARBS_H_ +//#define PARBS_H_ +//#include "Scheduler.h" +//#include "../core/ControllerCore.h" +//#include "Fr_Fcfs.h" -namespace scheduler { +//namespace scheduler { -class PAR_BS : public Scheduler -{ -public: - PAR_BS(core::ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize); - virtual ~PAR_BS(); +//class PAR_BS : public Scheduler +//{ +//public: +// PAR_BS(ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize); +// virtual ~PAR_BS(); - virtual bool hasPayloads() override; - virtual void schedule(gp* payload) override; - virtual gp* getNextPayload() override; - virtual void removePayload(gp* payload) override; +// virtual bool hasPayloads() override; +// virtual void schedule(gp* payload) override; +// virtual gp* getNextPayload() override; +// virtual void removePayload(gp* payload) override; -private: - void formBatch(); +//private: +// void formBatch(); - core::ControllerCore& controllerCore; - bool useExternalBankstates; - core::RowBufferState internalBankstates; - FR_FCFS *batch; - FR_FCFS *buffer; - unsigned int capsize; -}; +// ControllerCore& controllerCore; +// bool useExternalBankstates; +// RowBufferState internalBankstates; +// FR_FCFS *batch; +// FR_FCFS *buffer; +// unsigned int capsize; +//}; -} /* scheduler core */ +//} /* scheduler core */ -#endif +//#endif diff --git a/dram/src/controller/scheduler/Scheduler.cpp b/dram/src/controller/scheduler/Scheduler.cpp deleted file mode 100644 index a872e821..00000000 --- a/dram/src/controller/scheduler/Scheduler.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "Scheduler.h" -#include "../../common/DebugManager.h" -#include - - -using namespace std; -using namespace scheduler; - -std::string Scheduler::sendername = "scheduler"; - -void Scheduler::printDebugMessage(std::string message) -{ - //cout << "scheduler: " << message << std::endl; - DebugManager::getInstance().printDebugMessage(Scheduler::sendername, message); -} - diff --git a/dram/src/controller/scheduler/Scheduler.h b/dram/src/controller/scheduler/Scheduler.h deleted file mode 100644 index c117f760..00000000 --- a/dram/src/controller/scheduler/Scheduler.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SCHEDULER_H -#define SCHEDULER_H -#include -#include "../../common/dramExtension.h" - -namespace scheduler { - -typedef tlm::tlm_generic_payload gp; - -class Scheduler -{ -public: - virtual ~Scheduler(){} - virtual void schedule(gp* payload) = 0; - virtual bool hasPayloads() = 0; - virtual gp* getNextPayload() = 0; - virtual void removePayload(gp* payload) = 0; - static std::string sendername; - -protected: - void printDebugMessage(std::string message); -}; - -} - - - -#endif // SCHEDULER_H diff --git a/dram/src/controller/scheduler/ThreadLoad.cpp b/dram/src/controller/scheduler/ThreadLoad.cpp index fd551103..71d21259 100644 --- a/dram/src/controller/scheduler/ThreadLoad.cpp +++ b/dram/src/controller/scheduler/ThreadLoad.cpp @@ -1,71 +1,71 @@ -/* - * ThreadLoad.cpp - * - * Created on: Apr 9, 2014 - * Author: robert - */ -#include "ThreadLoad.h" +// * ThreadLoad.cpp +// * +// * Created on: Apr 9, 2014 +// * Author: robert +// */ -namespace scheduler { +//#include "ThreadLoad.h" -using namespace std; +//namespace scheduler { -ThreadLoad::ThreadLoad() -{ - // TODO Auto-generated constructor stub +//using namespace std; -} +//ThreadLoad::ThreadLoad() +//{ +// // TODO Auto-generated constructor stub -ThreadLoad::~ThreadLoad() -{ - // TODO Auto-generated destructor stub -} +//} -unsigned int ThreadLoad::getMaxBankLoad() const -{ - unsigned int maxLoad = 0; - for (auto& bankVectorPair : load) - { - if (bankVectorPair.second.size() > maxLoad) - maxLoad = bankVectorPair.second.size(); - } - return maxLoad; -} +//ThreadLoad::~ThreadLoad() +//{ +// // TODO Auto-generated destructor stub +//} -unsigned int ThreadLoad::getTotalLoad() const -{ - unsigned int totalLoad = 0; - for (auto& bankVectorPair : load) - { - totalLoad += bankVectorPair.second.size(); - } - return totalLoad; -} +//unsigned int ThreadLoad::getMaxBankLoad() const +//{ +// unsigned int maxLoad = 0; +// for (auto& bankVectorPair : load) +// { +// if (bankVectorPair.second.size() > maxLoad) +// maxLoad = bankVectorPair.second.size(); +// } +// return maxLoad; +//} -void ThreadLoad::addTransaction(gp* payload) -{ - load[DramExtension::getExtension(payload).getBank()].push_back(payload); -} +//unsigned int ThreadLoad::getTotalLoad() const +//{ +// unsigned int totalLoad = 0; +// for (auto& bankVectorPair : load) +// { +// totalLoad += bankVectorPair.second.size(); +// } +// return totalLoad; +//} -bool operator<(const ThreadLoad& lhs, const ThreadLoad& rhs) -{ - if (lhs.getMaxBankLoad() < rhs.getMaxBankLoad()) - return true; - else if (lhs.getMaxBankLoad() == rhs.getMaxBankLoad()) - return lhs.getTotalLoad() < rhs.getTotalLoad(); - else - return false; -} +//void ThreadLoad::addTransaction(gp* payload) +//{ +// load[DramExtension::getExtension(payload).getBank()].push_back(payload); +//} -vector ThreadLoad::getTransactions() -{ - vector result; - for (auto& bankVectorPair : load) - { - result.insert(result.end(), bankVectorPair.second.begin(), bankVectorPair.second.end()); - } - return result; -} +//bool operator<(const ThreadLoad& lhs, const ThreadLoad& rhs) +//{ +// if (lhs.getMaxBankLoad() < rhs.getMaxBankLoad()) +// return true; +// else if (lhs.getMaxBankLoad() == rhs.getMaxBankLoad()) +// return lhs.getTotalLoad() < rhs.getTotalLoad(); +// else +// return false; +//} -} /* namespace scheduler */ +//vector ThreadLoad::getTransactions() +//{ +// vector result; +// for (auto& bankVectorPair : load) +// { +// result.insert(result.end(), bankVectorPair.second.begin(), bankVectorPair.second.end()); +// } +// return result; +//} + +//} /* namespace scheduler diff --git a/dram/src/controller/scheduler/ThreadLoad.h b/dram/src/controller/scheduler/ThreadLoad.h index b26e62e3..d1c240f6 100644 --- a/dram/src/controller/scheduler/ThreadLoad.h +++ b/dram/src/controller/scheduler/ThreadLoad.h @@ -1,44 +1,44 @@ -/* - * ThreadLoad.h - * - * Created on: Apr 9, 2014 - * Author: robert - */ -#ifndef THREADLOAD_H_ -#define THREADLOAD_H_ -#include -#include -#include "../../common/dramExtension.h" +//// * ThreadLoad.h +//// * +//// * Created on: Apr 9, 2014 +//// * Author: robert +//// */ -namespace scheduler { +//#ifndef THREADLOAD_H_ +//#define THREADLOAD_H_ +//#include +//#include +//#include "../../common/dramExtension.h" -typedef tlm::tlm_generic_payload gp; +//namespace scheduler { -class ThreadLoad -{ -public: - ThreadLoad(); - virtual ~ThreadLoad(); +//typedef tlm::tlm_generic_payload gp; - unsigned int getMaxBankLoad() const; - unsigned int getTotalLoad() const; +//class ThreadLoad +//{ +//public: +// ThreadLoad();d +// virtual ~ThreadLoad(); - void addTransaction(gp* payload); - std::vector getTransactions(); +// unsigned int getMaxBankLoad() const; +// unsigned int getTotalLoad() const; -private: - std::map> load; -}; +// void addTransaction(gp* payload); +// std::vector getTransactions(); -bool operator< (const ThreadLoad &lhs, const ThreadLoad &rhs); +//private: +// std::map> load; +//}; -struct LoadPointerComparer { - bool operator()(const ThreadLoad* l, const ThreadLoad* r) { - return *l < *r; - } -}; +//bool operator< (const ThreadLoad &lhs, const ThreadLoad &rhs); -} /* namespace scheduler */ +//struct LoadPointerComparer { +// bool operator()(const ThreadLoad* l, const ThreadLoad* r) { +// return *l < *r; +// } +//}; -#endif /* THREADLOAD_H_ */ +//} /* namespace scheduler */ + +//#endif /* THREADLOAD_H_ diff --git a/dram/src/controller/scheduler/readwritegrouper.cpp b/dram/src/controller/scheduler/readwritegrouper.cpp index c96dd0e3..7cf43609 100644 --- a/dram/src/controller/scheduler/readwritegrouper.cpp +++ b/dram/src/controller/scheduler/readwritegrouper.cpp @@ -1,154 +1,154 @@ -#include "readwritegrouper.h" -#include "../../common/DebugManager.h" +//#include "readwritegrouper.h" +//#include "../../common/DebugManager.h" -namespace scheduler{ +//namespace scheduler{ -using namespace tlm; -using namespace std; +//using namespace tlm; +//using namespace std; -ReadWriteGrouper::ReadWriteGrouper(core::ControllerCore& controllerCore): controllerCore(controllerCore) -{ - batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); - batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); -} +//ReadWriteGrouper::ReadWriteGrouper(ControllerCore& controllerCore): controllerCore(controllerCore) +//{ +// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); +// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); +//} -ReadWriteGrouper::~ReadWriteGrouper() -{ +//ReadWriteGrouper::~ReadWriteGrouper() +//{ -} +//} -void ReadWriteGrouper::schedule(gp *payload) -{ - tlm_command command = payload->get_command(); +//void ReadWriteGrouper::schedule(gp *payload) +//{ +// tlm_command command = payload->get_command(); - if(batches.size() > 2) - { - if(command == TLM_READ_COMMAND) - { - //printDebugMessage("Scheduling read"); +// if(batches.size() > 2) +// { +// if(command == TLM_READ_COMMAND) +// { +// //printDebugMessage("Scheduling read"); - if(schedulingReadCausesHazardWithQueuedWrite(payload)) - { - printDebugMessage("Scheduling read causes hazard with queued write"); - batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); - batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); - } +// if(schedulingReadCausesHazardWithQueuedWrite(payload)) +// { +// printDebugMessage("Scheduling read causes hazard with queued write"); +// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); +// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); +// } - getLatestReadBatch().schedule(payload); - } - else if(command == TLM_WRITE_COMMAND) - { - //printDebugMessage("Scheduling write"); - getLatestWriteBatch().schedule(payload); - } - } - else if(batches.size() == 2) - { - if(command == TLM_READ_COMMAND) - { - //printDebugMessage("Scheduling read"); +// getLatestReadBatch().schedule(payload); +// } +// else if(command == TLM_WRITE_COMMAND) +// { +// //printDebugMessage("Scheduling write"); +// getLatestWriteBatch().schedule(payload); +// } +// } +// else if(batches.size() == 2) +// { +// if(command == TLM_READ_COMMAND) +// { +// //printDebugMessage("Scheduling read"); - if(getLatestReadBatch().hasPayloads() && schedulingReadCausesHazardWithQueuedWrite(payload)) - { - printDebugMessage("Scheduling read causes hazard with queued write"); - batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); - batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); - } - else if(!getLatestReadBatch().hasPayloads() && getLatestWriteBatch().hasPayloads()) - { - printDebugMessage("Scheduling read, but there are writes to be processed first"); - batches.erase(batches.begin()); - batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); - batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); - } - getLatestReadBatch().schedule(payload); +// if(getLatestReadBatch().hasPayloads() && schedulingReadCausesHazardWithQueuedWrite(payload)) +// { +// printDebugMessage("Scheduling read causes hazard with queued write"); +// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); +// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); +// } +// else if(!getLatestReadBatch().hasPayloads() && getLatestWriteBatch().hasPayloads()) +// { +// printDebugMessage("Scheduling read, but there are writes to be processed first"); +// batches.erase(batches.begin()); +// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); +// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); +// } +// getLatestReadBatch().schedule(payload); - } - else if(command == TLM_WRITE_COMMAND) - { - //printDebugMessage("Scheduling write"); - getLatestWriteBatch().schedule(payload); - } - } - else - { - sc_assert(false); - } -} +// } +// else if(command == TLM_WRITE_COMMAND) +// { +// //printDebugMessage("Scheduling write"); +// getLatestWriteBatch().schedule(payload); +// } +// } +// else +// { +// sc_assert(false); +// } +//} -gp *ReadWriteGrouper::getNextPayload() -{ - if(batches.size() > 2) - { - return batches.front()->getNextPayload(); - } - else if(batches.size() == 2) - { - if(getLatestReadBatch().hasPayloads()) - return getLatestReadBatch().getNextPayload(); - else if(getLatestWriteBatch().hasPayloads()) - return getLatestWriteBatch().getNextPayload(); - else - return NULL; - } - else - { - sc_assert(false); - return NULL; - } -} +//gp *ReadWriteGrouper::getNextPayload() +//{ +// if(batches.size() > 2) +// { +// return batches.front()->getNextPayload(); +// } +// else if(batches.size() == 2) +// { +// if(getLatestReadBatch().hasPayloads()) +// return getLatestReadBatch().getNextPayload(); +// else if(getLatestWriteBatch().hasPayloads()) +// return getLatestWriteBatch().getNextPayload(); +// else +// return NULL; +// } +// else +// { +// sc_assert(false); +// return NULL; +// } +//} -void ReadWriteGrouper::removePayload(gp *payload) -{ - if(batches.size() > 2) - { - batches.front()->removePayload(payload); - if(!batches.front()->hasPayloads()) - batches.erase(batches.begin()); - } - else if(batches.size() == 2) - { - if(payload->is_read()) - getLatestReadBatch().removePayload(payload); - else - getLatestWriteBatch().removePayload(payload); - } - else - { - sc_assert(false); - } -} +//void ReadWriteGrouper::removePayload(gp *payload) +//{ +// if(batches.size() > 2) +// { +// batches.front()->removePayload(payload); +// if(!batches.front()->hasPayloads()) +// batches.erase(batches.begin()); +// } +// else if(batches.size() == 2) +// { +// if(payload->is_read()) +// getLatestReadBatch().removePayload(payload); +// else +// getLatestWriteBatch().removePayload(payload); +// } +// else +// { +// sc_assert(false); +// } +//} -bool ReadWriteGrouper::hasPayloads() -{ - if(batches.size() > 2) - return true; - else if(batches.size() == 2) - return (getLatestReadBatch().hasPayloads() || getLatestWriteBatch().hasPayloads()); - else - { - sc_assert(false); - return NULL; - } -} +//bool ReadWriteGrouper::hasPayloads() +//{ +// if(batches.size() > 2) +// return true; +// else if(batches.size() == 2) +// return (getLatestReadBatch().hasPayloads() || getLatestWriteBatch().hasPayloads()); +// else +// { +// sc_assert(false); +// return NULL; +// } +//} -bool ReadWriteGrouper::schedulingReadCausesHazardWithQueuedWrite(gp *payload) -{ - sc_assert(payload->is_read()); - return getLatestWriteBatch().containsPayloadTragetingSameAddress(payload); -} +//bool ReadWriteGrouper::schedulingReadCausesHazardWithQueuedWrite(gp *payload) +//{ +// sc_assert(payload->is_read()); +// return getLatestWriteBatch().containsPayloadTragetingSameAddress(payload); +//} -FR_FCFS &ReadWriteGrouper::getLatestWriteBatch() -{ - return *batches[batches.size()-1]; -} +//FR_FCFS &ReadWriteGrouper::getLatestWriteBatch() +//{ +// return *batches[batches.size()-1]; +//} -FR_FCFS &ReadWriteGrouper::getLatestReadBatch() -{ - return *batches[batches.size()-2]; -} +//FR_FCFS &ReadWriteGrouper::getLatestReadBatch() +//{ +// return *batches[batches.size()-2]; +//} -} +//} diff --git a/dram/src/controller/scheduler/readwritegrouper.h b/dram/src/controller/scheduler/readwritegrouper.h index dedd0c5d..a82e510d 100644 --- a/dram/src/controller/scheduler/readwritegrouper.h +++ b/dram/src/controller/scheduler/readwritegrouper.h @@ -1,41 +1,41 @@ -#ifndef READWRITEGROUPER_H -#define READWRITEGROUPER_H -#include "Scheduler.h" -#include "Fr_Fcfs.h" -#include "../core/ControllerCore.h" -#include -#include +//#ifndef READWRITEGROUPER_H +//#define READWRITEGROUPER_H +//#include "Scheduler.h" +//#include "Fr_Fcfs.h" +//#include "../core/ControllerCore.h" +//#include +//#include -namespace scheduler{ +//namespace scheduler{ -class ReadWriteGrouper : public Scheduler -{ -public: - ReadWriteGrouper(core::ControllerCore& controllerCore); - ~ReadWriteGrouper(); - virtual void schedule(gp* payload) override; - virtual bool hasPayloads() override; - virtual gp* getNextPayload() override; - virtual void removePayload(gp* payload) override; +//class ReadWriteGrouper : public Scheduler +//{ +//public: +// ReadWriteGrouper(ControllerCore& controllerCore); +// ~ReadWriteGrouper(); +// virtual void schedule(gp* payload) override; +// virtual bool hasPayloads() override; +// virtual gp* getNextPayload() override; +// virtual void removePayload(gp* payload) override; -private: - // contains batches of requests - // last element always contains writes - // next-to-last element always contains reads - // there are always at least two batches - // if there are more than two batches, batches[0] is never empty and - // getNextPayload and removePayload are forwarded to batches[0] - std::vector> batches; - core::ControllerCore& controllerCore; +//private: +// // contains batches of requests +// // last element always contains writes +// // next-to-last element always contains reads +// // there are always at least two batches +// // if there are more than two batches, batches[0] is never empty and +// // getNextPayload and removePayload are forwarded to batches[0] +// std::vector> batches; +// ControllerCore& controllerCore; - bool schedulingReadCausesHazardWithQueuedWrite(gp* payload); - FR_FCFS& getLatestWriteBatch(); - FR_FCFS& getLatestReadBatch(); +// bool schedulingReadCausesHazardWithQueuedWrite(gp* payload); +// FR_FCFS& getLatestWriteBatch(); +// FR_FCFS& getLatestReadBatch(); -}; +//}; -} +//} -#endif // READWRITEGROUPER_H +//#endif // READWRITEGROUPER_H diff --git a/dram/src/simulation/Dram.h b/dram/src/simulation/Dram.h index 2b80a7ec..87b9cc13 100644 --- a/dram/src/simulation/Dram.h +++ b/dram/src/simulation/Dram.h @@ -26,11 +26,12 @@ using namespace std; using namespace tlm; -using namespace core; +; using namespace Data; -#define POWER //not better to define in simulation xml? also flag for storage simulation +//#define POWER +//not better to define in simulation xml? also flag for storage simulation //configuration->PowerAnalysys //configuration->ModelStorage //configuration->ModelErrotInjection diff --git a/dram/src/simulation/MemoryManager.cpp b/dram/src/simulation/MemoryManager.cpp index 1abc1b24..60461f46 100644 --- a/dram/src/simulation/MemoryManager.cpp +++ b/dram/src/simulation/MemoryManager.cpp @@ -23,8 +23,10 @@ MemoryManager::~MemoryManager() delete payload; numberOfFrees++; } - DebugManager::getInstance().printDebugMessage("MemomryManager","Number of allocated payloads: " + to_string(numberOfAllocations)); - DebugManager::getInstance().printDebugMessage("MemomryManager","Number of freed payloads: " + to_string(numberOfFrees)); + + //Comment in if you are suspecting a memory leak in the manager + //DebugManager::getInstance().printDebugMessage("MemoryManager","Number of allocated payloads: " + to_string(numberOfAllocations)); + //DebugManager::getInstance().printDebugMessage("MemoryManager","Number of freed payloads: " + to_string(numberOfFrees)); } gp* MemoryManager::allocate() diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index dce93447..d04cd5ba 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -44,18 +44,6 @@ Simulation::Simulation(sc_module_name /*name*/, string pathToResources, string t void Simulation::setupDebugManager(const string& traceName) { auto& dbg = DebugManager::getInstance(); - dbg.addToWhiteList(controller->name()); - dbg.addToWhiteList(player1->name()); - dbg.addToWhiteList(player2->name()); - dbg.addToWhiteList(player3->name()); - dbg.addToWhiteList(player4->name()); - - dbg.addToWhiteList(this->name()); - dbg.addToWhiteList(Scheduler::sendername); - dbg.addToWhiteList(TlmRecorder::senderName); - dbg.addToWhiteList(ControllerCore::senderName); - dbg.addToWhiteList(PowerDownManagerBankwise::senderName); - dbg.writeToConsole = true; dbg.writeToFile = true; if(dbg.writeToFile) @@ -77,7 +65,6 @@ void Simulation::setupTlmRecorder(const string &traceName, const string &pathToR { TlmRecorder::recordingEnabled = false; } - } void Simulation::instantiateModules(const string &pathToResources, const std::vector& devices) @@ -85,10 +72,8 @@ void Simulation::instantiateModules(const string &pathToResources, const std::ve dram = new Dram<>("dram"); arbiter = new Arbiter("arbiter"); controller = new Controller<>("controller"); - //reorder = new ReorderBuffer<>("reorder"); player1 = new StlPlayer<>("player1", pathToResources + string("traces/") + devices[0].trace, devices[0].clkMhz, this); - //player1 = new TraceGenerator<>("player1", 0, this); player2 = new StlPlayer<>("player2", pathToResources + string("traces/") + devices[1].trace, devices[1].clkMhz, this); player3 = new StlPlayer<>("player3", pathToResources + string("traces/") + devices[2].trace, devices[2].clkMhz, this); player4 = new StlPlayer<>("player4", pathToResources + string("traces/") + devices[3].trace, devices[3].clkMhz, this); @@ -97,9 +82,6 @@ void Simulation::instantiateModules(const string &pathToResources, const std::ve void Simulation::bindSockets() { player1->iSocket.bind(arbiter->tSockets[0]); - //player1->iSocket.bind(reorder->tSocket); - //reorder->iSocket.bind(arbiter->tSockets[0]); - player2->iSocket.bind(arbiter->tSockets[1]); player3->iSocket.bind(arbiter->tSockets[2]); player4->iSocket.bind(arbiter->tSockets[3]); diff --git a/dram/src/simulation/SimulationManager.cpp b/dram/src/simulation/SimulationManager.cpp index 33d63c44..045a5522 100644 --- a/dram/src/simulation/SimulationManager.cpp +++ b/dram/src/simulation/SimulationManager.cpp @@ -27,9 +27,6 @@ void SimulationManager::loadSimulationsFromXML(string uri) cout << headline << endl; exportPath = getFileName(uri); - - //basePath = boost::filesystem::path(uri).parent_path(); - loadXML(uri, simulationdoc); cout << "\t-> parsing simulation objects .." << endl; @@ -52,7 +49,7 @@ void SimulationManager::runSimulations() { for (auto& batch : simulationBatches) { - boost::filesystem::path dir(exportPath);// + "/" + batch.simulationName); + boost::filesystem::path dir(exportPath); boost::filesystem::create_directories(dir); for (auto& dramSetup : batch.dramSetups) @@ -81,8 +78,6 @@ void SimulationManager::parseSimulationBatch(XMLElement* simulation) XMLElement* memconfigs = simulation->FirstChildElement("memconfigs"); if(memconfigs == NULL) memconfigs = simulation; - - for (XMLElement* memspec = memspecs->FirstChildElement("memspec"); memspec != NULL; memspec = memspec->NextSiblingElement("memspec")) { @@ -131,11 +126,6 @@ void SimulationManager::startTraceAnalyzer() { string p = getenv("trace"); string run_tpr = p + " -f "; - for (auto batch : simulationBatches) - { - // run_tpr += exportPath + "/" + batch.simulationName + " "; - - } run_tpr += "&"; system(run_tpr.c_str()); } @@ -157,8 +147,6 @@ void SimulationManager::addTraceSetup(SimulationBatch& batch, tinyxml2::XMLEleme void SimulationManager::report(string message) { - //DebugManager::getInstance().printDebugMessage("Simulation Manager", message); - //if (DebugManager::getInstance().writeToConsole == false) cout << message << endl; } diff --git a/dram/src/simulation/StlPlayer.h b/dram/src/simulation/StlPlayer.h index 884756c2..46aecb33 100644 --- a/dram/src/simulation/StlPlayer.h +++ b/dram/src/simulation/StlPlayer.h @@ -104,11 +104,11 @@ StlPlayer::StlPlayer(sc_module_name /*name*/, string pathToTrace, unsi SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); if(clkMhz == 0) - clk = core::Configuration::getInstance().memSpec.clk; + clk = Configuration::getInstance().memSpec.clk; else - clk = core::FrequencyToClk(clkMhz); + clk = FrequencyToClk(clkMhz); - this->burstlenght = core::Configuration::getInstance().memSpec.BurstLength; + this->burstlenght = Configuration::getInstance().memSpec.BurstLength; } #endif // STLPLAYER_H diff --git a/dram/src/simulation/TraceGenerator.h b/dram/src/simulation/TraceGenerator.h index 7aaac7b4..e4c5126e 100644 --- a/dram/src/simulation/TraceGenerator.h +++ b/dram/src/simulation/TraceGenerator.h @@ -51,11 +51,11 @@ TraceGenerator::TraceGenerator(sc_module_name /*name*/, unsigned int c TracePlayer(listener), transCounter(0) { if(clkMhz == 0) - clk = core::Configuration::getInstance().memSpec.clk; + clk = Configuration::getInstance().memSpec.clk; else - clk = core::FrequencyToClk(clkMhz); + clk = FrequencyToClk(clkMhz); - this->burstlenght = core::Configuration::getInstance().memSpec.BurstLength; + this->burstlenght = Configuration::getInstance().memSpec.BurstLength; } #endif