Merge branch 'DRAMSys4.0_dev' into 'master'
Specific DRAMs and MemSpecs, renamed schedulers. See merge request ems/astdm/dram.sys!236
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,3 +21,4 @@ DRAMSys/analyzer/scripts/__pycache__/
|
||||
*.autosave
|
||||
*__pycache__*
|
||||
DRAMSys/gem5/boot_linux/linux-aarch32-ael.img
|
||||
DRAMSys/docs/doxygen
|
||||
|
||||
1228
DRAMSys/docs/doxyCfg.cfg
Normal file
1228
DRAMSys/docs/doxyCfg.cfg
Normal file
File diff suppressed because it is too large
Load Diff
@@ -86,18 +86,13 @@ QMAKE_CXXFLAGS += -isystem $${systemc_home}/include
|
||||
|
||||
SOURCES += \
|
||||
src/common/third_party/tinyxml2/tinyxml2.cpp \
|
||||
src/common/xmlAddressdecoder.cpp \
|
||||
src/common/Utils.cpp \
|
||||
src/common/TlmRecorder.cpp \
|
||||
src/common/dramExtension.cpp \
|
||||
src/common/DebugManager.cpp \
|
||||
src/controller/core/configuration/Configuration.cpp \
|
||||
src/controller/core/powerdown/PowerDownManagerTimeout.cpp \
|
||||
src/controller/core/powerdown/PowerDownManagerBankwise.cpp \
|
||||
src/controller/core/powerdown/PowerDownManager.cpp \
|
||||
src/controller/scheduler/ThreadLoad.cpp \
|
||||
src/controller/scheduler/PARBS.cpp \
|
||||
src/controller/scheduler/Fr_Fcfs.cpp \
|
||||
src/controller/scheduler/FrFcfs.cpp \
|
||||
src/controller/scheduler/Fifo.cpp \
|
||||
src/controller/scheduler/SMS.cpp \
|
||||
src/controller/core/refresh/RefreshManagerBankwise.cpp \
|
||||
@@ -113,12 +108,10 @@ SOURCES += \
|
||||
src/controller/core/scheduling/checker/PreBChecker.cpp \
|
||||
src/controller/core/scheduling/checker/ActBChecker.cpp \
|
||||
src/controller/core/scheduling/ScheduledCommand.cpp \
|
||||
src/controller/core/TimingCalculation.cpp \
|
||||
src/controller/core/Slots.cpp \
|
||||
src/controller/core/ControllerCore.cpp \
|
||||
src/simulation/MemoryManager.cpp \
|
||||
src/simulation/TemperatureController.cpp \
|
||||
src/controller/scheduler/readwritegrouper.cpp \
|
||||
src/controller/core/configuration/ConfigurationLoader.cpp \
|
||||
src/controller/core/powerdown/NoPowerDown.cpp \
|
||||
src/controller/Command.cpp \
|
||||
@@ -138,29 +131,35 @@ SOURCES += \
|
||||
src/error/ECC/Word.cpp \
|
||||
src/error/eccbaseclass.cpp \
|
||||
src/error/ecchamming.cpp \
|
||||
src/controller/scheduler/Fr_Fcfs_read_priority.cpp \
|
||||
src/controller/scheduler/Fr_Fcfs_grouper.cpp \
|
||||
src/controller/scheduler/FrFcfsRp.cpp \
|
||||
src/controller/scheduler/FrFcfsGrp.cpp \
|
||||
src/controller/scheduler/Grp.cpp \
|
||||
src/controller/RecordableController.cpp \
|
||||
src/common/AddressDecoder.cpp \
|
||||
src/controller/scheduler/grp.cpp \
|
||||
src/common/congenAddressDecoder.cpp
|
||||
src/simulation/Dram.cpp \
|
||||
src/simulation/RecordableDram.cpp \
|
||||
src/simulation/Arbiter.cpp \
|
||||
src/common/CongenAddressDecoder.cpp \
|
||||
src/common/XmlAddressDecoder.cpp \
|
||||
src/controller/core/timingCalculations.cpp \
|
||||
src/common/dramExtensions.cpp \
|
||||
src/common/utils.cpp \
|
||||
src/simulation/DramDDR3.cpp \
|
||||
src/simulation/DramDDR4.cpp \
|
||||
src/simulation/DramRecordable.cpp \
|
||||
src/simulation/DramWideIO.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/common/third_party/tinyxml2/tinyxml2.h \
|
||||
src/common/xmlAddressdecoder.h \
|
||||
src/common/Utils.h \
|
||||
src/common/TlmRecorder.h \
|
||||
src/common/tlm2_base_protocol_checker.h \
|
||||
src/common/protocol.h \
|
||||
src/common/dramExtension.h \
|
||||
src/common/DebugManager.h \
|
||||
src/controller/core/configuration/Configuration.h \
|
||||
src/controller/core/powerdown/PowerDownManagerTimeout.h \
|
||||
src/controller/core/powerdown/PowerDownManagerBankwise.h \
|
||||
src/controller/core/powerdown/PowerDownManager.h \
|
||||
src/controller/scheduler/ThreadLoad.h \
|
||||
src/controller/scheduler/PARBS.h \
|
||||
src/controller/scheduler/Fr_Fcfs.h \
|
||||
src/controller/scheduler/FrFcfs.h \
|
||||
src/controller/scheduler/Fifo.h \
|
||||
src/controller/scheduler/SMS.h \
|
||||
src/controller/Controller.h \
|
||||
@@ -178,9 +177,7 @@ HEADERS += \
|
||||
src/controller/core/scheduling/checker/ActivateChecker.h \
|
||||
src/controller/core/scheduling/checker/PreBChecker.h \
|
||||
src/controller/core/scheduling/checker/ActBChecker.h \
|
||||
src/controller/core/scheduling/Trigger.h \
|
||||
src/controller/core/scheduling/ScheduledCommand.h \
|
||||
src/controller/core/TimingCalculation.h \
|
||||
src/controller/core/Slots.h \
|
||||
src/controller/core/ControllerCore.h \
|
||||
src/simulation/TracePlayer.h \
|
||||
@@ -188,10 +185,8 @@ HEADERS += \
|
||||
src/simulation/Dram.h \
|
||||
src/simulation/Arbiter.h \
|
||||
src/common/libDRAMPower.h \
|
||||
src/controller/scheduler/readwritegrouper.h \
|
||||
src/simulation/ReorderBuffer.h \
|
||||
src/controller/core/configuration/MemSpec.h \
|
||||
src/controller/core/configuration/thermalSimConfig.h \
|
||||
src/simulation/StlPlayer.h \
|
||||
src/simulation/TracePlayerListener.h \
|
||||
src/simulation/TraceGenerator.h \
|
||||
@@ -216,15 +211,24 @@ HEADERS += \
|
||||
src/error/ECC/Word.h \
|
||||
src/error/eccbaseclass.h \
|
||||
src/error/ecchamming.h \
|
||||
src/controller/scheduler/Fr_Fcfs_read_priority.h \
|
||||
src/controller/scheduler/Fr_Fcfs_grouper.h \
|
||||
src/controller/scheduler/FrFcfsRp.h \
|
||||
src/controller/scheduler/FrFcfsGrp.h \
|
||||
src/controller/scheduler/Grp.h \
|
||||
src/simulation/IArbiter.h \
|
||||
src/simulation/SimpleArbiter.h \
|
||||
src/controller/RecordableController.h \
|
||||
src/simulation/RecordableDram.h \
|
||||
src/common/AddressDecoder.h \
|
||||
src/controller/scheduler/grp.h \
|
||||
src/common/congenAddressDecoder.h
|
||||
src/common/CongenAddressDecoder.h \
|
||||
src/common/XmlAddressDecoder.h \
|
||||
src/controller/core/timingCalculations.h \
|
||||
src/common/dramExtensions.h \
|
||||
src/common/utils.h \
|
||||
src/controller/core/configuration/TemperatureSimConfig.h \
|
||||
src/simulation/DramDDR3.h \
|
||||
src/simulation/DramDDR4.h \
|
||||
src/simulation/DramRecordable.h \
|
||||
src/simulation/DramWideIO.h
|
||||
#src/common/third_party/json/include/nlohmann/json.hpp \
|
||||
|
||||
thermalsim = $$(THERMALSIM)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<Scheduler value="FIFO" />
|
||||
<Scheduler value="Fifo" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<Scheduler value="FIFO_STRICT" />
|
||||
<Scheduler value="FifoStrict" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<Scheduler value="FIFO" />
|
||||
<Scheduler value="Fifo" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<Scheduler value="FR_FCFS" />
|
||||
<Scheduler value="FrFcfs" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<Scheduler value="FR_FCFS_GRP" />
|
||||
<Scheduler value="FrFcfsGrp" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<Scheduler value="FR_FCFS_RP" />
|
||||
<Scheduler value="FrFcfsRp" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="32" />
|
||||
<Scheduler value="GRP" />
|
||||
<Scheduler value="Grp" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<mcconfig>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="16" />
|
||||
<Scheduler value="FR_FCFS" />
|
||||
<Scheduler value="FrFcfs" />
|
||||
<Capsize value="5" />
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
*/
|
||||
|
||||
#include "AddressDecoder.h"
|
||||
#include "xmlAddressdecoder.h"
|
||||
#include "congenAddressDecoder.h"
|
||||
#include "XmlAddressDecoder.h"
|
||||
#include "CongenAddressDecoder.h"
|
||||
|
||||
AddressDecoder *AddressDecoder::m_pInstance = nullptr;
|
||||
|
||||
@@ -50,7 +50,7 @@ void AddressDecoder::createInstance(Type t)
|
||||
assert(m_pInstance == nullptr);
|
||||
switch (t) {
|
||||
case Type::XML:
|
||||
m_pInstance = new xmlAddressDecoder;
|
||||
m_pInstance = new XmlAddressDecoder;
|
||||
break;
|
||||
case Type::CONGEN:
|
||||
m_pInstance = new CongenAddressDecoder;
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
* Johannes Feldmann
|
||||
*/
|
||||
|
||||
#include "congenAddressDecoder.h"
|
||||
#include "Utils.h"
|
||||
#include "CongenAddressDecoder.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
@@ -47,8 +47,7 @@ using std::vector;
|
||||
using std::pair;
|
||||
using std::map;
|
||||
|
||||
class CongenAddressDecoder
|
||||
: private AddressDecoder
|
||||
class CongenAddressDecoder : private AddressDecoder
|
||||
{
|
||||
// Friendship needed so that the AddressDecoder can access the
|
||||
// constructor of this class to create the object in CreateInstance.
|
||||
@@ -34,13 +34,13 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef DEBUGMANAGER_H_
|
||||
#define DEBUGMANAGER_H_
|
||||
#ifndef DEBUGMANAGER_H
|
||||
#define DEBUGMANAGER_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "Utils.h"
|
||||
#include "utils.h"
|
||||
|
||||
class DebugManager
|
||||
{
|
||||
@@ -63,4 +63,4 @@ private:
|
||||
ofstream debugFile;
|
||||
};
|
||||
|
||||
#endif /* DEBUGMANAGER_H_ */
|
||||
#endif // DEBUGMANAGER_H
|
||||
|
||||
@@ -41,8 +41,8 @@
|
||||
|
||||
#include "TlmRecorder.h"
|
||||
#include "protocol.h"
|
||||
#include "dramExtension.h"
|
||||
#include "xmlAddressdecoder.h"
|
||||
#include "dramExtensions.h"
|
||||
#include "XmlAddressDecoder.h"
|
||||
#include "../controller/core/configuration/Configuration.h"
|
||||
#include "../controller/Controller.h"
|
||||
|
||||
@@ -323,9 +323,9 @@ void TlmRecorder::insertGeneralInfo()
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 2,
|
||||
simulationTimeCoveredByRecording.value());
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 3,
|
||||
Configuration::getInstance().memSpec.NumberOfBanks);
|
||||
Configuration::getInstance().memSpec->NumberOfBanks);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 4,
|
||||
Configuration::getInstance().memSpec.clk.value());
|
||||
Configuration::getInstance().memSpec->clk.value());
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 5, "PS", 2, NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 6, mcconfig.c_str(),
|
||||
mcconfig.length(), NULL);
|
||||
@@ -337,7 +337,7 @@ void TlmRecorder::insertGeneralInfo()
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 9, 0);
|
||||
else
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 9,
|
||||
(Configuration::getInstance().memSpec.clk *
|
||||
(Configuration::getInstance().memSpec->clk *
|
||||
Configuration::getInstance().WindowSize).value());
|
||||
if (Configuration::getInstance().ControllerCoreRefEnablePostpone
|
||||
|| Configuration::getInstance().ControllerCoreRefEnablePullIn) {
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
* Eder F. Zulian
|
||||
*/
|
||||
|
||||
#ifndef TLMPHASERECORDER_H
|
||||
#define TLMPHASERECORDER_H
|
||||
#ifndef TLMRECORDER_H
|
||||
#define TLMRECORDER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
@@ -49,9 +49,9 @@
|
||||
#include <cerrno>
|
||||
#include <tlm.h>
|
||||
#include <systemc.h>
|
||||
#include "xmlAddressdecoder.h"
|
||||
#include "XmlAddressDecoder.h"
|
||||
#include "DebugManager.h"
|
||||
#include "Utils.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -150,5 +150,5 @@ private:
|
||||
insertDebugMessageString, updateDataStrobeString, insertPowerString;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // TLMRECORDER_H
|
||||
|
||||
|
||||
@@ -35,21 +35,21 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#include "xmlAddressdecoder.h"
|
||||
#include "XmlAddressDecoder.h"
|
||||
#include <systemc.h>
|
||||
#include "Utils.h"
|
||||
#include "utils.h"
|
||||
#include "bitset"
|
||||
#include "../controller/core/configuration/Configuration.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace tinyxml2;
|
||||
|
||||
xmlAddressDecoder::xmlAddressDecoder()
|
||||
XmlAddressDecoder::XmlAddressDecoder()
|
||||
{
|
||||
addressmapping = NULL;
|
||||
}
|
||||
|
||||
void xmlAddressDecoder::setConfiguration(std::string addressConfigURI)
|
||||
void XmlAddressDecoder::setConfiguration(std::string addressConfigURI)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
loadXML(addressConfigURI, doc);
|
||||
@@ -76,7 +76,7 @@ void xmlAddressDecoder::setConfiguration(std::string addressConfigURI)
|
||||
}
|
||||
|
||||
|
||||
DecodedAddress xmlAddressDecoder::decodeAddress(sc_dt::uint64 addr)
|
||||
DecodedAddress XmlAddressDecoder::decodeAddress(sc_dt::uint64 addr)
|
||||
{
|
||||
DecodedAddress result;
|
||||
result.channel = (addr & masks["channel"]) >> shifts["channel"];
|
||||
@@ -84,15 +84,15 @@ DecodedAddress xmlAddressDecoder::decodeAddress(sc_dt::uint64 addr)
|
||||
//result.bankgroup = (addr & masks["bankgroup"]) >> shifts["bankgroup"];
|
||||
result.bank = (addr & masks["bank"]) >> shifts["bank"];
|
||||
result.bankgroup = result.bank %
|
||||
Configuration::getInstance().memSpec.NumberOfBankGroups;
|
||||
result.rank = result.bank % Configuration::getInstance().memSpec.NumberOfRanks;
|
||||
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"];
|
||||
return result;
|
||||
}
|
||||
|
||||
sc_dt::uint64 xmlAddressDecoder::encodeAddress(DecodedAddress n)
|
||||
sc_dt::uint64 XmlAddressDecoder::encodeAddress(DecodedAddress n)
|
||||
{
|
||||
return n.channel << shifts["channel"] |
|
||||
n.rank << shifts["rank"] |
|
||||
@@ -103,7 +103,7 @@ sc_dt::uint64 xmlAddressDecoder::encodeAddress(DecodedAddress n)
|
||||
n.bytes << shifts["bytes"];
|
||||
}
|
||||
|
||||
bool xmlAddressDecoder::testConfigFile(std::string url)
|
||||
bool XmlAddressDecoder::testConfigFile(std::string url)
|
||||
{
|
||||
// Simple test if the root node has the correct name.
|
||||
// This is suitable for now, but can be extended in future.
|
||||
@@ -115,7 +115,7 @@ bool xmlAddressDecoder::testConfigFile(std::string url)
|
||||
return (strcmp(addressMap->Name(), "addressmapping") == 0);
|
||||
}
|
||||
|
||||
void xmlAddressDecoder::print()
|
||||
void XmlAddressDecoder::print()
|
||||
{
|
||||
cout << headline << endl;
|
||||
cout << "Address Mapping:" << endl << endl;
|
||||
@@ -35,17 +35,16 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef _XMLADDRESSDECODER_H
|
||||
#define _XMLADDRESSDECODER_H
|
||||
#ifndef XMLADDRESSDECODER_H
|
||||
#define XMLADDRESSDECODER_H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "Utils.h"
|
||||
#include "utils.h"
|
||||
#include "third_party/tinyxml2/tinyxml2.h"
|
||||
#include "AddressDecoder.h"
|
||||
|
||||
class xmlAddressDecoder
|
||||
: private AddressDecoder
|
||||
class XmlAddressDecoder : private AddressDecoder
|
||||
{
|
||||
// Friendship needed so that the AddressDecoder can access the
|
||||
// constructor of this class to create the object in CreateInstance.
|
||||
@@ -58,7 +57,7 @@ private:
|
||||
tinyxml2::XMLElement *addressmapping;
|
||||
|
||||
public:
|
||||
xmlAddressDecoder();
|
||||
XmlAddressDecoder();
|
||||
|
||||
virtual DecodedAddress decodeAddress(sc_dt::uint64 addr);
|
||||
virtual sc_dt::uint64 encodeAddress(DecodedAddress n);
|
||||
@@ -71,4 +70,4 @@ public:
|
||||
virtual void print();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // XMLADDRESSDECODER_H
|
||||
@@ -35,10 +35,10 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#include "dramExtension.h"
|
||||
#include "dramExtensions.h"
|
||||
#include "../controller/core/configuration/Configuration.h"
|
||||
#include "map"
|
||||
#include "Utils.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
@@ -281,7 +281,7 @@ bool operator !=(const Row &lhs, const Row &rhs)
|
||||
|
||||
const Row Row::operator ++()
|
||||
{
|
||||
id = (id + 1) % Configuration::getInstance().memSpec.NumberOfRows;
|
||||
id = (id + 1) % Configuration::getInstance().memSpec->NumberOfRows;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -34,26 +34,23 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef DRAMEXTENSION_H_
|
||||
#define DRAMEXTENSION_H_
|
||||
#ifndef DRAMEXTENSIONS_H
|
||||
#define DRAMEXTENSIONS_H
|
||||
|
||||
#include <tlm.h>
|
||||
#include <iostream>
|
||||
#include <systemc.h>
|
||||
|
||||
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
explicit Thread(unsigned int id) :
|
||||
id(id)
|
||||
{
|
||||
}
|
||||
explicit Thread(unsigned int id) : id(id) {}
|
||||
|
||||
unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
@@ -61,14 +58,13 @@ private:
|
||||
class Channel
|
||||
{
|
||||
public:
|
||||
explicit Channel(unsigned int id) :
|
||||
id(id)
|
||||
{
|
||||
}
|
||||
explicit Channel(unsigned int id) : id(id) {}
|
||||
|
||||
unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
@@ -76,14 +72,13 @@ private:
|
||||
class BankGroup
|
||||
{
|
||||
public:
|
||||
explicit BankGroup(unsigned int id) :
|
||||
id(id)
|
||||
{
|
||||
}
|
||||
explicit BankGroup(unsigned int id) : id(id) {}
|
||||
|
||||
unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
@@ -91,10 +86,8 @@ private:
|
||||
class Bank
|
||||
{
|
||||
public:
|
||||
Bank(unsigned int id) :
|
||||
id(id)
|
||||
{
|
||||
}
|
||||
Bank(unsigned int id) : id(id) {}
|
||||
|
||||
unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
@@ -110,7 +103,6 @@ public:
|
||||
return std::to_string(id);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
@@ -120,14 +112,9 @@ class Row
|
||||
public:
|
||||
static const Row NO_ROW;
|
||||
|
||||
Row() :
|
||||
id(0), isNoRow(true)
|
||||
{
|
||||
}
|
||||
explicit Row(unsigned int id) :
|
||||
id(id), isNoRow(false)
|
||||
{
|
||||
}
|
||||
Row() : id(0), isNoRow(true) {}
|
||||
|
||||
explicit Row(unsigned int id) : id(id), isNoRow(false) {}
|
||||
|
||||
unsigned int ID() const
|
||||
{
|
||||
@@ -135,6 +122,7 @@ public:
|
||||
}
|
||||
|
||||
const Row operator++();
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
bool isNoRow;
|
||||
@@ -145,21 +133,19 @@ private:
|
||||
class Column
|
||||
{
|
||||
public:
|
||||
explicit Column(unsigned int id) :
|
||||
id(id)
|
||||
{
|
||||
}
|
||||
explicit Column(unsigned int id) : id(id) {}
|
||||
|
||||
unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
|
||||
class DramExtension: public tlm::tlm_extension<DramExtension>
|
||||
class DramExtension : public tlm::tlm_extension<DramExtension>
|
||||
{
|
||||
public:
|
||||
DramExtension();
|
||||
@@ -251,4 +237,4 @@ bool operator!=(const Row &lhs, const Row &rhs);
|
||||
bool operator==(const Column &lhs, const Column &rhs);
|
||||
bool operator!=(const Column &lhs, const Column &rhs);
|
||||
|
||||
#endif /* DRAMEXTENSION_H_ */
|
||||
#endif // DRAMEXTENSIONS_H
|
||||
@@ -35,8 +35,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef EXTENDED_PHASE_DRAM
|
||||
#define EXTENDED_PHASE_DRAM
|
||||
#ifndef PROTOCOL_H
|
||||
#define PROTOCOL_H
|
||||
|
||||
// DRAM Control Phases
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PREB);
|
||||
@@ -100,5 +100,5 @@ DECLARE_EXTENDED_PHASE(REF_TRIGGER);
|
||||
DECLARE_EXTENDED_PHASE(PDN_TRIGGER);
|
||||
|
||||
|
||||
#endif
|
||||
#endif // PROTOCOL_H
|
||||
|
||||
|
||||
@@ -35,11 +35,11 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#include "Utils.h"
|
||||
#include "utils.h"
|
||||
#include <string>
|
||||
#include <tlm.h>
|
||||
#include <fstream>
|
||||
#include "dramExtension.h"
|
||||
#include "dramExtensions.h"
|
||||
#include "../controller/Controller.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -35,8 +35,8 @@
|
||||
* Eder F. Zulian
|
||||
*/
|
||||
|
||||
#ifndef UTILS_COMMON_UTILS_H_
|
||||
#define UTILS_COMMON_UTILS_H_
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <map>
|
||||
@@ -44,7 +44,7 @@
|
||||
#include <ostream>
|
||||
#include <tlm.h>
|
||||
#include <iomanip>
|
||||
#include "dramExtension.h"
|
||||
#include "dramExtensions.h"
|
||||
#include "third_party/tinyxml2/tinyxml2.h"
|
||||
|
||||
#define DEF_SINGLETON( NAME ) \
|
||||
@@ -148,5 +148,5 @@ double queryDoubleParameter(tinyxml2::XMLElement *node, std::string name);
|
||||
|
||||
void setUpDummy(tlm::tlm_generic_payload &payload, Bank &bank);
|
||||
|
||||
#endif /* UTILS_COMMON_H_ */
|
||||
#endif // UTILS_H
|
||||
|
||||
@@ -33,13 +33,12 @@
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
*/
|
||||
#ifndef COMMAND_H_
|
||||
#define COMMAND_H_
|
||||
#ifndef COMMAND_H
|
||||
#define COMMAND_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
enum class Command {
|
||||
NOP,
|
||||
PreB,
|
||||
@@ -64,4 +63,4 @@ std::string commandToString(Command command);
|
||||
const std::vector<Command> &getAllCommands();
|
||||
bool commandIsIn(Command command, std::vector<Command> commands);
|
||||
|
||||
#endif /* COMMAND_H_ */
|
||||
#endif // COMMAND_H
|
||||
|
||||
@@ -39,13 +39,26 @@
|
||||
#include "Controller.h"
|
||||
#include <iostream>
|
||||
|
||||
Controller::Controller(sc_module_name /*name*/) :
|
||||
frontendPEQ(this, &Controller::frontendPEQCallback),
|
||||
dramPEQ(this, &Controller::dramPEQCallback),
|
||||
controllerCorePEQ(this, &Controller::controllerCorePEQCallback),
|
||||
debugManager(DebugManager::getInstance())
|
||||
{
|
||||
controllerCore = new ControllerCore("core", *this, numberOfPayloadsInSystem);
|
||||
buildScheduler();
|
||||
iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw);
|
||||
tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw);
|
||||
tSocket.register_transport_dbg(this, &Controller::transport_dbg);
|
||||
}
|
||||
|
||||
Controller::~Controller()
|
||||
{
|
||||
// Bandwidth:
|
||||
sc_time activeTime = numberOfTransactionsServed
|
||||
* Configuration::getInstance().memSpec.BurstLength
|
||||
/ Configuration::getInstance().memSpec.DataRate
|
||||
* Configuration::getInstance().memSpec.clk;
|
||||
* Configuration::getInstance().memSpec->BurstLength
|
||||
/ Configuration::getInstance().memSpec->DataRate
|
||||
* Configuration::getInstance().memSpec->clk;
|
||||
|
||||
sc_time idleTime = getIdleTime();
|
||||
sc_time endTime = getEndTime();
|
||||
@@ -56,11 +69,11 @@ Controller::~Controller()
|
||||
|
||||
double maxBandwidth = (
|
||||
// clk in Mhz e.g. 800 [MHz]:
|
||||
(1000000 / Configuration::getInstance().memSpec.clk.to_double())
|
||||
(1000000 / Configuration::getInstance().memSpec->clk.to_double())
|
||||
// DataRate e.g. 2
|
||||
* Configuration::getInstance().memSpec.DataRate
|
||||
* Configuration::getInstance().memSpec->DataRate
|
||||
// BusWidth e.g. 8 or 64
|
||||
* Configuration::getInstance().memSpec.bitWidth
|
||||
* Configuration::getInstance().memSpec->bitWidth
|
||||
// Number of devices on a DIMM e.g. 8
|
||||
* Configuration::getInstance().NumberOfDevicesOnDIMM ) / ( 1024 );
|
||||
|
||||
@@ -90,18 +103,18 @@ void Controller::buildScheduler()
|
||||
{
|
||||
string selectedScheduler = Configuration::getInstance().Scheduler;
|
||||
|
||||
if (selectedScheduler == "FIFO") {
|
||||
if (selectedScheduler == "Fifo") {
|
||||
scheduler = new Fifo(*controllerCore);
|
||||
} else if (selectedScheduler == "FIFO_STRICT") {
|
||||
} else if (selectedScheduler == "FifoStrict") {
|
||||
scheduler = new FifoStrict(*this, *controllerCore);
|
||||
} else if (selectedScheduler == "FR_FCFS") {
|
||||
scheduler = new FR_FCFS(*controllerCore);
|
||||
} else if (selectedScheduler == "FR_FCFS_RP") {
|
||||
scheduler = new FR_FCFS_RP(*controllerCore);
|
||||
} else if (selectedScheduler == "FR_FCFS_GRP") {
|
||||
scheduler = new FR_FCFS_GRP(*controllerCore, this);
|
||||
} else if (selectedScheduler == "GRP") {
|
||||
scheduler = new GRP(*controllerCore, this);
|
||||
} else if (selectedScheduler == "FrFcfs") {
|
||||
scheduler = new FrFcfs(*controllerCore);
|
||||
} else if (selectedScheduler == "FrFcfsRp") {
|
||||
scheduler = new FrFcfsRp(*controllerCore);
|
||||
} else if (selectedScheduler == "FrFcfsGrp") {
|
||||
scheduler = new FrFcfsGrp(*controllerCore, this);
|
||||
} else if (selectedScheduler == "Grp") {
|
||||
scheduler = new Grp(*controllerCore, this);
|
||||
} else if (selectedScheduler == "SMS") {
|
||||
scheduler = new SMS("SMS", *controllerCore,
|
||||
Configuration::getInstance().SJFProbability);
|
||||
@@ -127,7 +140,8 @@ void Controller::send(const ScheduledCommand &command,
|
||||
|
||||
tlm_phase phase;
|
||||
|
||||
switch (command.getCommand()) {
|
||||
switch (command.getCommand())
|
||||
{
|
||||
//TODO: refactor tlm recorder
|
||||
case Command::Read:
|
||||
phase = BEGIN_RD;
|
||||
@@ -142,9 +156,9 @@ void Controller::send(const ScheduledCommand &command,
|
||||
phase = BEGIN_WRA;
|
||||
break;
|
||||
case Command::AutoRefresh:
|
||||
if (!Configuration::getInstance().BankwiseLogic) {
|
||||
if (!Configuration::getInstance().BankwiseLogic)
|
||||
phase = BEGIN_REFA;
|
||||
} else
|
||||
else
|
||||
phase = BEGIN_REFB;
|
||||
break;
|
||||
case Command::Activate:
|
||||
@@ -163,39 +177,39 @@ void Controller::send(const ScheduledCommand &command,
|
||||
phase = BEGIN_PRE_ALL;
|
||||
break;
|
||||
case Command::PDNA:
|
||||
if (!Configuration::getInstance().BankwiseLogic) {
|
||||
if (!Configuration::getInstance().BankwiseLogic)
|
||||
phase = BEGIN_PDNA;
|
||||
} else
|
||||
else
|
||||
phase = BEGIN_PDNAB;
|
||||
break;
|
||||
case Command::PDNAX:
|
||||
if (!Configuration::getInstance().BankwiseLogic) {
|
||||
if (!Configuration::getInstance().BankwiseLogic)
|
||||
phase = END_PDNA;
|
||||
} else
|
||||
else
|
||||
phase = END_PDNAB;
|
||||
break;
|
||||
case Command::PDNP:
|
||||
if (!Configuration::getInstance().BankwiseLogic) {
|
||||
if (!Configuration::getInstance().BankwiseLogic)
|
||||
phase = BEGIN_PDNP;
|
||||
} else
|
||||
else
|
||||
phase = BEGIN_PDNPB;
|
||||
break;
|
||||
case Command::PDNPX:
|
||||
if (!Configuration::getInstance().BankwiseLogic) {
|
||||
if (!Configuration::getInstance().BankwiseLogic)
|
||||
phase = END_PDNP;
|
||||
} else
|
||||
else
|
||||
phase = END_PDNPB;
|
||||
break;
|
||||
case Command::SREF:
|
||||
if (!Configuration::getInstance().BankwiseLogic) {
|
||||
if (!Configuration::getInstance().BankwiseLogic)
|
||||
phase = BEGIN_SREF;
|
||||
} else
|
||||
else
|
||||
phase = BEGIN_SREFB;
|
||||
break;
|
||||
case Command::SREFX:
|
||||
if (!Configuration::getInstance().BankwiseLogic) {
|
||||
if (!Configuration::getInstance().BankwiseLogic)
|
||||
phase = END_SREF;
|
||||
} else
|
||||
else
|
||||
phase = END_SREFB;
|
||||
break;
|
||||
default:
|
||||
@@ -234,18 +248,23 @@ void Controller::send(Trigger trigger, sc_time time,
|
||||
void Controller::controllerCorePEQCallback(tlm_generic_payload &payload,
|
||||
const tlm_phase &phase)
|
||||
{
|
||||
if (phase == REF_TRIGGER) {
|
||||
if (phase == REF_TRIGGER)
|
||||
{
|
||||
controllerCore->triggerRefresh(payload);
|
||||
} else if (phase == PDN_TRIGGER) {
|
||||
}
|
||||
else if (phase == PDN_TRIGGER)
|
||||
{
|
||||
controllerCore->powerDownManager->sleep(DramExtension::getExtension(
|
||||
payload).getBank(), sc_time_stamp());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Bank bank = DramExtension::getBank(payload);
|
||||
sendToDram(payload, phase, SC_ZERO_TIME);
|
||||
|
||||
if (phase == BEGIN_RD || phase == BEGIN_WR) {
|
||||
if (phase == BEGIN_RD || phase == BEGIN_WR)
|
||||
scheduleNextFromScheduler(DramExtension::getBank(payload));
|
||||
} else if (phase == BEGIN_REFB)
|
||||
else if (phase == BEGIN_REFB)
|
||||
printDebugMessage("Entering REFB on bank " + to_string(bank.ID()));
|
||||
else if (phase == BEGIN_REFA)
|
||||
printDebugMessage("Entering REFA");
|
||||
@@ -276,18 +295,20 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload,
|
||||
{
|
||||
sc_time notDelay = fwDelay;
|
||||
|
||||
if (phase == BEGIN_REQ) {
|
||||
notDelay += Configuration::getInstance().memSpec.clk;
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
notDelay += Configuration::getInstance().memSpec->clk;
|
||||
|
||||
//Bandwidth IDLE
|
||||
if ((getTotalNumberOfPayloadsInSystem() == 0) && idleState) {
|
||||
// Bandwidth IDLE
|
||||
if ((getTotalNumberOfPayloadsInSystem() == 0) && idleState)
|
||||
endBandwidthIdleCollector();
|
||||
}
|
||||
} else if (phase == END_RESP) {
|
||||
// Badnwith IDLE
|
||||
if (getTotalNumberOfPayloadsInSystem() == 1) {
|
||||
}
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
// Bandwidth IDLE
|
||||
// TODO: getTotalNumberOfPayloadsInSystem() == 1 && !idleState ??
|
||||
if (getTotalNumberOfPayloadsInSystem() == 1)
|
||||
startBandwidthIdleCollector();
|
||||
}
|
||||
}
|
||||
|
||||
printDebugMessage("[fw] " + phaseNameToString(phase) + " notification in " +
|
||||
@@ -305,27 +326,37 @@ unsigned int Controller::transport_dbg(tlm::tlm_generic_payload &trans)
|
||||
void Controller::frontendPEQCallback(tlm_generic_payload &payload,
|
||||
const tlm_phase &phase)
|
||||
{
|
||||
if (phase == BEGIN_REQ) {
|
||||
printDebugMessage(string("Payload in system: ") + to_string(
|
||||
getTotalNumberOfPayloadsInSystem()));
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
printDebugMessage(string("Payloads in system: ") +
|
||||
to_string(getTotalNumberOfPayloadsInSystem()));
|
||||
payload.acquire();
|
||||
payloadEntersSystem(payload);
|
||||
|
||||
if (getTotalNumberOfPayloadsInSystem() >
|
||||
controllerCore->config.MaxNrOfTransactions) {
|
||||
controllerCore->config.MaxNrOfTransactions)
|
||||
{
|
||||
printDebugMessage("##Backpressure: Max number of transactions in system reached");
|
||||
backpressure = &payload;
|
||||
return;
|
||||
}
|
||||
payload.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
sendToFrontend(payload, END_REQ, SC_ZERO_TIME);
|
||||
else
|
||||
{
|
||||
payload.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
sendToFrontend(payload, END_REQ, SC_ZERO_TIME);
|
||||
|
||||
scheduler->storeRequest(&payload);
|
||||
scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank());
|
||||
} else if (phase == PendingRequest) {
|
||||
scheduler->storeRequest(&payload);
|
||||
scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank());
|
||||
}
|
||||
}
|
||||
else if (phase == PendingRequest)
|
||||
{
|
||||
// Schedule a pending request.
|
||||
scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank());
|
||||
} else if (phase == END_RESP) {
|
||||
if (backpressure != NULL) {
|
||||
}
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
if (backpressure != NULL)
|
||||
{
|
||||
printDebugMessage("##Backpressure released");
|
||||
backpressure->set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME);
|
||||
@@ -339,11 +370,11 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload,
|
||||
responseQueue.pop();
|
||||
payload.release();
|
||||
|
||||
if(!responseQueue.empty()) {
|
||||
if(!responseQueue.empty())
|
||||
sendToFrontend(*(responseQueue.front()), BEGIN_RESP, SC_ZERO_TIME);
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL(0,
|
||||
"Front-end PEQ in controller wrapper was triggered with unknown phase");
|
||||
}
|
||||
@@ -352,15 +383,16 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload,
|
||||
void Controller::payloadEntersSystem(tlm_generic_payload &payload)
|
||||
{
|
||||
Bank bank = DramExtension::getExtension(payload).getBank();
|
||||
numberOfPayloadsInSystem[bank]++;
|
||||
printDebugMessage(
|
||||
"Payload enters system on bank " + to_string(bank.ID()) +
|
||||
". Total number of payloads in Controller: "
|
||||
+ to_string(getTotalNumberOfPayloadsInSystem()));
|
||||
numberOfPayloadsInSystem[bank]++;
|
||||
// Set Start Time for Simulation
|
||||
if (startTimeSet == false) {
|
||||
if (!startTimeSet)
|
||||
{
|
||||
printDebugMessage("Simulation Timer Start");
|
||||
startTime = sc_time_stamp() - Configuration::getInstance().memSpec.clk;
|
||||
startTime = sc_time_stamp() - Configuration::getInstance().memSpec->clk;
|
||||
startTimeSet = true;
|
||||
}
|
||||
}
|
||||
@@ -379,51 +411,66 @@ void Controller::payloadLeavesSystem(tlm_generic_payload &payload)
|
||||
unsigned int Controller::getTotalNumberOfPayloadsInSystem()
|
||||
{
|
||||
unsigned int sum = 0;
|
||||
for (Bank bank : controllerCore->getBanks()) {
|
||||
for (Bank bank : controllerCore->getBanks())
|
||||
sum += numberOfPayloadsInSystem[bank];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
void Controller::scheduleNextFromScheduler(Bank bank)
|
||||
{
|
||||
if (controllerCore->bankIsBusy(bank)) {
|
||||
if (controllerCore->bankIsBusy(bank))
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: rescheduled always true?
|
||||
bool rescheduled = true;
|
||||
pair<Command, tlm::tlm_generic_payload *> nextRequest =
|
||||
scheduler->getNextRequest(bank);
|
||||
if (nextRequest.second != NULL) {
|
||||
if (nextRequest.second != NULL)
|
||||
{
|
||||
schedule(nextRequest.first, *nextRequest.second);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
gp *pendingRequest = scheduler->getPendingRequest(bank);
|
||||
if (pendingRequest != NULL) {
|
||||
// TODO: if path (pendingRequest != NULL) is only used by SMS scheduler
|
||||
if (pendingRequest != NULL)
|
||||
{
|
||||
rescheduled = true;
|
||||
frontendPEQ.notify(*(pendingRequest), PendingRequest,
|
||||
Configuration::getInstance().memSpec.clk);
|
||||
Configuration::getInstance().memSpec->clk);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: only used with FifoStrict scheduler
|
||||
queue<Bank> blocked;
|
||||
while (!blockedRequests.empty()) {
|
||||
while (!blockedRequests.empty())
|
||||
{
|
||||
bank = blockedRequests.front();
|
||||
blockedRequests.pop();
|
||||
|
||||
pair<Command, tlm::tlm_generic_payload *> nextRequest =
|
||||
scheduler->getNextRequest(bank);
|
||||
if (nextRequest.second != NULL) {
|
||||
if (nextRequest.second != NULL)
|
||||
{
|
||||
schedule(nextRequest.first, *nextRequest.second);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
gp *pendingRequest = scheduler->getPendingRequest(bank);
|
||||
if (pendingRequest != NULL) {
|
||||
if (pendingRequest != NULL)
|
||||
{
|
||||
//Pending request
|
||||
if (!rescheduled) {
|
||||
if (!rescheduled)
|
||||
{
|
||||
// TODO: never reached, rescheduled is always true
|
||||
rescheduled = true;
|
||||
frontendPEQ.notify(*(pendingRequest), PendingRequest,
|
||||
Configuration::getInstance().memSpec.clk);
|
||||
} else
|
||||
Configuration::getInstance().memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
blocked.push(bank);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -434,7 +481,8 @@ void Controller::schedule(Command command, gp &payload)
|
||||
{
|
||||
controllerCore->powerDownManager->wakeUp(DramExtension::getBank(payload),
|
||||
sc_time_stamp());
|
||||
if (controllerCore->scheduleRequest(command, payload)) {
|
||||
if (controllerCore->scheduleRequest(command, payload))
|
||||
{
|
||||
printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(
|
||||
command) + "] (unblocked)");
|
||||
}
|
||||
@@ -464,47 +512,59 @@ void Controller::dramPEQCallback(tlm_generic_payload &payload,
|
||||
printDebugMessage("Received " + phaseNameToString(phase) + " on bank " +
|
||||
to_string(bank.ID()) + " from DRAM");
|
||||
|
||||
if (phase == END_RD || phase == END_WR) {
|
||||
if(responseQueue.empty()) {
|
||||
if (phase == END_RD || phase == END_WR)
|
||||
{
|
||||
if(responseQueue.empty())
|
||||
sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME);
|
||||
}
|
||||
|
||||
responseQueue.push(&payload);
|
||||
} else if (phase == END_RDA || phase == END_WRA) {
|
||||
if(responseQueue.empty()) {
|
||||
}
|
||||
else if (phase == END_RDA || phase == END_WRA)
|
||||
{
|
||||
if(responseQueue.empty())
|
||||
sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME);
|
||||
}
|
||||
|
||||
responseQueue.push(&payload);
|
||||
scheduleNextFromScheduler(bank);
|
||||
} else if (phase == END_REFA) {
|
||||
}
|
||||
else if (phase == END_REFA)
|
||||
{
|
||||
printDebugMessage("Finished auto refresh on all banks ");
|
||||
|
||||
bool sleepy = true;
|
||||
for (Bank bank : controllerCore->getBanks()) {
|
||||
if (numberOfPayloadsInSystem[bank] != 0) {
|
||||
for (Bank bank : controllerCore->getBanks())
|
||||
{
|
||||
if (numberOfPayloadsInSystem[bank] != 0)
|
||||
{
|
||||
sleepy = false;
|
||||
scheduleNextFromScheduler(bank);
|
||||
}
|
||||
}
|
||||
|
||||
if (sleepy == true) {
|
||||
if (sleepy == true)
|
||||
controllerCore->powerDownManager->sleep(0, sc_time_stamp());
|
||||
}
|
||||
} else if (phase == END_REFB) {
|
||||
}
|
||||
else if (phase == END_REFB)
|
||||
{
|
||||
printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID()));
|
||||
|
||||
if (numberOfPayloadsInSystem[bank] == 0) {
|
||||
if (numberOfPayloadsInSystem[bank] == 0)
|
||||
controllerCore->powerDownManager->sleep(bank, sc_time_stamp());
|
||||
} else {
|
||||
else
|
||||
scheduleNextFromScheduler(bank);
|
||||
}
|
||||
scheduleNextFromScheduler(bank);
|
||||
} else if (containsPhase(phase, {END_PREB, END_PRE, END_ACTB, END_ACT})) {
|
||||
|
||||
scheduleNextFromScheduler(bank);
|
||||
}
|
||||
else if (phase == END_PRE_ALL) {
|
||||
else if (containsPhase(phase, {END_PREB, END_PRE, END_ACTB, 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 {
|
||||
}
|
||||
else
|
||||
{
|
||||
string str =
|
||||
string("DRAM PEQ in controller wrapper was triggered with unsupported phase ")
|
||||
+ phaseNameToString(phase);
|
||||
@@ -566,7 +626,7 @@ void Controller::endBandwidthIdleCollector()
|
||||
{
|
||||
printDebugMessage("IDLE End");
|
||||
idleTime += sc_time_stamp() - idleStart +
|
||||
Configuration::getInstance().memSpec.clk;
|
||||
Configuration::getInstance().memSpec->clk;
|
||||
idleState = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
* Eder F. Zulian
|
||||
*/
|
||||
|
||||
#ifndef CONTROLLERWRAPPER_H_
|
||||
#define CONTROLLERWRAPPER_H_
|
||||
#ifndef CONTROLLER_H
|
||||
#define CONTROLLER_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
@@ -49,11 +49,11 @@
|
||||
#include <tlm_utils/simple_initiator_socket.h>
|
||||
#include <tlm_utils/simple_target_socket.h>
|
||||
|
||||
#include "../common/dramExtension.h"
|
||||
#include "../common/dramExtensions.h"
|
||||
#include "../common/DebugManager.h"
|
||||
#include "../common/protocol.h"
|
||||
#include "../common/TlmRecorder.h"
|
||||
#include "../common/Utils.h"
|
||||
#include "../common/utils.h"
|
||||
#include "core/configuration/Configuration.h"
|
||||
#include "core/configuration/MemSpec.h"
|
||||
#include "Command.h"
|
||||
@@ -62,14 +62,13 @@
|
||||
#include "IController.h"
|
||||
#include "core/powerdown/IPowerDownManager.h"
|
||||
#include "core/scheduling/ScheduledCommand.h"
|
||||
#include "core/scheduling/Trigger.h"
|
||||
#include "core/TimingCalculation.h"
|
||||
#include "core/timingCalculations.h"
|
||||
#include "scheduler/Fifo.h"
|
||||
#include "scheduler/grp.h"
|
||||
#include "scheduler/Grp.h"
|
||||
#include "scheduler/FifoStrict.h"
|
||||
#include "scheduler/Fr_Fcfs.h"
|
||||
#include "scheduler/Fr_Fcfs_read_priority.h"
|
||||
#include "scheduler/Fr_Fcfs_grouper.h"
|
||||
#include "scheduler/FrFcfs.h"
|
||||
#include "scheduler/FrFcfsRp.h"
|
||||
#include "scheduler/FrFcfsGrp.h"
|
||||
#include "scheduler/SMS.h"
|
||||
#include "scheduler/IScheduler.h"
|
||||
|
||||
@@ -78,21 +77,10 @@ using namespace tlm;
|
||||
|
||||
DECLARE_EXTENDED_PHASE(PendingRequest);
|
||||
|
||||
class Controller: public sc_module, public IController
|
||||
class Controller : public sc_module, public IController
|
||||
{
|
||||
public:
|
||||
Controller(sc_module_name /*name*/) :
|
||||
frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this,
|
||||
&Controller::dramPEQCallback), controllerCorePEQ(this,
|
||||
&Controller::controllerCorePEQCallback),
|
||||
debugManager(DebugManager::getInstance())
|
||||
{
|
||||
controllerCore = new ControllerCore("core", *this, numberOfPayloadsInSystem);
|
||||
buildScheduler();
|
||||
iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw);
|
||||
tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw);
|
||||
tSocket.register_transport_dbg(this, &Controller::transport_dbg);
|
||||
}
|
||||
Controller(sc_module_name);
|
||||
|
||||
virtual ~Controller();
|
||||
|
||||
@@ -108,8 +96,9 @@ public:
|
||||
virtual void send(Trigger trigger, sc_time time,
|
||||
tlm_generic_payload &payload) override;
|
||||
|
||||
tlm_utils::simple_initiator_socket<Controller> iSocket;
|
||||
tlm_utils::simple_target_socket<Controller> tSocket;
|
||||
tlm_utils::simple_initiator_socket<Controller> iSocket;
|
||||
|
||||
unsigned int getTotalNumberOfPayloadsInSystem();
|
||||
void scheduleNextFromScheduler(Bank bank) override;
|
||||
|
||||
@@ -151,9 +140,9 @@ protected:
|
||||
//Scheduler* scheduler;
|
||||
IScheduler *scheduler;
|
||||
std::map<Bank, int> numberOfPayloadsInSystem;
|
||||
std::vector<gp * > refreshCollisionRequets;
|
||||
std::vector<gp *> refreshCollisionRequets;
|
||||
tlm::tlm_generic_payload *backpressure = NULL;
|
||||
std::queue<gp * > responseQueue;
|
||||
std::queue<gp *> responseQueue;
|
||||
|
||||
tlm_utils::peq_with_cb_and_phase<Controller> frontendPEQ;
|
||||
tlm_utils::peq_with_cb_and_phase<Controller> dramPEQ;
|
||||
@@ -167,7 +156,7 @@ protected:
|
||||
sc_time idleTime;
|
||||
sc_time endTime;
|
||||
sc_time startTime;
|
||||
int startTimeSet = false;
|
||||
bool startTimeSet = false;
|
||||
unsigned long long int numberOfTransactionsServed = 0;
|
||||
void startBandwidthIdleCollector();
|
||||
void endBandwidthIdleCollector();
|
||||
@@ -178,5 +167,5 @@ protected:
|
||||
static const unsigned int controllerThreadId = INT_MAX;
|
||||
};
|
||||
|
||||
#endif /* CONTROLLERWRAPPER_H_ */
|
||||
#endif // CONTROLLER_H
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include "ControllerState.h"
|
||||
#include <algorithm>
|
||||
#include "core/TimingCalculation.h"
|
||||
#include "core/timingCalculations.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -51,7 +51,7 @@ const ScheduledCommand ControllerState::getLastCommand(Command command)
|
||||
{
|
||||
ScheduledCommand max;
|
||||
|
||||
for (unsigned int i = 0; i < config->memSpec.NumberOfBanks; ++i) {
|
||||
for (unsigned int i = 0; i < config->memSpec->NumberOfBanks; ++i) {
|
||||
ScheduledCommand current = getLastCommand(command, Bank(i));
|
||||
if (current.getStart() > max.getStart())
|
||||
max = current;
|
||||
@@ -65,7 +65,7 @@ const ScheduledCommand ControllerState::getLastScheduledCommand()
|
||||
ScheduledCommand lastCommand;
|
||||
|
||||
for (Command cmd : getAllCommands()) {
|
||||
for (Bank bank : Configuration::getInstance().memSpec.getBanks()) {
|
||||
for (Bank bank : Configuration::getInstance().memSpec->getBanks()) {
|
||||
ScheduledCommand ¤t = lastScheduledByCommandAndBank[cmd][bank];
|
||||
if (current.getStart() > lastCommand.getStart())
|
||||
lastCommand = current;
|
||||
@@ -154,17 +154,17 @@ void ControllerState::cleanUp(sc_time time)
|
||||
vector<ScheduledCommand> tmp;
|
||||
for (ScheduledCommand &command : lastDataStrobeCommands) {
|
||||
if (command.getEnd() >= time
|
||||
|| getDistance(command.getEnd(), time) <= config->memSpec.tDataStrobeHistory())
|
||||
|| getDistance(command.getEnd(), time) <= config->memSpec->tDataStrobeHistory())
|
||||
tmp.push_back(command);
|
||||
}
|
||||
lastDataStrobeCommands = tmp;
|
||||
if (time >= config->memSpec.tActHistory())
|
||||
if (time >= config->memSpec->tActHistory())
|
||||
lastActivates.erase(lastActivates.begin(),
|
||||
lastActivates.lower_bound(time - config->memSpec.tActHistory()));
|
||||
lastActivates.lower_bound(time - config->memSpec->tActHistory()));
|
||||
|
||||
if (time >= config->memSpec.tActBHistory())
|
||||
if (time >= config->memSpec->tActBHistory())
|
||||
lastActivatesB.erase(lastActivatesB.begin(),
|
||||
lastActivatesB.lower_bound(time - config->memSpec.tActBHistory()));
|
||||
lastActivatesB.lower_bound(time - config->memSpec->tActBHistory()));
|
||||
}
|
||||
|
||||
void ControllerState::printDebugMessage(std::string message)
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef CONTROLLER_STATE_H_
|
||||
#define CONTROLLER_STATE_H_
|
||||
#ifndef CONTROLLERSTATE_H
|
||||
#define CONTROLLERSTATE_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include "RowBufferStates.h"
|
||||
@@ -49,7 +49,7 @@ class ControllerState
|
||||
{
|
||||
public:
|
||||
ControllerState(std::string ownerName,
|
||||
Configuration *config) : bus(config->memSpec.clk), ownerName(ownerName),
|
||||
Configuration *config) : bus(config->memSpec->clk), ownerName(ownerName),
|
||||
config(config)
|
||||
{
|
||||
rowBufferStates = new RowBufferState(ownerName);
|
||||
@@ -84,5 +84,5 @@ private:
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
#endif /* CONTROLLER_STATE_H_ */
|
||||
#endif // CONTROLLERSTATE_H
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
#include <queue>
|
||||
#include <systemc.h>
|
||||
#include "core/scheduling/ScheduledCommand.h"
|
||||
#include "core/scheduling/Trigger.h"
|
||||
#include "../common/dramExtension.h"
|
||||
#include "../common/dramExtensions.h"
|
||||
|
||||
enum Trigger {REFTrigger, PDNTrigger};
|
||||
|
||||
// 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
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "RowBufferStates.h"
|
||||
#include "core/ControllerCore.h"
|
||||
#include "../common/DebugManager.h"
|
||||
#include "../common/Utils.h"
|
||||
#include "../common/utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -76,7 +76,7 @@ void RowBufferState::closeRowBuffer(Bank bank)
|
||||
|
||||
bool RowBufferState::allRowBuffersAreClosed() const
|
||||
{
|
||||
for (unsigned int i = 0; i < Configuration::getInstance().memSpec.NumberOfBanks;
|
||||
for (unsigned int i = 0; i < Configuration::getInstance().memSpec->NumberOfBanks;
|
||||
++i) {
|
||||
if (rowBufferIsOpen(Bank(i)))
|
||||
return false;
|
||||
@@ -86,7 +86,7 @@ bool RowBufferState::allRowBuffersAreClosed() const
|
||||
|
||||
void RowBufferState::closeAllRowBuffers()
|
||||
{
|
||||
for (unsigned int i = 0; i < Configuration::getInstance().memSpec.NumberOfBanks;
|
||||
for (unsigned int i = 0; i < Configuration::getInstance().memSpec->NumberOfBanks;
|
||||
++i) {
|
||||
rowsInRowBuffers[Bank(i)] = Row::NO_ROW;
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef ROWBUFFERSTATES_H_
|
||||
#define ROWBUFFERSTATES_H_
|
||||
#ifndef ROWBUFFERSTATES_H
|
||||
#define ROWBUFFERSTATES_H
|
||||
|
||||
#include <map>
|
||||
#include "../common/dramExtension.h"
|
||||
#include "../common/dramExtensions.h"
|
||||
|
||||
class RowBufferState
|
||||
{
|
||||
@@ -60,5 +60,5 @@ private:
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
#endif /* BANKSTATES_H_ */
|
||||
#endif // ROWBUFFERSTATES_H
|
||||
|
||||
|
||||
@@ -49,9 +49,9 @@
|
||||
#include "refresh/RefreshManagerBankwise.h"
|
||||
#include "refresh/RefreshManager.h"
|
||||
#include "refresh/RGR.h"
|
||||
#include "../../common/dramExtension.h"
|
||||
#include "../../common/Utils.h"
|
||||
#include "TimingCalculation.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../../common/utils.h"
|
||||
#include "timingCalculations.h"
|
||||
|
||||
#include "powerdown/PowerDownManager.h"
|
||||
#include "powerdown/PowerDownManagerTimeout.h"
|
||||
@@ -87,13 +87,16 @@ ControllerCore::ControllerCore(sc_module_name /*name*/,
|
||||
|
||||
if (config.RowGranularRef) {
|
||||
refreshManager = new RGR("RGR", *this);
|
||||
assert(config.getTrasb() <= config.memSpec.tRAS);
|
||||
assert(config.getTrasb() >= config.memSpec.tRCD);
|
||||
assert(config.getTrrdb_L() <= config.memSpec.tRRD_L);
|
||||
assert(config.getTrrdb_S() <= config.memSpec.tRRD_S);
|
||||
assert(config.getTrpb() <= config.memSpec.tRP);
|
||||
assert(config.getTrcb() <= config.memSpec.tRC);
|
||||
assert(config.getTfawb() <= config.memSpec.tNAW);
|
||||
// TODO: How to use asserts with new memspec?
|
||||
/*
|
||||
assert(config.getTrasb() <= config.memSpec->tRAS);
|
||||
assert(config.getTrasb() >= config.memSpec->tRCD);
|
||||
assert(config.getTrrdb_L() <= config.memSpec->tRRD_L);
|
||||
assert(config.getTrrdb_S() <= config.memSpec->tRRD_S);
|
||||
assert(config.getTrpb() <= config.memSpec->tRP);
|
||||
assert(config.getTrcb() <= config.memSpec->tRC);
|
||||
assert(config.getTfawb() <= config.memSpec->tNAW);
|
||||
*/
|
||||
} else {
|
||||
if (config.BankwiseLogic) {
|
||||
refreshManager = new RefreshManagerBankwise("refManagerBw", *this);
|
||||
@@ -138,27 +141,27 @@ ControllerCore::~ControllerCore()
|
||||
void ControllerCore::triggerRefresh(tlm::tlm_generic_payload &payload)
|
||||
{
|
||||
/* Refresh can be disabled for tests purpose */
|
||||
if (config.ControllerCoreRefDisable == false) {
|
||||
if (config.ControllerCoreRefDisable == false)
|
||||
{
|
||||
sc_time time = sc_time_stamp();
|
||||
Bank bank = DramExtension::getExtension(payload).getBank();
|
||||
|
||||
state->cleanUp(time);
|
||||
|
||||
if (!refreshManager->isInvalidated(payload, time)
|
||||
&& !powerDownManager->isInSelfRefresh(bank)) {
|
||||
&& !powerDownManager->isInSelfRefresh(bank))
|
||||
{
|
||||
printDebugMessage("Triggering refresh on bank " + to_string(bank.ID()));
|
||||
powerDownManager->wakeUpForRefresh(bank,
|
||||
time); //expects PDNA and PDNP to exit without delay
|
||||
bool pdnpToSrefTransition = false;
|
||||
if (config.PowerDownMode == EPowerDownMode::Staggered) {
|
||||
pdnpToSrefTransition = state->getLastCommand(Command::PDNPX,
|
||||
bank).getStart() >= time;
|
||||
}
|
||||
if (pdnpToSrefTransition) {
|
||||
if (config.PowerDownMode == EPowerDownMode::Staggered)
|
||||
pdnpToSrefTransition = (state->getLastCommand(Command::PDNPX,
|
||||
bank).getStart() >= time);
|
||||
if (pdnpToSrefTransition)
|
||||
powerDownManager->sleep(bank, time);
|
||||
} else {
|
||||
else
|
||||
refreshManager->scheduleRefresh(payload, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,13 +172,17 @@ bool ControllerCore::scheduleRequest(Command command,
|
||||
sc_time start = clkAlign(sc_time_stamp());
|
||||
state->cleanUp(start);
|
||||
ScheduledCommand scheduledCommand = schedule(command, start, payload);
|
||||
if (config.ControllerCoreRefDisable == true) {
|
||||
if (config.ControllerCoreRefDisable)
|
||||
{
|
||||
state->change(scheduledCommand);
|
||||
controller.send(scheduledCommand, payload);
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!((command == Command::Precharge || command == Command::Activate)
|
||||
&& refreshManager->hasCollision(scheduledCommand))) {
|
||||
&& refreshManager->hasCollision(scheduledCommand)))
|
||||
{
|
||||
state->change(scheduledCommand);
|
||||
controller.send(scheduledCommand, payload);
|
||||
return true;
|
||||
@@ -189,17 +196,17 @@ ScheduledCommand ControllerCore::schedule(Command command, sc_time start,
|
||||
{
|
||||
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);
|
||||
getCommandChecker(command).delayToSatisfyConstraints(scheduledCommand);
|
||||
return scheduledCommand;
|
||||
}
|
||||
|
||||
bool ControllerCore::hasPendingRequests()
|
||||
{
|
||||
for (Bank bank : getBanks()) {
|
||||
for (Bank bank : getBanks())
|
||||
{
|
||||
if (numberOfPayloads[bank] != 0)
|
||||
return true;
|
||||
}
|
||||
@@ -217,22 +224,31 @@ bool ControllerCore::bankIsBusy(Bank bank)
|
||||
ScheduledCommand lastScheduledCommand = state->getLastScheduledCommand(bank);
|
||||
|
||||
if (lastScheduledCommand.isNoCommand())
|
||||
{
|
||||
return false;
|
||||
else if (lastScheduledCommand.commandIsIn( { Command::Write, Command::Read })) {
|
||||
}
|
||||
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, Command::PreB, Command::Precharge, Command::PrechargeAll, Command::ActB, Command::Activate })) {
|
||||
else if (lastScheduledCommand.commandIsIn({Command::WriteA, Command::ReadA, Command::PreB,
|
||||
Command::Precharge, Command::PrechargeAll,
|
||||
Command::ActB, Command::Activate}))
|
||||
{
|
||||
return (time < lastScheduledCommand.getEnd());
|
||||
}
|
||||
else if (lastScheduledCommand.getCommand() == Command::AutoRefresh) {
|
||||
else if (lastScheduledCommand.getCommand() == Command::AutoRefresh)
|
||||
{
|
||||
return (time < lastScheduledCommand.getEnd());
|
||||
} else if (lastScheduledCommand.commandIsIn( { Command::SREFX, Command::PDNPX, Command::PDNAX, Command::SREF, Command::PDNP,
|
||||
Command::PDNA
|
||||
})) {
|
||||
}
|
||||
else if (lastScheduledCommand.commandIsIn({Command::SREFX, Command::PDNPX, Command::PDNAX,
|
||||
Command::SREF, Command::PDNP, Command::PDNA}))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("Core", "Last command unkown");
|
||||
return false;
|
||||
}
|
||||
@@ -243,7 +259,7 @@ const std::vector<Bank> &ControllerCore::getBanks()
|
||||
static std::vector<Bank> banks;
|
||||
|
||||
if (banks.size() == 0) {
|
||||
for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; i++) {
|
||||
for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; i++) {
|
||||
banks.push_back(Bank(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef CONTROLLER_H_
|
||||
#define CONTROLLER_H_
|
||||
#ifndef CONTROLLERCORE_H
|
||||
#define CONTROLLERCORE_H
|
||||
|
||||
#include <tlm.h>
|
||||
#include <map>
|
||||
@@ -88,5 +88,5 @@ private:
|
||||
void printDebugMessage(string message);
|
||||
};
|
||||
|
||||
#endif /* CONTROLLER_H_ */
|
||||
#endif // CONTROLLERCORE_H
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "Slots.h"
|
||||
#include "TimingCalculation.h"
|
||||
#include "timingCalculations.h"
|
||||
|
||||
|
||||
Slots::Slots(sc_time clk) :
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef SLOTS_H_
|
||||
#define SLOTS_H_
|
||||
#ifndef SLOTS_H
|
||||
#define SLOTS_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <set>
|
||||
#include "scheduling/ScheduledCommand.h"
|
||||
|
||||
|
||||
class Slots
|
||||
{
|
||||
public:
|
||||
@@ -60,4 +60,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* SLOTS_H_ */
|
||||
#endif // SLOTS_H
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#include "Configuration.h"
|
||||
#include "ConfigurationLoader.h"
|
||||
#include "../../../common/xmlAddressdecoder.h"
|
||||
#include "../../../common/XmlAddressDecoder.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -349,10 +349,10 @@ void Configuration::setParameters(std::map<std::string, std::string>
|
||||
std::uint64_t Configuration::getSimMemSizeInBytes()
|
||||
{
|
||||
// 1. Get number of banks, rows, columns and data width in bits for one die (or chip)
|
||||
std::uint64_t banks = memSpec.NumberOfBanks;
|
||||
std::uint64_t rows = memSpec.NumberOfRows;
|
||||
std::uint64_t columns = memSpec.NumberOfColumns;
|
||||
std::uint64_t bitWidth = memSpec.bitWidth;
|
||||
std::uint64_t banks = memSpec->NumberOfBanks;
|
||||
std::uint64_t rows = memSpec->NumberOfRows;
|
||||
std::uint64_t columns = memSpec->NumberOfColumns;
|
||||
std::uint64_t bitWidth = memSpec->bitWidth;
|
||||
// 2. Calculate size of one DRAM chip in bits
|
||||
std::uint64_t chipBitSize = banks * rows * columns * bitWidth;
|
||||
// 3. Calculate size of one DRAM chip in bytes
|
||||
@@ -381,7 +381,7 @@ std::uint64_t Configuration::getSimMemSizeInBytes()
|
||||
// The bus width is given in bits, e.g., 64-bit data bus, 128-bit data bus, etc.
|
||||
unsigned int Configuration::getDataBusWidth()
|
||||
{
|
||||
unsigned int dataBusWidth = memSpec.bitWidth * NumberOfDevicesOnDIMM;
|
||||
unsigned int dataBusWidth = memSpec->bitWidth * NumberOfDevicesOnDIMM;
|
||||
assert(dataBusWidth > 0);
|
||||
return dataBusWidth;
|
||||
}
|
||||
@@ -390,7 +390,7 @@ unsigned int Configuration::getDataBusWidth()
|
||||
unsigned int Configuration::getBytesPerBurst()
|
||||
{
|
||||
// First multiply to get the number of bits in a burst, then divide by 8 to get the value in bytes. The order is important. Think on a single x4 device.
|
||||
unsigned int bytesPerBurst = (memSpec.BurstLength * getDataBusWidth()) / 8;
|
||||
unsigned int bytesPerBurst = (memSpec->BurstLength * getDataBusWidth()) / 8;
|
||||
assert(bytesPerBurst > 0);
|
||||
|
||||
if (NumberOfDevicesOnDIMM > 1) {
|
||||
@@ -399,7 +399,7 @@ unsigned int Configuration::getBytesPerBurst()
|
||||
// or burst element has N bytes. N = 2^(# bits for byte offset)).
|
||||
unsigned int burstElementSizeInBytes =
|
||||
AddressDecoder::getInstance().amount["bytes"];
|
||||
assert(bytesPerBurst == (burstElementSizeInBytes * memSpec.BurstLength));
|
||||
assert(bytesPerBurst == (burstElementSizeInBytes * memSpec->BurstLength));
|
||||
}
|
||||
|
||||
return bytesPerBurst;
|
||||
@@ -407,27 +407,27 @@ unsigned int Configuration::getBytesPerBurst()
|
||||
|
||||
sc_time Configuration::getTrasb()
|
||||
{
|
||||
return trasbclk * memSpec.clk;
|
||||
return trasbclk * memSpec->clk;
|
||||
}
|
||||
sc_time Configuration::getTrrdb_L()
|
||||
{
|
||||
return trrdblclk * memSpec.clk;
|
||||
return trrdblclk * memSpec->clk;
|
||||
}
|
||||
sc_time Configuration::getTrrdb_S()
|
||||
{
|
||||
return trrdbsclk * memSpec.clk;
|
||||
return trrdbsclk * memSpec->clk;
|
||||
}
|
||||
sc_time Configuration::getTrpb()
|
||||
{
|
||||
return trpbclk * memSpec.clk;
|
||||
return trpbclk * memSpec->clk;
|
||||
}
|
||||
sc_time Configuration::getTrcb()
|
||||
{
|
||||
return trcbclk * memSpec.clk;
|
||||
return trcbclk * memSpec->clk;
|
||||
}
|
||||
sc_time Configuration::getTfawb()
|
||||
{
|
||||
return tfawbclk * memSpec.clk;
|
||||
return tfawbclk * memSpec->clk;
|
||||
}
|
||||
bool Configuration::getRGRBank(unsigned int w)
|
||||
{
|
||||
|
||||
@@ -36,15 +36,15 @@
|
||||
* Felipe S. Prado
|
||||
*/
|
||||
|
||||
#ifndef CONFIGURATION_H_
|
||||
#define CONFIGURATION_H_
|
||||
#ifndef CONFIGURATION_H
|
||||
#define CONFIGURATION_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include "MemSpec.h"
|
||||
#include "thermalSimConfig.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "TemperatureSimConfig.h"
|
||||
#include "../../../common/utils.h"
|
||||
|
||||
#include "../../../error/eccbaseclass.h"
|
||||
|
||||
@@ -54,7 +54,8 @@ enum class EPowerDownMode {NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF};
|
||||
|
||||
enum class ECCControllerMode {Disabled, Hamming};
|
||||
|
||||
struct Configuration {
|
||||
struct Configuration
|
||||
{
|
||||
static std::string memspecUri;
|
||||
static std::string mcconfigUri;
|
||||
std::string pathToResources;
|
||||
@@ -71,7 +72,7 @@ struct Configuration {
|
||||
unsigned int Capsize = 5;
|
||||
sc_time getPowerDownTimeout()
|
||||
{
|
||||
return powerDownTimeoutInClk * memSpec.clk;
|
||||
return powerDownTimeoutInClk * memSpec->clk;
|
||||
}
|
||||
EPowerDownMode PowerDownMode = EPowerDownMode::Staggered;
|
||||
bool ReadWriteGrouping = false;
|
||||
@@ -138,7 +139,7 @@ struct Configuration {
|
||||
unsigned long long int AddressOffset = 0;
|
||||
|
||||
// MemSpec (from DRAM-Power XML)
|
||||
MemSpec memSpec;
|
||||
MemSpec *memSpec;
|
||||
|
||||
void setParameter(std::string name, std::string value);
|
||||
void setParameters(std::map<std::string, std::string> parameterMap);
|
||||
@@ -163,5 +164,5 @@ private:
|
||||
unsigned int powerDownTimeoutInClk = 3;
|
||||
};
|
||||
|
||||
#endif /* CONFIGURATION_H_ */
|
||||
#endif // CONFIGURATION_H
|
||||
|
||||
|
||||
@@ -32,11 +32,12 @@
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "ConfigurationLoader.h"
|
||||
#include "MemSpec.h"
|
||||
#include "../TimingCalculation.h"
|
||||
#include "../timingCalculations.h"
|
||||
|
||||
using namespace tinyxml2;
|
||||
using namespace std;
|
||||
@@ -101,34 +102,6 @@ void ConfigurationLoader::loadConfigFromUri(Configuration &config,
|
||||
loadConfig(config, e);
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadMemSpec(Configuration &config, string memspecUri)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
config.memspecUri = memspecUri;
|
||||
loadXML(memspecUri, doc);
|
||||
XMLElement *memspec = doc.FirstChildElement("memspec");
|
||||
loadMemSpec(config, memspec);
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadMemSpec(Configuration &config,
|
||||
XMLElement *memspec)
|
||||
{
|
||||
config.memSpec.MemoryId = queryStringParameter(memspec, "memoryId");
|
||||
config.memSpec.MemoryType = queryStringParameter(memspec, "memoryType");
|
||||
|
||||
if (config.memSpec.MemoryType == "DDR4") {
|
||||
loadDDR4(config, memspec);
|
||||
} else if (config.memSpec.MemoryType == "DDR3") {
|
||||
loadDDR3(config, memspec);
|
||||
} else if (config.memSpec.MemoryType == "LPDDR4") {
|
||||
loadLPDDR4(config, memspec);
|
||||
} else if (config.memSpec.MemoryType == "WIDEIO_SDR") {
|
||||
loadWideIO(config, memspec);
|
||||
} else {
|
||||
reportFatal("ConfigurationLoader", "Unsupported DRAM type");
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadMCConfig(Configuration &config,
|
||||
string mcconfigUri)
|
||||
{
|
||||
@@ -155,236 +128,278 @@ void ConfigurationLoader::loadMCConfig(Configuration &config,
|
||||
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadMemSpec(Configuration &config, string memspecUri)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
config.memspecUri = memspecUri;
|
||||
loadXML(memspecUri, doc);
|
||||
XMLElement *memspec = doc.FirstChildElement("memspec");
|
||||
loadMemSpec(config, memspec);
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadMemSpec(Configuration &config,
|
||||
XMLElement *memspec)
|
||||
{
|
||||
string memoryType = queryStringParameter(memspec, "memoryType");
|
||||
|
||||
if (memoryType == "DDR4") {
|
||||
Configuration::getInstance().memSpec =
|
||||
new MemSpecDDR4;
|
||||
loadDDR4(config, memspec);
|
||||
} else if (memoryType == "DDR3") {
|
||||
Configuration::getInstance().memSpec =
|
||||
new MemSpecDDR3;
|
||||
loadDDR3(config, memspec);
|
||||
} else if (memoryType == "LPDDR4") {
|
||||
Configuration::getInstance().memSpec =
|
||||
new MemSpecLPDDR4;
|
||||
loadLPDDR4(config, memspec);
|
||||
} else if (memoryType == "WIDEIO_SDR") {
|
||||
Configuration::getInstance().memSpec =
|
||||
new MemSpecWideIO;
|
||||
loadWideIO(config, memspec);
|
||||
} else {
|
||||
reportFatal("ConfigurationLoader", "Unsupported DRAM type");
|
||||
}
|
||||
|
||||
loadCommons(config, memspec);
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadCommons(Configuration &config, XMLElement *memspec)
|
||||
{
|
||||
config.memSpec->MemoryId = queryStringParameter(memspec, "memoryId");
|
||||
config.memSpec->MemoryType = queryStringParameter(memspec, "memoryType");
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadDDR3(Configuration &config, XMLElement *memspec)
|
||||
{
|
||||
//MemArchitecture
|
||||
XMLElement *architecture = memspec->FirstChildElement("memarchitecturespec");
|
||||
|
||||
config.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
config.memSpec.NumberOfBankGroups = 1;
|
||||
config.memSpec.NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength");
|
||||
config.memSpec.nActivate = 4;
|
||||
config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec.NumberOfColumns = queryUIntParameter(architecture,
|
||||
config.memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
config.memSpec->NumberOfBankGroups = 1;
|
||||
config.memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
config.memSpec->BurstLength = queryUIntParameter(architecture, "burstLength");
|
||||
config.memSpec->nActivate = 4;
|
||||
config.memSpec->DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec->NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec->NumberOfColumns = queryUIntParameter(architecture,
|
||||
"nbrOfColumns");
|
||||
config.memSpec.bitWidth = queryUIntParameter(architecture, "width");
|
||||
config.memSpec.DLL = true;
|
||||
config.memSpec.termination = true;
|
||||
config.memSpec->bitWidth = queryUIntParameter(architecture, "width");
|
||||
config.memSpec->DLL = true;
|
||||
config.memSpec->termination = true;
|
||||
|
||||
//MemTimings
|
||||
XMLElement *timings = memspec->FirstChildElement("memtimingspec");
|
||||
config.memSpec.clkMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
config.memSpec.clk = FrequencyToClk(config.memSpec.clkMHz);
|
||||
sc_time clk = config.memSpec.clk;
|
||||
config.memSpec.tRP = clk * queryUIntParameter(timings, "RP");
|
||||
config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
config.memSpec.tRC = clk * queryUIntParameter(timings, "RC");
|
||||
config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec.tRRD_L = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec.tCCD_L = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
config.memSpec.tNAW = clk * queryUIntParameter(timings, "FAW");
|
||||
config.memSpec.tRL = clk * queryUIntParameter(timings, "RL");
|
||||
config.memSpec.tWL = clk * queryUIntParameter(timings, "WL");
|
||||
config.memSpec.tWR = clk * queryUIntParameter(timings, "WR");
|
||||
config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec.tWTR_L = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
config.memSpec.tXP = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec.tXPDLL = clk * queryUIntParameter(timings, "XPDLL");
|
||||
config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec.tXSRDLL = clk * queryUIntParameter(timings, "XSDLL");
|
||||
config.memSpec.tAL = clk * queryUIntParameter(timings, "AL");
|
||||
config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
config.memSpec.tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
config.memSpec->clkMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
config.memSpec->clk = FrequencyToClk(config.memSpec->clkMHz);
|
||||
sc_time clk = config.memSpec->clk;
|
||||
config.memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
config.memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
config.memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
config.memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
config.memSpec->tRRD_S = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec->tRRD_L = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec->tCCD_S = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec->tCCD_L = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec->tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
config.memSpec->tNAW = clk * queryUIntParameter(timings, "FAW");
|
||||
config.memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
config.memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
config.memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
config.memSpec->tWTR_S = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec->tWTR_L = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
config.memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
config.memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec->tXPDLL = clk * queryUIntParameter(timings, "XPDLL");
|
||||
config.memSpec->tXSR = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec->tXSRDLL = clk * queryUIntParameter(timings, "XSDLL");
|
||||
config.memSpec->tAL = clk * queryUIntParameter(timings, "AL");
|
||||
config.memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
config.memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
config.memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
|
||||
config.memSpec.refreshTimings.clear();
|
||||
for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) {
|
||||
config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC,
|
||||
config.memSpec.tREFI);
|
||||
config.memSpec->refreshTimings.clear();
|
||||
for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; ++i) {
|
||||
config.memSpec->refreshTimings[Bank(i)] = RefreshTiming(config.memSpec->tRFC,
|
||||
config.memSpec->tREFI);
|
||||
}
|
||||
|
||||
// Currents and Volatages: TODO Check if this is correct.
|
||||
XMLElement *powers = memspec->FirstChildElement("mempowerspec");
|
||||
config.memSpec.iDD0 = queryDoubleParameter(powers, "idd0");
|
||||
config.memSpec.iDD02 = 0;
|
||||
config.memSpec.iDD2P0 = queryDoubleParameter(powers, "idd2p0");
|
||||
config.memSpec.iDD2P1 = queryDoubleParameter(powers, "idd2p1");
|
||||
config.memSpec.iDD2N = queryDoubleParameter(powers, "idd2n");
|
||||
config.memSpec.iDD3P0 = queryDoubleParameter(powers, "idd3p0");
|
||||
config.memSpec.iDD3P1 = queryDoubleParameter(powers, "idd3p1");
|
||||
config.memSpec.iDD3N = queryDoubleParameter(powers, "idd3n");
|
||||
config.memSpec.iDD4R = queryDoubleParameter(powers, "idd4r");
|
||||
config.memSpec.iDD4W = queryDoubleParameter(powers, "idd4w");
|
||||
config.memSpec.iDD5 = queryDoubleParameter(powers, "idd5");
|
||||
config.memSpec.iDD6 = queryDoubleParameter(powers, "idd6");
|
||||
config.memSpec.iDD62 = 0;
|
||||
config.memSpec.vDD = queryDoubleParameter(powers, "vdd");
|
||||
config.memSpec.vDD2 = 0;
|
||||
config.memSpec->iDD0 = queryDoubleParameter(powers, "idd0");
|
||||
config.memSpec->iDD02 = 0;
|
||||
config.memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p0");
|
||||
config.memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p1");
|
||||
config.memSpec->iDD2N = queryDoubleParameter(powers, "idd2n");
|
||||
config.memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p0");
|
||||
config.memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p1");
|
||||
config.memSpec->iDD3N = queryDoubleParameter(powers, "idd3n");
|
||||
config.memSpec->iDD4R = queryDoubleParameter(powers, "idd4r");
|
||||
config.memSpec->iDD4W = queryDoubleParameter(powers, "idd4w");
|
||||
config.memSpec->iDD5 = queryDoubleParameter(powers, "idd5");
|
||||
config.memSpec->iDD6 = queryDoubleParameter(powers, "idd6");
|
||||
config.memSpec->iDD62 = 0;
|
||||
config.memSpec->vDD = queryDoubleParameter(powers, "vdd");
|
||||
config.memSpec->vDD2 = 0;
|
||||
}
|
||||
|
||||
|
||||
void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *memspec)
|
||||
{
|
||||
//MemArchitecture
|
||||
XMLElement *architecture = memspec->FirstChildElement("memarchitecturespec");
|
||||
|
||||
config.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
config.memSpec.NumberOfBankGroups = queryUIntParameter(architecture,
|
||||
config.memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
config.memSpec->NumberOfBankGroups = queryUIntParameter(architecture,
|
||||
"nbrOfBankGroups");
|
||||
config.memSpec.NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength");
|
||||
config.memSpec.nActivate = 4;
|
||||
config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec.NumberOfColumns = queryUIntParameter(architecture,
|
||||
config.memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
config.memSpec->BurstLength = queryUIntParameter(architecture, "burstLength");
|
||||
config.memSpec->nActivate = 4;
|
||||
config.memSpec->DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec->NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec->NumberOfColumns = queryUIntParameter(architecture,
|
||||
"nbrOfColumns");
|
||||
config.memSpec.bitWidth = queryUIntParameter(architecture, "width");
|
||||
config.memSpec.DLL = true;
|
||||
config.memSpec.termination = true;
|
||||
config.memSpec->bitWidth = queryUIntParameter(architecture, "width");
|
||||
config.memSpec->DLL = true;
|
||||
config.memSpec->termination = true;
|
||||
|
||||
//MemTimings
|
||||
XMLElement *timings = memspec->FirstChildElement("memtimingspec");
|
||||
config.memSpec.clkMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
config.memSpec.clk = FrequencyToClk(config.memSpec.clkMHz);
|
||||
sc_time clk = config.memSpec.clk;
|
||||
config.memSpec.tRP = clk * queryUIntParameter(timings, "RP");
|
||||
config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
config.memSpec.tRC = clk * queryUIntParameter(timings, "RC");
|
||||
config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD_S");
|
||||
config.memSpec.tRRD_L = clk * queryUIntParameter(timings, "RRD_L");
|
||||
config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD_S");
|
||||
config.memSpec.tCCD_L = clk * queryUIntParameter(timings, "CCD_L");
|
||||
config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
config.memSpec.tNAW = clk * queryUIntParameter(timings, "FAW");
|
||||
config.memSpec.tRL = clk * queryUIntParameter(timings, "RL");
|
||||
config.memSpec.tWL = clk * queryUIntParameter(timings, "WL");
|
||||
config.memSpec.tWR = clk * queryUIntParameter(timings, "WR");
|
||||
config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR_S");
|
||||
config.memSpec.tWTR_L = clk * queryUIntParameter(timings, "WTR_L");
|
||||
config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
config.memSpec.tXP = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec.tXPDLL = clk * queryUIntParameter(timings, "XPDLL");
|
||||
config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec.tXSRDLL = clk * queryUIntParameter(timings, "XSDLL");
|
||||
config.memSpec.tAL = clk * queryUIntParameter(timings, "AL");
|
||||
config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
config.memSpec.tRFC2 = clk * queryUIntParameter(timings, "RFC2");
|
||||
config.memSpec.tRFC4 = clk * queryUIntParameter(timings, "RFC4");
|
||||
config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
config.memSpec.tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
config.memSpec->clkMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
config.memSpec->clk = FrequencyToClk(config.memSpec->clkMHz);
|
||||
sc_time clk = config.memSpec->clk;
|
||||
config.memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
config.memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
config.memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
config.memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
config.memSpec->tRRD_S = clk * queryUIntParameter(timings, "RRD_S");
|
||||
config.memSpec->tRRD_L = clk * queryUIntParameter(timings, "RRD_L");
|
||||
config.memSpec->tCCD_S = clk * queryUIntParameter(timings, "CCD_S");
|
||||
config.memSpec->tCCD_L = clk * queryUIntParameter(timings, "CCD_L");
|
||||
config.memSpec->tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
config.memSpec->tNAW = clk * queryUIntParameter(timings, "FAW");
|
||||
config.memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
config.memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
config.memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
config.memSpec->tWTR_S = clk * queryUIntParameter(timings, "WTR_S");
|
||||
config.memSpec->tWTR_L = clk * queryUIntParameter(timings, "WTR_L");
|
||||
config.memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
config.memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
config.memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec->tXPDLL = clk * queryUIntParameter(timings, "XPDLL");
|
||||
config.memSpec->tXSR = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec->tXSRDLL = clk * queryUIntParameter(timings, "XSDLL");
|
||||
config.memSpec->tAL = clk * queryUIntParameter(timings, "AL");
|
||||
config.memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
config.memSpec->tRFC2 = clk * queryUIntParameter(timings, "RFC2");
|
||||
config.memSpec->tRFC4 = clk * queryUIntParameter(timings, "RFC4");
|
||||
config.memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
config.memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
|
||||
config.memSpec.refreshTimings.clear();
|
||||
for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) {
|
||||
config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC,
|
||||
config.memSpec.tRFC2,
|
||||
config.memSpec.tRFC4,
|
||||
config.memSpec.tREFI);
|
||||
config.memSpec->refreshTimings.clear();
|
||||
for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; ++i) {
|
||||
config.memSpec->refreshTimings[Bank(i)] = RefreshTiming(config.memSpec->tRFC,
|
||||
config.memSpec->tRFC2,
|
||||
config.memSpec->tRFC4,
|
||||
config.memSpec->tREFI);
|
||||
}
|
||||
|
||||
// Currents and Volatages:
|
||||
XMLElement *powers = memspec->FirstChildElement("mempowerspec");
|
||||
config.memSpec.iDD0 = queryDoubleParameter(powers, "idd0");
|
||||
config.memSpec.iDD02 = queryDoubleParameter(powers, "idd02");
|
||||
config.memSpec.iDD2P0 = queryDoubleParameter(powers, "idd2p0");
|
||||
config.memSpec.iDD2P1 = queryDoubleParameter(powers, "idd2p1");
|
||||
config.memSpec.iDD2N = queryDoubleParameter(powers, "idd2n");
|
||||
config.memSpec.iDD3P0 = queryDoubleParameter(powers, "idd3p0");
|
||||
config.memSpec.iDD3P1 = queryDoubleParameter(powers, "idd3p1");
|
||||
config.memSpec.iDD3N = queryDoubleParameter(powers, "idd3n");
|
||||
config.memSpec.iDD4R = queryDoubleParameter(powers, "idd4r");
|
||||
config.memSpec.iDD4W = queryDoubleParameter(powers, "idd4w");
|
||||
config.memSpec.iDD5 = queryDoubleParameter(powers, "idd5");
|
||||
config.memSpec.iDD6 = queryDoubleParameter(powers, "idd6");
|
||||
config.memSpec.iDD62 = queryDoubleParameter(powers, "idd62");
|
||||
config.memSpec.vDD = queryDoubleParameter(powers, "vdd");
|
||||
config.memSpec.vDD2 = queryDoubleParameter(powers, "vdd2");
|
||||
config.memSpec->iDD0 = queryDoubleParameter(powers, "idd0");
|
||||
config.memSpec->iDD02 = queryDoubleParameter(powers, "idd02");
|
||||
config.memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p0");
|
||||
config.memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p1");
|
||||
config.memSpec->iDD2N = queryDoubleParameter(powers, "idd2n");
|
||||
config.memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p0");
|
||||
config.memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p1");
|
||||
config.memSpec->iDD3N = queryDoubleParameter(powers, "idd3n");
|
||||
config.memSpec->iDD4R = queryDoubleParameter(powers, "idd4r");
|
||||
config.memSpec->iDD4W = queryDoubleParameter(powers, "idd4w");
|
||||
config.memSpec->iDD5 = queryDoubleParameter(powers, "idd5");
|
||||
config.memSpec->iDD6 = queryDoubleParameter(powers, "idd6");
|
||||
config.memSpec->iDD62 = queryDoubleParameter(powers, "idd62");
|
||||
config.memSpec->vDD = queryDoubleParameter(powers, "vdd");
|
||||
config.memSpec->vDD2 = queryDoubleParameter(powers, "vdd2");
|
||||
}
|
||||
|
||||
// TODO: fix this for LPDDR4
|
||||
// TODO: change timings for LPDDR4
|
||||
void ConfigurationLoader::loadLPDDR4(Configuration &config, XMLElement *memspec)
|
||||
{
|
||||
//MemArchitecture:
|
||||
XMLElement *architecture = memspec->FirstChildElement("memarchitecturespec");
|
||||
|
||||
config.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
config.memSpec.NumberOfBankGroups = 1;
|
||||
config.memSpec.NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength");
|
||||
config.memSpec.nActivate = 4;
|
||||
config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec.NumberOfColumns = queryUIntParameter(architecture,
|
||||
config.memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
config.memSpec->NumberOfBankGroups = 1;
|
||||
config.memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
config.memSpec->BurstLength = queryUIntParameter(architecture, "burstLength");
|
||||
config.memSpec->nActivate = 4;
|
||||
config.memSpec->DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec->NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec->NumberOfColumns = queryUIntParameter(architecture,
|
||||
"nbrOfColumns");
|
||||
config.memSpec.bitWidth = queryUIntParameter(architecture, "width");
|
||||
config.memSpec.DLL = false; // TODO: Correct?
|
||||
config.memSpec.termination = true; // TODO: Correct?
|
||||
config.memSpec->bitWidth = queryUIntParameter(architecture, "width");
|
||||
config.memSpec->DLL = false; // TODO: Correct?
|
||||
config.memSpec->termination = true; // TODO: Correct?
|
||||
|
||||
//MemTimings
|
||||
XMLElement *timings = memspec->FirstChildElement("memtimingspec");
|
||||
config.memSpec.clkMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
config.memSpec.clk = FrequencyToClk(config.memSpec.clkMHz);
|
||||
sc_time clk = config.memSpec.clk;
|
||||
config.memSpec.tRP = clk * queryUIntParameter(timings, "RPPB");
|
||||
config.memSpec.tRPAB = clk * queryUIntParameter(timings, "RPAB");
|
||||
config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
config.memSpec.tRC = clk * queryUIntParameter(timings, "RC");
|
||||
config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec.tRRD_L = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec.tCCD_L = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
config.memSpec.tNAW = clk * queryUIntParameter(timings, "FAW");
|
||||
config.memSpec.tRL = clk * queryUIntParameter(timings, "RL");
|
||||
config.memSpec.tWL = clk * queryUIntParameter(timings, "WL");
|
||||
config.memSpec.tWR = clk * queryUIntParameter(timings, "WR");
|
||||
config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec.tWTR_L = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
config.memSpec.tXP = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec.tXPDLL = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec.tXSRDLL = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec.tAL = clk * queryUIntParameter(timings, "AL");
|
||||
config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFCAB");
|
||||
// TODO: config.memSpec.tRFCPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFIAB");
|
||||
// TODO: config.memSpec.tREFIPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
config.memSpec.tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
config.memSpec->clkMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
config.memSpec->clk = FrequencyToClk(config.memSpec->clkMHz);
|
||||
sc_time clk = config.memSpec->clk;
|
||||
config.memSpec->tRP = clk * queryUIntParameter(timings, "RPPB");
|
||||
config.memSpec->tRPAB = clk * queryUIntParameter(timings, "RPAB");
|
||||
config.memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
config.memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
config.memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
config.memSpec->tRRD_S = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec->tRRD_L = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec->tCCD_S = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec->tCCD_L = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec->tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
config.memSpec->tNAW = clk * queryUIntParameter(timings, "FAW");
|
||||
config.memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
config.memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
config.memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
config.memSpec->tWTR_S = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec->tWTR_L = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
config.memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
config.memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec->tXPDLL = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec->tXSR = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec->tXSRDLL = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec->tAL = clk * queryUIntParameter(timings, "AL");
|
||||
config.memSpec->tRFC = clk * queryUIntParameter(timings, "RFCAB");
|
||||
// TODO: config.memSpec->tRFCPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
config.memSpec->tREFI = clk * queryUIntParameter(timings, "REFIAB");
|
||||
// TODO: config.memSpec->tREFIPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
config.memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK");
|
||||
|
||||
config.memSpec.refreshTimings.clear();
|
||||
for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) {
|
||||
config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC,
|
||||
config.memSpec.tREFI);
|
||||
config.memSpec->refreshTimings.clear();
|
||||
for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; ++i) {
|
||||
config.memSpec->refreshTimings[Bank(i)] = RefreshTiming(config.memSpec->tRFC,
|
||||
config.memSpec->tREFI);
|
||||
}
|
||||
|
||||
// Currents and Volatages:
|
||||
XMLElement *powers = memspec->FirstChildElement("mempowerspec");
|
||||
config.memSpec.iDD0 = queryDoubleParameter(powers, "idd0");
|
||||
config.memSpec.iDD02 = queryDoubleParameter(powers, "idd02");
|
||||
config.memSpec.iDD2P0 = queryDoubleParameter(powers, "idd2p");
|
||||
config.memSpec.iDD2P1 = queryDoubleParameter(powers, "idd2p2");
|
||||
config.memSpec.iDD2N = queryDoubleParameter(powers, "idd2n");
|
||||
config.memSpec.iDD3P0 = queryDoubleParameter(powers, "idd3p");
|
||||
config.memSpec.iDD3P1 = queryDoubleParameter(powers, "idd3p2");
|
||||
config.memSpec.iDD3N = queryDoubleParameter(powers, "idd3n");
|
||||
config.memSpec.iDD4R = queryDoubleParameter(powers, "idd4r");
|
||||
config.memSpec.iDD4W = queryDoubleParameter(powers, "idd4w");
|
||||
config.memSpec.iDD5 = queryDoubleParameter(powers, "idd5");
|
||||
config.memSpec.iDD6 = queryDoubleParameter(powers, "idd6");
|
||||
config.memSpec.iDD62 = queryDoubleParameter(powers, "idd62");
|
||||
config.memSpec.vDD = queryDoubleParameter(powers, "vdd");
|
||||
config.memSpec.vDD2 = queryDoubleParameter(powers, "vdd2");
|
||||
config.memSpec->iDD0 = queryDoubleParameter(powers, "idd0");
|
||||
config.memSpec->iDD02 = queryDoubleParameter(powers, "idd02");
|
||||
config.memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p");
|
||||
config.memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p2");
|
||||
config.memSpec->iDD2N = queryDoubleParameter(powers, "idd2n");
|
||||
config.memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p");
|
||||
config.memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p2");
|
||||
config.memSpec->iDD3N = queryDoubleParameter(powers, "idd3n");
|
||||
config.memSpec->iDD4R = queryDoubleParameter(powers, "idd4r");
|
||||
config.memSpec->iDD4W = queryDoubleParameter(powers, "idd4w");
|
||||
config.memSpec->iDD5 = queryDoubleParameter(powers, "idd5");
|
||||
config.memSpec->iDD6 = queryDoubleParameter(powers, "idd6");
|
||||
config.memSpec->iDD62 = queryDoubleParameter(powers, "idd62");
|
||||
config.memSpec->vDD = queryDoubleParameter(powers, "vdd");
|
||||
config.memSpec->vDD2 = queryDoubleParameter(powers, "vdd2");
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *memspec)
|
||||
@@ -392,79 +407,79 @@ void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *memspec)
|
||||
//MemSpecification
|
||||
XMLElement *architecture = memspec->FirstChildElement("memarchitecturespec");
|
||||
|
||||
config.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
config.memSpec.NumberOfBankGroups = 1;
|
||||
config.memSpec.NumberOfRanks = 1;
|
||||
config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength");
|
||||
config.memSpec.nActivate = 2;
|
||||
config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec.NumberOfColumns = queryUIntParameter(architecture,
|
||||
config.memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
config.memSpec->NumberOfBankGroups = 1;
|
||||
config.memSpec->NumberOfRanks = 1;
|
||||
config.memSpec->BurstLength = queryUIntParameter(architecture, "burstLength");
|
||||
config.memSpec->nActivate = 2;
|
||||
config.memSpec->DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec->NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec->NumberOfColumns = queryUIntParameter(architecture,
|
||||
"nbrOfColumns");
|
||||
config.memSpec.bitWidth = queryUIntParameter(architecture, "width");
|
||||
config.memSpec.DLL = false;
|
||||
config.memSpec.termination = false;
|
||||
config.memSpec->bitWidth = queryUIntParameter(architecture, "width");
|
||||
config.memSpec->DLL = false;
|
||||
config.memSpec->termination = false;
|
||||
|
||||
//MemTimings
|
||||
XMLElement *timings = memspec->FirstChildElement("memtimingspec");
|
||||
config.memSpec.clkMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
config.memSpec.clk = FrequencyToClk(config.memSpec.clkMHz);
|
||||
sc_time clk = config.memSpec.clk;
|
||||
config.memSpec.tRP = clk * queryUIntParameter(timings, "RP");
|
||||
config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
config.memSpec.tRC = clk * queryUIntParameter(timings, "RC");
|
||||
config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec.tRRD_L = config.memSpec.tRRD_S;
|
||||
config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec.tCCD_L = config.memSpec.tCCD_S;
|
||||
config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
config.memSpec.tNAW = clk * queryUIntParameter(timings, "TAW");
|
||||
config.memSpec.tRL = clk * queryUIntParameter(timings, "RL");
|
||||
config.memSpec.tWL = clk * queryUIntParameter(timings, "WL");
|
||||
config.memSpec.tWR = clk * queryUIntParameter(timings, "WR");
|
||||
config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec.tWTR_L = config.memSpec.tWTR_S;
|
||||
config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
config.memSpec.tXP = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec.tXPDLL = config.memSpec.tXP;
|
||||
config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec.tXSRDLL = config.memSpec.tXSR;
|
||||
config.memSpec.tAL = clk * queryUIntParameter(timings, "AL");
|
||||
config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
config.memSpec->clkMHz = queryDoubleParameter(timings, "clkMhz");
|
||||
config.memSpec->clk = FrequencyToClk(config.memSpec->clkMHz);
|
||||
sc_time clk = config.memSpec->clk;
|
||||
config.memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
config.memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
config.memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
config.memSpec->tRRD_S = clk * queryUIntParameter(timings, "RRD");
|
||||
config.memSpec->tRRD_L = config.memSpec->tRRD_S;
|
||||
config.memSpec->tCCD_S = clk * queryUIntParameter(timings, "CCD");
|
||||
config.memSpec->tCCD_L = config.memSpec->tCCD_S;
|
||||
config.memSpec->tRCD = clk * queryUIntParameter(timings, "RCD");
|
||||
config.memSpec->tNAW = clk * queryUIntParameter(timings, "TAW");
|
||||
config.memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
config.memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
config.memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
config.memSpec->tWTR_S = clk * queryUIntParameter(timings, "WTR");
|
||||
config.memSpec->tWTR_L = config.memSpec->tWTR_S;
|
||||
config.memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
config.memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
config.memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
config.memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
config.memSpec->tXPDLL = config.memSpec->tXP;
|
||||
config.memSpec->tXSR = clk * queryUIntParameter(timings, "XS");
|
||||
config.memSpec->tXSRDLL = config.memSpec->tXSR;
|
||||
config.memSpec->tAL = clk * queryUIntParameter(timings, "AL");
|
||||
config.memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
config.memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
|
||||
config.memSpec.refreshTimings.clear();
|
||||
for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) {
|
||||
config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC,
|
||||
config.memSpec.tREFI);
|
||||
config.memSpec->refreshTimings.clear();
|
||||
for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; ++i) {
|
||||
config.memSpec->refreshTimings[Bank(i)] = RefreshTiming(config.memSpec->tRFC,
|
||||
config.memSpec->tREFI);
|
||||
}
|
||||
|
||||
// Currents and Volatages:
|
||||
XMLElement *powers = memspec->FirstChildElement("mempowerspec");
|
||||
config.memSpec.iDD0 = queryDoubleParameter(powers, "idd0");
|
||||
config.memSpec.iDD02 = queryDoubleParameter(powers, "idd02");
|
||||
config.memSpec.iDD2P0 = queryDoubleParameter(powers, "idd2p0");
|
||||
config.memSpec.iDD2P02 = queryDoubleParameter(powers, "idd2p02");
|
||||
config.memSpec.iDD2P1 = queryDoubleParameter(powers, "idd2p1");
|
||||
config.memSpec.iDD2P12 = queryDoubleParameter(powers, "idd2p12");
|
||||
config.memSpec.iDD2N = queryDoubleParameter(powers, "idd2n");
|
||||
config.memSpec.iDD2N2 = queryDoubleParameter(powers, "idd2n2");
|
||||
config.memSpec.iDD3P0 = queryDoubleParameter(powers, "idd3p0");
|
||||
config.memSpec.iDD3P02 = queryDoubleParameter(powers, "idd3p02");
|
||||
config.memSpec.iDD3P1 = queryDoubleParameter(powers, "idd3p1");
|
||||
config.memSpec.iDD3P12 = queryDoubleParameter(powers, "idd3p12");
|
||||
config.memSpec.iDD3N = queryDoubleParameter(powers, "idd3n");
|
||||
config.memSpec.iDD3N2 = queryDoubleParameter(powers, "idd3n2");
|
||||
config.memSpec.iDD4R = queryDoubleParameter(powers, "idd4r");
|
||||
config.memSpec.iDD4R2 = queryDoubleParameter(powers, "idd4r2");
|
||||
config.memSpec.iDD4W = queryDoubleParameter(powers, "idd4w");
|
||||
config.memSpec.iDD4W2 = queryDoubleParameter(powers, "idd4w2");
|
||||
config.memSpec.iDD5 = queryDoubleParameter(powers, "idd5");
|
||||
config.memSpec.iDD52 = queryDoubleParameter(powers, "idd52");
|
||||
config.memSpec.iDD6 = queryDoubleParameter(powers, "idd6");
|
||||
config.memSpec.iDD62 = queryDoubleParameter(powers, "idd62");
|
||||
config.memSpec.vDD = queryDoubleParameter(powers, "vdd");
|
||||
config.memSpec.vDD2 = queryDoubleParameter(powers, "vdd2");
|
||||
config.memSpec->iDD0 = queryDoubleParameter(powers, "idd0");
|
||||
config.memSpec->iDD02 = queryDoubleParameter(powers, "idd02");
|
||||
config.memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p0");
|
||||
config.memSpec->iDD2P02 = queryDoubleParameter(powers, "idd2p02");
|
||||
config.memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p1");
|
||||
config.memSpec->iDD2P12 = queryDoubleParameter(powers, "idd2p12");
|
||||
config.memSpec->iDD2N = queryDoubleParameter(powers, "idd2n");
|
||||
config.memSpec->iDD2N2 = queryDoubleParameter(powers, "idd2n2");
|
||||
config.memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p0");
|
||||
config.memSpec->iDD3P02 = queryDoubleParameter(powers, "idd3p02");
|
||||
config.memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p1");
|
||||
config.memSpec->iDD3P12 = queryDoubleParameter(powers, "idd3p12");
|
||||
config.memSpec->iDD3N = queryDoubleParameter(powers, "idd3n");
|
||||
config.memSpec->iDD3N2 = queryDoubleParameter(powers, "idd3n2");
|
||||
config.memSpec->iDD4R = queryDoubleParameter(powers, "idd4r");
|
||||
config.memSpec->iDD4R2 = queryDoubleParameter(powers, "idd4r2");
|
||||
config.memSpec->iDD4W = queryDoubleParameter(powers, "idd4w");
|
||||
config.memSpec->iDD4W2 = queryDoubleParameter(powers, "idd4w2");
|
||||
config.memSpec->iDD5 = queryDoubleParameter(powers, "idd5");
|
||||
config.memSpec->iDD52 = queryDoubleParameter(powers, "idd52");
|
||||
config.memSpec->iDD6 = queryDoubleParameter(powers, "idd6");
|
||||
config.memSpec->iDD62 = queryDoubleParameter(powers, "idd62");
|
||||
config.memSpec->vDD = queryDoubleParameter(powers, "vdd");
|
||||
config.memSpec->vDD2 = queryDoubleParameter(powers, "vdd2");
|
||||
}
|
||||
|
||||
@@ -32,14 +32,15 @@
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef CONFIGURATIONLOADER_H_
|
||||
#define CONFIGURATIONLOADER_H_
|
||||
#ifndef CONFIGURATIONLOADER_H
|
||||
#define CONFIGURATIONLOADER_H
|
||||
|
||||
#include <string>
|
||||
#include "../../../common/third_party/tinyxml2/tinyxml2.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../../../common/utils.h"
|
||||
#include "Configuration.h"
|
||||
|
||||
class ConfigurationLoader
|
||||
@@ -65,8 +66,9 @@ private:
|
||||
static void loadConfig(Configuration &config, tinyxml2::XMLElement *configNode);
|
||||
static void loadConfigFromUri(Configuration &config, std::string uri,
|
||||
std::string first_element);
|
||||
|
||||
//specific loader
|
||||
// Loads common config of DRAMs
|
||||
static void loadCommons(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
// Load specific config
|
||||
static void loadDDR3(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
static void loadDDR4(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
static void loadLPDDR4(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
@@ -74,4 +76,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* CONFIGURATIONLOADER_H_ */
|
||||
#endif // CONFIGURATIONLOADER_H
|
||||
|
||||
@@ -32,17 +32,18 @@
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef MemSpec_H_
|
||||
#define MemSpec_H_
|
||||
#ifndef MEMSPEC_H
|
||||
#define MEMSPEC_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <map>
|
||||
#include "../../../common/dramExtension.h"
|
||||
#include "../../../common/dramExtensions.h"
|
||||
|
||||
|
||||
struct RefreshTiming {
|
||||
struct RefreshTiming
|
||||
{
|
||||
RefreshTiming() {}
|
||||
RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tRFC2(SC_ZERO_TIME),
|
||||
tRFC4(SC_ZERO_TIME), tREFI(tREFI) {}
|
||||
@@ -54,12 +55,8 @@ struct RefreshTiming {
|
||||
sc_time tREFI;
|
||||
};
|
||||
|
||||
struct MemSpec {
|
||||
MemSpec()
|
||||
{
|
||||
//default DDR4
|
||||
}
|
||||
|
||||
struct MemSpec
|
||||
{
|
||||
const std::vector<Bank> &getBanks() const
|
||||
{
|
||||
static std::vector<Bank> banks;
|
||||
@@ -90,24 +87,31 @@ struct MemSpec {
|
||||
// Memspec Variables:
|
||||
double clkMHz;
|
||||
sc_time clk;
|
||||
sc_time tRP; //precharge-time (pre -> act same bank)
|
||||
sc_time tRP; //precharge-time (pre -> act same bank
|
||||
sc_time tRTP; //Read to precharge
|
||||
sc_time tRCD; //act -> read/write
|
||||
sc_time tRL; //read latency (read command start to data strobe)
|
||||
sc_time tWL; //write latency
|
||||
sc_time tWR; //write recovery (write to precharge)
|
||||
sc_time tCKESR; //min time in sref
|
||||
sc_time tCKE; //min time in pdna or pdnp
|
||||
|
||||
sc_time tRFC; //min ref->act delay 1X mode
|
||||
sc_time tRFC2; //min ref->act delay 2X mode
|
||||
sc_time tRFC4; //min ref->act delay 4X mode
|
||||
sc_time tREFI; //auto refresh must be issued at an average periodic interval tREFI
|
||||
|
||||
// TODO: move to specific memspecs
|
||||
sc_time tRPAB; //precharge-all time only for LPDDR4
|
||||
sc_time tRAS; //active-time (act -> pre same bank)
|
||||
sc_time tRC; //RAS-cycle-time (min time bw 2 succesive ACT to same bank)
|
||||
sc_time tCCD_S; //max(bl, tCCD) is relevant for rd->rd
|
||||
sc_time tCCD_L;
|
||||
sc_time tRTP; //Read to precharge
|
||||
sc_time tRRD_S; //min time bw 2 succesive ACT to different banks (different bank group)
|
||||
sc_time tRRD_L; //.. (same bank group)
|
||||
sc_time tRCD; //act -> read/write
|
||||
sc_time tNAW; //n activate window
|
||||
sc_time tRL; //read latency (read command start to data strobe)
|
||||
sc_time tWL; //write latency
|
||||
sc_time tWR; //write recovery (write to precharge)
|
||||
sc_time tWTR_S; //write to read (different bank group)
|
||||
sc_time tWTR_L; //.. (same bank group)
|
||||
sc_time tCKESR; //min time in sref
|
||||
sc_time tCKE; //min time in pdna or pdnp
|
||||
sc_time tXP; //min delay to row access command after pdnpx pdnax
|
||||
sc_time tXPDLL; //min delay to row access command after pdnpx pdnax for dll commands
|
||||
sc_time tXSR; //min delay to row access command after srefx
|
||||
@@ -115,11 +119,6 @@ struct MemSpec {
|
||||
sc_time tAL; //additive delay (delayed execution in dram)
|
||||
sc_time tDQSCK;
|
||||
|
||||
sc_time tRFC; //min ref->act delay 1X mode
|
||||
sc_time tRFC2; //min ref->act delay 2X mode
|
||||
sc_time tRFC4; //min ref->act delay 4X mode
|
||||
sc_time tREFI; //auto refresh must be issued at an average periodic interval tREFI
|
||||
|
||||
// Currents and Voltages:
|
||||
double iDD0;
|
||||
double iDD02;
|
||||
@@ -165,5 +164,25 @@ struct MemSpec {
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* MemSpec_H_ */
|
||||
struct MemSpecDDR3 : public MemSpec
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
struct MemSpecDDR4 : public MemSpec
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
struct MemSpecWideIO : public MemSpec
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
struct MemSpecLPDDR4 : public MemSpec
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
#endif // MEMSPEC_H
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef THERMALSIM_CONFIG_H
|
||||
#define THERMALSIM_CONFIG_H
|
||||
#ifndef TEMPERATURESIMCONFIG_H
|
||||
#define TEMPERATURESIMCONFIG_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <iostream>
|
||||
@@ -43,10 +43,10 @@
|
||||
|
||||
#include "../../../common/DebugManager.h"
|
||||
#include "../../../common/third_party/tinyxml2/tinyxml2.h"
|
||||
#include "../../../common/Utils.h"
|
||||
|
||||
struct TemperatureSimConfig {
|
||||
#include "../../../common/utils.h"
|
||||
|
||||
struct TemperatureSimConfig
|
||||
{
|
||||
// Temperature Scale
|
||||
std::string TemperatureScale;
|
||||
std::string pathToResources;
|
||||
@@ -132,5 +132,5 @@ struct TemperatureSimConfig {
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* THERMALSIM_CONFIG_H */
|
||||
#endif // TEMPERATURESIMCONFIG_H
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef IPOWERDOWNMANAGER_H_
|
||||
#define IPOWERDOWNMANAGER_H_
|
||||
#ifndef IPOWERDOWNMANAGER_H
|
||||
#define IPOWERDOWNMANAGER_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include "../../../common/dramExtension.h"
|
||||
#include "../../../common/dramExtensions.h"
|
||||
#include "../../Command.h"
|
||||
|
||||
|
||||
@@ -126,4 +126,4 @@ inline std::string powerDownStateToString(PowerDownState powerDownState)
|
||||
}
|
||||
|
||||
|
||||
#endif /* IPOWERDOWNMANAGER_H_ */
|
||||
#endif // IPOWERDOWNMANAGER_H
|
||||
|
||||
@@ -40,12 +40,12 @@
|
||||
|
||||
#include "PowerDownManager.h"
|
||||
#include <systemc.h>
|
||||
#include "../../../common/dramExtension.h"
|
||||
#include "../../../common/dramExtensions.h"
|
||||
#include "../scheduling/ScheduledCommand.h"
|
||||
|
||||
|
||||
|
||||
class NoPowerDown: public IPowerDownManager
|
||||
class NoPowerDown : public IPowerDownManager
|
||||
{
|
||||
public:
|
||||
NoPowerDown() {}
|
||||
|
||||
@@ -39,10 +39,10 @@
|
||||
#include <string>
|
||||
#include "PowerDownManager.h"
|
||||
#include "../ControllerCore.h"
|
||||
#include "../TimingCalculation.h"
|
||||
#include "../timingCalculations.h"
|
||||
#include "../../../common/DebugManager.h"
|
||||
#include <algorithm>
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../../../common/utils.h"
|
||||
|
||||
using namespace tlm;
|
||||
using namespace std;
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef POWERDOWNMANAGER_H_
|
||||
#define POWERDOWNMANAGER_H_
|
||||
#ifndef POWERDOWNMANAGER_H
|
||||
#define POWERDOWNMANAGER_H
|
||||
|
||||
#include "PowerDownManagerBankwise.h"
|
||||
|
||||
@@ -68,4 +68,4 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
#endif /* POWERDOWNMANAGER_H_ */
|
||||
#endif // POWERDOWNMANAGER_H
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
|
||||
#include "PowerDownManager.h"
|
||||
#include "../ControllerCore.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../../../common/utils.h"
|
||||
#include "../../../common/DebugManager.h"
|
||||
#include "../TimingCalculation.h"
|
||||
#include "../timingCalculations.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
|
||||
@@ -34,15 +34,15 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef POWERDOWNMANAGERBANKWISE_H_
|
||||
#define POWERDOWNMANAGERBANKWISE_H_
|
||||
#ifndef POWERDOWNMANAGERBANKWISE_H
|
||||
#define POWERDOWNMANAGERBANKWISE_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "../../Command.h"
|
||||
#include "../../../common/dramExtension.h"
|
||||
#include "../../../common/dramExtensions.h"
|
||||
#include "../scheduling/ScheduledCommand.h"
|
||||
#include "IPowerDownManager.h"
|
||||
|
||||
@@ -82,5 +82,5 @@ protected:
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
#endif /* POWERDOWNMANAGERBANKWISE_H_ */
|
||||
#endif // POWERDOWNMANAGERBANKWISE_H
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
|
||||
#include "PowerDownManagerTimeout.h"
|
||||
#include "../ControllerCore.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../../../common/utils.h"
|
||||
#include "../../../common/DebugManager.h"
|
||||
#include "../TimingCalculation.h"
|
||||
#include "../timingCalculations.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
|
||||
@@ -36,12 +36,12 @@
|
||||
* Felipe S. Prado
|
||||
*/
|
||||
|
||||
#ifndef POWERDOWNMANAGERTIMEOUT_H_
|
||||
#define POWERDOWNMANAGERTIMEOUT_H_
|
||||
#ifndef POWERDOWNMANAGERTIMEOUT_H
|
||||
#define POWERDOWNMANAGERTIMEOUT_H
|
||||
|
||||
#include "PowerDownManager.h"
|
||||
#include <systemc.h>
|
||||
#include "../../../common/dramExtension.h"
|
||||
#include "../../../common/dramExtensions.h"
|
||||
#include "../scheduling/ScheduledCommand.h"
|
||||
#include <map>
|
||||
|
||||
@@ -60,4 +60,4 @@ public:
|
||||
|
||||
|
||||
|
||||
#endif /* POWERDOWNMANAGERTIMEOUT_H_ */
|
||||
#endif // POWERDOWNMANAGERTIMEOUT_H
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
|
||||
#include "PowerDownManagerTimeoutBankwise.h"
|
||||
#include "../ControllerCore.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../../../common/utils.h"
|
||||
#include "../../../common/DebugManager.h"
|
||||
#include "../TimingCalculation.h"
|
||||
#include "../timingCalculations.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
|
||||
@@ -36,12 +36,12 @@
|
||||
* Felipe S. Prado
|
||||
*/
|
||||
|
||||
#ifndef POWERDOWNMANAGERTIMEOUTBANKWISE_H_
|
||||
#define POWERDOWNMANAGERTIMEOUTBANKWISE_H_
|
||||
#ifndef POWERDOWNMANAGERTIMEOUTBANKWISE_H
|
||||
#define POWERDOWNMANAGERTIMEOUTBANKWISE_H
|
||||
|
||||
#include "PowerDownManager.h"
|
||||
#include <systemc.h>
|
||||
#include "../../../common/dramExtension.h"
|
||||
#include "../../../common/dramExtensions.h"
|
||||
#include "../scheduling/ScheduledCommand.h"
|
||||
#include <map>
|
||||
|
||||
@@ -60,4 +60,4 @@ public:
|
||||
|
||||
|
||||
|
||||
#endif /* POWERDOWNMANAGERTIMEOUTBANKWISE_H_ */
|
||||
#endif // POWERDOWNMANAGERTIMEOUTBANKWISE_H
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef IREFRESHMANAGER_H_
|
||||
#define IREFRESHMANAGER_H_
|
||||
#ifndef IREFRESHMANAGER_H
|
||||
#define IREFRESHMANAGER_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include "../scheduling/ScheduledCommand.h"
|
||||
@@ -62,5 +62,5 @@ public:
|
||||
virtual bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) = 0;
|
||||
};
|
||||
|
||||
#endif /* IREFRESHMANAGER_H_ */
|
||||
#endif // IREFRESHMANAGER_H
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
|
||||
#include "RGR.h"
|
||||
#include "../ControllerCore.h"
|
||||
#include "../TimingCalculation.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../timingCalculations.h"
|
||||
#include "../../../common/utils.h"
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE !(TRUE)
|
||||
@@ -46,19 +46,19 @@
|
||||
using namespace std;
|
||||
|
||||
RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore),
|
||||
timing(ctrlcore.config.memSpec.refreshTimings[ccore.getBanks()[0]])
|
||||
timing(ctrlcore.config.memSpec->refreshTimings[ccore.getBanks()[0]])
|
||||
{
|
||||
fmb = ccore.config.ControllerCoreRefForceMaxPostponeBurst;
|
||||
bwl = ccore.config.BankwiseLogic;
|
||||
ri = ccore.config.getRowInc();
|
||||
auto nr = ccore.config.memSpec.NumberOfRows;
|
||||
auto nr = ccore.config.memSpec->NumberOfRows;
|
||||
auto nar = ccore.config.getNumAR();
|
||||
auto m = ccore.config.getRefMode();
|
||||
rpr = (nr / m) / nar;
|
||||
assert(rpr > 0);
|
||||
tREFIx = timing.tREFI / m;
|
||||
trp = ccore.config.getTrpb();
|
||||
trcd = ccore.config.memSpec.tRCD;
|
||||
trcd = ccore.config.memSpec->tRCD;
|
||||
postponeEnabled = ccore.config.ControllerCoreRefEnablePostpone;
|
||||
pullInEnabled = ccore.config.ControllerCoreRefEnablePullIn;
|
||||
maxpostpone = ccore.config.ControllerCoreRefMaxPostponed * m;
|
||||
@@ -73,7 +73,7 @@ RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore),
|
||||
}
|
||||
#if INITIAL_DISPLACEMENT == TRUE
|
||||
if (bwl) {
|
||||
auto nbs = ccore.config.memSpec.NumberOfBanks;
|
||||
auto nbs = ccore.config.memSpec->NumberOfBanks;
|
||||
for (Bank b : ccore.getBanks()) {
|
||||
nextPlannedRefreshs[b] = b.ID() * tREFIx / nbs;
|
||||
}
|
||||
|
||||
@@ -32,12 +32,15 @@
|
||||
* Author: Éder F. Zulian
|
||||
*/
|
||||
|
||||
#ifndef RGR_MANAGER_H_
|
||||
#define RGR_MANAGER_H_
|
||||
#include "../../../common/dramExtension.h"
|
||||
#ifndef RGR_H
|
||||
#define RGR_H
|
||||
|
||||
#include "../../../common/dramExtensions.h"
|
||||
#include "../configuration/MemSpec.h"
|
||||
#include "IRefreshManager.h"
|
||||
|
||||
class ControllerCore;
|
||||
|
||||
class RGR : public IRefreshManager, public sc_module
|
||||
{
|
||||
public:
|
||||
@@ -73,5 +76,6 @@ private:
|
||||
void planNextRefresh(Bank b, sc_time t, bool align);
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
#endif /* RGR_MANAGER_H_ */
|
||||
|
||||
#endif // RGR_H
|
||||
|
||||
|
||||
@@ -39,14 +39,14 @@
|
||||
|
||||
#include "RefreshManager.h"
|
||||
#include "../ControllerCore.h"
|
||||
#include "../TimingCalculation.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../timingCalculations.h"
|
||||
#include "../../../common/utils.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManager::RefreshManager(sc_module_name,
|
||||
ControllerCore &controller) : controllerCore(controller),
|
||||
timing(controller.config.memSpec.refreshTimings[Bank(0)])
|
||||
timing(controller.config.memSpec->refreshTimings[Bank(0)])
|
||||
{
|
||||
auto m = controllerCore.config.getRefMode();
|
||||
tREFIx = timing.tREFI / m;
|
||||
@@ -159,7 +159,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload,
|
||||
pre = doRefresh(payload, time);
|
||||
nrt = tRFCx;
|
||||
if (pre)
|
||||
nrt += controllerCore.config.memSpec.tRP;
|
||||
nrt += controllerCore.config.memSpec->tRP;
|
||||
nextRefTiming = nrt;
|
||||
nextState = ST_PULLIN;
|
||||
} else {
|
||||
@@ -175,7 +175,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload,
|
||||
pre = doRefresh(payload, time);
|
||||
nrt = tRFCx;
|
||||
if (pre)
|
||||
nrt += controllerCore.config.memSpec.tRP;
|
||||
nrt += controllerCore.config.memSpec->tRP;
|
||||
nextRefTiming = nrt;
|
||||
nextState = ST_PULLIN;
|
||||
} else {
|
||||
@@ -220,7 +220,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload,
|
||||
} else {
|
||||
nrt = tRFCx;
|
||||
if (pre)
|
||||
nrt += controllerCore.config.memSpec.tRP;
|
||||
nrt += controllerCore.config.memSpec->tRP;
|
||||
nextRefTiming = nrt;
|
||||
nextState = ST_BURST;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
* Éder F. Zulian
|
||||
*/
|
||||
|
||||
#ifndef REFRESHMANAGER_H_
|
||||
#define REFRESHMANAGER_H_
|
||||
#ifndef REFRESHMANAGER_H
|
||||
#define REFRESHMANAGER_H
|
||||
|
||||
#include "IRefreshManager.h"
|
||||
#include "../configuration/MemSpec.h"
|
||||
@@ -78,5 +78,5 @@ private:
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
#endif /* REFRESHMANAGER_H_ */
|
||||
#endif // REFRESHMANAGER_H
|
||||
|
||||
|
||||
@@ -37,14 +37,14 @@
|
||||
|
||||
#include "RefreshManagerBankwise.h"
|
||||
#include "../ControllerCore.h"
|
||||
#include "../TimingCalculation.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../timingCalculations.h"
|
||||
#include "../../../common/utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name,
|
||||
ControllerCore &controller) : controllerCore(controller),
|
||||
timing(controller.config.memSpec.refreshTimings[Bank(0)])
|
||||
timing(controller.config.memSpec->refreshTimings[Bank(0)])
|
||||
{
|
||||
auto m = controllerCore.config.getRefMode();
|
||||
tREFIx = timing.tREFI / m;
|
||||
@@ -146,7 +146,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
|
||||
pre = doRefresh(payload, time);
|
||||
nrt = tRFCx;
|
||||
if (pre)
|
||||
nrt += controllerCore.config.memSpec.tRP;
|
||||
nrt += controllerCore.config.memSpec->tRP;
|
||||
nextRefTiming = nrt;
|
||||
nextState[bank] = ST_PULLIN;
|
||||
} else {
|
||||
@@ -162,7 +162,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
|
||||
pre = doRefresh(payload, time);
|
||||
nrt = tRFCx;
|
||||
if (pre)
|
||||
nrt += controllerCore.config.memSpec.tRP;
|
||||
nrt += controllerCore.config.memSpec->tRP;
|
||||
nextRefTiming = nrt;
|
||||
nextState[bank] = ST_PULLIN;
|
||||
} else {
|
||||
@@ -208,7 +208,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload,
|
||||
} else {
|
||||
nrt = tRFCx;
|
||||
if (pre)
|
||||
nrt += controllerCore.config.memSpec.tRP;
|
||||
nrt += controllerCore.config.memSpec->tRP;
|
||||
nextRefTiming = nrt;
|
||||
nextState[bank] = ST_BURST;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
* Éder F. Zulian
|
||||
*/
|
||||
|
||||
#ifndef BANKWISEREFRESHMANAGER_H_
|
||||
#define BANKWISEREFRESHMANAGER_H_
|
||||
#ifndef REFRESHMANAGERBANKWISE_H
|
||||
#define REFRESHMANAGERBANKWISE_H
|
||||
|
||||
//#include "../../../common/dramExtension.h"
|
||||
#include "IRefreshManager.h"
|
||||
@@ -79,5 +79,5 @@ private:
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
#endif /* BANKWISEREFRESHMANAGER_H_ */
|
||||
#endif // REFRESHMANAGERBANKWISE_H
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
*/
|
||||
|
||||
#include "ScheduledCommand.h"
|
||||
#include "../TimingCalculation.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../timingCalculations.h"
|
||||
#include "../../../common/utils.h"
|
||||
#include "../configuration/Configuration.h"
|
||||
|
||||
bool ScheduledCommand::isNoCommand() const
|
||||
@@ -127,13 +127,13 @@ TimeInterval ScheduledCommand::getIntervalOnDataStrobe() const
|
||||
|| getCommand() == Command::Write
|
||||
|| getCommand() == Command::WriteA);
|
||||
|
||||
MemSpec &timings = Configuration::getInstance().memSpec;
|
||||
MemSpec *timings = Configuration::getInstance().memSpec;
|
||||
|
||||
if (getCommand() == Command::Read || getCommand() == Command::ReadA) {
|
||||
return TimeInterval(getStart() + timings.tRL,
|
||||
getStart() + timings.tRL + getReadAccessTime());
|
||||
return TimeInterval(getStart() + timings->tRL,
|
||||
getStart() + timings->tRL + getReadAccessTime());
|
||||
} else {
|
||||
return TimeInterval(getStart() + timings.tWL - timings.clk / 2,
|
||||
getStart() + timings.tWL + getWriteAccessTime() - timings.clk / 2);
|
||||
return TimeInterval(getStart() + timings->tWL - timings->clk / 2,
|
||||
getStart() + timings->tWL + getWriteAccessTime() - timings->clk / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,14 +34,14 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef SCHEDULEDCOMMAND_H_
|
||||
#define SCHEDULEDCOMMAND_H_
|
||||
#ifndef SCHEDULEDCOMMAND_H
|
||||
#define SCHEDULEDCOMMAND_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "../../Command.h"
|
||||
#include "../../../common/dramExtension.h"
|
||||
#include "../../../common/Utils.h"
|
||||
#include "../../../common/dramExtensions.h"
|
||||
#include "../../../common/utils.h"
|
||||
|
||||
class ScheduledCommand
|
||||
{
|
||||
@@ -98,5 +98,5 @@ private:
|
||||
DramExtension extension;
|
||||
};
|
||||
|
||||
#endif /* SCHEDULEDCOMMAND_H_ */
|
||||
#endif // SCHEDULEDCOMMAND_H
|
||||
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include "ActBChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
#include "../../timingCalculations.h"
|
||||
#include "../../../../common/DebugManager.h"
|
||||
#include "../../../Command.h"
|
||||
#include "../../../../common/Utils.h"
|
||||
#include "../../../../common/utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -53,27 +53,27 @@ void ActBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const
|
||||
Configuration::getInstance().getTrpb());
|
||||
} else if (lcb.getCommand() == Command::Precharge
|
||||
|| lcb.getCommand() == Command::PrechargeAll) {
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRP);
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRP);
|
||||
} else if (lcb.getCommand() == Command::ReadA) {
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(),
|
||||
config.memSpec.tRTP + config.memSpec.tRP);
|
||||
config.memSpec->tRTP + config.memSpec->tRP);
|
||||
} else if (lcb.getCommand() == Command::WriteA) {
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR +
|
||||
config.memSpec->tRP);
|
||||
} else if (lcb.getCommand() == Command::AutoRefresh) {
|
||||
auto m = Configuration::getInstance().getRefMode();
|
||||
if (m == 4)
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC4);
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRFC4);
|
||||
else if (m == 2)
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC2);
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRFC2);
|
||||
else
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC);
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRFC);
|
||||
} else if (lcb.getCommand() == Command::PDNPX
|
||||
|| lcb.getCommand() == Command::PDNAX) {
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tXP);
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tXP);
|
||||
} else if (lcb.getCommand() == Command::SREFX) {
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tXSR);
|
||||
cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tXSR);
|
||||
} else {
|
||||
reportFatal("ActB Checker",
|
||||
"ActB can not follow " + commandToString(lcb.getCommand()));
|
||||
@@ -81,13 +81,13 @@ void ActBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const
|
||||
}
|
||||
ScheduledCommand lc;
|
||||
if ((lc = state.getLastCommand(Command::PrechargeAll)).isValidCommand()) {
|
||||
cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec.tRP);
|
||||
cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec->tRP);
|
||||
}
|
||||
delay_to_satisfy_activateToActivate_sameBank(cmd);
|
||||
while (!(state.bus.isFree(cmd.getStart())
|
||||
&& satsfies_activateToActivate_differentBank(cmd)
|
||||
&& satisfies_nActivateWindow(cmd))) {
|
||||
cmd.delayStart(config.memSpec.clk);
|
||||
cmd.delayStart(config.memSpec->clk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ void ActBChecker::delay_to_satisfy_activateToActivate_sameBank(
|
||||
ScheduledCommand lastActOnBank = state.getLastCommand(Command::Activate,
|
||||
cmd.getBank());
|
||||
if (lastActOnBank.isValidCommand()) {
|
||||
cmd.establishMinDistanceFromStart(lastActOnBank.getStart(), config.memSpec.tRC);
|
||||
cmd.establishMinDistanceFromStart(lastActOnBank.getStart(), config.memSpec->tRC);
|
||||
}
|
||||
ScheduledCommand lastActBOnBank = state.getLastCommand(Command::ActB,
|
||||
cmd.getBank());
|
||||
@@ -121,7 +121,7 @@ bool ActBChecker::satsfies_activateToActivate_differentBank(
|
||||
}
|
||||
for (auto act : state.lastActivates) {
|
||||
sc_time t = act.first, tRRD = (cmd.getBankGroup() == act.second.getBankGroup() ?
|
||||
config.memSpec.tRRD_L : config.memSpec.tRRD_S);
|
||||
config.memSpec->tRRD_L : config.memSpec->tRRD_S);
|
||||
if ((t < cmd.getStart() && cmd.getStart() - t < tRRD) || (cmd.getStart() <= t
|
||||
&& t - cmd.getStart() < tRRD)) {
|
||||
return false;
|
||||
@@ -132,11 +132,11 @@ bool ActBChecker::satsfies_activateToActivate_differentBank(
|
||||
|
||||
bool ActBChecker::satisfies_nActivateWindow(ScheduledCommand &cmd) const
|
||||
{
|
||||
if (state.lastActivatesB.size() >= config.memSpec.nActivate) {
|
||||
if (state.lastActivatesB.size() >= config.memSpec->nActivate) {
|
||||
map<sc_time, ScheduledCommand>lastActivates = state.lastActivatesB;
|
||||
lastActivates.emplace(cmd.getStart(), cmd);
|
||||
auto upper = lastActivates.begin();
|
||||
advance(upper, config.memSpec.nActivate);
|
||||
advance(upper, config.memSpec->nActivate);
|
||||
auto lower = lastActivates.begin();
|
||||
while (upper != lastActivates.end()) {
|
||||
if (upper->first - lower->first < Configuration::getInstance().getTfawb()) {
|
||||
|
||||
@@ -31,13 +31,16 @@
|
||||
*
|
||||
* Author: Éder F. Zulian
|
||||
*/
|
||||
#ifndef ACTB_CHECKER_H_
|
||||
#define ACTB_CHECKER_H_
|
||||
|
||||
#ifndef ACTBCHECKER_H
|
||||
#define ACTBCHECKER_H
|
||||
|
||||
#include <map>
|
||||
#include "ICommandChecker.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../../ControllerState.h"
|
||||
class ActBChecker: public ICommandChecker
|
||||
|
||||
class ActBChecker : public ICommandChecker
|
||||
{
|
||||
public:
|
||||
ActBChecker(const Configuration &config,
|
||||
@@ -53,4 +56,5 @@ private:
|
||||
bool satsfies_activateToActivate_differentBank(ScheduledCommand &command) const;
|
||||
bool satisfies_nActivateWindow(ScheduledCommand &command) const;
|
||||
};
|
||||
#endif /* ACTB_CHECKER_H_ */
|
||||
|
||||
#endif // ACTBCHECKER_H
|
||||
|
||||
@@ -38,10 +38,10 @@
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include "ActivateChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
#include "../../timingCalculations.h"
|
||||
#include "../../../../common/DebugManager.h"
|
||||
#include "../../../Command.h"
|
||||
#include "../../../../common/Utils.h"
|
||||
#include "../../../../common/utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -56,32 +56,32 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
|| lastCommandOnBank.getCommand() == Command::Precharge
|
||||
|| lastCommandOnBank.getCommand() == Command::PrechargeAll) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tRP);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::ReadA) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tRTP + config.memSpec.tRP);
|
||||
config.memSpec->tRTP + config.memSpec->tRP);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::WriteA) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR +
|
||||
config.memSpec->tRP);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) {
|
||||
auto m = Configuration::getInstance().getRefMode();
|
||||
if (m == 4)
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tRFC4);
|
||||
config.memSpec->tRFC4);
|
||||
else if (m == 2)
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tRFC2);
|
||||
config.memSpec->tRFC2);
|
||||
else
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tRFC);
|
||||
config.memSpec->tRFC);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::PDNPX
|
||||
|| lastCommandOnBank.getCommand() == Command::PDNAX) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tXP);
|
||||
config.memSpec->tXP);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::SREFX) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tXSR);
|
||||
config.memSpec->tXSR);
|
||||
} else
|
||||
reportFatal("Activate Checker",
|
||||
"Activate can not follow " + commandToString(lastCommandOnBank.getCommand()));
|
||||
@@ -92,7 +92,7 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
while (!(state.bus.isFree(command.getStart())
|
||||
&& satsfies_activateToActivate_differentBank(command)
|
||||
&& satisfies_nActivateWindow(command))) {
|
||||
command.delayStart(config.memSpec.clk);
|
||||
command.delayStart(config.memSpec->clk);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -104,14 +104,14 @@ void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank(
|
||||
command.getBank());
|
||||
if (lastActivateOnBank.isValidCommand()) {
|
||||
command.establishMinDistanceFromStart(lastActivateOnBank.getStart(),
|
||||
config.memSpec.tRC);
|
||||
config.memSpec->tRC);
|
||||
}
|
||||
|
||||
ScheduledCommand lastActBOnBank = state.getLastCommand(Command::ActB,
|
||||
command.getBank());
|
||||
if (lastActBOnBank.isValidCommand()) {
|
||||
command.establishMinDistanceFromStart(lastActivateOnBank.getStart(),
|
||||
config.memSpec.tRC);
|
||||
config.memSpec->tRC);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ bool ActivateChecker::satsfies_activateToActivate_differentBank(
|
||||
for (auto act : state.lastActivates) {
|
||||
sc_time time = act.first;
|
||||
sc_time tRRD = (command.getBankGroup() == act.second.getBankGroup()) ?
|
||||
config.memSpec.tRRD_L : config.memSpec.tRRD_S;
|
||||
config.memSpec->tRRD_L : config.memSpec->tRRD_S;
|
||||
|
||||
if ((time < command.getStart() && command.getStart() - time < tRRD)
|
||||
|| (command.getStart() <= time && time - command.getStart() < tRRD))
|
||||
@@ -137,15 +137,15 @@ bool ActivateChecker::satisfies_nActivateWindow(ScheduledCommand &command) const
|
||||
* command in a copied set (not necessarily the last in time),
|
||||
* and check if the n-act constraint holds for the whole set.
|
||||
*/
|
||||
if (state.lastActivates.size() >= config.memSpec.nActivate) {
|
||||
if (state.lastActivates.size() >= config.memSpec->nActivate) {
|
||||
map<sc_time, ScheduledCommand> lastActivates = state.lastActivates;
|
||||
lastActivates.emplace(command.getStart(), command);
|
||||
auto upper = lastActivates.begin();
|
||||
advance(upper, config.memSpec.nActivate);
|
||||
advance(upper, config.memSpec->nActivate);
|
||||
auto lower = lastActivates.begin();
|
||||
|
||||
while (upper != lastActivates.end()) {
|
||||
if (upper->first - lower->first < config.memSpec.tNAW)
|
||||
if (upper->first - lower->first < config.memSpec->tNAW)
|
||||
return false;
|
||||
++upper;
|
||||
++lower;
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef ACTIVATESCHEDULER_H_
|
||||
#define ACTIVATESCHEDULER_H_
|
||||
#ifndef ACTIVATECHECKER_H
|
||||
#define ACTIVATECHECKER_H
|
||||
|
||||
#include <map>
|
||||
#include "ICommandChecker.h"
|
||||
@@ -61,4 +61,4 @@ private:
|
||||
bool satisfies_nActivateWindow(ScheduledCommand &command) const;
|
||||
};
|
||||
|
||||
#endif /* ACTIVATESCHEDULER_H_ */
|
||||
#endif // ACTIVATECHECKER_H
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef ICOMMANDSCHEDULER_H_
|
||||
#define ICOMMANDSCHEDULER_H_
|
||||
#ifndef ICOMMANDCHECKER_H
|
||||
#define ICOMMANDCHECKER_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include "../ScheduledCommand.h"
|
||||
@@ -50,4 +50,4 @@ public:
|
||||
|
||||
|
||||
|
||||
#endif /* ICOMMANDSCHEDULER_H_ */
|
||||
#endif // ICOMMANDCHECKER_H
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
#include "PowerDownChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
#include "../../timingCalculations.h"
|
||||
|
||||
sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd,
|
||||
Command pdnCmd) const
|
||||
@@ -47,26 +47,26 @@ sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd,
|
||||
sc_time constraint;
|
||||
|
||||
if (lastCmd == Command::Read || lastCmd == Command::ReadA) {
|
||||
constraint = config.memSpec.tRL + getReadAccessTime() + config.memSpec.clk;
|
||||
constraint = config.memSpec->tRL + getReadAccessTime() + config.memSpec->clk;
|
||||
} else if (lastCmd == Command::Write) {
|
||||
constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR;
|
||||
constraint = config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR;
|
||||
} else if (lastCmd == Command::WriteA) {
|
||||
constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
|
||||
config.memSpec.clk;
|
||||
constraint = config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR +
|
||||
config.memSpec->clk;
|
||||
} else if (lastCmd == Command::AutoRefresh) {
|
||||
auto m = Configuration::getInstance().getRefMode();
|
||||
if (m == 4)
|
||||
constraint = config.memSpec.tRFC4;
|
||||
constraint = config.memSpec->tRFC4;
|
||||
else if (m == 2)
|
||||
constraint = config.memSpec.tRFC2;
|
||||
constraint = config.memSpec->tRFC2;
|
||||
else
|
||||
constraint = config.memSpec.tRFC;
|
||||
constraint = config.memSpec->tRFC;
|
||||
} else if (lastCmd == Command::PDNPX || lastCmd == Command::PDNAX) {
|
||||
constraint = config.memSpec.tXP;
|
||||
constraint = config.memSpec->tXP;
|
||||
} else if (lastCmd == Command::SREFX) {
|
||||
constraint = config.memSpec.tXSR;
|
||||
constraint = config.memSpec->tXSR;
|
||||
} else if (lastCmd == Command::Precharge || lastCmd == Command::PrechargeAll) {
|
||||
constraint = config.memSpec.tRP;
|
||||
constraint = config.memSpec->tRP;
|
||||
} else {
|
||||
reportFatal("Powerdown checker",
|
||||
commandToString(pdnCmd) + " can not follow " + commandToString(lastCmd));
|
||||
@@ -117,17 +117,17 @@ const
|
||||
|
||||
} else if (pdnCmd == Command::PDNAX) {
|
||||
// Leaving Active Power Down
|
||||
timeConstraint = config.memSpec.tCKE;
|
||||
timeConstraint = config.memSpec->tCKE;
|
||||
command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNA,
|
||||
bank).getStart(), timeConstraint);
|
||||
} else if (pdnCmd == Command::PDNPX) {
|
||||
// Leaving Precharge Power Down
|
||||
timeConstraint = config.memSpec.tCKE;
|
||||
timeConstraint = config.memSpec->tCKE;
|
||||
command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNP,
|
||||
bank).getStart(), timeConstraint);
|
||||
} else if (pdnCmd == Command::SREFX) {
|
||||
// Leaving Self Refresh
|
||||
timeConstraint = config.memSpec.tCKESR;
|
||||
timeConstraint = config.memSpec->tCKESR;
|
||||
command.establishMinDistanceFromStart(state.getLastCommand(Command::SREF,
|
||||
bank).getStart(), timeConstraint);
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef POWERDOWNCHECKER_H_
|
||||
#define POWERDOWNCHECKER_H_
|
||||
#ifndef POWERDOWNCHECKER_H
|
||||
#define POWERDOWNCHECKER_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
@@ -60,5 +60,5 @@ private:
|
||||
Command pdnCmd) const;
|
||||
};
|
||||
|
||||
#endif /* POWERDOWNCHECKER_H_ */
|
||||
#endif // POWERDOWNCHECKER_H
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
*/
|
||||
|
||||
#include "PreBChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd)const
|
||||
#include "../../timingCalculations.h"
|
||||
void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const
|
||||
{
|
||||
sc_assert(cmd.getCommand() == Command::PreB);
|
||||
ScheduledCommand lastCmd = state.getLastScheduledCommand(cmd.getBank());
|
||||
@@ -43,21 +43,21 @@ void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd)const
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(),
|
||||
Configuration::getInstance().getTrpb());
|
||||
} else if (lastCmd.getCommand() == Command::Precharge) {
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRP);
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRP);
|
||||
} else if (lastCmd.getCommand() == Command::PrechargeAll) {
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRP);
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRP);
|
||||
} else if (lastCmd.getCommand() == Command::ActB) {
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(),
|
||||
config.memSpec.tRCD); // XXX: trcd is less than the NEW! trasb! ok!
|
||||
config.memSpec->tRCD); // XXX: trcd is less than the NEW! trasb! ok!
|
||||
} else if (lastCmd.getCommand() == Command::Activate) {
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRCD);
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRCD);
|
||||
} else if (lastCmd.getCommand() == Command::Read) {
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRTP);
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRTP);
|
||||
} else if (lastCmd.getCommand() == Command::Write) {
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR);
|
||||
config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR);
|
||||
} else if (lastCmd.getCommand() == Command::PDNAX) {
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tXP);
|
||||
cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tXP);
|
||||
} else {
|
||||
reportFatal("PreB Checker",
|
||||
"PreB can not follow " + commandToString(lastCmd.getCommand()));
|
||||
@@ -65,11 +65,11 @@ void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd)const
|
||||
}
|
||||
ScheduledCommand lc;
|
||||
if ((lc = state.getLastCommand(Command::PrechargeAll)).isValidCommand()) {
|
||||
cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec.tRP);
|
||||
cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec->tRP);
|
||||
}
|
||||
if ((lc = state.getLastCommand(Command::Activate,
|
||||
cmd.getBank())).isValidCommand()) {
|
||||
cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec.tRAS);
|
||||
cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec->tRAS);
|
||||
}
|
||||
if ((lc = state.getLastCommand(Command::ActB,
|
||||
cmd.getBank())).isValidCommand()) {
|
||||
|
||||
@@ -31,11 +31,14 @@
|
||||
*
|
||||
* Author: Éder F. Zulian
|
||||
*/
|
||||
#ifndef PREB_CHECKER_H_
|
||||
#define PREB_CHECKER_H_
|
||||
|
||||
#ifndef PREBCHECKER_H
|
||||
#define PREBCHECKER_H
|
||||
|
||||
#include "ICommandChecker.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../../ControllerState.h"
|
||||
|
||||
class PreBChecker: public ICommandChecker
|
||||
{
|
||||
public:
|
||||
@@ -48,4 +51,5 @@ private:
|
||||
const Configuration &config;
|
||||
ControllerState &state;
|
||||
};
|
||||
#endif /* PREB_CHECKER_H_ */
|
||||
|
||||
#endif // PREBCHECKER_H
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
#include "PrechargeAllChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
#include "../../timingCalculations.h"
|
||||
|
||||
|
||||
void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand &command)
|
||||
@@ -45,48 +45,48 @@ 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) {
|
||||
for (unsigned int bank = 0; bank < config.memSpec->NumberOfBanks; ++bank) {
|
||||
ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank));
|
||||
if (lastCommand.isValidCommand()) {
|
||||
if (lastCommand.getCommand() == Command::Precharge
|
||||
|| lastCommand.getCommand() == Command::PreB) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tRP);
|
||||
} else if (lastCommand.getCommand() == Command::Activate
|
||||
|| lastCommand.getCommand() == Command::ActB) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRCD);
|
||||
config.memSpec->tRCD);
|
||||
} else if (lastCommand.getCommand() == Command::Read) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRTP);
|
||||
config.memSpec->tRTP);
|
||||
} else if (lastCommand.getCommand() == Command::ReadA) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRTP + config.memSpec.tRP);
|
||||
config.memSpec->tRTP + config.memSpec->tRP);
|
||||
} else if (lastCommand.getCommand() == Command::Write) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR);
|
||||
config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR);
|
||||
} else if (lastCommand.getCommand() == Command::WriteA) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR +
|
||||
config.memSpec->tRP);
|
||||
} else if (lastCommand.getCommand() == Command::AutoRefresh) {
|
||||
auto m = Configuration::getInstance().getRefMode();
|
||||
if (m == 4)
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRFC4);
|
||||
config.memSpec->tRFC4);
|
||||
else if (m == 2)
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRFC2);
|
||||
config.memSpec->tRFC2);
|
||||
else
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRFC);
|
||||
config.memSpec->tRFC);
|
||||
} else if (lastCommand.getCommand() == Command::PDNAX
|
||||
|| lastCommand.getCommand() == Command::PDNPX) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tXP);
|
||||
config.memSpec->tXP);
|
||||
} else if (lastCommand.getCommand() == Command::SREFX) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tXSR);
|
||||
config.memSpec->tXSR);
|
||||
} else
|
||||
reportFatal("Precharge All Checker",
|
||||
"Precharge All can not follow " + commandToString(lastCommand.getCommand()));
|
||||
@@ -97,7 +97,7 @@ const
|
||||
command.getBank());
|
||||
if (lastActivate.isValidCommand()) {
|
||||
command.establishMinDistanceFromStart(lastActivate.getStart(),
|
||||
config.memSpec.tRAS);
|
||||
config.memSpec->tRAS);
|
||||
}
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
|
||||
@@ -34,14 +34,13 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef PRECHARGEALLCHECKER_H_
|
||||
#define PRECHARGEALLCHECKER_H_
|
||||
#ifndef PRECHARGEALLCHECKER_H
|
||||
#define PRECHARGEALLCHECKER_H
|
||||
|
||||
#include "ICommandChecker.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../../ControllerState.h"
|
||||
|
||||
|
||||
class PrechargeAllChecker: public ICommandChecker
|
||||
{
|
||||
public:
|
||||
@@ -62,4 +61,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* PRECHARGEALLCHECKER_H_ */
|
||||
#endif // PRECHARGEALLCHECKER_H
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "PrechargeChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
#include "../../timingCalculations.h"
|
||||
|
||||
|
||||
void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand &command)
|
||||
@@ -52,23 +52,23 @@ const
|
||||
if (lastCommand.getCommand() == Command::Precharge
|
||||
|| lastCommand.getCommand() == Command::PreB) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tRP);
|
||||
} else if (lastCommand.getCommand() == Command::Activate
|
||||
|| lastCommand.getCommand() == Command::ActB) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRCD);
|
||||
config.memSpec->tRCD);
|
||||
}
|
||||
|
||||
else if (lastCommand.getCommand() == Command::Read) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRTP);
|
||||
config.memSpec->tRTP);
|
||||
} else if (lastCommand.getCommand() == Command::Write) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR);
|
||||
config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR);
|
||||
|
||||
} else if (lastCommand.getCommand() == Command::PDNAX) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tXP);
|
||||
config.memSpec->tXP);
|
||||
} else
|
||||
reportFatal("Precharge Checker",
|
||||
"Precharge can not follow " + commandToString(lastCommand.getCommand()));
|
||||
@@ -78,7 +78,7 @@ const
|
||||
command.getBank());
|
||||
if (lastActivate.isValidCommand()) {
|
||||
command.establishMinDistanceFromStart(lastActivate.getStart(),
|
||||
config.memSpec.tRAS);
|
||||
config.memSpec->tRAS);
|
||||
}
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
|
||||
@@ -34,14 +34,13 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef PRECHARGECHECKER_H_
|
||||
#define PRECHARGECHECKER_H_
|
||||
#ifndef PRECHARGECHECKER_H
|
||||
#define PRECHARGECHECKER_H
|
||||
|
||||
#include "ICommandChecker.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../../ControllerState.h"
|
||||
|
||||
|
||||
class PrechargeChecker: public ICommandChecker
|
||||
{
|
||||
public:
|
||||
@@ -57,4 +56,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* PRECHARGECHECKER_H_ */
|
||||
#endif // PRECHARGECHECKER_
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
*/
|
||||
|
||||
#include "ReadChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
#include "../../../../common/Utils.h"
|
||||
#include "../../timingCalculations.h"
|
||||
#include "../../../../common/utils.h"
|
||||
#include "WriteChecker.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -52,7 +52,7 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
if (lastCommand.getCommand() == Command::Activate
|
||||
|| lastCommand.getCommand() == Command::ActB) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRCD);
|
||||
config.memSpec->tRCD);
|
||||
} else if (lastCommand.getCommand() == Command::Read) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
ReadChecker::readToRead(lastCommand, command));
|
||||
@@ -62,14 +62,14 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
} else if (lastCommand.getCommand() == Command::PDNPX
|
||||
|| lastCommand.getCommand() == Command::PDNAX) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tXP);
|
||||
config.memSpec->tXP);
|
||||
} else
|
||||
reportFatal("Read Checker",
|
||||
"Read can not follow " + commandToString(lastCommand.getCommand()));
|
||||
}
|
||||
|
||||
while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe(command)) {
|
||||
command.delayStart(config.memSpec.clk);
|
||||
command.delayStart(config.memSpec->clk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ void ReadChecker::delayToSatisfyDLL(ScheduledCommand &read) const
|
||||
read.getBank());
|
||||
if (lastSREFX.isValidCommand())
|
||||
read.establishMinDistanceFromStart(lastSREFX.getStart(),
|
||||
config.memSpec.tXSRDLL);
|
||||
config.memSpec->tXSRDLL);
|
||||
}
|
||||
|
||||
sc_time ReadChecker::readToRead(ScheduledCommand &firstRead,
|
||||
@@ -123,9 +123,9 @@ sc_time ReadChecker::readToRead(ScheduledCommand &firstRead,
|
||||
sc_assert(secondRead.getCommand() == Command::Read
|
||||
|| secondRead.getCommand() == Command::ReadA);
|
||||
|
||||
MemSpec &config = Configuration::getInstance().memSpec;
|
||||
MemSpec *config = Configuration::getInstance().memSpec;
|
||||
sc_time tCCD = (firstRead.getBankGroup() == secondRead.getBankGroup()) ?
|
||||
config.tCCD_L : config.tCCD_S;
|
||||
config->tCCD_L : config->tCCD_S;
|
||||
return max(tCCD, getReadAccessTime());
|
||||
}
|
||||
|
||||
@@ -137,9 +137,9 @@ sc_time ReadChecker::writeToRead(ScheduledCommand &write,
|
||||
sc_assert(write.getCommand() == Command::Write
|
||||
|| write.getCommand() == Command::WriteA);
|
||||
|
||||
MemSpec &config = Configuration::getInstance().memSpec;
|
||||
sc_time tWTR = (write.getBankGroup() == read.getBankGroup()) ? config.tWTR_L :
|
||||
config.tWTR_S;
|
||||
return config.tWL + getWriteAccessTime() + tWTR;
|
||||
MemSpec *config = Configuration::getInstance().memSpec;
|
||||
sc_time tWTR = (write.getBankGroup() == read.getBankGroup()) ? config->tWTR_L :
|
||||
config->tWTR_S;
|
||||
return config->tWL + getWriteAccessTime() + tWTR;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef READCHECKER_H_
|
||||
#define READCHECKER_H_
|
||||
#ifndef READCHECKER_H
|
||||
#define READCHECKER_H
|
||||
|
||||
#include "ICommandChecker.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
@@ -65,5 +65,5 @@ private:
|
||||
ScheduledCommand &strobeCommand) const;
|
||||
};
|
||||
|
||||
#endif /* READCHECKER_H_ */
|
||||
#endif // READCHECKER_H
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
#include "RefreshChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
#include "../../timingCalculations.h"
|
||||
|
||||
void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
{
|
||||
@@ -50,53 +50,53 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
if (lastCommandOnBank.getCommand() == Command::Precharge
|
||||
|| lastCommandOnBank.getCommand() == Command::PrechargeAll) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tRP);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::ReadA) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tRTP + config.memSpec.tRP);
|
||||
config.memSpec->tRTP + config.memSpec->tRP);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::WriteA) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR +
|
||||
config.memSpec->tRP);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::PDNPX
|
||||
|| lastCommandOnBank.getCommand() == Command::PDNAX) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tXP);
|
||||
config.memSpec->tXP);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::SREFX) {
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tXSR);
|
||||
config.memSpec->tXSR);
|
||||
} else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) {
|
||||
} else
|
||||
reportFatal("Refresh Checker",
|
||||
"Refresh can not follow " + commandToString(lastCommandOnBank.getCommand()));
|
||||
}
|
||||
} else {
|
||||
for (unsigned int bank = 0; bank < config.memSpec.NumberOfBanks; ++bank) {
|
||||
for (unsigned int bank = 0; bank < config.memSpec->NumberOfBanks; ++bank) {
|
||||
ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank));
|
||||
if (lastCommand.isValidCommand()) {
|
||||
if (lastCommand.getCommand() == Command::Precharge
|
||||
|| lastCommand.getCommand() == Command::PrechargeAll
|
||||
|| lastCommand.getCommand() == Command::PreB) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tRP);
|
||||
} else if (lastCommand.getCommand() == Command::Activate
|
||||
|| lastCommand.getCommand() == Command::ActB) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRCD);
|
||||
config.memSpec->tRCD);
|
||||
} else if (lastCommand.getCommand() == Command::ReadA) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRTP + config.memSpec.tRP);
|
||||
config.memSpec->tRTP + config.memSpec->tRP);
|
||||
} else if (lastCommand.getCommand() == Command::WriteA) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR +
|
||||
config.memSpec.tRP);
|
||||
config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR +
|
||||
config.memSpec->tRP);
|
||||
} else if (lastCommand.getCommand() == Command::PDNAX
|
||||
|| lastCommand.getCommand() == Command::PDNPX) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tXP);
|
||||
config.memSpec->tXP);
|
||||
} else if (lastCommand.getCommand() == Command::SREFX) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tXSR);
|
||||
config.memSpec->tXSR);
|
||||
} else if (lastCommand.getCommand() == Command::AutoRefresh) {
|
||||
} else
|
||||
reportFatal("Refresh Checker",
|
||||
|
||||
@@ -34,16 +34,15 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef REFRESHCHECKER_H_
|
||||
#define REFRESHCHECKER_H_
|
||||
#ifndef REFRESHCHECKER_H
|
||||
#define REFRESHCHECKER_H
|
||||
|
||||
#include "ICommandChecker.h"
|
||||
#include "../../../ControllerState.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include <systemc>
|
||||
|
||||
|
||||
class RefreshChecker: public ICommandChecker
|
||||
class RefreshChecker : public ICommandChecker
|
||||
{
|
||||
public:
|
||||
RefreshChecker(const Configuration &config, ControllerState &state) :
|
||||
@@ -64,4 +63,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* REFRESHCHECKER_H_ */
|
||||
#endif // REFRESHCHECKER_H
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
*/
|
||||
|
||||
#include "WriteChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
#include "../../../../common/Utils.h"
|
||||
#include "../../timingCalculations.h"
|
||||
#include "../../../../common/utils.h"
|
||||
#include "ReadChecker.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -52,7 +52,7 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
if (lastCommand.getCommand() == Command::Activate
|
||||
|| lastCommand.getCommand() == Command::ActB) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tRCD);
|
||||
config.memSpec->tRCD);
|
||||
} else if (lastCommand.getCommand() == Command::Read) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
WriteChecker::readToWrite(lastCommand, command));
|
||||
@@ -62,14 +62,14 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
} else if (lastCommand.getCommand() == Command::PDNPX
|
||||
|| lastCommand.getCommand() == Command::PDNAX) {
|
||||
command.establishMinDistanceFromStart(lastCommand.getStart(),
|
||||
config.memSpec.tXP);
|
||||
config.memSpec->tXP);
|
||||
} else
|
||||
reportFatal("Write Checker",
|
||||
"Write can not follow " + commandToString(lastCommand.getCommand()));
|
||||
}
|
||||
|
||||
while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe(command)) {
|
||||
command.delayStart(config.memSpec.clk);
|
||||
command.delayStart(config.memSpec->clk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +114,9 @@ sc_time WriteChecker::writeToWrite(ScheduledCommand &firstWrite,
|
||||
sc_assert(secondWrite.getCommand() == Command::Write
|
||||
|| secondWrite.getCommand() == Command::WriteA);
|
||||
|
||||
MemSpec &config = Configuration::getInstance().memSpec;
|
||||
MemSpec *config = Configuration::getInstance().memSpec;
|
||||
sc_time tCCD = (firstWrite.getBankGroup() == secondWrite.getBankGroup()) ?
|
||||
config.tCCD_L : config.tCCD_S;
|
||||
config->tCCD_L : config->tCCD_S;
|
||||
return max(tCCD, getWriteAccessTime());
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ sc_time WriteChecker::readToWrite(ScheduledCommand &read __attribute__((
|
||||
sc_assert(write.getCommand() == Command::Write
|
||||
|| write.getCommand() == Command::WriteA);
|
||||
|
||||
MemSpec &config = Configuration::getInstance().memSpec;
|
||||
return config.tRL + getReadAccessTime() - config.tWL + config.clk * 2;
|
||||
MemSpec *config = Configuration::getInstance().memSpec;
|
||||
return config->tRL + getReadAccessTime() - config->tWL + config->clk * 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,15 +34,14 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef WRITECHECKER_H_
|
||||
#define WRITECHECKER_H_
|
||||
#ifndef WRITECHECKER_H
|
||||
#define WRITECHECKER_H
|
||||
|
||||
#include "ICommandChecker.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../../ControllerState.h"
|
||||
|
||||
|
||||
class WriteChecker: public ICommandChecker
|
||||
class WriteChecker : public ICommandChecker
|
||||
{
|
||||
public:
|
||||
WriteChecker(const Configuration &config,
|
||||
@@ -64,4 +63,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* WRITECHECKER_H_ */
|
||||
#endif // WRITECHECKER_H
|
||||
|
||||
@@ -34,12 +34,12 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#include "TimingCalculation.h"
|
||||
#include "timingCalculations.h"
|
||||
#include "configuration/MemSpec.h"
|
||||
#include "ControllerCore.h"
|
||||
#include "../../common/DebugManager.h"
|
||||
#include "configuration/Configuration.h"
|
||||
#include "../../common/Utils.h"
|
||||
#include "../../common/utils.h"
|
||||
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ const sc_time FrequencyToClk(double frequencyMhz)
|
||||
|
||||
const sc_time clkAlign(sc_time time, Alignment alignment)
|
||||
{
|
||||
sc_time clk = Configuration::getInstance().memSpec.clk;
|
||||
sc_time clk = Configuration::getInstance().memSpec->clk;
|
||||
if (alignment == UP)
|
||||
return ceil(time / clk) * clk;
|
||||
else
|
||||
@@ -69,39 +69,39 @@ const sc_time clkAlign(sc_time time, Alignment alignment)
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload)
|
||||
{
|
||||
MemSpec &config = Configuration::getInstance().memSpec;
|
||||
MemSpec *config = Configuration::getInstance().memSpec;
|
||||
|
||||
if (command == Command::PreB) {
|
||||
return Configuration::getInstance().getTrpb();
|
||||
} else if (command == Command::Precharge || command == Command::PrechargeAll) {
|
||||
return config.tRP;
|
||||
return config->tRP;
|
||||
} else if (command == Command::ActB) {
|
||||
return config.tRCD;
|
||||
return config->tRCD;
|
||||
} else if (command == Command::Activate) {
|
||||
return config.tRCD;
|
||||
return config->tRCD;
|
||||
} else if (command == Command::Read) {
|
||||
return config.tRL + getReadAccessTime();
|
||||
return config->tRL + getReadAccessTime();
|
||||
} else if (command == Command::ReadA) {
|
||||
return config.tRTP + config.tRP;
|
||||
return config->tRTP + config->tRP;
|
||||
} else if (command == Command::Write) {
|
||||
return config.tWL + getWriteAccessTime();
|
||||
return config->tWL + getWriteAccessTime();
|
||||
} else if (command == Command::WriteA) {
|
||||
return config.tWL + getWriteAccessTime() + config.tWR + config.tRP;
|
||||
return config->tWL + getWriteAccessTime() + config->tWR + config->tRP;
|
||||
} else if (command == Command::PrechargeAll) {
|
||||
return config.tRP;
|
||||
return config->tRP;
|
||||
} else if (command == Command::AutoRefresh) {
|
||||
if (Configuration::getInstance().getRefMode() == 4)
|
||||
return getElementFromMap(config.refreshTimings,
|
||||
return getElementFromMap(config->refreshTimings,
|
||||
DramExtension::getExtension(payload).getBank()).tRFC4;
|
||||
else if (Configuration::getInstance().getRefMode() == 2)
|
||||
return getElementFromMap(config.refreshTimings,
|
||||
return getElementFromMap(config->refreshTimings,
|
||||
DramExtension::getExtension(payload).getBank()).tRFC2;
|
||||
else
|
||||
return getElementFromMap(config.refreshTimings,
|
||||
return getElementFromMap(config->refreshTimings,
|
||||
DramExtension::getExtension(payload).getBank()).tRFC;
|
||||
} else if (command == Command::PDNAX || command == Command::PDNPX
|
||||
|| command == Command::SREFX) {
|
||||
return config.clk;
|
||||
return config->clk;
|
||||
} else {
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
"command not known or command doesn't have a fixed execution time");
|
||||
@@ -112,11 +112,11 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload)
|
||||
// Returns the minimum execution time for commands that have a variable execution time
|
||||
sc_time getMinExecutionTimeForPowerDownCmd(Command command)
|
||||
{
|
||||
MemSpec &config = Configuration::getInstance().memSpec;
|
||||
MemSpec *config = Configuration::getInstance().memSpec;
|
||||
if (command == Command::PDNA || command == Command::PDNP) {
|
||||
return config.tCKE;
|
||||
return config->tCKE;
|
||||
} else if (command == Command::SREF) {
|
||||
return config.tCKESR;
|
||||
return config->tCKESR;
|
||||
} else {
|
||||
SC_REPORT_FATAL("getMinimalExecutionTime",
|
||||
"command is not know or command has a fixed execution time");
|
||||
@@ -133,19 +133,19 @@ bool isClkAligned(sc_time time, sc_time clk)
|
||||
sc_time getReadAccessTime()
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
return (config.memSpec.BurstLength / config.memSpec.DataRate) *
|
||||
config.memSpec.clk;
|
||||
return (config.memSpec->BurstLength / config.memSpec->DataRate) *
|
||||
config.memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time getWriteAccessTime()
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
|
||||
if (config.memSpec.DataRate == 1) {
|
||||
return config.memSpec.clk * (config.memSpec.BurstLength);
|
||||
if (config.memSpec->DataRate == 1) {
|
||||
return config.memSpec->clk * (config.memSpec->BurstLength);
|
||||
} else {
|
||||
return config.memSpec.clk * (config.memSpec.BurstLength /
|
||||
config.memSpec.DataRate);
|
||||
return config.memSpec->clk * (config.memSpec->BurstLength /
|
||||
config.memSpec->DataRate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,15 +34,14 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef UTILS_H_
|
||||
#define UTILS_H_
|
||||
#ifndef TIMINGCALCULATIONS_H
|
||||
#define TIMINGCALCULATIONS_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "../../common/dramExtension.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../Command.h"
|
||||
|
||||
|
||||
sc_time getMinExecutionTimeForPowerDownCmd(Command command);
|
||||
sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload);
|
||||
|
||||
@@ -56,4 +55,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_ */
|
||||
#endif // TIMINGCALCULATIONS_H
|
||||
@@ -36,27 +36,30 @@
|
||||
|
||||
#include "Fifo.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Fifo::storeRequest(gp *payload)
|
||||
{
|
||||
buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload);
|
||||
Bank bank = DramExtension::getExtension(payload).getBank();
|
||||
buffer[bank].emplace_back(payload);
|
||||
}
|
||||
|
||||
pair<Command, tlm::tlm_generic_payload *> Fifo::getNextRequest(Bank bank)
|
||||
std::pair<Command, tlm::tlm_generic_payload *> Fifo::getNextRequest(Bank bank)
|
||||
{
|
||||
if (!buffer[bank].empty()) {
|
||||
if (!buffer[bank].empty())
|
||||
{
|
||||
gp *payload = buffer[bank].front();
|
||||
Command command = IScheduler::getNextCommand(*payload);
|
||||
Command command = IScheduler::getNextCommand(payload);
|
||||
if (command == Command::Read || command == Command::ReadA
|
||||
|| command == Command::Write || command == Command::WriteA) {
|
||||
|| command == Command::Write || command == Command::WriteA)
|
||||
{
|
||||
buffer[bank].pop_front();
|
||||
}
|
||||
|
||||
return pair<Command, tlm::tlm_generic_payload *>(command, payload);
|
||||
return std::pair<Command, tlm::tlm_generic_payload *>(command, payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
}
|
||||
|
||||
return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
}
|
||||
|
||||
gp *Fifo::getPendingRequest(Bank /*bank*/)
|
||||
|
||||
@@ -34,15 +34,16 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef FIFO_H_
|
||||
#define FIFO_H_
|
||||
#ifndef FIFO_H
|
||||
#define FIFO_H
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "../core/ControllerCore.h"
|
||||
#include "../Command.h"
|
||||
#include "IScheduler.h"
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
class Fifo : public IScheduler
|
||||
{
|
||||
@@ -51,12 +52,12 @@ public:
|
||||
virtual ~Fifo() {}
|
||||
|
||||
void storeRequest(gp *payload) override;
|
||||
std::pair<Command, tlm::tlm_generic_payload *> getNextRequest(
|
||||
Bank bank) override;
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
getNextRequest(Bank bank) override;
|
||||
virtual gp *getPendingRequest(Bank bank) override;
|
||||
|
||||
private:
|
||||
std::map<Bank, std::deque<gp *>> buffer;
|
||||
};
|
||||
|
||||
#endif /* FIFO_H_ */
|
||||
#endif // FIFO_H
|
||||
|
||||
@@ -61,21 +61,21 @@ std::pair<Command, tlm::tlm_generic_payload *> FifoStrict::getNextRequest(
|
||||
// enqueued request until the appropriate sequence of commands is
|
||||
// sent to the DRAM.
|
||||
//
|
||||
// Every time getNextRequest() it is called it calls
|
||||
// Every time getNextRequest() is called it calls
|
||||
// getNextCommand() that returns the suitable command to be sent
|
||||
// to the DRAM.
|
||||
//
|
||||
// getNextCommand() returns the proper command based on the
|
||||
// internal status of the DRAM.
|
||||
//
|
||||
// In the worst case getNextCommand() need to be called three
|
||||
// In the worst case getNextCommand() needs to be called three
|
||||
// times for a given element in the requests queue: first for
|
||||
// precharge, second for activate and finally for read or write
|
||||
// (accordingly the nature of the request). In contrast, for the
|
||||
// case of an already open row (due to a previous request) the
|
||||
// command itself could be directly issued.
|
||||
//
|
||||
Command command = IScheduler::getNextCommand(*payload);
|
||||
Command command = IScheduler::getNextCommand(payload);
|
||||
|
||||
if (commandIsIn(command, {Command::Read, Command::Write, Command::ReadA, Command::WriteA})) {
|
||||
buffer.pop_front();
|
||||
@@ -84,7 +84,7 @@ std::pair<Command, tlm::tlm_generic_payload *> FifoStrict::getNextRequest(
|
||||
|
||||
if (!buffer.empty()) {
|
||||
tlm::tlm_generic_payload *p = buffer.front().second;
|
||||
Command cmd = IScheduler::getNextCommand(*p);
|
||||
Command cmd = IScheduler::getNextCommand(p);
|
||||
if (commandIsIn(cmd, {Command::Read, Command::Write, Command::ReadA, Command::WriteA})) {
|
||||
Bank b = DramExtension::getBank(p);
|
||||
controller.blockedRequests.push(b);
|
||||
@@ -92,7 +92,7 @@ std::pair<Command, tlm::tlm_generic_payload *> FifoStrict::getNextRequest(
|
||||
}
|
||||
}
|
||||
|
||||
return pair<Command, tlm::tlm_generic_payload *>(command, payload);
|
||||
return std::pair<Command, tlm::tlm_generic_payload *>(command, payload);
|
||||
|
||||
} else {
|
||||
// The next request in the FIFO is NOT for the bank passed as parameter.
|
||||
@@ -110,24 +110,24 @@ std::pair<Command, tlm::tlm_generic_payload *> FifoStrict::getNextRequest(
|
||||
// Reads and writes will not be issued since this
|
||||
// scheduler executes all read and writes in a strict
|
||||
// order.
|
||||
Command command = getNextCommand(*payload);
|
||||
Command command = getNextCommand(payload);
|
||||
if (commandIsIn(command, {Command::Read, Command::Write, Command::ReadA, Command::WriteA})) {
|
||||
// Reads and writes must be executed in order. Then if
|
||||
// the next command for this request is read or write
|
||||
// NOP will be returned and no operation will be
|
||||
// performed.
|
||||
return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
return std::pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
}
|
||||
else {
|
||||
// Commands other than read and write are issued normally.
|
||||
return pair<Command, tlm::tlm_generic_payload *>(command, payload);
|
||||
return std::pair<Command, tlm::tlm_generic_payload *>(command, payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
return std::pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
}
|
||||
|
||||
gp *FifoStrict::getPendingRequest(Bank /*bank*/)
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#define FIFOSTRICT_H
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
//#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "../core/ControllerCore.h"
|
||||
@@ -51,19 +51,19 @@ class FifoStrict : public IScheduler
|
||||
{
|
||||
public:
|
||||
IController &controller;
|
||||
FifoStrict(IController &controller,
|
||||
ControllerCore &controllerCore) : IScheduler(controllerCore),
|
||||
controller(controller) {}
|
||||
FifoStrict(IController &controller, ControllerCore &controllerCore)
|
||||
: IScheduler(controllerCore), controller(controller) {}
|
||||
|
||||
virtual ~FifoStrict() {}
|
||||
|
||||
void storeRequest(gp *payload) override;
|
||||
std::pair<Command, tlm::tlm_generic_payload *> getNextRequest(
|
||||
Bank bank) override;
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
getNextRequest(Bank bank) override;
|
||||
virtual gp *getPendingRequest(Bank bank) override;
|
||||
|
||||
private:
|
||||
std::deque<std::pair<Bank, tlm::tlm_generic_payload *>> buffer;
|
||||
};
|
||||
|
||||
#endif /* FIFOSTRICT_H */
|
||||
#endif // FIFOSTRICT_H
|
||||
|
||||
|
||||
@@ -35,17 +35,17 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#include "Fr_Fcfs.h"
|
||||
#include "../../common/dramExtension.h"
|
||||
#include "FrFcfs.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../core/configuration/Configuration.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// The FR_FCFS is descibed in a 2000 paper from Rixner et al.:
|
||||
// The FrFcfs (First Ready First Come First Served) is descibed in a 2000 paper from Rixner et al.:
|
||||
// Memory Access Scheduling
|
||||
//
|
||||
// The FR_FCFS scheduler features for each bank in the DRAM a specific
|
||||
// The FrFcfs scheduler features for each bank in the DRAM a specific
|
||||
// scheduling buffer for example:
|
||||
//
|
||||
// Bank0: OOOOOOOO
|
||||
@@ -58,7 +58,7 @@ using namespace std;
|
||||
// Bank6: OOOOO0XX
|
||||
// Bank7: XXXXXXXX
|
||||
|
||||
void FR_FCFS::storeRequest(gp *payload)
|
||||
void FrFcfs::storeRequest(gp *payload)
|
||||
{
|
||||
// FIXME: Question: what if the buffer is full? IMHO the schedule function
|
||||
// should provide a true or false when the placement into the buffer worked
|
||||
@@ -67,26 +67,26 @@ void FR_FCFS::storeRequest(gp *payload)
|
||||
.emplace_back(payload);
|
||||
}
|
||||
|
||||
std::pair<Command, gp *> FR_FCFS::getNextRequest(Bank bank)
|
||||
std::pair<Command, gp *> FrFcfs::getNextRequest(Bank bank)
|
||||
{
|
||||
// If the bank is empty like Bank0 in the example we do nothing
|
||||
if (buffer[bank].empty()) {
|
||||
return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
}
|
||||
if (buffer[bank].empty())
|
||||
return std::pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
|
||||
// In FR_FCFS row hits have always the highest priority, therefore we search
|
||||
// In FrFcfs row hits have always the highest priority, therefore we search
|
||||
// for row hits. If we find a row hit, we remove the transaction from the
|
||||
// queue and send it to the DRAM.
|
||||
deque<gp *>::iterator it = FindRowHit(bank);
|
||||
if (it != buffer[bank].end()) {
|
||||
std::deque<gp *>::iterator it = findRowHit(bank);
|
||||
if (it != buffer[bank].end())
|
||||
{
|
||||
gp *payload = *it;
|
||||
buffer[bank].erase(it);
|
||||
return pair<Command, gp *>(getReadWriteCommand(*payload), payload);
|
||||
return std::pair<Command, gp *>(getReadWriteCommand(payload), payload);
|
||||
}
|
||||
|
||||
// If there is no row hit, the FR_FCFS takes always the oldest transaction
|
||||
// If there is no row hit, the FrFcfs takes always the oldest transaction
|
||||
// in the buffer, i.e. the transaction in the front.
|
||||
return pair<Command, gp *>(getNextCommand(buffer[bank].front()),
|
||||
return std::pair<Command, gp *>(getNextCommand(buffer[bank].front()),
|
||||
buffer[bank].front());
|
||||
}
|
||||
|
||||
@@ -97,27 +97,26 @@ std::pair<Command, gp *> FR_FCFS::getNextRequest(Bank bank)
|
||||
// deque container. The past-the-end element is the theoretical element that
|
||||
// would follow the last element in the deque container. It does not point to
|
||||
// any element, and thus shall not be dereferenced.
|
||||
deque<gp *>::iterator FR_FCFS::FindRowHit(Bank bank)
|
||||
std::deque<gp *>::iterator FrFcfs::findRowHit(Bank bank)
|
||||
{
|
||||
deque<gp *> &queue = buffer[bank];
|
||||
std::deque<gp *> &queue = buffer[bank];
|
||||
Row activeRow = controllerCore.getRowBufferStates().getRowInRowBuffer(bank);
|
||||
|
||||
if (!controllerCore.getRowBufferStates().rowBufferIsOpen(bank))
|
||||
return queue.end();
|
||||
|
||||
// Traverse the scheduling queue of the specific bank:
|
||||
for (auto it = queue.begin(); it != queue.end(); it++) {
|
||||
gp *payload = *it;
|
||||
for (auto it = queue.begin(); it != queue.end(); it++)
|
||||
{
|
||||
//Found row-hit and return the according iterator
|
||||
if (DramExtension::getRow(payload)
|
||||
== controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) {
|
||||
if (DramExtension::getRow(*it) == activeRow)
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
||||
return queue.end();
|
||||
}
|
||||
|
||||
gp *FR_FCFS::getPendingRequest(Bank /*bank*/)
|
||||
gp *FrFcfs::getPendingRequest(Bank /*bank*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -35,8 +35,8 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef FR_FCFS_H_
|
||||
#define FR_FCFS_H_
|
||||
#ifndef FRFCFS_H
|
||||
#define FRFCFS_H
|
||||
|
||||
#include "IScheduler.h"
|
||||
#include "../core/ControllerCore.h"
|
||||
@@ -44,25 +44,23 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class FR_FCFS : public IScheduler
|
||||
class FrFcfs : public IScheduler
|
||||
{
|
||||
public:
|
||||
FR_FCFS(ControllerCore &controllerCore) : IScheduler(controllerCore) {}
|
||||
virtual ~FR_FCFS() {}
|
||||
FrFcfs(ControllerCore &controllerCore) : IScheduler(controllerCore) {}
|
||||
virtual ~FrFcfs() {}
|
||||
|
||||
void storeRequest(gp *payload) override;
|
||||
std::pair<Command, tlm::tlm_generic_payload *> getNextRequest(
|
||||
Bank bank) override;
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
getNextRequest(Bank bank) override;
|
||||
virtual gp *getPendingRequest(Bank bank) override;
|
||||
|
||||
protected:
|
||||
std::map<Bank, std::deque<gp *>> buffer;
|
||||
std::deque<gp *>::iterator FindRowHit(Bank bank);
|
||||
std::deque<gp *>::iterator findRowHit(Bank bank);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif // FRFCFS_H
|
||||
@@ -33,14 +33,15 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#include "Fr_Fcfs_grouper.h"
|
||||
#include "FrFcfsGrp.h"
|
||||
|
||||
// The FR_FCFS_Read_Priority works exactly like the FR_FCFS_RP.
|
||||
// However writes are grouped! For detailed documentation look into the FR_FCFS.
|
||||
// The FrFcfsGrp (First Ready First Come First Served Grouper) works exactly
|
||||
// like the FrFcfsRp (First Ready First Come First Served Read Priority).
|
||||
// However writes are grouped! For detailed documentation look into the FrFcfs.
|
||||
// TODO: what is missed is a check if the buffers are full. This will only work
|
||||
// if we have buffers with a fixed size (Prado's future patch).
|
||||
|
||||
std::pair<Command, gp *> FR_FCFS_GRP::getNextRequest(Bank bank)
|
||||
std::pair<Command, gp *> FrFcfsGrp::getNextRequest(Bank bank)
|
||||
{
|
||||
// If the bank is empty we do nothing:
|
||||
if (buffer[bank].empty()) {
|
||||
@@ -74,7 +75,7 @@ std::pair<Command, gp *> FR_FCFS_GRP::getNextRequest(Bank bank)
|
||||
if (hazardDetection(bank, it) == false) {
|
||||
buffer[bank].erase(it);
|
||||
printDebugMessage("Read Hit found");
|
||||
return pair<Command, gp *>(getReadWriteCommand(*read),
|
||||
return pair<Command, gp *>(getReadWriteCommand(read),
|
||||
read);
|
||||
} else {
|
||||
// If there was a hazard, switch the mode and try again:
|
||||
@@ -112,7 +113,7 @@ std::pair<Command, gp *> FR_FCFS_GRP::getNextRequest(Bank bank)
|
||||
.getRowInRowBuffer(bank)) {
|
||||
buffer[bank].erase(it);
|
||||
printDebugMessage("Write Hit found");
|
||||
return pair<Command, gp *>(getReadWriteCommand(*write),
|
||||
return pair<Command, gp *>(getReadWriteCommand(write),
|
||||
write);
|
||||
}
|
||||
}
|
||||
@@ -131,7 +132,7 @@ std::pair<Command, gp *> FR_FCFS_GRP::getNextRequest(Bank bank)
|
||||
|
||||
// If nothing was found we check the other banks before we switch the mode:
|
||||
pair<Command, gp *> other(Command::NOP, NULL);
|
||||
unsigned int B = Configuration::getInstance().memSpec.NumberOfBanks;
|
||||
unsigned int B = Configuration::getInstance().memSpec->NumberOfBanks;
|
||||
|
||||
for (unsigned int i = 1; i < B; i++) {
|
||||
Bank nextBank((bank.ID() + i) % B);
|
||||
@@ -144,12 +145,12 @@ std::pair<Command, gp *> FR_FCFS_GRP::getNextRequest(Bank bank)
|
||||
readMode = !readMode;
|
||||
return getNextRequest(bank);
|
||||
|
||||
reportFatal("FR_FCFS_GRP", "Never should go here ...");
|
||||
reportFatal("FrFcfsGrp", "Never should go here ...");
|
||||
}
|
||||
|
||||
// There is a hazard if a read is found which will be scheduled before a write
|
||||
// to the same column and the same row of the same bank:
|
||||
bool FR_FCFS_GRP::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
|
||||
bool FrFcfsGrp::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
|
||||
{
|
||||
gp *read = *ext;
|
||||
|
||||
@@ -170,11 +171,11 @@ bool FR_FCFS_GRP::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
|
||||
}
|
||||
|
||||
// Estimate the number of writes/reads in all bank buffers:
|
||||
unsigned int FR_FCFS_GRP::getNumberOfRequest(tlm::tlm_command cmd)
|
||||
unsigned int FrFcfsGrp::getNumberOfRequest(tlm::tlm_command cmd)
|
||||
{
|
||||
unsigned int numberOfRequests = 0;
|
||||
for (unsigned int i = 0;
|
||||
i < Configuration::getInstance().memSpec.NumberOfBanks;
|
||||
i < Configuration::getInstance().memSpec->NumberOfBanks;
|
||||
i++) {
|
||||
for (auto it = buffer[i].begin(); it != buffer[i].end(); it++) {
|
||||
gp *trans = *it;
|
||||
@@ -187,7 +188,7 @@ unsigned int FR_FCFS_GRP::getNumberOfRequest(tlm::tlm_command cmd)
|
||||
return numberOfRequests;
|
||||
}
|
||||
|
||||
void FR_FCFS_GRP::printDebugMessage(std::string message)
|
||||
void FrFcfsGrp::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage("FR_FCFS_GRP", message);
|
||||
DebugManager::getInstance().printDebugMessage("FrFcfsGrp", message);
|
||||
}
|
||||
@@ -33,29 +33,24 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef FR_FCFS_GROUPER_H
|
||||
#define FR_FCFS_GROUPER_H
|
||||
#ifndef FRFCFSGRP_H
|
||||
#define FRFCFSGRP_H
|
||||
|
||||
#include "Fr_Fcfs.h"
|
||||
#include "FrFcfs.h"
|
||||
#include "../Controller.h"
|
||||
|
||||
class Controller;
|
||||
|
||||
class FR_FCFS_GRP : public FR_FCFS
|
||||
class FrFcfsGrp : public FrFcfs
|
||||
{
|
||||
public:
|
||||
FR_FCFS_GRP(ControllerCore &controllerCore, Controller *c) :
|
||||
FR_FCFS(controllerCore),
|
||||
ctrl(c),
|
||||
readMode(true)
|
||||
{
|
||||
}
|
||||
FrFcfsGrp(ControllerCore &controllerCore, Controller *c)
|
||||
: FrFcfs(controllerCore), ctrl(c), readMode(true) {}
|
||||
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
getNextRequest(Bank bank) override;
|
||||
|
||||
private:
|
||||
|
||||
Controller *ctrl;
|
||||
bool hazardDetection(Bank bank, std::deque<gp *>::iterator ext);
|
||||
unsigned int getNumberOfRequest(tlm::tlm_command cmd);
|
||||
@@ -63,4 +58,4 @@ private:
|
||||
bool readMode;
|
||||
};
|
||||
|
||||
#endif // FR_FCFS_GROUPER_H
|
||||
#endif // FRFCFSGRP_H
|
||||
@@ -33,12 +33,13 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#include "Fr_Fcfs_read_priority.h"
|
||||
#include "FrFcfsRp.h"
|
||||
|
||||
// The FR_FCFS_Read_Priority works exactly like the FR_FCFS but reads are
|
||||
// prioratized over writes. For detailed documentation look into the FR_FCFS.
|
||||
// The FrFcfsRp (First Ready First Come First Served Read Priority) works
|
||||
// exactly like the FrFcfs but reads are prioratized over writes.
|
||||
// For detailed documentation look into the FrFcfs.
|
||||
|
||||
std::pair<Command, gp *> FR_FCFS_RP::getNextRequest(Bank bank)
|
||||
std::pair<Command, gp *> FrFcfsRp::getNextRequest(Bank bank)
|
||||
{
|
||||
// If the bank is empty like Bank0 in the example we do nothing:
|
||||
if (buffer[bank].empty()) {
|
||||
@@ -62,7 +63,7 @@ std::pair<Command, gp *> FR_FCFS_RP::getNextRequest(Bank bank)
|
||||
if (hazardDetection(bank, it) == false) {
|
||||
buffer[bank].erase(it);
|
||||
printDebugMessage("Read Hit found");
|
||||
return pair<Command, gp *>(getReadWriteCommand(*read), read);
|
||||
return pair<Command, gp *>(getReadWriteCommand(read), read);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,7 +79,7 @@ std::pair<Command, gp *> FR_FCFS_RP::getNextRequest(Bank bank)
|
||||
== controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) {
|
||||
buffer[bank].erase(it);
|
||||
printDebugMessage("Write Hit found");
|
||||
return pair<Command, gp *>(getReadWriteCommand(*write), write);
|
||||
return pair<Command, gp *>(getReadWriteCommand(write), write);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,13 +108,13 @@ std::pair<Command, gp *> FR_FCFS_RP::getNextRequest(Bank bank)
|
||||
}
|
||||
}
|
||||
|
||||
reportFatal("FR_FCFS_RP", "Never should go here ...");
|
||||
reportFatal("FrFcfsRp", "Never should go here ...");
|
||||
return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
}
|
||||
|
||||
// There is a hazard if a read is found which will be scheduled before a write
|
||||
// to the same column and the same row of the same bank:
|
||||
bool FR_FCFS_RP::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
|
||||
bool FrFcfsRp::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
|
||||
{
|
||||
gp *read = *ext;
|
||||
|
||||
@@ -133,7 +134,7 @@ bool FR_FCFS_RP::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
|
||||
return false;
|
||||
}
|
||||
|
||||
void FR_FCFS_RP::printDebugMessage(std::string message)
|
||||
void FrFcfsRp::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage("FR_FCFS_RP", message);
|
||||
DebugManager::getInstance().printDebugMessage("FrFcfsRp", message);
|
||||
}
|
||||
@@ -33,23 +33,21 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef FR_FCFS_READ_PRIORITY_H
|
||||
#define FR_FCFS_READ_PRIORITY_H
|
||||
#ifndef FRFCFSRP_H
|
||||
#define FRFCFSRP_H
|
||||
|
||||
#include "Fr_Fcfs.h"
|
||||
#include "FrFcfs.h"
|
||||
|
||||
class FR_FCFS_RP : public FR_FCFS
|
||||
class FrFcfsRp : public FrFcfs
|
||||
{
|
||||
public:
|
||||
FR_FCFS_RP(ControllerCore &controllerCore) : FR_FCFS(controllerCore) {}
|
||||
|
||||
FrFcfsRp(ControllerCore &controllerCore) : FrFcfs(controllerCore) {}
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
getNextRequest(Bank bank) override;
|
||||
|
||||
private:
|
||||
|
||||
bool hazardDetection(Bank bank, std::deque<gp *>::iterator ext);
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
#endif // FR_FCFS_READ_PRIORITY_H
|
||||
#endif // FRFCFSRP_H
|
||||
@@ -33,14 +33,14 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#include "grp.h"
|
||||
#include "Grp.h"
|
||||
|
||||
// GRP just reorders w.r.t. read write grouping, however is not aware of the
|
||||
// row buffer. For a row buffer aware grouper refer to FR_FCFS_GRP.
|
||||
// Grp (Grouper) just reorders w.r.t. read write grouping, however is not aware of the
|
||||
// row buffer. For a row buffer aware grouper refer to FrFcfsGrp.
|
||||
// TODO: what is missed is a check if the buffers are full. This will only work
|
||||
// if we have buffers with a fixed size (Prado's future patch).
|
||||
|
||||
std::pair<Command, gp *> GRP::getNextRequest(Bank bank)
|
||||
std::pair<Command, gp *> Grp::getNextRequest(Bank bank)
|
||||
{
|
||||
// If the bank is empty we do nothing:
|
||||
if (buffer[bank].empty()) {
|
||||
@@ -74,7 +74,7 @@ std::pair<Command, gp *> GRP::getNextRequest(Bank bank)
|
||||
if (hazardDetection(bank, it) == false) {
|
||||
buffer[bank].erase(it);
|
||||
printDebugMessage("Read Hit found");
|
||||
return pair<Command, gp *>(getReadWriteCommand(*read),
|
||||
return pair<Command, gp *>(getReadWriteCommand(read),
|
||||
read);
|
||||
} else {
|
||||
// If there was a hazard, switch the mode and try again:
|
||||
@@ -106,7 +106,7 @@ std::pair<Command, gp *> GRP::getNextRequest(Bank bank)
|
||||
.getRowInRowBuffer(bank)) {
|
||||
buffer[bank].erase(it);
|
||||
printDebugMessage("Write Hit found");
|
||||
return pair<Command, gp *>(getReadWriteCommand(*write),
|
||||
return pair<Command, gp *>(getReadWriteCommand(write),
|
||||
write);
|
||||
} else {
|
||||
printDebugMessage("Write miss found");
|
||||
@@ -118,7 +118,7 @@ std::pair<Command, gp *> GRP::getNextRequest(Bank bank)
|
||||
|
||||
// If nothing was found we check the other banks before we switch the mode:
|
||||
pair<Command, gp *> other(Command::NOP, NULL);
|
||||
unsigned int B = Configuration::getInstance().memSpec.NumberOfBanks;
|
||||
unsigned int B = Configuration::getInstance().memSpec->NumberOfBanks;
|
||||
|
||||
for (unsigned int i = 1; i < B; i++) {
|
||||
Bank nextBank((bank.ID() + i) % B);
|
||||
@@ -131,12 +131,12 @@ std::pair<Command, gp *> GRP::getNextRequest(Bank bank)
|
||||
readMode = !readMode;
|
||||
return getNextRequest(bank);
|
||||
|
||||
reportFatal("GRP", "Never should go here ...");
|
||||
reportFatal("Grp", "Never should go here ...");
|
||||
}
|
||||
|
||||
// There is a hazard if a read is found which will be scheduled before a write
|
||||
// to the same column and the same row of the same bank:
|
||||
bool GRP::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
|
||||
bool Grp::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
|
||||
{
|
||||
gp *read = *ext;
|
||||
|
||||
@@ -157,11 +157,11 @@ bool GRP::hazardDetection(Bank bank, std::deque<gp *>::iterator ext)
|
||||
}
|
||||
|
||||
// Estimate the number of writes/reads in all bank buffers:
|
||||
unsigned int GRP::getNumberOfRequest(tlm::tlm_command cmd)
|
||||
unsigned int Grp::getNumberOfRequest(tlm::tlm_command cmd)
|
||||
{
|
||||
unsigned int numberOfRequests = 0;
|
||||
for (unsigned int i = 0;
|
||||
i < Configuration::getInstance().memSpec.NumberOfBanks;
|
||||
i < Configuration::getInstance().memSpec->NumberOfBanks;
|
||||
i++) {
|
||||
for (auto it = buffer[i].begin(); it != buffer[i].end(); it++) {
|
||||
gp *trans = *it;
|
||||
@@ -174,7 +174,7 @@ unsigned int GRP::getNumberOfRequest(tlm::tlm_command cmd)
|
||||
return numberOfRequests;
|
||||
}
|
||||
|
||||
void GRP::printDebugMessage(std::string message)
|
||||
void Grp::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage("FR_FCFS_GRP", message);
|
||||
DebugManager::getInstance().printDebugMessage("FrFcfsGrp", message);
|
||||
}
|
||||
@@ -33,29 +33,24 @@
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef GROUPER_H
|
||||
#define GROUPER_H
|
||||
#ifndef GRP_H
|
||||
#define GRP_H
|
||||
|
||||
#include "Fr_Fcfs.h"
|
||||
#include "FrFcfs.h"
|
||||
#include "../Controller.h"
|
||||
|
||||
class Controller;
|
||||
|
||||
class GRP : public FR_FCFS
|
||||
class Grp : public FrFcfs
|
||||
{
|
||||
public:
|
||||
GRP(ControllerCore &controllerCore, Controller *c) :
|
||||
FR_FCFS(controllerCore),
|
||||
ctrl(c),
|
||||
readMode(true)
|
||||
{
|
||||
}
|
||||
Grp(ControllerCore &controllerCore, Controller *c)
|
||||
: FrFcfs(controllerCore), ctrl(c), readMode(true) {}
|
||||
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
getNextRequest(Bank bank) override;
|
||||
|
||||
private:
|
||||
|
||||
Controller *ctrl;
|
||||
bool hazardDetection(Bank bank, std::deque<gp *>::iterator ext);
|
||||
unsigned int getNumberOfRequest(tlm::tlm_command cmd);
|
||||
@@ -63,4 +58,4 @@ private:
|
||||
bool readMode;
|
||||
};
|
||||
|
||||
#endif // GROUPER_H
|
||||
#endif // GRP_H
|
||||
@@ -50,13 +50,18 @@ void IScheduler::printDebugMessage(std::string message)
|
||||
Command IScheduler::getNextCommand(gp &payload)
|
||||
{
|
||||
Bank bank = DramExtension::getBank(payload);
|
||||
if (!controllerCore.getRowBufferStates().rowBufferIsOpen(bank)) {
|
||||
if (!controllerCore.getRowBufferStates().rowBufferIsOpen(bank))
|
||||
{
|
||||
return Command::Activate;
|
||||
} else if (controllerCore.getRowBufferStates().rowBufferIsOpen(bank) &&
|
||||
}
|
||||
else if (controllerCore.getRowBufferStates().rowBufferIsOpen(bank) &&
|
||||
controllerCore.getRowBufferStates().getRowInRowBuffer(bank) !=
|
||||
DramExtension::getRow(payload)) {
|
||||
DramExtension::getRow(payload))
|
||||
{
|
||||
return Command::Precharge;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return getReadWriteCommand(payload);
|
||||
}
|
||||
}
|
||||
@@ -68,13 +73,15 @@ Command IScheduler::getNextCommand(gp *payload)
|
||||
|
||||
Command IScheduler::getReadWriteCommand(gp &payload)
|
||||
{
|
||||
|
||||
if (payload.get_command() == tlm::TLM_READ_COMMAND) {
|
||||
if (payload.get_command() == tlm::TLM_READ_COMMAND)
|
||||
{
|
||||
if (Configuration::getInstance().OpenPagePolicy)
|
||||
return Command::Read;
|
||||
else
|
||||
return Command::ReadA;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Configuration::getInstance().OpenPagePolicy)
|
||||
return Command::Write;
|
||||
else
|
||||
@@ -86,3 +93,4 @@ Command IScheduler::getReadWriteCommand(gp *payload)
|
||||
{
|
||||
return getReadWriteCommand(*payload);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +38,8 @@
|
||||
#ifndef ISCHEDULER_H
|
||||
#define ISCHEDULER_H
|
||||
|
||||
|
||||
#include <tlm.h>
|
||||
#include "../../common/dramExtension.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../Command.h"
|
||||
#include "../core/ControllerCore.h"
|
||||
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, University of Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Robert Gernhardt
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
|
||||
//// * 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 <algorithm>
|
||||
|
||||
//namespace scheduler {
|
||||
|
||||
//using namespace std;
|
||||
|
||||
//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()
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
//bool PAR_BS::hasPayloads()
|
||||
//{
|
||||
// return batch->hasPayloads() || buffer->hasPayloads();
|
||||
//}
|
||||
|
||||
//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* result = batch->getNextPayload();
|
||||
// if(result == NULL)
|
||||
// result = buffer->getNextPayload();
|
||||
// return result;
|
||||
//}
|
||||
|
||||
//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());
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
//void PAR_BS::formBatch()
|
||||
//{
|
||||
// map<Thread, ThreadLoad> 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);
|
||||
// }
|
||||
// }
|
||||
|
||||
// vector<ThreadLoad*> sortedLoads;
|
||||
// for (auto& threadLoadPair : loads)
|
||||
// {
|
||||
// sortedLoads.push_back(&threadLoadPair.second);
|
||||
// }
|
||||
|
||||
// sort(sortedLoads.begin(), sortedLoads.end(), LoadPointerComparer());
|
||||
|
||||
// for (auto& load : sortedLoads)
|
||||
// {
|
||||
// batch->schedule(load->getTransactions());
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
//}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, University of Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Robert Gernhardt
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
|
||||
//// * 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"
|
||||
|
||||
//namespace scheduler {
|
||||
|
||||
//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;
|
||||
|
||||
//private:
|
||||
// void formBatch();
|
||||
|
||||
// ControllerCore& controllerCore;
|
||||
// bool useExternalBankstates;
|
||||
// RowBufferState internalBankstates;
|
||||
// FR_FCFS *batch;
|
||||
// FR_FCFS *buffer;
|
||||
// unsigned int capsize;
|
||||
//};
|
||||
|
||||
//} /* scheduler core */
|
||||
|
||||
//#endif
|
||||
@@ -30,7 +30,7 @@ std::pair<Command, gp *> SMS::getNextRequest(Bank bank)
|
||||
return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
} else {
|
||||
gp *payload = bankBuffers[bank].front();
|
||||
Command command = IScheduler::getNextCommand(*payload);
|
||||
Command command = IScheduler::getNextCommand(payload);
|
||||
if (command == Command::Read || command == Command::ReadA
|
||||
|| command == Command::Write
|
||||
|| command == Command::WriteA) {
|
||||
@@ -46,7 +46,7 @@ std::pair<Command, gp *> SMS::getNextRequest(Bank bank)
|
||||
|
||||
void SMS::batchScheduler()
|
||||
{
|
||||
sc_time memClk = Configuration::getInstance().memSpec.clk;
|
||||
sc_time memClk = Configuration::getInstance().memSpec->clk;
|
||||
std::default_random_engine generator;
|
||||
std::bernoulli_distribution distribution((double) SJFprobability / 100.0);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "IScheduler.h"
|
||||
#include "../core/ControllerCore.h"
|
||||
#include "../core/configuration/Configuration.h"
|
||||
#include "../../common/dramExtension.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../../common/DebugManager.h"
|
||||
|
||||
#define LOW_SYSTEM_LOAD 16
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user