Merge branch 'bug/missing_config' into 'develop'
Add missing config parameters, fix BM issue. See merge request ems/astdm/modeling.dram/dram.sys!352
This commit is contained in:
@@ -44,7 +44,7 @@ using namespace sc_core;
|
|||||||
|
|
||||||
void DebugManager::printDebugMessage(const std::string &sender, const std::string &message)
|
void DebugManager::printDebugMessage(const std::string &sender, const std::string &message)
|
||||||
{
|
{
|
||||||
if (Configuration::getInstance().debug)
|
if (debugEnabled)
|
||||||
{
|
{
|
||||||
if (writeToConsole)
|
if (writeToConsole)
|
||||||
std::cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message << std::endl;
|
std::cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message << std::endl;
|
||||||
@@ -54,6 +54,13 @@ void DebugManager::printDebugMessage(const std::string &sender, const std::strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugManager::setup(bool _debugEnabled, bool _writeToConsole, bool _writeToFile)
|
||||||
|
{
|
||||||
|
debugEnabled = _debugEnabled;
|
||||||
|
writeToConsole = _writeToConsole;
|
||||||
|
writeToFile = _writeToFile;
|
||||||
|
}
|
||||||
|
|
||||||
void DebugManager::printMessage(const std::string &sender, const std::string &message)
|
void DebugManager::printMessage(const std::string &sender, const std::string &message)
|
||||||
{
|
{
|
||||||
std::cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message << std::endl;
|
std::cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message << std::endl;
|
||||||
@@ -67,7 +74,7 @@ void DebugManager::openDebugFile(const std::string &filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DebugManager::DebugManager()
|
DebugManager::DebugManager()
|
||||||
: writeToConsole(false), writeToFile(false)
|
: debugEnabled(false), writeToConsole(false), writeToFile(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,14 +69,17 @@ private:
|
|||||||
DebugManager & operator = (const DebugManager &);
|
DebugManager & operator = (const DebugManager &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool writeToConsole;
|
void setup(bool _debugEnabled, bool _writeToConsole, bool _writeToFile);
|
||||||
bool writeToFile;
|
|
||||||
|
|
||||||
void printDebugMessage(const std::string &sender, const std::string &message);
|
void printDebugMessage(const std::string &sender, const std::string &message);
|
||||||
static void printMessage(const std::string &sender, const std::string &message);
|
static void printMessage(const std::string &sender, const std::string &message);
|
||||||
void openDebugFile(const std::string &filename);
|
void openDebugFile(const std::string &filename);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool debugEnabled;
|
||||||
|
bool writeToConsole;
|
||||||
|
bool writeToFile;
|
||||||
|
|
||||||
std::ofstream debugFile;
|
std::ofstream debugFile;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -49,8 +49,8 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
TlmRecorder::TlmRecorder(const std::string &name, const std::string &dbName) :
|
TlmRecorder::TlmRecorder(const std::string& name, const Configuration& config, const std::string& dbName) :
|
||||||
name(name), totalNumTransactions(0), simulationTimeCoveredByRecording(SC_ZERO_TIME)
|
name(name), config(config), totalNumTransactions(0), simulationTimeCoveredByRecording(SC_ZERO_TIME)
|
||||||
{
|
{
|
||||||
currentDataBuffer = &recordingDataBuffer[0];
|
currentDataBuffer = &recordingDataBuffer[0];
|
||||||
storageDataBuffer = &recordingDataBuffer[1];
|
storageDataBuffer = &recordingDataBuffer[1];
|
||||||
@@ -345,29 +345,28 @@ void TlmRecorder::insertGeneralInfo()
|
|||||||
{
|
{
|
||||||
sqlite3_bind_int64(insertGeneralInfoStatement, 1, static_cast<int64_t>(totalNumTransactions));
|
sqlite3_bind_int64(insertGeneralInfoStatement, 1, static_cast<int64_t>(totalNumTransactions));
|
||||||
sqlite3_bind_int64(insertGeneralInfoStatement, 2, static_cast<int64_t>(simulationTimeCoveredByRecording.value()));
|
sqlite3_bind_int64(insertGeneralInfoStatement, 2, static_cast<int64_t>(simulationTimeCoveredByRecording.value()));
|
||||||
sqlite3_bind_int(insertGeneralInfoStatement, 3, static_cast<int>(Configuration::getInstance().memSpec->ranksPerChannel));
|
sqlite3_bind_int(insertGeneralInfoStatement, 3, static_cast<int>(config.memSpec->ranksPerChannel));
|
||||||
sqlite3_bind_int(insertGeneralInfoStatement, 4, static_cast<int>(Configuration::getInstance().memSpec->bankGroupsPerChannel));
|
sqlite3_bind_int(insertGeneralInfoStatement, 4, static_cast<int>(config.memSpec->bankGroupsPerChannel));
|
||||||
sqlite3_bind_int(insertGeneralInfoStatement, 5, static_cast<int>(Configuration::getInstance().memSpec->banksPerChannel));
|
sqlite3_bind_int(insertGeneralInfoStatement, 5, static_cast<int>(config.memSpec->banksPerChannel));
|
||||||
sqlite3_bind_int64(insertGeneralInfoStatement, 6, static_cast<int64_t>(Configuration::getInstance().memSpec->tCK.value()));
|
sqlite3_bind_int64(insertGeneralInfoStatement, 6, static_cast<int64_t>(config.memSpec->tCK.value()));
|
||||||
sqlite3_bind_text(insertGeneralInfoStatement, 7, "PS", 2, nullptr);
|
sqlite3_bind_text(insertGeneralInfoStatement, 7, "PS", 2, nullptr);
|
||||||
|
|
||||||
sqlite3_bind_text(insertGeneralInfoStatement, 8, mcconfig.c_str(), static_cast<int>(mcconfig.length()), nullptr);
|
sqlite3_bind_text(insertGeneralInfoStatement, 8, mcconfig.c_str(), static_cast<int>(mcconfig.length()), nullptr);
|
||||||
sqlite3_bind_text(insertGeneralInfoStatement, 9, memspec.c_str(), static_cast<int>(memspec.length()), nullptr);
|
sqlite3_bind_text(insertGeneralInfoStatement, 9, memspec.c_str(), static_cast<int>(memspec.length()), nullptr);
|
||||||
sqlite3_bind_text(insertGeneralInfoStatement, 10, traces.c_str(), static_cast<int>(traces.length()), nullptr);
|
sqlite3_bind_text(insertGeneralInfoStatement, 10, traces.c_str(), static_cast<int>(traces.length()), nullptr);
|
||||||
if (Configuration::getInstance().enableWindowing)
|
if (config.enableWindowing)
|
||||||
sqlite3_bind_int64(insertGeneralInfoStatement, 11, static_cast<int64_t>((Configuration::getInstance().memSpec->tCK
|
sqlite3_bind_int64(insertGeneralInfoStatement, 11, static_cast<int64_t>((config.memSpec->tCK
|
||||||
* Configuration::getInstance().windowSize).value()));
|
* config.windowSize).value()));
|
||||||
else
|
else
|
||||||
sqlite3_bind_int64(insertGeneralInfoStatement, 11, 0);
|
sqlite3_bind_int64(insertGeneralInfoStatement, 11, 0);
|
||||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, static_cast<int>(Configuration::getInstance().refreshMaxPostponed));
|
sqlite3_bind_int(insertGeneralInfoStatement, 12, static_cast<int>(config.refreshMaxPostponed));
|
||||||
sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(Configuration::getInstance().refreshMaxPulledin));
|
sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(config.refreshMaxPulledin));
|
||||||
sqlite3_bind_int64(insertGeneralInfoStatement, 14, static_cast<int64_t>(UINT64_MAX));
|
sqlite3_bind_int64(insertGeneralInfoStatement, 14, static_cast<int64_t>(UINT64_MAX));
|
||||||
sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast<int>(Configuration::getInstance().requestBufferSize));
|
sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast<int>(config.requestBufferSize));
|
||||||
sqlite3_bind_int(insertGeneralInfoStatement, 16,
|
sqlite3_bind_int(insertGeneralInfoStatement, 16, static_cast<int>(config.memSpec->getPer2BankOffset()));
|
||||||
static_cast<int>(Configuration::getInstance().memSpec->getPer2BankOffset()));
|
|
||||||
|
|
||||||
const auto memSpec = Configuration::getInstance().memSpec;
|
const MemSpec& memSpec = *config.memSpec;
|
||||||
const auto memoryType = memSpec->memoryType;
|
const auto memoryType = memSpec.memoryType;
|
||||||
bool rowColumnCommandBus = [memoryType]() -> bool {
|
bool rowColumnCommandBus = [memoryType]() -> bool {
|
||||||
if (memoryType == MemSpec::MemoryType::HBM2)
|
if (memoryType == MemSpec::MemoryType::HBM2)
|
||||||
return true;
|
return true;
|
||||||
@@ -375,11 +374,11 @@ void TlmRecorder::insertGeneralInfo()
|
|||||||
return false;
|
return false;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
bool pseudoChannelMode = [memSpec, memoryType]() -> bool {
|
bool pseudoChannelMode = [&memSpec, memoryType]() -> bool {
|
||||||
if (memoryType != MemSpec::MemoryType::HBM2)
|
if (memoryType != MemSpec::MemoryType::HBM2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (memSpec->pseudoChannelsPerChannel != 1)
|
if (memSpec.pseudoChannelsPerChannel != 1)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
@@ -392,14 +391,14 @@ void TlmRecorder::insertGeneralInfo()
|
|||||||
|
|
||||||
void TlmRecorder::insertCommandLengths()
|
void TlmRecorder::insertCommandLengths()
|
||||||
{
|
{
|
||||||
const MemSpec *memSpec = Configuration::getInstance().memSpec;
|
const MemSpec& memSpec = *config.memSpec;
|
||||||
|
|
||||||
auto insertCommandLength = [this, memSpec](Command command) {
|
auto insertCommandLength = [this, &memSpec](Command command) {
|
||||||
auto commandName = command.toString();
|
auto commandName = command.toString();
|
||||||
|
|
||||||
sqlite3_bind_text(insertCommandLengthsStatement, 1, commandName.c_str(), commandName.length(), nullptr);
|
sqlite3_bind_text(insertCommandLengthsStatement, 1, commandName.c_str(), commandName.length(), nullptr);
|
||||||
sqlite3_bind_int(insertCommandLengthsStatement, 2,
|
sqlite3_bind_int(insertCommandLengthsStatement, 2,
|
||||||
static_cast<int>(lround(memSpec->getCommandLength(command) / memSpec->tCK)));
|
static_cast<int>(lround(memSpec.getCommandLength(command) / memSpec.tCK)));
|
||||||
executeSqlStatement(insertCommandLengthsStatement);
|
executeSqlStatement(insertCommandLengthsStatement);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -51,11 +51,12 @@
|
|||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
#include "dramExtensions.h"
|
#include "dramExtensions.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "../configuration/Configuration.h"
|
||||||
|
|
||||||
class TlmRecorder
|
class TlmRecorder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TlmRecorder(const std::string &name, const std::string &dbName);
|
TlmRecorder(const std::string& name, const Configuration& config, const std::string& dbName);
|
||||||
TlmRecorder(const TlmRecorder&) = delete;
|
TlmRecorder(const TlmRecorder&) = delete;
|
||||||
TlmRecorder(TlmRecorder&&) = default;
|
TlmRecorder(TlmRecorder&&) = default;
|
||||||
|
|
||||||
@@ -84,6 +85,8 @@ public:
|
|||||||
void finalize();
|
void finalize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const Configuration& config;
|
||||||
|
|
||||||
struct Transaction
|
struct Transaction
|
||||||
{
|
{
|
||||||
Transaction() = default;
|
Transaction() = default;
|
||||||
@@ -143,11 +146,11 @@ private:
|
|||||||
sc_core::sc_time simulationTimeCoveredByRecording;
|
sc_core::sc_time simulationTimeCoveredByRecording;
|
||||||
|
|
||||||
sqlite3 *db = nullptr;
|
sqlite3 *db = nullptr;
|
||||||
sqlite3_stmt *insertTransactionStatement, *insertRangeStatement,
|
sqlite3_stmt *insertTransactionStatement = nullptr, *insertRangeStatement = nullptr,
|
||||||
*updateRangeStatement, *insertPhaseStatement, *updatePhaseStatement,
|
*updateRangeStatement = nullptr, *insertPhaseStatement = nullptr, *updatePhaseStatement = nullptr,
|
||||||
*insertGeneralInfoStatement, *insertCommandLengthsStatement,
|
*insertGeneralInfoStatement = nullptr, *insertCommandLengthsStatement = nullptr,
|
||||||
*insertDebugMessageStatement, *updateDataStrobeStatement,
|
*insertDebugMessageStatement = nullptr, *updateDataStrobeStatement = nullptr,
|
||||||
*insertPowerStatement, *insertBufferDepthStatement, *insertBandwidthStatement;
|
*insertPowerStatement = nullptr, *insertBufferDepthStatement = nullptr, *insertBandwidthStatement = nullptr;
|
||||||
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString,
|
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString,
|
||||||
updatePhaseString, insertGeneralInfoString, insertCommandLengthsString,
|
updatePhaseString, insertGeneralInfoString, insertCommandLengthsString,
|
||||||
insertDebugMessageString, updateDataStrobeString, insertPowerString,
|
insertDebugMessageString, updateDataStrobeString, insertPowerString,
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ void to_json(json &j, const McConfig &c)
|
|||||||
{
|
{
|
||||||
j = json{{"PagePolicy", c.pagePolicy},
|
j = json{{"PagePolicy", c.pagePolicy},
|
||||||
{"Scheduler", c.scheduler},
|
{"Scheduler", c.scheduler},
|
||||||
|
{"HighWatermark", c.highWatermark},
|
||||||
|
{"LowWatermark", c.lowWatermark},
|
||||||
{"SchedulerBuffer", c.schedulerBuffer},
|
{"SchedulerBuffer", c.schedulerBuffer},
|
||||||
{"RequestBufferSize", c.requestBufferSize},
|
{"RequestBufferSize", c.requestBufferSize},
|
||||||
{"CmdMux", c.cmdMux},
|
{"CmdMux", c.cmdMux},
|
||||||
@@ -73,6 +75,12 @@ void from_json(const json &j, McConfig &c)
|
|||||||
if (j_mcconfig.contains("Scheduler"))
|
if (j_mcconfig.contains("Scheduler"))
|
||||||
j_mcconfig.at("Scheduler").get_to(c.scheduler);
|
j_mcconfig.at("Scheduler").get_to(c.scheduler);
|
||||||
|
|
||||||
|
if (j_mcconfig.contains("HighWatermark"))
|
||||||
|
j_mcconfig.at("HighWatermark").get_to(c.highWatermark);
|
||||||
|
|
||||||
|
if (j_mcconfig.contains("LowWatermark"))
|
||||||
|
j_mcconfig.at("LowWatermark").get_to(c.lowWatermark);
|
||||||
|
|
||||||
if (j_mcconfig.contains("SchedulerBuffer"))
|
if (j_mcconfig.contains("SchedulerBuffer"))
|
||||||
j_mcconfig.at("SchedulerBuffer").get_to(c.schedulerBuffer);
|
j_mcconfig.at("SchedulerBuffer").get_to(c.schedulerBuffer);
|
||||||
|
|
||||||
|
|||||||
@@ -154,6 +154,8 @@ struct McConfig
|
|||||||
{
|
{
|
||||||
std::optional<PagePolicy> pagePolicy;
|
std::optional<PagePolicy> pagePolicy;
|
||||||
std::optional<Scheduler> scheduler;
|
std::optional<Scheduler> scheduler;
|
||||||
|
std::optional<unsigned int> highWatermark;
|
||||||
|
std::optional<unsigned int> lowWatermark;
|
||||||
std::optional<SchedulerBuffer> schedulerBuffer;
|
std::optional<SchedulerBuffer> schedulerBuffer;
|
||||||
std::optional<unsigned int> requestBufferSize;
|
std::optional<unsigned int> requestBufferSize;
|
||||||
std::optional<CmdMux> cmdMux;
|
std::optional<CmdMux> cmdMux;
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ void to_json(json &j, const TraceSetup &c)
|
|||||||
json transition_j;
|
json transition_j;
|
||||||
transition_j["from"] = transition.first;
|
transition_j["from"] = transition.first;
|
||||||
transition_j["to"] = transition.second.to;
|
transition_j["to"] = transition.second.to;
|
||||||
transition_j["propability"] = transition.second.propability;
|
transition_j["probability"] = transition.second.probability;
|
||||||
remove_null_values(transition_j);
|
remove_null_values(transition_j);
|
||||||
transitions_j.insert(transitions_j.end(), transition_j);
|
transitions_j.insert(transitions_j.end(), transition_j);
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ void from_json(const json &j, TraceSetup &c)
|
|||||||
TraceGeneratorStateTransition transition;
|
TraceGeneratorStateTransition transition;
|
||||||
unsigned int from = transition_j.at("from");
|
unsigned int from = transition_j.at("from");
|
||||||
transition.to = transition_j.at("to");
|
transition.to = transition_j.at("to");
|
||||||
transition.propability = transition_j.at("propability");
|
transition.probability = transition_j.at("probability");
|
||||||
generator.transitions.emplace(from, transition);
|
generator.transitions.emplace(from, transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ struct TraceGeneratorIdleState : public TraceGeneratorState
|
|||||||
struct TraceGeneratorStateTransition
|
struct TraceGeneratorStateTransition
|
||||||
{
|
{
|
||||||
unsigned int to;
|
unsigned int to;
|
||||||
float propability;
|
float probability;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraceGenerator : public TrafficInitiator
|
struct TraceGenerator : public TrafficInitiator
|
||||||
|
|||||||
@@ -292,11 +292,6 @@ uint64_t DramExtension::getChannelPayloadID() const
|
|||||||
return channelPayloadID;
|
return channelPayloadID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DramExtension::incrementRow()
|
|
||||||
{
|
|
||||||
++row;
|
|
||||||
}
|
|
||||||
|
|
||||||
tlm_extension_base *GenerationExtension::clone() const
|
tlm_extension_base *GenerationExtension::clone() const
|
||||||
{
|
{
|
||||||
return new GenerationExtension(timeOfGeneration);
|
return new GenerationExtension(timeOfGeneration);
|
||||||
@@ -433,12 +428,6 @@ bool operator !=(const Row &lhs, const Row &rhs)
|
|||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Row Row::operator ++()
|
|
||||||
{
|
|
||||||
id = (id + 1) % Configuration::getInstance().memSpec->rowsPerBank;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//COLUMN
|
//COLUMN
|
||||||
bool operator ==(const Column &lhs, const Column &rhs)
|
bool operator ==(const Column &lhs, const Column &rhs)
|
||||||
|
|||||||
@@ -218,7 +218,6 @@ public:
|
|||||||
unsigned int getBurstLength() const;
|
unsigned int getBurstLength() const;
|
||||||
uint64_t getThreadPayloadID() const;
|
uint64_t getThreadPayloadID() const;
|
||||||
uint64_t getChannelPayloadID() const;
|
uint64_t getChannelPayloadID() const;
|
||||||
void incrementRow();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread thread;
|
Thread thread;
|
||||||
|
|||||||
@@ -76,64 +76,64 @@ enum sc_time_unit string2TimeUnit(const std::string &s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::loadSimConfig(Configuration &config, const DRAMSysConfiguration::SimConfig &simConfig)
|
void Configuration::loadSimConfig(const DRAMSysConfiguration::SimConfig &simConfig)
|
||||||
{
|
{
|
||||||
if (const auto &addressOffset = simConfig.addressOffset)
|
if (const auto& _addressOffset = simConfig.addressOffset)
|
||||||
config.addressOffset = *addressOffset;
|
addressOffset = *_addressOffset;
|
||||||
|
|
||||||
if (const auto &checkTLM2Protocol = simConfig.checkTLM2Protocol)
|
if (const auto& _checkTLM2Protocol = simConfig.checkTLM2Protocol)
|
||||||
config.checkTLM2Protocol = *checkTLM2Protocol;
|
checkTLM2Protocol = *_checkTLM2Protocol;
|
||||||
|
|
||||||
if (const auto &databaseRecording = simConfig.databaseRecording)
|
if (const auto& _databaseRecording = simConfig.databaseRecording)
|
||||||
config.databaseRecording = *databaseRecording;
|
databaseRecording = *_databaseRecording;
|
||||||
|
|
||||||
if (const auto &debug = simConfig.debug)
|
if (const auto& _debug = simConfig.debug)
|
||||||
config.debug = *debug;
|
debug = *_debug;
|
||||||
|
|
||||||
if (const auto &enableWindowing = simConfig.enableWindowing)
|
if (const auto& _enableWindowing = simConfig.enableWindowing)
|
||||||
config.enableWindowing = *enableWindowing;
|
enableWindowing = *_enableWindowing;
|
||||||
|
|
||||||
if (const auto &powerAnalysis = simConfig.powerAnalysis)
|
if (const auto& _powerAnalysis = simConfig.powerAnalysis)
|
||||||
config.powerAnalysis = *powerAnalysis;
|
powerAnalysis = *_powerAnalysis;
|
||||||
|
|
||||||
if (const auto &simulationName = simConfig.simulationName)
|
if (const auto& _simulationName = simConfig.simulationName)
|
||||||
config.simulationName = *simulationName;
|
simulationName = *_simulationName;
|
||||||
|
|
||||||
if (const auto &simulationProgressBar = simConfig.simulationProgressBar)
|
if (const auto& _simulationProgressBar = simConfig.simulationProgressBar)
|
||||||
config.simulationProgressBar = *simulationProgressBar;
|
simulationProgressBar = *_simulationProgressBar;
|
||||||
|
|
||||||
if (const auto &thermalSimulation = simConfig.thermalSimulation)
|
if (const auto& _thermalSimulation = simConfig.thermalSimulation)
|
||||||
config.thermalSimulation = *thermalSimulation;
|
thermalSimulation = *_thermalSimulation;
|
||||||
|
|
||||||
if (const auto &useMalloc = simConfig.useMalloc)
|
if (const auto& _useMalloc = simConfig.useMalloc)
|
||||||
config.useMalloc = *useMalloc;
|
useMalloc = *_useMalloc;
|
||||||
|
|
||||||
if (const auto &windowSize = simConfig.windowSize)
|
if (const auto& _windowSize = simConfig.windowSize)
|
||||||
config.windowSize = *windowSize;
|
windowSize = *_windowSize;
|
||||||
|
|
||||||
if (config.windowSize == 0)
|
if (windowSize == 0)
|
||||||
SC_REPORT_FATAL("Configuration", "Minimum window size is 1");
|
SC_REPORT_FATAL("Configuration", "Minimum window size is 1");
|
||||||
|
|
||||||
if (const auto &errorCsvFile = simConfig.errorCsvFile)
|
if (const auto& _errorCsvFile = simConfig.errorCsvFile)
|
||||||
config.errorCSVFile = *errorCsvFile;
|
errorCSVFile = *_errorCsvFile;
|
||||||
|
|
||||||
if (const auto &errorChipSeed = simConfig.errorChipSeed)
|
if (const auto& _errorChipSeed = simConfig.errorChipSeed)
|
||||||
config.errorChipSeed = *errorChipSeed;
|
errorChipSeed = *_errorChipSeed;
|
||||||
|
|
||||||
if (const auto &storeMode = simConfig.storeMode)
|
if (const auto& _storeMode = simConfig.storeMode)
|
||||||
config.storeMode = [=] {
|
storeMode = [=] {
|
||||||
if (storeMode == DRAMSysConfiguration::StoreMode::NoStorage)
|
if (_storeMode == DRAMSysConfiguration::StoreMode::NoStorage)
|
||||||
return StoreMode::NoStorage;
|
return StoreMode::NoStorage;
|
||||||
else if (storeMode == DRAMSysConfiguration::StoreMode::Store)
|
else if (_storeMode == DRAMSysConfiguration::StoreMode::Store)
|
||||||
return StoreMode::Store;
|
return StoreMode::Store;
|
||||||
else
|
else
|
||||||
return StoreMode::ErrorModel;
|
return StoreMode::ErrorModel;
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::loadTemperatureSimConfig(Configuration &config, const DRAMSysConfiguration::ThermalConfig &thermalConfig)
|
void Configuration::loadTemperatureSimConfig(const DRAMSysConfiguration::ThermalConfig &thermalConfig)
|
||||||
{
|
{
|
||||||
config.temperatureSim.temperatureScale = [=] {
|
temperatureSim.temperatureScale = [=] {
|
||||||
if (thermalConfig.temperatureScale == DRAMSysConfiguration::TemperatureScale::Celsius)
|
if (thermalConfig.temperatureScale == DRAMSysConfiguration::TemperatureScale::Celsius)
|
||||||
return TemperatureSimConfig::TemperatureScale::Celsius;
|
return TemperatureSimConfig::TemperatureScale::Celsius;
|
||||||
else if (thermalConfig.temperatureScale == DRAMSysConfiguration::TemperatureScale::Fahrenheit)
|
else if (thermalConfig.temperatureScale == DRAMSysConfiguration::TemperatureScale::Fahrenheit)
|
||||||
@@ -142,10 +142,10 @@ void Configuration::loadTemperatureSimConfig(Configuration &config, const DRAMSy
|
|||||||
return TemperatureSimConfig::TemperatureScale::Kelvin;
|
return TemperatureSimConfig::TemperatureScale::Kelvin;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
config.temperatureSim.staticTemperatureDefaultValue = thermalConfig.staticTemperatureDefaultValue;
|
temperatureSim.staticTemperatureDefaultValue = thermalConfig.staticTemperatureDefaultValue;
|
||||||
config.temperatureSim.thermalSimPeriod = thermalConfig.thermalSimPeriod;
|
temperatureSim.thermalSimPeriod = thermalConfig.thermalSimPeriod;
|
||||||
|
|
||||||
config.temperatureSim.thermalSimUnit = [=] {
|
temperatureSim.thermalSimUnit = [=] {
|
||||||
if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Seconds)
|
if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Seconds)
|
||||||
return sc_core::SC_SEC;
|
return sc_core::SC_SEC;
|
||||||
else if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Milliseconds)
|
else if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Milliseconds)
|
||||||
@@ -162,183 +162,189 @@ void Configuration::loadTemperatureSimConfig(Configuration &config, const DRAMSy
|
|||||||
|
|
||||||
for (const auto &channel : thermalConfig.powerInfo.channels)
|
for (const auto &channel : thermalConfig.powerInfo.channels)
|
||||||
{
|
{
|
||||||
config.temperatureSim.powerInitialValues.push_back(channel.init_pow);
|
temperatureSim.powerInitialValues.push_back(channel.init_pow);
|
||||||
config.temperatureSim.powerThresholds.push_back(channel.threshold);
|
temperatureSim.powerThresholds.push_back(channel.threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.temperatureSim.iceServerIp = thermalConfig.iceServerIp;
|
temperatureSim.iceServerIp = thermalConfig.iceServerIp;
|
||||||
config.temperatureSim.iceServerPort = thermalConfig.iceServerPort;
|
temperatureSim.iceServerPort = thermalConfig.iceServerPort;
|
||||||
config.temperatureSim.simPeriodAdjustFactor = thermalConfig.simPeriodAdjustFactor;
|
temperatureSim.simPeriodAdjustFactor = thermalConfig.simPeriodAdjustFactor;
|
||||||
config.temperatureSim.nPowStableCyclesToIncreasePeriod = thermalConfig.nPowStableCyclesToIncreasePeriod;
|
temperatureSim.nPowStableCyclesToIncreasePeriod = thermalConfig.nPowStableCyclesToIncreasePeriod;
|
||||||
config.temperatureSim.generateTemperatureMap = thermalConfig.generateTemperatureMap;
|
temperatureSim.generateTemperatureMap = thermalConfig.generateTemperatureMap;
|
||||||
config.temperatureSim.generatePowerMap = thermalConfig.generatePowerMap;
|
temperatureSim.generatePowerMap = thermalConfig.generatePowerMap;
|
||||||
|
|
||||||
config.temperatureSim.showTemperatureSimConfig();
|
temperatureSim.showTemperatureSimConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::loadMCConfig(Configuration &config, const DRAMSysConfiguration::McConfig &mcConfig)
|
void Configuration::loadMCConfig(const DRAMSysConfiguration::McConfig &mcConfig)
|
||||||
{
|
{
|
||||||
if (const auto &pagePolicy = mcConfig.pagePolicy)
|
if (const auto& _pagePolicy = mcConfig.pagePolicy)
|
||||||
config.pagePolicy = [=] {
|
pagePolicy = [=] {
|
||||||
if (pagePolicy == DRAMSysConfiguration::PagePolicy::Open)
|
if (_pagePolicy == DRAMSysConfiguration::PagePolicy::Open)
|
||||||
return PagePolicy::Open;
|
return PagePolicy::Open;
|
||||||
else if (pagePolicy == DRAMSysConfiguration::PagePolicy::OpenAdaptive)
|
else if (_pagePolicy == DRAMSysConfiguration::PagePolicy::OpenAdaptive)
|
||||||
return PagePolicy::OpenAdaptive;
|
return PagePolicy::OpenAdaptive;
|
||||||
else if (pagePolicy == DRAMSysConfiguration::PagePolicy::Closed)
|
else if (_pagePolicy == DRAMSysConfiguration::PagePolicy::Closed)
|
||||||
return PagePolicy::Closed;
|
return PagePolicy::Closed;
|
||||||
else
|
else
|
||||||
return PagePolicy::ClosedAdaptive;
|
return PagePolicy::ClosedAdaptive;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (const auto &scheduler = mcConfig.scheduler)
|
if (const auto& _scheduler = mcConfig.scheduler)
|
||||||
config.scheduler = [=] {
|
scheduler = [=] {
|
||||||
if (scheduler == DRAMSysConfiguration::Scheduler::Fifo)
|
if (_scheduler == DRAMSysConfiguration::Scheduler::Fifo)
|
||||||
return Scheduler::Fifo;
|
return Scheduler::Fifo;
|
||||||
else if (scheduler == DRAMSysConfiguration::Scheduler::FrFcfs)
|
else if (_scheduler == DRAMSysConfiguration::Scheduler::FrFcfs)
|
||||||
return Scheduler::FrFcfs;
|
return Scheduler::FrFcfs;
|
||||||
else if (scheduler == DRAMSysConfiguration::Scheduler::FrFcfsGrp)
|
else if (_scheduler == DRAMSysConfiguration::Scheduler::FrFcfsGrp)
|
||||||
return Scheduler::FrFcfsGrp;
|
return Scheduler::FrFcfsGrp;
|
||||||
else if (scheduler == DRAMSysConfiguration::Scheduler::GrpFrFcfs)
|
else if (_scheduler == DRAMSysConfiguration::Scheduler::GrpFrFcfs)
|
||||||
return Scheduler::GrpFrFcfs;
|
return Scheduler::GrpFrFcfs;
|
||||||
else
|
else
|
||||||
return Scheduler::GrpFrFcfsWm;
|
return Scheduler::GrpFrFcfsWm;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (const auto &schedulerBuffer = mcConfig.schedulerBuffer)
|
if (const auto& _highWatermark = mcConfig.highWatermark)
|
||||||
config.schedulerBuffer = [=] {
|
highWatermark = *mcConfig.highWatermark;
|
||||||
if (schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::Bankwise)
|
|
||||||
|
if (const auto& _lowWatermark = mcConfig.lowWatermark)
|
||||||
|
lowWatermark = *mcConfig.lowWatermark;
|
||||||
|
|
||||||
|
if (const auto& _schedulerBuffer = mcConfig.schedulerBuffer)
|
||||||
|
schedulerBuffer = [=] {
|
||||||
|
if (_schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::Bankwise)
|
||||||
return SchedulerBuffer::Bankwise;
|
return SchedulerBuffer::Bankwise;
|
||||||
else if (schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::ReadWrite)
|
else if (_schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::ReadWrite)
|
||||||
return SchedulerBuffer::ReadWrite;
|
return SchedulerBuffer::ReadWrite;
|
||||||
else
|
else
|
||||||
return SchedulerBuffer::Shared;
|
return SchedulerBuffer::Shared;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (const auto &requestBufferSize = mcConfig.requestBufferSize)
|
if (const auto& _requestBufferSize = mcConfig.requestBufferSize)
|
||||||
config.requestBufferSize = *mcConfig.requestBufferSize;
|
requestBufferSize = *mcConfig.requestBufferSize;
|
||||||
|
|
||||||
if (config.requestBufferSize == 0)
|
if (requestBufferSize == 0)
|
||||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||||
|
|
||||||
if (const auto &cmdMux = mcConfig.cmdMux)
|
if (const auto& _cmdMux = mcConfig.cmdMux)
|
||||||
config.cmdMux = [=] {
|
cmdMux = [=] {
|
||||||
if (cmdMux == DRAMSysConfiguration::CmdMux::Oldest)
|
if (_cmdMux == DRAMSysConfiguration::CmdMux::Oldest)
|
||||||
return CmdMux::Oldest;
|
return CmdMux::Oldest;
|
||||||
else
|
else
|
||||||
return CmdMux::Strict;
|
return CmdMux::Strict;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (const auto &respQueue = mcConfig.respQueue)
|
if (const auto& _respQueue = mcConfig.respQueue)
|
||||||
config.respQueue = [=] {
|
respQueue = [=] {
|
||||||
if (respQueue == DRAMSysConfiguration::RespQueue::Fifo)
|
if (_respQueue == DRAMSysConfiguration::RespQueue::Fifo)
|
||||||
return RespQueue::Fifo;
|
return RespQueue::Fifo;
|
||||||
else
|
else
|
||||||
return RespQueue::Reorder;
|
return RespQueue::Reorder;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (const auto &refreshPolicy = mcConfig.refreshPolicy)
|
if (const auto& _refreshPolicy = mcConfig.refreshPolicy)
|
||||||
config.refreshPolicy = [=] {
|
refreshPolicy = [=] {
|
||||||
if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::NoRefresh)
|
if (_refreshPolicy == DRAMSysConfiguration::RefreshPolicy::NoRefresh)
|
||||||
return RefreshPolicy::NoRefresh;
|
return RefreshPolicy::NoRefresh;
|
||||||
else if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::AllBank)
|
else if (_refreshPolicy == DRAMSysConfiguration::RefreshPolicy::AllBank)
|
||||||
return RefreshPolicy::AllBank;
|
return RefreshPolicy::AllBank;
|
||||||
else if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::PerBank)
|
else if (_refreshPolicy == DRAMSysConfiguration::RefreshPolicy::PerBank)
|
||||||
return RefreshPolicy::PerBank;
|
return RefreshPolicy::PerBank;
|
||||||
else if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::Per2Bank)
|
else if (_refreshPolicy == DRAMSysConfiguration::RefreshPolicy::Per2Bank)
|
||||||
return RefreshPolicy::Per2Bank;
|
return RefreshPolicy::Per2Bank;
|
||||||
else // if (policy == DRAMSysConfiguration::RefreshPolicy::SameBank)
|
else // if (policy == DRAMSysConfiguration::RefreshPolicy::SameBank)
|
||||||
return RefreshPolicy::SameBank;
|
return RefreshPolicy::SameBank;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (const auto &refreshMaxPostponed = mcConfig.refreshMaxPostponed)
|
if (const auto& _refreshMaxPostponed = mcConfig.refreshMaxPostponed)
|
||||||
config.refreshMaxPostponed = *refreshMaxPostponed;
|
refreshMaxPostponed = *_refreshMaxPostponed;
|
||||||
|
|
||||||
if (const auto &refreshMaxPulledin = mcConfig.refreshMaxPulledin)
|
if (const auto& _refreshMaxPulledin = mcConfig.refreshMaxPulledin)
|
||||||
config.refreshMaxPulledin = *refreshMaxPulledin;
|
refreshMaxPulledin = *_refreshMaxPulledin;
|
||||||
|
|
||||||
if (const auto &powerDownPolicy = mcConfig.powerDownPolicy)
|
if (const auto& _powerDownPolicy = mcConfig.powerDownPolicy)
|
||||||
config.powerDownPolicy = [=] {
|
powerDownPolicy = [=] {
|
||||||
if (powerDownPolicy == DRAMSysConfiguration::PowerDownPolicy::NoPowerDown)
|
if (_powerDownPolicy == DRAMSysConfiguration::PowerDownPolicy::NoPowerDown)
|
||||||
return PowerDownPolicy::NoPowerDown;
|
return PowerDownPolicy::NoPowerDown;
|
||||||
else
|
else
|
||||||
return PowerDownPolicy::Staggered;
|
return PowerDownPolicy::Staggered;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (const auto &arbiter = mcConfig.arbiter)
|
if (const auto& _arbiter = mcConfig.arbiter)
|
||||||
config.arbiter = [=] {
|
arbiter = [=] {
|
||||||
if (arbiter == DRAMSysConfiguration::Arbiter::Simple)
|
if (_arbiter == DRAMSysConfiguration::Arbiter::Simple)
|
||||||
return Arbiter::Simple;
|
return Arbiter::Simple;
|
||||||
else if (arbiter == DRAMSysConfiguration::Arbiter::Fifo)
|
else if (_arbiter == DRAMSysConfiguration::Arbiter::Fifo)
|
||||||
return Arbiter::Fifo;
|
return Arbiter::Fifo;
|
||||||
else
|
else
|
||||||
return Arbiter::Reorder;
|
return Arbiter::Reorder;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (const auto &maxActiveTransactions = mcConfig.maxActiveTransactions)
|
if (const auto& _maxActiveTransactions = mcConfig.maxActiveTransactions)
|
||||||
config.maxActiveTransactions = *maxActiveTransactions;
|
maxActiveTransactions = *_maxActiveTransactions;
|
||||||
|
|
||||||
if (const auto &refreshManagement = mcConfig.refreshManagement)
|
if (const auto& _refreshManagement = mcConfig.refreshManagement)
|
||||||
config.refreshManagement = *refreshManagement;
|
refreshManagement = *_refreshManagement;
|
||||||
|
|
||||||
if (const auto &arbitrationDelayFw = mcConfig.arbitrationDelayFw)
|
if (const auto& _arbitrationDelayFw = mcConfig.arbitrationDelayFw)
|
||||||
{
|
{
|
||||||
config.arbitrationDelayFw = std::round(sc_time(*arbitrationDelayFw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK;
|
arbitrationDelayFw = std::round(sc_time(*_arbitrationDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto &arbitrationDelayBw = mcConfig.arbitrationDelayBw)
|
if (const auto& _arbitrationDelayBw = mcConfig.arbitrationDelayBw)
|
||||||
{
|
{
|
||||||
config.arbitrationDelayBw = std::round(sc_time(*arbitrationDelayBw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK;
|
arbitrationDelayBw = std::round(sc_time(*_arbitrationDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto &thinkDelayFw = mcConfig.thinkDelayFw)
|
if (const auto& _thinkDelayFw = mcConfig.thinkDelayFw)
|
||||||
{
|
{
|
||||||
config.thinkDelayFw = std::round(sc_time(*thinkDelayFw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK;
|
thinkDelayFw = std::round(sc_time(*_thinkDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto &thinkDelayBw = mcConfig.thinkDelayBw)
|
if (const auto& _thinkDelayBw = mcConfig.thinkDelayBw)
|
||||||
{
|
{
|
||||||
config.thinkDelayBw = std::round(sc_time(*thinkDelayBw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK;
|
thinkDelayBw = std::round(sc_time(*_thinkDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto &phyDelayFw = mcConfig.phyDelayFw)
|
if (const auto& _phyDelayFw = mcConfig.phyDelayFw)
|
||||||
{
|
{
|
||||||
config.phyDelayFw = std::round(sc_time(*phyDelayFw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK;
|
phyDelayFw = std::round(sc_time(*_phyDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto &phyDelayBw = mcConfig.phyDelayBw)
|
if (const auto& _phyDelayBw = mcConfig.phyDelayBw)
|
||||||
{
|
{
|
||||||
config.phyDelayBw = std::round(sc_time(*phyDelayBw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK;
|
phyDelayBw = std::round(sc_time(*_phyDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::loadMemSpec(Configuration &config, const DRAMSysConfiguration::MemSpec &memSpecConfig)
|
void Configuration::loadMemSpec(const DRAMSysConfiguration::MemSpec &memSpecConfig)
|
||||||
{
|
{
|
||||||
std::string memoryType = memSpecConfig.memoryType;
|
std::string memoryType = memSpecConfig.memoryType;
|
||||||
|
|
||||||
if (memoryType == "DDR3")
|
if (memoryType == "DDR3")
|
||||||
config.memSpec = new MemSpecDDR3(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecDDR3>(memSpecConfig);
|
||||||
else if (memoryType == "DDR4")
|
else if (memoryType == "DDR4")
|
||||||
config.memSpec = new MemSpecDDR4(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecDDR4>(memSpecConfig);
|
||||||
else if (memoryType == "DDR5")
|
else if (memoryType == "DDR5")
|
||||||
config.memSpec = new MemSpecDDR5(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecDDR5>(memSpecConfig);
|
||||||
else if (memoryType == "LPDDR4")
|
else if (memoryType == "LPDDR4")
|
||||||
config.memSpec = new MemSpecLPDDR4(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecLPDDR4>(memSpecConfig);
|
||||||
else if (memoryType == "LPDDR5")
|
else if (memoryType == "LPDDR5")
|
||||||
config.memSpec = new MemSpecLPDDR5(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecLPDDR5>(memSpecConfig);
|
||||||
else if (memoryType == "WIDEIO_SDR")
|
else if (memoryType == "WIDEIO_SDR")
|
||||||
config.memSpec = new MemSpecWideIO(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecWideIO>(memSpecConfig);
|
||||||
else if (memoryType == "WIDEIO2")
|
else if (memoryType == "WIDEIO2")
|
||||||
config.memSpec = new MemSpecWideIO2(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecWideIO2>(memSpecConfig);
|
||||||
else if (memoryType == "HBM2")
|
else if (memoryType == "HBM2")
|
||||||
config.memSpec = new MemSpecHBM2(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecHBM2>(memSpecConfig);
|
||||||
else if (memoryType == "GDDR5")
|
else if (memoryType == "GDDR5")
|
||||||
config.memSpec = new MemSpecGDDR5(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecGDDR5>(memSpecConfig);
|
||||||
else if (memoryType == "GDDR5X")
|
else if (memoryType == "GDDR5X")
|
||||||
config.memSpec = new MemSpecGDDR5X(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecGDDR5X>(memSpecConfig);
|
||||||
else if (memoryType == "GDDR6")
|
else if (memoryType == "GDDR6")
|
||||||
config.memSpec = new MemSpecGDDR6(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecGDDR6>(memSpecConfig);
|
||||||
else if (memoryType == "STT-MRAM")
|
else if (memoryType == "STT-MRAM")
|
||||||
config.memSpec = new MemSpecSTTMRAM(memSpecConfig);
|
memSpec = std::make_unique<const MemSpecSTTMRAM>(memSpecConfig);
|
||||||
else
|
else
|
||||||
SC_REPORT_FATAL("Configuration", "Unsupported DRAM type");
|
SC_REPORT_FATAL("Configuration", "Unsupported DRAM type");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,23 +51,17 @@
|
|||||||
class Configuration
|
class Configuration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Configuration &getInstance()
|
|
||||||
{
|
|
||||||
static Configuration _instance;
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Configuration() = default;
|
Configuration() = default;
|
||||||
Configuration(const Configuration &);
|
Configuration(const Configuration&) = delete;
|
||||||
Configuration &operator = (const Configuration &);
|
Configuration& operator=(const Configuration &) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// MCConfig:
|
// MCConfig:
|
||||||
enum class PagePolicy {Open, Closed, OpenAdaptive, ClosedAdaptive} pagePolicy = PagePolicy::Open;
|
enum class PagePolicy {Open, Closed, OpenAdaptive, ClosedAdaptive} pagePolicy = PagePolicy::Open;
|
||||||
enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp, GrpFrFcfs, GrpFrFcfsWm} scheduler = Scheduler::FrFcfs;
|
enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp, GrpFrFcfs, GrpFrFcfsWm} scheduler = Scheduler::FrFcfs;
|
||||||
enum class SchedulerBuffer {Bankwise, ReadWrite, Shared} schedulerBuffer = SchedulerBuffer::Bankwise;
|
enum class SchedulerBuffer {Bankwise, ReadWrite, Shared} schedulerBuffer = SchedulerBuffer::Bankwise;
|
||||||
unsigned int lowWatermark = 8;
|
unsigned int lowWatermark = 0;
|
||||||
unsigned int highWatermark = 16;
|
unsigned int highWatermark = 0;
|
||||||
enum class CmdMux {Oldest, Strict} cmdMux = CmdMux::Oldest;
|
enum class CmdMux {Oldest, Strict} cmdMux = CmdMux::Oldest;
|
||||||
enum class RespQueue {Fifo, Reorder} respQueue = RespQueue::Fifo;
|
enum class RespQueue {Fifo, Reorder} respQueue = RespQueue::Fifo;
|
||||||
enum class Arbiter {Simple, Fifo, Reorder} arbiter = Arbiter::Simple;
|
enum class Arbiter {Simple, Fifo, Reorder} arbiter = Arbiter::Simple;
|
||||||
@@ -105,15 +99,15 @@ public:
|
|||||||
enum class StoreMode {NoStorage, Store, ErrorModel} storeMode = StoreMode::NoStorage;
|
enum class StoreMode {NoStorage, Store, ErrorModel} storeMode = StoreMode::NoStorage;
|
||||||
|
|
||||||
// MemSpec (from DRAM-Power)
|
// MemSpec (from DRAM-Power)
|
||||||
const MemSpec *memSpec = nullptr;
|
std::unique_ptr<const MemSpec> memSpec;
|
||||||
|
|
||||||
// Temperature Simulation related
|
// Temperature Simulation related
|
||||||
TemperatureSimConfig temperatureSim;
|
TemperatureSimConfig temperatureSim;
|
||||||
|
|
||||||
static void loadMCConfig(Configuration &config, const DRAMSysConfiguration::McConfig &mcConfig);
|
void loadMCConfig(const DRAMSysConfiguration::McConfig& mcConfig);
|
||||||
static void loadSimConfig(Configuration &config, const DRAMSysConfiguration::SimConfig &simConfig);
|
void loadSimConfig(const DRAMSysConfiguration::SimConfig& simConfig);
|
||||||
static void loadMemSpec(Configuration &config, const DRAMSysConfiguration::MemSpec &memSpec);
|
void loadMemSpec(const DRAMSysConfiguration::MemSpec& memSpec);
|
||||||
static void loadTemperatureSimConfig(Configuration &config, const DRAMSysConfiguration::ThermalConfig &thermalConfig);
|
void loadTemperatureSimConfig(const DRAMSysConfiguration::ThermalConfig& thermalConfig);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONFIGURATION_H
|
#endif // CONFIGURATION_H
|
||||||
|
|||||||
@@ -81,18 +81,18 @@ MemSpecDDR3::MemSpecDDR3(const DRAMSysConfiguration::MemSpec &memSpec)
|
|||||||
tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")),
|
tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")),
|
||||||
tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")),
|
tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")),
|
||||||
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
|
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
|
||||||
iDD0 (memSpec.memPowerSpec.value().entries.at("idd0")),
|
iDD0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd0") : 0),
|
||||||
iDD2N (memSpec.memPowerSpec.value().entries.at("idd2n")),
|
iDD2N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n") : 0),
|
||||||
iDD3N (memSpec.memPowerSpec.value().entries.at("idd3n")),
|
iDD3N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n") : 0),
|
||||||
iDD4R (memSpec.memPowerSpec.value().entries.at("idd4r")),
|
iDD4R (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r") : 0),
|
||||||
iDD4W (memSpec.memPowerSpec.value().entries.at("idd4w")),
|
iDD4W (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w") : 0),
|
||||||
iDD5 (memSpec.memPowerSpec.value().entries.at("idd5")),
|
iDD5 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd5") : 0),
|
||||||
iDD6 (memSpec.memPowerSpec.value().entries.at("idd6")),
|
iDD6 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd6") : 0),
|
||||||
vDD (memSpec.memPowerSpec.value().entries.at("vdd")),
|
vDD (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd") : 0),
|
||||||
iDD2P0 (memSpec.memPowerSpec.value().entries.at("idd2p0")),
|
iDD2P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p0") : 0),
|
||||||
iDD2P1 (memSpec.memPowerSpec.value().entries.at("idd2p1")),
|
iDD2P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p1") : 0),
|
||||||
iDD3P0 (memSpec.memPowerSpec.value().entries.at("idd3p0")),
|
iDD3P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p0") : 0),
|
||||||
iDD3P1 (memSpec.memPowerSpec.value().entries.at("idd3p1"))
|
iDD3P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p1") : 0)
|
||||||
{
|
{
|
||||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
|
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
|
||||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||||
|
|||||||
@@ -96,28 +96,28 @@ MemSpecDDR4::MemSpecDDR4(const DRAMSysConfiguration::MemSpec &memSpec)
|
|||||||
tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")),
|
tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")),
|
||||||
tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")),
|
tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")),
|
||||||
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
|
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
|
||||||
iDD0 (memSpec.memPowerSpec.value().entries.at("idd0")),
|
iDD0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd0") : 0),
|
||||||
iDD2N (memSpec.memPowerSpec.value().entries.at("idd2n")),
|
iDD2N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n") : 0),
|
||||||
iDD3N (memSpec.memPowerSpec.value().entries.at("idd3n")),
|
iDD3N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n") : 0),
|
||||||
iDD4R (memSpec.memPowerSpec.value().entries.at("idd4r")),
|
iDD4R (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r") : 0),
|
||||||
iDD4W (memSpec.memPowerSpec.value().entries.at("idd4w")),
|
iDD4W (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w") : 0),
|
||||||
iDD5 (memSpec.memPowerSpec.value().entries.at("idd5")),
|
iDD5 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd5") : 0),
|
||||||
iDD6 (memSpec.memPowerSpec.value().entries.at("idd6")),
|
iDD6 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd6") : 0),
|
||||||
vDD (memSpec.memPowerSpec.value().entries.at("vdd")),
|
vDD (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd") : 0),
|
||||||
iDD02 (memSpec.memPowerSpec.value().entries.at("idd02")),
|
iDD02 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd02") : 0),
|
||||||
iDD2P0 (memSpec.memPowerSpec.value().entries.at("idd2p0")),
|
iDD2P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p0") : 0),
|
||||||
iDD2P1 (memSpec.memPowerSpec.value().entries.at("idd2p1")),
|
iDD2P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p1") : 0),
|
||||||
iDD3P0 (memSpec.memPowerSpec.value().entries.at("idd3p0")),
|
iDD3P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p0") : 0),
|
||||||
iDD3P1 (memSpec.memPowerSpec.value().entries.at("idd3p1")),
|
iDD3P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p1") : 0),
|
||||||
iDD62 (memSpec.memPowerSpec.value().entries.at("idd62")),
|
iDD62 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd62") : 0),
|
||||||
vDD2 (memSpec.memPowerSpec.value().entries.at("vdd2"))
|
vDD2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd2") : 0)
|
||||||
{
|
{
|
||||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
|
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
|
||||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||||
memorySizeBytes = deviceSizeBytes * devicesPerRank * ranksPerChannel * numberOfChannels;
|
memorySizeBytes = deviceSizeBytes * devicesPerRank * ranksPerChannel * numberOfChannels;
|
||||||
|
|
||||||
if (!memSpec.memPowerSpec.has_value())
|
if (!memSpec.memPowerSpec.has_value())
|
||||||
SC_REPORT_FATAL("MemSpec", "No power spec defined!");
|
SC_REPORT_WARNING("MemSpec", "No power spec defined!");
|
||||||
|
|
||||||
std::cout << headline << std::endl;
|
std::cout << headline << std::endl;
|
||||||
std::cout << "Memory Configuration:" << std::endl << std::endl;
|
std::cout << "Memory Configuration:" << std::endl << std::endl;
|
||||||
|
|||||||
@@ -75,30 +75,30 @@ MemSpecWideIO::MemSpecWideIO(const DRAMSysConfiguration::MemSpec &memSpec)
|
|||||||
tTAW (tCK * memSpec.memTimingSpec.entries.at("TAW")),
|
tTAW (tCK * memSpec.memTimingSpec.entries.at("TAW")),
|
||||||
tWTR (tCK * memSpec.memTimingSpec.entries.at("WTR")),
|
tWTR (tCK * memSpec.memTimingSpec.entries.at("WTR")),
|
||||||
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
|
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
|
||||||
iDD0 (memSpec.memPowerSpec.value().entries.at("idd0")),
|
iDD0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd0") : 0),
|
||||||
iDD2N (memSpec.memPowerSpec.value().entries.at("idd2n")),
|
iDD2N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n") : 0),
|
||||||
iDD3N (memSpec.memPowerSpec.value().entries.at("idd3n")),
|
iDD3N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n") : 0),
|
||||||
iDD4R (memSpec.memPowerSpec.value().entries.at("idd4r")),
|
iDD4R (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r") : 0),
|
||||||
iDD4W (memSpec.memPowerSpec.value().entries.at("idd4w")),
|
iDD4W (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w") : 0),
|
||||||
iDD5 (memSpec.memPowerSpec.value().entries.at("idd5")),
|
iDD5 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd5") : 0),
|
||||||
iDD6 (memSpec.memPowerSpec.value().entries.at("idd6")),
|
iDD6 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd6") : 0),
|
||||||
vDD (memSpec.memPowerSpec.value().entries.at("vdd")),
|
vDD (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd") : 0),
|
||||||
iDD02 (memSpec.memPowerSpec.value().entries.at("idd02")),
|
iDD02 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd02") : 0),
|
||||||
iDD2P0 (memSpec.memPowerSpec.value().entries.at("idd2p0")),
|
iDD2P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p0") : 0),
|
||||||
iDD2P02 (memSpec.memPowerSpec.value().entries.at("idd2p02")),
|
iDD2P02 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p02") : 0),
|
||||||
iDD2P1 (memSpec.memPowerSpec.value().entries.at("idd2p1")),
|
iDD2P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p1") : 0),
|
||||||
iDD2P12 (memSpec.memPowerSpec.value().entries.at("idd2p12")),
|
iDD2P12 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p12") : 0),
|
||||||
iDD2N2 (memSpec.memPowerSpec.value().entries.at("idd2n2")),
|
iDD2N2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n2") : 0),
|
||||||
iDD3P0 (memSpec.memPowerSpec.value().entries.at("idd3p0")),
|
iDD3P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p0") : 0),
|
||||||
iDD3P02 (memSpec.memPowerSpec.value().entries.at("idd3p02")),
|
iDD3P02 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p02") : 0),
|
||||||
iDD3P1 (memSpec.memPowerSpec.value().entries.at("idd3p1")),
|
iDD3P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p1") : 0),
|
||||||
iDD3P12 (memSpec.memPowerSpec.value().entries.at("idd3p12")),
|
iDD3P12 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p12") : 0),
|
||||||
iDD3N2 (memSpec.memPowerSpec.value().entries.at("idd3n2")),
|
iDD3N2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n2") : 0),
|
||||||
iDD4R2 (memSpec.memPowerSpec.value().entries.at("idd4r2")),
|
iDD4R2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r2") : 0),
|
||||||
iDD4W2 (memSpec.memPowerSpec.value().entries.at("idd4w2")),
|
iDD4W2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w2") : 0),
|
||||||
iDD52 (memSpec.memPowerSpec.value().entries.at("idd52")),
|
iDD52 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd52") : 0),
|
||||||
iDD62 (memSpec.memPowerSpec.value().entries.at("idd62")),
|
iDD62 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd62") : 0),
|
||||||
vDD2 (memSpec.memPowerSpec.value().entries.at("vdd2"))
|
vDD2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd2") : 0)
|
||||||
{
|
{
|
||||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
|
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
|
||||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||||
|
|||||||
@@ -40,13 +40,12 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
BankMachine::BankMachine(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
BankMachine::BankMachine(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||||
: scheduler(scheduler), checker(checker), bank(bank)
|
: scheduler(scheduler), checker(checker), bank(bank), memSpec(*config.memSpec)
|
||||||
{
|
{
|
||||||
memSpec = Configuration::getInstance().memSpec;
|
rank = Rank(bank.ID() / memSpec.banksPerRank);
|
||||||
rank = Rank(bank.ID() / memSpec->banksPerRank);
|
bankgroup = BankGroup(bank.ID() / memSpec.banksPerGroup);
|
||||||
bankgroup = BankGroup(bank.ID() / memSpec->banksPerGroup);
|
refreshManagement = config.refreshManagement;
|
||||||
refreshManagement = Configuration::getInstance().refreshManagement;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandTuple::Type BankMachine::getNextCommand()
|
CommandTuple::Type BankMachine::getNextCommand()
|
||||||
@@ -61,46 +60,53 @@ void BankMachine::updateState(Command command)
|
|||||||
case Command::ACT:
|
case Command::ACT:
|
||||||
state = State::Activated;
|
state = State::Activated;
|
||||||
openRow = DramExtension::getRow(currentPayload);
|
openRow = DramExtension::getRow(currentPayload);
|
||||||
|
keepTrans = true;
|
||||||
refreshManagementCounter++;
|
refreshManagementCounter++;
|
||||||
break;
|
break;
|
||||||
case Command::PREPB: case Command::PRESB: case Command::PREAB:
|
case Command::PREPB: case Command::PRESB: case Command::PREAB:
|
||||||
state = State::Precharged;
|
state = State::Precharged;
|
||||||
|
keepTrans = false;
|
||||||
break;
|
break;
|
||||||
case Command::RD: case Command::WR:
|
case Command::RD: case Command::WR:
|
||||||
currentPayload = nullptr;
|
currentPayload = nullptr;
|
||||||
|
keepTrans = false;
|
||||||
break;
|
break;
|
||||||
case Command::RDA: case Command::WRA:
|
case Command::RDA: case Command::WRA:
|
||||||
state = State::Precharged;
|
state = State::Precharged;
|
||||||
currentPayload = nullptr;
|
currentPayload = nullptr;
|
||||||
|
keepTrans = false;
|
||||||
break;
|
break;
|
||||||
case Command::PDEA: case Command::PDEP: case Command::SREFEN:
|
case Command::PDEA: case Command::PDEP: case Command::SREFEN:
|
||||||
|
assert(!keepTrans);
|
||||||
sleeping = true;
|
sleeping = true;
|
||||||
break;
|
break;
|
||||||
case Command::REFPB: case Command::REFP2B: case Command::REFSB: case Command::REFAB:
|
case Command::REFPB: case Command::REFP2B: case Command::REFSB: case Command::REFAB:
|
||||||
sleeping = false;
|
sleeping = false;
|
||||||
blocked = false;
|
blocked = false;
|
||||||
|
|
||||||
if (refreshManagement)
|
if (refreshManagement)
|
||||||
{
|
{
|
||||||
if (refreshManagementCounter > memSpec->getRAACDR())
|
if (refreshManagementCounter > memSpec.getRAACDR())
|
||||||
refreshManagementCounter -= memSpec->getRAACDR();
|
refreshManagementCounter -= memSpec.getRAACDR();
|
||||||
else
|
else
|
||||||
refreshManagementCounter = 0;
|
refreshManagementCounter = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Command::RFMPB: case Command::RFMP2B: case Command::RFMSB: case Command::RFMAB:
|
case Command::RFMPB: case Command::RFMP2B: case Command::RFMSB: case Command::RFMAB:
|
||||||
|
assert(!keepTrans);
|
||||||
sleeping = false;
|
sleeping = false;
|
||||||
blocked = false;
|
blocked = false;
|
||||||
|
|
||||||
if (refreshManagement)
|
if (refreshManagement)
|
||||||
{
|
{
|
||||||
if (refreshManagementCounter > memSpec->getRAAIMT())
|
if (refreshManagementCounter > memSpec.getRAAIMT())
|
||||||
refreshManagementCounter -= memSpec->getRAAIMT();
|
refreshManagementCounter -= memSpec.getRAAIMT();
|
||||||
else
|
else
|
||||||
refreshManagementCounter = 0;
|
refreshManagementCounter = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Command::PDXA: case Command::PDXP:
|
case Command::PDXA: case Command::PDXP:
|
||||||
|
assert(!keepTrans);
|
||||||
sleeping = false;
|
sleeping = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -155,8 +161,9 @@ bool BankMachine::isPrecharged() const
|
|||||||
return state == State::Precharged;
|
return state == State::Precharged;
|
||||||
}
|
}
|
||||||
|
|
||||||
BankMachineOpen::BankMachineOpen(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
BankMachineOpen::BankMachineOpen(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker,
|
||||||
: BankMachine(scheduler, checker, bank) {}
|
Bank bank)
|
||||||
|
: BankMachine(config, scheduler, checker, bank) {}
|
||||||
|
|
||||||
sc_time BankMachineOpen::start()
|
sc_time BankMachineOpen::start()
|
||||||
{
|
{
|
||||||
@@ -165,33 +172,50 @@ sc_time BankMachineOpen::start()
|
|||||||
|
|
||||||
if (!(sleeping || blocked))
|
if (!(sleeping || blocked))
|
||||||
{
|
{
|
||||||
currentPayload = scheduler.getNextRequest(*this);
|
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
|
||||||
if (currentPayload != nullptr)
|
if (newPayload == nullptr)
|
||||||
{
|
{
|
||||||
|
return timeToSchedule;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(!keepTrans || currentPayload != nullptr);
|
||||||
|
if (keepTrans)
|
||||||
|
{
|
||||||
|
if (DramExtension::getRow(newPayload) == openRow)
|
||||||
|
currentPayload = newPayload;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentPayload = newPayload;
|
||||||
|
}
|
||||||
|
|
||||||
if (state == State::Precharged) // bank precharged
|
if (state == State::Precharged) // bank precharged
|
||||||
nextCommand = Command::ACT;
|
nextCommand = Command::ACT;
|
||||||
else if (state == State::Activated)
|
else if (state == State::Activated)
|
||||||
{
|
{
|
||||||
if (DramExtension::getRow(currentPayload) == openRow) // row hit
|
if (DramExtension::getRow(currentPayload) == openRow) // row hit
|
||||||
{
|
{
|
||||||
|
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||||
if (currentPayload->is_read())
|
if (currentPayload->is_read())
|
||||||
nextCommand = Command::RD;
|
nextCommand = Command::RD;
|
||||||
else if (currentPayload->is_write())
|
|
||||||
nextCommand = Command::WR;
|
|
||||||
else
|
else
|
||||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
nextCommand = Command::WR;
|
||||||
}
|
}
|
||||||
else // row miss
|
else // row miss
|
||||||
nextCommand = Command::PREPB;
|
nextCommand = Command::PREPB;
|
||||||
}
|
}
|
||||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
||||||
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return timeToSchedule;
|
else
|
||||||
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
BankMachineClosed::BankMachineClosed(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
BankMachineClosed::BankMachineClosed(const Configuration& config, const SchedulerIF& scheduler,
|
||||||
: BankMachine(scheduler, checker, bank) {}
|
const CheckerIF& checker, Bank bank)
|
||||||
|
: BankMachine(config, scheduler, checker, bank) {}
|
||||||
|
|
||||||
sc_time BankMachineClosed::start()
|
sc_time BankMachineClosed::start()
|
||||||
{
|
{
|
||||||
@@ -200,28 +224,45 @@ sc_time BankMachineClosed::start()
|
|||||||
|
|
||||||
if (!(sleeping || blocked))
|
if (!(sleeping || blocked))
|
||||||
{
|
{
|
||||||
currentPayload = scheduler.getNextRequest(*this);
|
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
|
||||||
if (currentPayload != nullptr)
|
if (newPayload == nullptr)
|
||||||
{
|
{
|
||||||
|
return timeToSchedule;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(!keepTrans || currentPayload != nullptr);
|
||||||
|
if (keepTrans)
|
||||||
|
{
|
||||||
|
if (DramExtension::getRow(newPayload) == openRow)
|
||||||
|
currentPayload = newPayload;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentPayload = newPayload;
|
||||||
|
}
|
||||||
|
|
||||||
if (state == State::Precharged) // bank precharged
|
if (state == State::Precharged) // bank precharged
|
||||||
nextCommand = Command::ACT;
|
nextCommand = Command::ACT;
|
||||||
else if (state == State::Activated)
|
else if (state == State::Activated)
|
||||||
{
|
{
|
||||||
|
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||||
if (currentPayload->is_read())
|
if (currentPayload->is_read())
|
||||||
nextCommand = Command::RDA;
|
nextCommand = Command::RDA;
|
||||||
else if (currentPayload->is_write())
|
|
||||||
nextCommand = Command::WRA;
|
|
||||||
else
|
else
|
||||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
nextCommand = Command::WRA;
|
||||||
}
|
}
|
||||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
||||||
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return timeToSchedule;
|
else
|
||||||
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
BankMachineOpenAdaptive::BankMachineOpenAdaptive(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
BankMachineOpenAdaptive::BankMachineOpenAdaptive(const Configuration& config, const SchedulerIF& scheduler,
|
||||||
: BankMachine(scheduler, checker, bank) {}
|
const CheckerIF& checker, Bank bank)
|
||||||
|
: BankMachine(config, scheduler, checker, bank) {}
|
||||||
|
|
||||||
sc_time BankMachineOpenAdaptive::start()
|
sc_time BankMachineOpenAdaptive::start()
|
||||||
{
|
{
|
||||||
@@ -230,9 +271,24 @@ sc_time BankMachineOpenAdaptive::start()
|
|||||||
|
|
||||||
if (!(sleeping || blocked))
|
if (!(sleeping || blocked))
|
||||||
{
|
{
|
||||||
currentPayload = scheduler.getNextRequest(*this);
|
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
|
||||||
if (currentPayload != nullptr)
|
if (newPayload == nullptr)
|
||||||
{
|
{
|
||||||
|
return timeToSchedule;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(!keepTrans || currentPayload != nullptr);
|
||||||
|
if (keepTrans)
|
||||||
|
{
|
||||||
|
if (DramExtension::getRow(newPayload) == openRow)
|
||||||
|
currentPayload = newPayload;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentPayload = newPayload;
|
||||||
|
}
|
||||||
|
|
||||||
if (state == State::Precharged) // bank precharged
|
if (state == State::Precharged) // bank precharged
|
||||||
nextCommand = Command::ACT;
|
nextCommand = Command::ACT;
|
||||||
else if (state == State::Activated)
|
else if (state == State::Activated)
|
||||||
@@ -240,36 +296,37 @@ sc_time BankMachineOpenAdaptive::start()
|
|||||||
if (DramExtension::getRow(currentPayload) == openRow) // row hit
|
if (DramExtension::getRow(currentPayload) == openRow) // row hit
|
||||||
{
|
{
|
||||||
if (scheduler.hasFurtherRequest(bank, currentPayload->get_command())
|
if (scheduler.hasFurtherRequest(bank, currentPayload->get_command())
|
||||||
&&!scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command()))
|
&& !scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command()))
|
||||||
{
|
{
|
||||||
|
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||||
if (currentPayload->is_read())
|
if (currentPayload->is_read())
|
||||||
nextCommand = Command::RDA;
|
nextCommand = Command::RDA;
|
||||||
else if (currentPayload->is_write())
|
|
||||||
nextCommand = Command::WRA;
|
|
||||||
else
|
else
|
||||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
nextCommand = Command::WRA;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||||
if (currentPayload->is_read())
|
if (currentPayload->is_read())
|
||||||
nextCommand = Command::RD;
|
nextCommand = Command::RD;
|
||||||
else if (currentPayload->is_write())
|
|
||||||
nextCommand = Command::WR;
|
|
||||||
else
|
else
|
||||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
nextCommand = Command::WR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // row miss
|
else // row miss
|
||||||
nextCommand = Command::PREPB;
|
nextCommand = Command::PREPB;
|
||||||
}
|
}
|
||||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
||||||
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return timeToSchedule;
|
else
|
||||||
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
BankMachineClosedAdaptive::BankMachineClosedAdaptive(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
BankMachineClosedAdaptive::BankMachineClosedAdaptive(const Configuration& config, const SchedulerIF& scheduler,
|
||||||
: BankMachine(scheduler, checker, bank) {}
|
const CheckerIF& checker, Bank bank)
|
||||||
|
: BankMachine(config, scheduler, checker, bank) {}
|
||||||
|
|
||||||
sc_time BankMachineClosedAdaptive::start()
|
sc_time BankMachineClosedAdaptive::start()
|
||||||
{
|
{
|
||||||
@@ -278,10 +335,25 @@ sc_time BankMachineClosedAdaptive::start()
|
|||||||
|
|
||||||
if (!(sleeping || blocked))
|
if (!(sleeping || blocked))
|
||||||
{
|
{
|
||||||
currentPayload = scheduler.getNextRequest(*this);
|
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
|
||||||
if (currentPayload != nullptr)
|
if (newPayload == nullptr)
|
||||||
{
|
{
|
||||||
if (state == State::Precharged && !blocked) // bank precharged
|
return timeToSchedule;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(!keepTrans || currentPayload != nullptr);
|
||||||
|
if (keepTrans)
|
||||||
|
{
|
||||||
|
if (DramExtension::getRow(newPayload) == openRow)
|
||||||
|
currentPayload = newPayload;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentPayload = newPayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == State::Precharged) // bank precharged
|
||||||
nextCommand = Command::ACT;
|
nextCommand = Command::ACT;
|
||||||
else if (state == State::Activated)
|
else if (state == State::Activated)
|
||||||
{
|
{
|
||||||
@@ -289,28 +361,28 @@ sc_time BankMachineClosedAdaptive::start()
|
|||||||
{
|
{
|
||||||
if (scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command()))
|
if (scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command()))
|
||||||
{
|
{
|
||||||
|
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||||
if (currentPayload->is_read())
|
if (currentPayload->is_read())
|
||||||
nextCommand = Command::RD;
|
nextCommand = Command::RD;
|
||||||
else if (currentPayload->is_write())
|
|
||||||
nextCommand = Command::WR;
|
|
||||||
else
|
else
|
||||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
nextCommand = Command::WR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||||
if (currentPayload->is_read())
|
if (currentPayload->is_read())
|
||||||
nextCommand = Command::RDA;
|
nextCommand = Command::RDA;
|
||||||
else if (currentPayload->is_write())
|
|
||||||
nextCommand = Command::WRA;
|
|
||||||
else
|
else
|
||||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
nextCommand = Command::WRA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // row miss, should never happen
|
else // row miss, can happen when RD/WR mode is switched
|
||||||
SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy");
|
nextCommand = Command::PREPB;
|
||||||
}
|
}
|
||||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
||||||
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return timeToSchedule;
|
else
|
||||||
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include "scheduler/SchedulerIF.h"
|
#include "scheduler/SchedulerIF.h"
|
||||||
#include "checker/CheckerIF.h"
|
#include "checker/CheckerIF.h"
|
||||||
#include "../configuration/memspec/MemSpec.h"
|
#include "../configuration/memspec/MemSpec.h"
|
||||||
|
#include "../configuration/Configuration.h"
|
||||||
|
|
||||||
class BankMachine
|
class BankMachine
|
||||||
{
|
{
|
||||||
@@ -63,8 +64,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum class State {Precharged, Activated} state = State::Precharged;
|
enum class State {Precharged, Activated} state = State::Precharged;
|
||||||
BankMachine(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
BankMachine(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
||||||
const MemSpec* memSpec;
|
const MemSpec& memSpec;
|
||||||
tlm::tlm_generic_payload *currentPayload = nullptr;
|
tlm::tlm_generic_payload *currentPayload = nullptr;
|
||||||
const SchedulerIF& scheduler;
|
const SchedulerIF& scheduler;
|
||||||
const CheckerIF& checker;
|
const CheckerIF& checker;
|
||||||
@@ -78,33 +79,36 @@ protected:
|
|||||||
bool sleeping = false;
|
bool sleeping = false;
|
||||||
unsigned refreshManagementCounter = 0;
|
unsigned refreshManagementCounter = 0;
|
||||||
bool refreshManagement = false;
|
bool refreshManagement = false;
|
||||||
|
bool keepTrans = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BankMachineOpen final : public BankMachine
|
class BankMachineOpen final : public BankMachine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BankMachineOpen(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
BankMachineOpen(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
||||||
sc_core::sc_time start() override;
|
sc_core::sc_time start() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BankMachineClosed final : public BankMachine
|
class BankMachineClosed final : public BankMachine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BankMachineClosed(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
BankMachineClosed(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
||||||
sc_core::sc_time start() override;
|
sc_core::sc_time start() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BankMachineOpenAdaptive final : public BankMachine
|
class BankMachineOpenAdaptive final : public BankMachine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BankMachineOpenAdaptive(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
BankMachineOpenAdaptive(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker,
|
||||||
|
Bank bank);
|
||||||
sc_core::sc_time start() override;
|
sc_core::sc_time start() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BankMachineClosedAdaptive final : public BankMachine
|
class BankMachineClosedAdaptive final : public BankMachine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BankMachineClosedAdaptive(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
BankMachineClosedAdaptive(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker,
|
||||||
|
Bank bank);
|
||||||
sc_core::sc_time start() override;
|
sc_core::sc_time start() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -69,15 +69,13 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
Controller::Controller(const sc_module_name &name) :
|
Controller::Controller(const sc_module_name& name, const Configuration& config) :
|
||||||
ControllerIF(name)
|
ControllerIF(name, config)
|
||||||
{
|
{
|
||||||
SC_METHOD(controllerMethod);
|
SC_METHOD(controllerMethod);
|
||||||
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
|
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
|
||||||
|
|
||||||
Configuration &config = Configuration::getInstance();
|
ranksNumberOfPayloads = std::vector<unsigned>(memSpec.ranksPerChannel);
|
||||||
memSpec = config.memSpec;
|
|
||||||
ranksNumberOfPayloads = std::vector<unsigned>(memSpec->ranksPerChannel);
|
|
||||||
|
|
||||||
thinkDelayFw = config.thinkDelayFw;
|
thinkDelayFw = config.thinkDelayFw;
|
||||||
thinkDelayBw = config.thinkDelayBw;
|
thinkDelayBw = config.thinkDelayBw;
|
||||||
@@ -85,59 +83,59 @@ Controller::Controller(const sc_module_name &name) :
|
|||||||
phyDelayBw = config.phyDelayBw;
|
phyDelayBw = config.phyDelayBw;
|
||||||
|
|
||||||
// reserve buffer for command tuples
|
// reserve buffer for command tuples
|
||||||
readyCommands.reserve(memSpec->banksPerChannel);
|
readyCommands.reserve(memSpec.banksPerChannel);
|
||||||
|
|
||||||
// instantiate timing checker
|
// instantiate timing checker
|
||||||
if (memSpec->memoryType == MemSpec::MemoryType::DDR3)
|
if (memSpec.memoryType == MemSpec::MemoryType::DDR3)
|
||||||
checker = std::make_unique<CheckerDDR3>();
|
checker = std::make_unique<CheckerDDR3>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::DDR4)
|
else if (memSpec.memoryType == MemSpec::MemoryType::DDR4)
|
||||||
checker = std::make_unique<CheckerDDR4>();
|
checker = std::make_unique<CheckerDDR4>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::DDR5)
|
else if (memSpec.memoryType == MemSpec::MemoryType::DDR5)
|
||||||
checker = std::make_unique<CheckerDDR5>();
|
checker = std::make_unique<CheckerDDR5>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::WideIO)
|
else if (memSpec.memoryType == MemSpec::MemoryType::WideIO)
|
||||||
checker = std::make_unique<CheckerWideIO>();
|
checker = std::make_unique<CheckerWideIO>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::LPDDR4)
|
else if (memSpec.memoryType == MemSpec::MemoryType::LPDDR4)
|
||||||
checker = std::make_unique<CheckerLPDDR4>();
|
checker = std::make_unique<CheckerLPDDR4>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::LPDDR5)
|
else if (memSpec.memoryType == MemSpec::MemoryType::LPDDR5)
|
||||||
checker = std::make_unique<CheckerLPDDR5>();
|
checker = std::make_unique<CheckerLPDDR5>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::WideIO2)
|
else if (memSpec.memoryType == MemSpec::MemoryType::WideIO2)
|
||||||
checker = std::make_unique<CheckerWideIO2>();
|
checker = std::make_unique<CheckerWideIO2>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::HBM2)
|
else if (memSpec.memoryType == MemSpec::MemoryType::HBM2)
|
||||||
checker = std::make_unique<CheckerHBM2>();
|
checker = std::make_unique<CheckerHBM2>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5)
|
else if (memSpec.memoryType == MemSpec::MemoryType::GDDR5)
|
||||||
checker = std::make_unique<CheckerGDDR5>();
|
checker = std::make_unique<CheckerGDDR5>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5X)
|
else if (memSpec.memoryType == MemSpec::MemoryType::GDDR5X)
|
||||||
checker = std::make_unique<CheckerGDDR5X>();
|
checker = std::make_unique<CheckerGDDR5X>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR6)
|
else if (memSpec.memoryType == MemSpec::MemoryType::GDDR6)
|
||||||
checker = std::make_unique<CheckerGDDR6>();
|
checker = std::make_unique<CheckerGDDR6>(config);
|
||||||
else if (memSpec->memoryType == MemSpec::MemoryType::STTMRAM)
|
else if (memSpec.memoryType == MemSpec::MemoryType::STTMRAM)
|
||||||
checker = std::make_unique<CheckerSTTMRAM>();
|
checker = std::make_unique<CheckerSTTMRAM>(config);
|
||||||
|
|
||||||
// instantiate scheduler and command mux
|
// instantiate scheduler and command mux
|
||||||
if (config.scheduler == Configuration::Scheduler::Fifo)
|
if (config.scheduler == Configuration::Scheduler::Fifo)
|
||||||
scheduler = std::make_unique<SchedulerFifo>();
|
scheduler = std::make_unique<SchedulerFifo>(config);
|
||||||
else if (config.scheduler == Configuration::Scheduler::FrFcfs)
|
else if (config.scheduler == Configuration::Scheduler::FrFcfs)
|
||||||
scheduler = std::make_unique<SchedulerFrFcfs>();
|
scheduler = std::make_unique<SchedulerFrFcfs>(config);
|
||||||
else if (config.scheduler == Configuration::Scheduler::FrFcfsGrp)
|
else if (config.scheduler == Configuration::Scheduler::FrFcfsGrp)
|
||||||
scheduler = std::make_unique<SchedulerFrFcfsGrp>();
|
scheduler = std::make_unique<SchedulerFrFcfsGrp>(config);
|
||||||
else if (config.scheduler == Configuration::Scheduler::GrpFrFcfs)
|
else if (config.scheduler == Configuration::Scheduler::GrpFrFcfs)
|
||||||
scheduler = std::make_unique<SchedulerGrpFrFcfs>();
|
scheduler = std::make_unique<SchedulerGrpFrFcfs>(config);
|
||||||
else if (config.scheduler == Configuration::Scheduler::GrpFrFcfsWm)
|
else if (config.scheduler == Configuration::Scheduler::GrpFrFcfsWm)
|
||||||
scheduler = std::make_unique<SchedulerGrpFrFcfsWm>();
|
scheduler = std::make_unique<SchedulerGrpFrFcfsWm>(config);
|
||||||
|
|
||||||
if (config.cmdMux == Configuration::CmdMux::Oldest)
|
if (config.cmdMux == Configuration::CmdMux::Oldest)
|
||||||
{
|
{
|
||||||
if (memSpec->hasRasAndCasBus())
|
if (memSpec.hasRasAndCasBus())
|
||||||
cmdMux = std::make_unique<CmdMuxOldestRasCas>();
|
cmdMux = std::make_unique<CmdMuxOldestRasCas>(config);
|
||||||
else
|
else
|
||||||
cmdMux = std::make_unique<CmdMuxOldest>();
|
cmdMux = std::make_unique<CmdMuxOldest>(config);
|
||||||
}
|
}
|
||||||
else if (config.cmdMux == Configuration::CmdMux::Strict)
|
else if (config.cmdMux == Configuration::CmdMux::Strict)
|
||||||
{
|
{
|
||||||
if (memSpec->hasRasAndCasBus())
|
if (memSpec.hasRasAndCasBus())
|
||||||
cmdMux = std::make_unique<CmdMuxStrictRasCas>();
|
cmdMux = std::make_unique<CmdMuxStrictRasCas>(config);
|
||||||
else
|
else
|
||||||
cmdMux = std::make_unique<CmdMuxStrict>();
|
cmdMux = std::make_unique<CmdMuxStrict>(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.respQueue == Configuration::RespQueue::Fifo)
|
if (config.respQueue == Configuration::RespQueue::Fifo)
|
||||||
@@ -148,42 +146,46 @@ Controller::Controller(const sc_module_name &name) :
|
|||||||
// instantiate bank machines (one per bank)
|
// instantiate bank machines (one per bank)
|
||||||
if (config.pagePolicy == Configuration::PagePolicy::Open)
|
if (config.pagePolicy == Configuration::PagePolicy::Open)
|
||||||
{
|
{
|
||||||
for (unsigned bankID = 0; bankID < memSpec->banksPerChannel; bankID++)
|
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||||
bankMachines.emplace_back(std::make_unique<BankMachineOpen>(*scheduler, *checker, Bank(bankID)));
|
bankMachines.emplace_back(std::make_unique<BankMachineOpen>
|
||||||
|
(config, *scheduler, *checker, Bank(bankID)));
|
||||||
}
|
}
|
||||||
else if (config.pagePolicy == Configuration::PagePolicy::OpenAdaptive)
|
else if (config.pagePolicy == Configuration::PagePolicy::OpenAdaptive)
|
||||||
{
|
{
|
||||||
for (unsigned bankID = 0; bankID < memSpec->banksPerChannel; bankID++)
|
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||||
bankMachines.emplace_back(std::make_unique<BankMachineOpenAdaptive>(*scheduler, *checker, Bank(bankID)));
|
bankMachines.emplace_back(std::make_unique<BankMachineOpenAdaptive>
|
||||||
|
(config, *scheduler, *checker, Bank(bankID)));
|
||||||
}
|
}
|
||||||
else if (config.pagePolicy == Configuration::PagePolicy::Closed)
|
else if (config.pagePolicy == Configuration::PagePolicy::Closed)
|
||||||
{
|
{
|
||||||
for (unsigned bankID = 0; bankID < memSpec->banksPerChannel; bankID++)
|
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||||
bankMachines.emplace_back(std::make_unique<BankMachineClosed>(*scheduler, *checker, Bank(bankID)));
|
bankMachines.emplace_back(std::make_unique<BankMachineClosed>
|
||||||
|
(config, *scheduler, *checker, Bank(bankID)));
|
||||||
}
|
}
|
||||||
else if (config.pagePolicy == Configuration::PagePolicy::ClosedAdaptive)
|
else if (config.pagePolicy == Configuration::PagePolicy::ClosedAdaptive)
|
||||||
{
|
{
|
||||||
for (unsigned bankID = 0; bankID < memSpec->banksPerChannel; bankID++)
|
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||||
bankMachines.emplace_back(std::make_unique<BankMachineClosedAdaptive>(*scheduler, *checker, Bank(bankID)));
|
bankMachines.emplace_back(std::make_unique<BankMachineClosedAdaptive>
|
||||||
|
(config, *scheduler, *checker, Bank(bankID)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bankMachinesOnRank = std::vector<std::vector<BankMachine*>>(memSpec->ranksPerChannel,
|
bankMachinesOnRank = std::vector<std::vector<BankMachine*>>(memSpec.ranksPerChannel,
|
||||||
std::vector<BankMachine*>(memSpec->banksPerRank));
|
std::vector<BankMachine*>(memSpec.banksPerRank));
|
||||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||||
{
|
{
|
||||||
for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++)
|
for (unsigned bankID = 0; bankID < memSpec.banksPerRank; bankID++)
|
||||||
bankMachinesOnRank[rankID][bankID] = bankMachines[rankID * memSpec->banksPerRank + bankID].get();
|
bankMachinesOnRank[rankID][bankID] = bankMachines[rankID * memSpec.banksPerRank + bankID].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// instantiate power-down managers (one per rank)
|
// instantiate power-down managers (one per rank)
|
||||||
if (config.powerDownPolicy == Configuration::PowerDownPolicy::NoPowerDown)
|
if (config.powerDownPolicy == Configuration::PowerDownPolicy::NoPowerDown)
|
||||||
{
|
{
|
||||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||||
powerDownManagers.emplace_back(std::make_unique<PowerDownManagerDummy>());
|
powerDownManagers.emplace_back(std::make_unique<PowerDownManagerDummy>());
|
||||||
}
|
}
|
||||||
else if (config.powerDownPolicy == Configuration::PowerDownPolicy::Staggered)
|
else if (config.powerDownPolicy == Configuration::PowerDownPolicy::Staggered)
|
||||||
{
|
{
|
||||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||||
{
|
{
|
||||||
powerDownManagers.emplace_back(std::make_unique<PowerDownManagerStaggered>(bankMachinesOnRank[rankID],
|
powerDownManagers.emplace_back(std::make_unique<PowerDownManagerStaggered>(bankMachinesOnRank[rankID],
|
||||||
Rank(rankID), *checker));
|
Rank(rankID), *checker));
|
||||||
@@ -193,41 +195,41 @@ Controller::Controller(const sc_module_name &name) :
|
|||||||
// instantiate refresh managers (one per rank)
|
// instantiate refresh managers (one per rank)
|
||||||
if (config.refreshPolicy == Configuration::RefreshPolicy::NoRefresh)
|
if (config.refreshPolicy == Configuration::RefreshPolicy::NoRefresh)
|
||||||
{
|
{
|
||||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerDummy>());
|
refreshManagers.emplace_back(std::make_unique<RefreshManagerDummy>());
|
||||||
}
|
}
|
||||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::AllBank)
|
else if (config.refreshPolicy == Configuration::RefreshPolicy::AllBank)
|
||||||
{
|
{
|
||||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||||
{
|
{
|
||||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerAllBank>
|
refreshManagers.emplace_back(std::make_unique<RefreshManagerAllBank>
|
||||||
(bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID), *checker));
|
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID), *checker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::SameBank)
|
else if (config.refreshPolicy == Configuration::RefreshPolicy::SameBank)
|
||||||
{
|
{
|
||||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||||
{
|
{
|
||||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerSameBank>
|
refreshManagers.emplace_back(std::make_unique<RefreshManagerSameBank>
|
||||||
(bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID), *checker));
|
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID), *checker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::PerBank)
|
else if (config.refreshPolicy == Configuration::RefreshPolicy::PerBank)
|
||||||
{
|
{
|
||||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||||
{
|
{
|
||||||
// TODO: remove bankMachines in constructor
|
// TODO: remove bankMachines in constructor
|
||||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerPerBank>
|
refreshManagers.emplace_back(std::make_unique<RefreshManagerPerBank>
|
||||||
(bankMachinesOnRank[rankID], *powerDownManagers[rankID], Rank(rankID), *checker));
|
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID], Rank(rankID), *checker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::Per2Bank)
|
else if (config.refreshPolicy == Configuration::RefreshPolicy::Per2Bank)
|
||||||
{
|
{
|
||||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||||
{
|
{
|
||||||
// TODO: remove bankMachines in constructor
|
// TODO: remove bankMachines in constructor
|
||||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerPer2Bank>
|
refreshManagers.emplace_back(std::make_unique<RefreshManagerPer2Bank>
|
||||||
(bankMachinesOnRank[rankID], *powerDownManagers[rankID], Rank(rankID), *checker));
|
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID], Rank(rankID), *checker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -260,7 +262,7 @@ void Controller::controllerMethod()
|
|||||||
// clear command buffer
|
// clear command buffer
|
||||||
readyCommands.clear();
|
readyCommands.clear();
|
||||||
|
|
||||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||||
{
|
{
|
||||||
// (4.1) Check for power-down commands (PDEA/PDEP/SREFEN or PDXA/PDXP/SREFEX)
|
// (4.1) Check for power-down commands (PDEA/PDEP/SREFEN or PDXA/PDXP/SREFEX)
|
||||||
commandTuple = powerDownManagers[rankID]->getNextCommand();
|
commandTuple = powerDownManagers[rankID]->getNextCommand();
|
||||||
@@ -302,14 +304,14 @@ void Controller::controllerMethod()
|
|||||||
}
|
}
|
||||||
else if (command.isGroupCommand())
|
else if (command.isGroupCommand())
|
||||||
{
|
{
|
||||||
for (unsigned bankID = (bank.ID() % memSpec->banksPerGroup);
|
for (unsigned bankID = (bank.ID() % memSpec.banksPerGroup);
|
||||||
bankID < memSpec->banksPerRank; bankID += memSpec->banksPerGroup)
|
bankID < memSpec.banksPerRank; bankID += memSpec.banksPerGroup)
|
||||||
bankMachinesOnRank[rank.ID()][bankID]->updateState(command);
|
bankMachinesOnRank[rank.ID()][bankID]->updateState(command);
|
||||||
}
|
}
|
||||||
else if (command.is2BankCommand())
|
else if (command.is2BankCommand())
|
||||||
{
|
{
|
||||||
bankMachines[bank.ID()]->updateState(command);
|
bankMachines[bank.ID()]->updateState(command);
|
||||||
bankMachines[bank.ID() + memSpec->getPer2BankOffset()]->updateState(command);
|
bankMachines[bank.ID() + memSpec.getPer2BankOffset()]->updateState(command);
|
||||||
}
|
}
|
||||||
else // if (isBankCommand(command))
|
else // if (isBankCommand(command))
|
||||||
bankMachines[bank.ID()]->updateState(command);
|
bankMachines[bank.ID()]->updateState(command);
|
||||||
@@ -324,7 +326,7 @@ void Controller::controllerMethod()
|
|||||||
manageRequests(thinkDelayFw);
|
manageRequests(thinkDelayFw);
|
||||||
respQueue->insertPayload(payload, sc_time_stamp()
|
respQueue->insertPayload(payload, sc_time_stamp()
|
||||||
+ thinkDelayFw + phyDelayFw
|
+ thinkDelayFw + phyDelayFw
|
||||||
+ memSpec->getIntervalOnDataStrobe(command, *payload).end
|
+ memSpec.getIntervalOnDataStrobe(command, *payload).end
|
||||||
+ phyDelayBw + thinkDelayBw);
|
+ phyDelayBw + thinkDelayBw);
|
||||||
|
|
||||||
sc_time triggerTime = respQueue->getTriggerTime();
|
sc_time triggerTime = respQueue->getTriggerTime();
|
||||||
@@ -469,7 +471,7 @@ void Controller::manageResponses()
|
|||||||
{
|
{
|
||||||
// last payload was released in this cycle
|
// last payload was released in this cycle
|
||||||
tlm_phase bwPhase = BEGIN_RESP;
|
tlm_phase bwPhase = BEGIN_RESP;
|
||||||
sc_time bwDelay = memSpec->tCK;
|
sc_time bwDelay = memSpec.tCK;
|
||||||
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
|
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
|
||||||
transToRelease.time = sc_max_time();
|
transToRelease.time = sc_max_time();
|
||||||
}
|
}
|
||||||
@@ -491,7 +493,7 @@ void Controller::manageResponses()
|
|||||||
tlm_phase bwPhase = BEGIN_RESP;
|
tlm_phase bwPhase = BEGIN_RESP;
|
||||||
sc_time bwDelay;
|
sc_time bwDelay;
|
||||||
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
|
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
|
||||||
bwDelay = memSpec->tCK;
|
bwDelay = memSpec.tCK;
|
||||||
else
|
else
|
||||||
bwDelay = SC_ZERO_TIME;
|
bwDelay = SC_ZERO_TIME;
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
class Controller : public ControllerIF
|
class Controller : public ControllerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Controller(const sc_core::sc_module_name &name);
|
Controller(const sc_core::sc_module_name& name, const Configuration& config);
|
||||||
SC_HAS_PROCESS(Controller);
|
SC_HAS_PROCESS(Controller);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -70,7 +70,6 @@ protected:
|
|||||||
virtual void controllerMethod();
|
virtual void controllerMethod();
|
||||||
|
|
||||||
std::unique_ptr<SchedulerIF> scheduler;
|
std::unique_ptr<SchedulerIF> scheduler;
|
||||||
const MemSpec *memSpec;
|
|
||||||
|
|
||||||
sc_core::sc_time thinkDelayFw;
|
sc_core::sc_time thinkDelayFw;
|
||||||
sc_core::sc_time thinkDelayBw;
|
sc_core::sc_time thinkDelayBw;
|
||||||
|
|||||||
@@ -54,56 +54,57 @@ public:
|
|||||||
tlm_utils::simple_target_socket<ControllerIF> tSocket; // Arbiter side
|
tlm_utils::simple_target_socket<ControllerIF> tSocket; // Arbiter side
|
||||||
tlm_utils::simple_initiator_socket<ControllerIF> iSocket; // DRAM side
|
tlm_utils::simple_initiator_socket<ControllerIF> iSocket; // DRAM side
|
||||||
|
|
||||||
// Destructor
|
void end_of_simulation() override
|
||||||
~ControllerIF() override
|
|
||||||
{
|
{
|
||||||
sc_core::sc_time activeTime = static_cast<double>(numberOfBeatsServed)
|
sc_core::sc_time activeTime = static_cast<double>(numberOfBeatsServed)
|
||||||
/ Configuration::getInstance().memSpec->dataRate
|
/ memSpec.dataRate
|
||||||
* Configuration::getInstance().memSpec->tCK
|
* memSpec.tCK
|
||||||
/ Configuration::getInstance().memSpec->pseudoChannelsPerChannel;
|
/ memSpec.pseudoChannelsPerChannel;
|
||||||
|
|
||||||
double bandwidth = activeTime / sc_core::sc_time_stamp();
|
double bandwidth = activeTime / sc_core::sc_time_stamp();
|
||||||
double bandwidthWoIdle = activeTime / (sc_core::sc_time_stamp() - idleTimeCollector.getIdleTime());
|
double bandwidthWoIdle = activeTime / (sc_core::sc_time_stamp() - idleTimeCollector.getIdleTime());
|
||||||
|
|
||||||
double maxBandwidth = (
|
double maxBandwidth = (
|
||||||
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
|
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
|
||||||
(1000 / Configuration::getInstance().memSpec->tCK.to_double())
|
(1000 / memSpec.tCK.to_double())
|
||||||
// DataRate e.g. 2
|
// DataRate e.g. 2
|
||||||
* Configuration::getInstance().memSpec->dataRate
|
* memSpec.dataRate
|
||||||
// BusWidth e.g. 8 or 64
|
// BusWidth e.g. 8 or 64
|
||||||
* Configuration::getInstance().memSpec->bitWidth
|
* memSpec.bitWidth
|
||||||
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
|
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
|
||||||
* Configuration::getInstance().memSpec->devicesPerRank
|
* memSpec.devicesPerRank
|
||||||
// HBM specific, one or two pseudo channels per channel
|
// HBM specific, one or two pseudo channels per channel
|
||||||
* Configuration::getInstance().memSpec->pseudoChannelsPerChannel);
|
* memSpec.pseudoChannelsPerChannel);
|
||||||
|
|
||||||
std::cout << name() << std::string(" Total Time: ")
|
std::cout << name() << std::string(" Total Time: ")
|
||||||
<< sc_core::sc_time_stamp().to_string()
|
<< sc_core::sc_time_stamp().to_string()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cout << name() << std::string(" AVG BW: ")
|
std::cout << name() << std::string(" AVG BW: ")
|
||||||
<< std::fixed << std::setprecision(2)
|
<< std::fixed << std::setprecision(2)
|
||||||
<< std::setw(6) << (bandwidth * maxBandwidth) << " Gb/s | "
|
<< std::setw(6) << (bandwidth * maxBandwidth) << " Gb/s | "
|
||||||
<< std::setw(6) << (bandwidth * maxBandwidth / 8) << " GB/s | "
|
<< std::setw(6) << (bandwidth * maxBandwidth / 8) << " GB/s | "
|
||||||
<< std::setw(6) << (bandwidth * 100) << " %"
|
<< std::setw(6) << (bandwidth * 100) << " %"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cout << name() << std::string(" AVG BW\\IDLE: ")
|
std::cout << name() << std::string(" AVG BW\\IDLE: ")
|
||||||
<< std::fixed << std::setprecision(2)
|
<< std::fixed << std::setprecision(2)
|
||||||
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth) << " Gb/s | "
|
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth) << " Gb/s | "
|
||||||
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth / 8) << " GB/s | "
|
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth / 8) << " GB/s | "
|
||||||
<< std::setw(6) << (bandwidthWoIdle * 100) << " %"
|
<< std::setw(6) << (bandwidthWoIdle * 100) << " %"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cout << name() << std::string(" MAX BW: ")
|
std::cout << name() << std::string(" MAX BW: ")
|
||||||
<< std::fixed << std::setprecision(2)
|
<< std::fixed << std::setprecision(2)
|
||||||
<< std::setw(6) << maxBandwidth << " Gb/s | "
|
<< std::setw(6) << maxBandwidth << " Gb/s | "
|
||||||
<< std::setw(6) << maxBandwidth / 8 << " GB/s | "
|
<< std::setw(6) << maxBandwidth / 8 << " GB/s | "
|
||||||
<< std::setw(6) << 100.0 << " %"
|
<< std::setw(6) << 100.0 << " %"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const MemSpec& memSpec;
|
||||||
|
|
||||||
// Bind sockets with virtual functions
|
// Bind sockets with virtual functions
|
||||||
explicit ControllerIF(const sc_core::sc_module_name& name)
|
ControllerIF(const sc_core::sc_module_name& name, const Configuration& config)
|
||||||
: sc_core::sc_module(name), tSocket("tSocket"), iSocket("iSocket")
|
: sc_core::sc_module(name), tSocket("tSocket"), iSocket("iSocket"), memSpec(*config.memSpec)
|
||||||
{
|
{
|
||||||
tSocket.register_nb_transport_fw(this, &ControllerIF::nb_transport_fw);
|
tSocket.register_nb_transport_fw(this, &ControllerIF::nb_transport_fw);
|
||||||
tSocket.register_transport_dbg(this, &ControllerIF::transport_dbg);
|
tSocket.register_transport_dbg(this, &ControllerIF::transport_dbg);
|
||||||
|
|||||||
@@ -39,13 +39,15 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
ControllerRecordable::ControllerRecordable(const sc_module_name &name, TlmRecorder& tlmRecorder)
|
ControllerRecordable::ControllerRecordable(const sc_module_name &name, const Configuration& config,
|
||||||
: Controller(name), tlmRecorder(tlmRecorder)
|
TlmRecorder& tlmRecorder)
|
||||||
|
: Controller(name, config), tlmRecorder(tlmRecorder),
|
||||||
|
activeTimeMultiplier(config.memSpec->tCK / config.memSpec->dataRate), enableWindowing(config.enableWindowing)
|
||||||
{
|
{
|
||||||
if (Configuration::getInstance().enableWindowing)
|
if (enableWindowing)
|
||||||
{
|
{
|
||||||
sensitive << windowEvent;
|
sensitive << windowEvent;
|
||||||
windowSizeTime = Configuration::getInstance().windowSize * memSpec->tCK;
|
windowSizeTime = config.windowSize * memSpec.tCK;
|
||||||
slidingAverageBufferDepth = std::vector<sc_time>(scheduler->getBufferDepth().size());
|
slidingAverageBufferDepth = std::vector<sc_time>(scheduler->getBufferDepth().size());
|
||||||
windowAverageBufferDepth = std::vector<double>(scheduler->getBufferDepth().size());
|
windowAverageBufferDepth = std::vector<double>(scheduler->getBufferDepth().size());
|
||||||
windowEvent.notify(windowSizeTime);
|
windowEvent.notify(windowSizeTime);
|
||||||
@@ -77,7 +79,7 @@ void ControllerRecordable::sendToDram(Command command, tlm_generic_payload& payl
|
|||||||
{
|
{
|
||||||
if (command.isCasCommand())
|
if (command.isCasCommand())
|
||||||
{
|
{
|
||||||
TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command, payload);
|
TimeInterval dataStrobe = memSpec.getIntervalOnDataStrobe(command, payload);
|
||||||
tlmRecorder.updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start,
|
tlmRecorder.updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start,
|
||||||
sc_time_stamp() + delay + dataStrobe.end, payload);
|
sc_time_stamp() + delay + dataStrobe.end, payload);
|
||||||
}
|
}
|
||||||
@@ -108,7 +110,7 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, const tlm_pha
|
|||||||
|
|
||||||
void ControllerRecordable::controllerMethod()
|
void ControllerRecordable::controllerMethod()
|
||||||
{
|
{
|
||||||
if (Configuration::getInstance().enableWindowing)
|
if (enableWindowing)
|
||||||
{
|
{
|
||||||
sc_time timeDiff = sc_time_stamp() - lastTimeCalled;
|
sc_time timeDiff = sc_time_stamp() - lastTimeCalled;
|
||||||
lastTimeCalled = sc_time_stamp();
|
lastTimeCalled = sc_time_stamp();
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
class ControllerRecordable final : public Controller
|
class ControllerRecordable final : public Controller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ControllerRecordable(const sc_core::sc_module_name &name, TlmRecorder& tlmRecorder);
|
ControllerRecordable(const sc_core::sc_module_name &name, const Configuration& config, TlmRecorder& tlmRecorder);
|
||||||
~ControllerRecordable() override = default;
|
~ControllerRecordable() override = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -69,8 +69,8 @@ private:
|
|||||||
sc_core::sc_time lastTimeCalled = sc_core::SC_ZERO_TIME;
|
sc_core::sc_time lastTimeCalled = sc_core::SC_ZERO_TIME;
|
||||||
|
|
||||||
uint64_t lastNumberOfBeatsServed = 0;
|
uint64_t lastNumberOfBeatsServed = 0;
|
||||||
sc_core::sc_time activeTimeMultiplier = Configuration::getInstance().memSpec->tCK
|
sc_core::sc_time activeTimeMultiplier;
|
||||||
/ Configuration::getInstance().memSpec->dataRate;
|
bool enableWindowing;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONTROLLERRECORDABLE_H
|
#endif // CONTROLLERRECORDABLE_H
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerDDR3::CheckerDDR3()
|
CheckerDDR3::CheckerDDR3(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecDDR3 *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecDDR3 *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerDDR3 final : public CheckerIF
|
class CheckerDDR3 final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerDDR3();
|
explicit CheckerDDR3(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerDDR4::CheckerDDR4()
|
CheckerDDR4::CheckerDDR4(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecDDR4 *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecDDR4 *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerDDR4", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerDDR4", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerDDR4 final : public CheckerIF
|
class CheckerDDR4 final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerDDR4();
|
explicit CheckerDDR4(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerDDR5::CheckerDDR5()
|
CheckerDDR5::CheckerDDR5(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecDDR5 *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecDDR5 *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
class CheckerDDR5 final : public CheckerIF
|
class CheckerDDR5 final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerDDR5();
|
explicit CheckerDDR5(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerGDDR5::CheckerGDDR5()
|
CheckerGDDR5::CheckerGDDR5(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecGDDR5 *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecGDDR5 *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerGDDR5", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerGDDR5", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerGDDR5 final : public CheckerIF
|
class CheckerGDDR5 final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerGDDR5();
|
explicit CheckerGDDR5(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerGDDR5X::CheckerGDDR5X()
|
CheckerGDDR5X::CheckerGDDR5X(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecGDDR5X *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecGDDR5X *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerGDDR5X", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerGDDR5X", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerGDDR5X final : public CheckerIF
|
class CheckerGDDR5X final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerGDDR5X();
|
explicit CheckerGDDR5X(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerGDDR6::CheckerGDDR6()
|
CheckerGDDR6::CheckerGDDR6(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecGDDR6 *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecGDDR6 *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerGDDR6", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerGDDR6", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerGDDR6 final : public CheckerIF
|
class CheckerGDDR6 final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerGDDR6();
|
explicit CheckerGDDR6(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerHBM2::CheckerHBM2()
|
CheckerHBM2::CheckerHBM2(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecHBM2 *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecHBM2 *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerHBM2", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerHBM2", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerHBM2 final : public CheckerIF
|
class CheckerHBM2 final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerHBM2();
|
explicit CheckerHBM2(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#define CHECKERIF_H
|
#define CHECKERIF_H
|
||||||
|
|
||||||
#include <systemc>
|
#include <systemc>
|
||||||
|
|
||||||
#include "../Command.h"
|
#include "../Command.h"
|
||||||
|
|
||||||
class CheckerIF
|
class CheckerIF
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerLPDDR4::CheckerLPDDR4()
|
CheckerLPDDR4::CheckerLPDDR4(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecLPDDR4 *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecLPDDR4 *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerLPDDR4", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerLPDDR4", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerLPDDR4 final : public CheckerIF
|
class CheckerLPDDR4 final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerLPDDR4();
|
explicit CheckerLPDDR4(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerLPDDR5::CheckerLPDDR5()
|
CheckerLPDDR5::CheckerLPDDR5(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecLPDDR5 *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecLPDDR5 *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerLPDDR5", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerLPDDR5", "Wrong MemSpec chosen");
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
class CheckerLPDDR5 final : public CheckerIF
|
class CheckerLPDDR5 final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerLPDDR5();
|
explicit CheckerLPDDR5(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerSTTMRAM::CheckerSTTMRAM()
|
CheckerSTTMRAM::CheckerSTTMRAM(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecSTTMRAM *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecSTTMRAM *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerSTTMRAM final : public CheckerIF
|
class CheckerSTTMRAM final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerSTTMRAM();
|
explicit CheckerSTTMRAM(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerWideIO::CheckerWideIO()
|
CheckerWideIO::CheckerWideIO(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecWideIO *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecWideIO *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerWideIO", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerWideIO", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerWideIO final : public CheckerIF
|
class CheckerWideIO final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerWideIO();
|
explicit CheckerWideIO(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,9 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
CheckerWideIO2::CheckerWideIO2()
|
CheckerWideIO2::CheckerWideIO2(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
memSpec = dynamic_cast<const MemSpecWideIO2 *>(config.memSpec.get());
|
||||||
memSpec = dynamic_cast<const MemSpecWideIO2 *>(config.memSpec);
|
|
||||||
if (memSpec == nullptr)
|
if (memSpec == nullptr)
|
||||||
SC_REPORT_FATAL("CheckerWideIO2", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("CheckerWideIO2", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
class CheckerWideIO2 final : public CheckerIF
|
class CheckerWideIO2 final : public CheckerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckerWideIO2();
|
explicit CheckerWideIO2(const Configuration& config);
|
||||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
|
|
||||||
CmdMuxOldest::CmdMuxOldest() : memSpec(Configuration::getInstance().memSpec) {}
|
CmdMuxOldest::CmdMuxOldest(const Configuration& config) : memSpec(*config.memSpec) {}
|
||||||
|
|
||||||
CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommands)
|
CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommands)
|
||||||
{
|
{
|
||||||
@@ -51,7 +51,7 @@ CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommand
|
|||||||
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++)
|
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++)
|
||||||
{
|
{
|
||||||
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
||||||
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
|
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
|
||||||
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
||||||
|
|
||||||
if (newTimestamp < lastTimestamp)
|
if (newTimestamp < lastTimestamp)
|
||||||
@@ -75,10 +75,10 @@ CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CmdMuxOldestRasCas::CmdMuxOldestRasCas() : memSpec(Configuration::getInstance().memSpec)
|
CmdMuxOldestRasCas::CmdMuxOldestRasCas(const Configuration& config) : memSpec(*config.memSpec)
|
||||||
{
|
{
|
||||||
readyRasCommands.reserve(memSpec->banksPerChannel);
|
readyRasCommands.reserve(memSpec.banksPerChannel);
|
||||||
readyCasCommands.reserve(memSpec->banksPerChannel);
|
readyCasCommands.reserve(memSpec.banksPerChannel);
|
||||||
readyRasCasCommands.reserve(2);
|
readyRasCasCommands.reserve(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
|
|||||||
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++)
|
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++)
|
||||||
{
|
{
|
||||||
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
||||||
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
|
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
|
||||||
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
||||||
|
|
||||||
if (newTimestamp < lastTimestamp)
|
if (newTimestamp < lastTimestamp)
|
||||||
@@ -129,7 +129,7 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
|
|||||||
for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); it++)
|
for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); it++)
|
||||||
{
|
{
|
||||||
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
||||||
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
|
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
|
||||||
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
||||||
|
|
||||||
if (newTimestamp < lastTimestamp)
|
if (newTimestamp < lastTimestamp)
|
||||||
|
|||||||
@@ -41,22 +41,22 @@
|
|||||||
class CmdMuxOldest : public CmdMuxIF
|
class CmdMuxOldest : public CmdMuxIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CmdMuxOldest();
|
explicit CmdMuxOldest(const Configuration& config);
|
||||||
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const MemSpec *memSpec;
|
const MemSpec& memSpec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CmdMuxOldestRasCas : public CmdMuxIF
|
class CmdMuxOldestRasCas : public CmdMuxIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CmdMuxOldestRasCas();
|
explicit CmdMuxOldestRasCas(const Configuration& config);
|
||||||
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const MemSpec *memSpec;
|
const MemSpec& memSpec;
|
||||||
ReadyCommands readyRasCommands;
|
ReadyCommands readyRasCommands;
|
||||||
ReadyCommands readyCasCommands;
|
ReadyCommands readyCasCommands;
|
||||||
ReadyCommands readyRasCasCommands;
|
ReadyCommands readyRasCasCommands;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
|
|
||||||
CmdMuxStrict::CmdMuxStrict() : memSpec(Configuration::getInstance().memSpec) {}
|
CmdMuxStrict::CmdMuxStrict(const Configuration& config) : memSpec(*config.memSpec) {}
|
||||||
|
|
||||||
CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommands)
|
CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommands)
|
||||||
{
|
{
|
||||||
@@ -51,7 +51,7 @@ CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommand
|
|||||||
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++)
|
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++)
|
||||||
{
|
{
|
||||||
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
||||||
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
|
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
|
||||||
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
||||||
|
|
||||||
if (newTimestamp < lastTimestamp)
|
if (newTimestamp < lastTimestamp)
|
||||||
@@ -85,10 +85,10 @@ CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CmdMuxStrictRasCas::CmdMuxStrictRasCas() : memSpec(Configuration::getInstance().memSpec)
|
CmdMuxStrictRasCas::CmdMuxStrictRasCas(const Configuration& config) : memSpec(*config.memSpec)
|
||||||
{
|
{
|
||||||
readyRasCommands.reserve(memSpec->banksPerChannel);
|
readyRasCommands.reserve(memSpec.banksPerChannel);
|
||||||
readyCasCommands.reserve(memSpec->banksPerChannel);
|
readyCasCommands.reserve(memSpec.banksPerChannel);
|
||||||
readyRasCasCommands.reserve(2);
|
readyRasCasCommands.reserve(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyC
|
|||||||
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++)
|
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++)
|
||||||
{
|
{
|
||||||
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
|
||||||
memSpec->getCommandLength(std::get<CommandTuple::Command>(*it));
|
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
|
||||||
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
||||||
|
|
||||||
if (newTimestamp < lastTimestamp)
|
if (newTimestamp < lastTimestamp)
|
||||||
|
|||||||
@@ -41,23 +41,23 @@
|
|||||||
class CmdMuxStrict : public CmdMuxIF
|
class CmdMuxStrict : public CmdMuxIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CmdMuxStrict();
|
explicit CmdMuxStrict(const Configuration& config);
|
||||||
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t nextPayloadID = 1;
|
uint64_t nextPayloadID = 1;
|
||||||
const MemSpec *memSpec;
|
const MemSpec& memSpec;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CmdMuxStrictRasCas : public CmdMuxIF
|
class CmdMuxStrictRasCas : public CmdMuxIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CmdMuxStrictRasCas();
|
explicit CmdMuxStrictRasCas(const Configuration& config);
|
||||||
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t nextPayloadID = 1;
|
uint64_t nextPayloadID = 1;
|
||||||
const MemSpec *memSpec;
|
const MemSpec& memSpec;
|
||||||
ReadyCommands readyRasCommands;
|
ReadyCommands readyRasCommands;
|
||||||
ReadyCommands readyCasCommands;
|
ReadyCommands readyCasCommands;
|
||||||
ReadyCommands readyRasCasCommands;
|
ReadyCommands readyRasCasCommands;
|
||||||
|
|||||||
@@ -43,14 +43,13 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
RefreshManagerAllBank::RefreshManagerAllBank(std::vector<BankMachine*>& bankMachinesOnRank,
|
RefreshManagerAllBank::RefreshManagerAllBank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
||||||
: bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), checker(checker)
|
: bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), checker(checker),
|
||||||
|
memSpec(*config.memSpec)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalAB(),
|
||||||
memSpec = config.memSpec;
|
rank, memSpec.ranksPerChannel);
|
||||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec->getRefreshIntervalAB(),
|
|
||||||
rank, memSpec->ranksPerChannel);
|
|
||||||
setUpDummy(refreshPayload, 0, rank);
|
setUpDummy(refreshPayload, 0, rank);
|
||||||
|
|
||||||
maxPostponed = static_cast<int>(config.refreshMaxPostponed);
|
maxPostponed = static_cast<int>(config.refreshMaxPostponed);
|
||||||
@@ -76,9 +75,9 @@ sc_time RefreshManagerAllBank::start()
|
|||||||
if (sleeping)
|
if (sleeping)
|
||||||
return timeToSchedule;
|
return timeToSchedule;
|
||||||
|
|
||||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalAB())
|
if (sc_time_stamp() >= timeForNextTrigger + memSpec.getRefreshIntervalAB())
|
||||||
{
|
{
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
timeForNextTrigger += memSpec.getRefreshIntervalAB();
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,18 +86,18 @@ sc_time RefreshManagerAllBank::start()
|
|||||||
bool doRefresh = true;
|
bool doRefresh = true;
|
||||||
if (flexibilityCounter == maxPostponed) // forced refresh
|
if (flexibilityCounter == maxPostponed) // forced refresh
|
||||||
{
|
{
|
||||||
for (auto it : bankMachinesOnRank)
|
for (auto* it : bankMachinesOnRank)
|
||||||
it->block();
|
it->block();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (auto it : bankMachinesOnRank)
|
for (const auto* it : bankMachinesOnRank)
|
||||||
{
|
{
|
||||||
if (!it->isIdle())
|
if (!it->isIdle())
|
||||||
{
|
{
|
||||||
doRefresh = false;
|
doRefresh = false;
|
||||||
flexibilityCounter++;
|
flexibilityCounter++;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
timeForNextTrigger += memSpec.getRefreshIntervalAB();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,19 +117,20 @@ sc_time RefreshManagerAllBank::start()
|
|||||||
else // if (state == RmState::Pulledin)
|
else // if (state == RmState::Pulledin)
|
||||||
{
|
{
|
||||||
bool doRefresh = true;
|
bool doRefresh = true;
|
||||||
for (auto it : bankMachinesOnRank)
|
for (const auto* it : bankMachinesOnRank)
|
||||||
{
|
{
|
||||||
if (!it->isIdle())
|
if (!it->isIdle())
|
||||||
{
|
{
|
||||||
doRefresh = false;
|
doRefresh = false;
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
timeForNextTrigger += memSpec.getRefreshIntervalAB();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doRefresh)
|
if (doRefresh)
|
||||||
{
|
{
|
||||||
|
assert(activatedBanks == 0);
|
||||||
nextCommand = Command::REFAB;
|
nextCommand = Command::REFAB;
|
||||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, refreshPayload);
|
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, refreshPayload);
|
||||||
return timeToSchedule;
|
return timeToSchedule;
|
||||||
@@ -146,12 +146,12 @@ sc_time RefreshManagerAllBank::start()
|
|||||||
|
|
||||||
bool refreshManagementRequired = true;
|
bool refreshManagementRequired = true;
|
||||||
|
|
||||||
if (maxThreshold >= memSpec->getRAAMMT())
|
if (maxThreshold >= memSpec.getRAAMMT())
|
||||||
{
|
{
|
||||||
for (auto* bankMachine : bankMachinesOnRank)
|
for (auto* bankMachine : bankMachinesOnRank)
|
||||||
bankMachine->block();
|
bankMachine->block();
|
||||||
}
|
}
|
||||||
else if (maxThreshold >= memSpec->getRAAIMT())
|
else if (maxThreshold >= memSpec.getRAAIMT())
|
||||||
{
|
{
|
||||||
for (const auto* bankMachine : bankMachinesOnRank)
|
for (const auto* bankMachine : bankMachinesOnRank)
|
||||||
{
|
{
|
||||||
@@ -200,7 +200,7 @@ void RefreshManagerAllBank::updateState(Command command)
|
|||||||
{
|
{
|
||||||
// Refresh command after SREFEX
|
// Refresh command after SREFEX
|
||||||
state = State::Regular; // TODO: check if this assignment is necessary
|
state = State::Regular; // TODO: check if this assignment is necessary
|
||||||
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalAB();
|
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalAB();
|
||||||
sleeping = false;
|
sleeping = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -213,7 +213,7 @@ void RefreshManagerAllBank::updateState(Command command)
|
|||||||
if (flexibilityCounter == maxPulledin)
|
if (flexibilityCounter == maxPulledin)
|
||||||
{
|
{
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
timeForNextTrigger += memSpec.getRefreshIntervalAB();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include <tlm>
|
#include <tlm>
|
||||||
#include "RefreshManagerIF.h"
|
#include "RefreshManagerIF.h"
|
||||||
#include "../checker/CheckerIF.h"
|
#include "../checker/CheckerIF.h"
|
||||||
|
#include "../../configuration/Configuration.h"
|
||||||
#include "../../configuration/memspec/MemSpec.h"
|
#include "../../configuration/memspec/MemSpec.h"
|
||||||
|
|
||||||
class BankMachine;
|
class BankMachine;
|
||||||
@@ -49,7 +50,7 @@ class PowerDownManagerIF;
|
|||||||
class RefreshManagerAllBank final : public RefreshManagerIF
|
class RefreshManagerAllBank final : public RefreshManagerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RefreshManagerAllBank(std::vector<BankMachine*>& bankMachinesOnRank,
|
RefreshManagerAllBank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
||||||
|
|
||||||
CommandTuple::Type getNextCommand() override;
|
CommandTuple::Type getNextCommand() override;
|
||||||
@@ -58,7 +59,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum class State {Regular, Pulledin} state = State::Regular;
|
enum class State {Regular, Pulledin} state = State::Regular;
|
||||||
const MemSpec *memSpec;
|
const MemSpec& memSpec;
|
||||||
std::vector<BankMachine*>& bankMachinesOnRank;
|
std::vector<BankMachine*>& bankMachinesOnRank;
|
||||||
PowerDownManagerIF& powerDownManager;
|
PowerDownManagerIF& powerDownManager;
|
||||||
tlm::tlm_generic_payload refreshPayload;
|
tlm::tlm_generic_payload refreshPayload;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
virtual void updateState(Command) = 0;
|
virtual void updateState(Command) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static sc_core::sc_time getTimeForFirstTrigger(const sc_core::sc_time &refreshInterval,
|
static sc_core::sc_time getTimeForFirstTrigger(const sc_core::sc_time& tCK, const sc_core::sc_time &refreshInterval,
|
||||||
Rank rank, unsigned numberOfRanks)
|
Rank rank, unsigned numberOfRanks)
|
||||||
{
|
{
|
||||||
// Calculate bit-reversal rank ID
|
// Calculate bit-reversal rank ID
|
||||||
@@ -74,7 +74,6 @@ protected:
|
|||||||
|
|
||||||
// Use bit-reversal order for refreshes on ranks
|
// Use bit-reversal order for refreshes on ranks
|
||||||
sc_core::sc_time timeForFirstTrigger = refreshInterval - reverseRankID * (refreshInterval / numberOfRanks);
|
sc_core::sc_time timeForFirstTrigger = refreshInterval - reverseRankID * (refreshInterval / numberOfRanks);
|
||||||
sc_core::sc_time tCK = Configuration::getInstance().memSpec->tCK;
|
|
||||||
timeForFirstTrigger = std::ceil(timeForFirstTrigger / tCK) * tCK;
|
timeForFirstTrigger = std::ceil(timeForFirstTrigger / tCK) * tCK;
|
||||||
|
|
||||||
return timeForFirstTrigger;
|
return timeForFirstTrigger;
|
||||||
|
|||||||
@@ -42,22 +42,21 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
RefreshManagerPer2Bank::RefreshManagerPer2Bank(std::vector<BankMachine*>& bankMachinesOnRank,
|
RefreshManagerPer2Bank::RefreshManagerPer2Bank(const Configuration& config,
|
||||||
|
std::vector<BankMachine*>& bankMachinesOnRank,
|
||||||
PowerDownManagerIF& powerDownManager, Rank rank,
|
PowerDownManagerIF& powerDownManager, Rank rank,
|
||||||
const CheckerIF& checker)
|
const CheckerIF& checker)
|
||||||
: powerDownManager(powerDownManager), checker(checker)
|
: powerDownManager(powerDownManager), checker(checker), memSpec(*config.memSpec)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalP2B(), rank,
|
||||||
memSpec = config.memSpec;
|
memSpec.ranksPerChannel);
|
||||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec->getRefreshIntervalP2B(),
|
|
||||||
rank, memSpec->ranksPerChannel);
|
|
||||||
|
|
||||||
// each bank pair has one payload (e.g. 0-8, 1-9, 2-10, 3-11, ...)
|
// each bank pair has one payload (e.g. 0-8, 1-9, 2-10, 3-11, ...)
|
||||||
for (unsigned outerID = 0; outerID < memSpec->banksPerRank; outerID += (memSpec->getPer2BankOffset() * 2))
|
for (unsigned outerID = 0; outerID < memSpec.banksPerRank; outerID += (memSpec.getPer2BankOffset() * 2))
|
||||||
{
|
{
|
||||||
for (unsigned bankID = outerID; bankID < (outerID + memSpec->getPer2BankOffset()); bankID++)
|
for (unsigned bankID = outerID; bankID < (outerID + memSpec.getPer2BankOffset()); bankID++)
|
||||||
{
|
{
|
||||||
unsigned bankID2 = bankID + memSpec->getPer2BankOffset();
|
unsigned bankID2 = bankID + memSpec.getPer2BankOffset();
|
||||||
setUpDummy(refreshPayloads[bankMachinesOnRank[bankID]], 0, rank,
|
setUpDummy(refreshPayloads[bankMachinesOnRank[bankID]], 0, rank,
|
||||||
bankMachinesOnRank[bankID]->getBankGroup(), bankMachinesOnRank[bankID]->getBank());
|
bankMachinesOnRank[bankID]->getBankGroup(), bankMachinesOnRank[bankID]->getBank());
|
||||||
setUpDummy(refreshPayloads[bankMachinesOnRank[bankID2]], 0, rank,
|
setUpDummy(refreshPayloads[bankMachinesOnRank[bankID2]], 0, rank,
|
||||||
@@ -70,8 +69,8 @@ RefreshManagerPer2Bank::RefreshManagerPer2Bank(std::vector<BankMachine*>& bankMa
|
|||||||
currentIterator = remainingBankMachines.begin();
|
currentIterator = remainingBankMachines.begin();
|
||||||
currentRefreshPayload = &refreshPayloads[currentIterator->front()];
|
currentRefreshPayload = &refreshPayloads[currentIterator->front()];
|
||||||
|
|
||||||
maxPostponed = static_cast<int>(config.refreshMaxPostponed * memSpec->banksPerRank / 2);
|
maxPostponed = static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerRank / 2);
|
||||||
maxPulledin = -static_cast<int>(config.refreshMaxPulledin * memSpec->banksPerRank / 2);
|
maxPulledin = -static_cast<int>(config.refreshMaxPulledin * memSpec.banksPerRank / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandTuple::Type RefreshManagerPer2Bank::getNextCommand()
|
CommandTuple::Type RefreshManagerPer2Bank::getNextCommand()
|
||||||
@@ -90,9 +89,9 @@ sc_time RefreshManagerPer2Bank::start()
|
|||||||
if (sleeping)
|
if (sleeping)
|
||||||
return timeToSchedule;
|
return timeToSchedule;
|
||||||
|
|
||||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalP2B())
|
if (sc_time_stamp() >= timeForNextTrigger + memSpec.getRefreshIntervalP2B())
|
||||||
{
|
{
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalP2B();
|
timeForNextTrigger += memSpec.getRefreshIntervalP2B();
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +106,7 @@ sc_time RefreshManagerPer2Bank::start()
|
|||||||
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
||||||
{
|
{
|
||||||
bool pairIsBusy = false;
|
bool pairIsBusy = false;
|
||||||
for (auto pairIt : *bankIt)
|
for (const auto* pairIt : *bankIt)
|
||||||
{
|
{
|
||||||
if (!pairIt->isIdle())
|
if (!pairIt->isIdle())
|
||||||
{
|
{
|
||||||
@@ -127,14 +126,14 @@ sc_time RefreshManagerPer2Bank::start()
|
|||||||
if (allBankPairsBusy && !forcedRefresh)
|
if (allBankPairsBusy && !forcedRefresh)
|
||||||
{
|
{
|
||||||
flexibilityCounter++;
|
flexibilityCounter++;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalP2B();
|
timeForNextTrigger += memSpec.getRefreshIntervalP2B();
|
||||||
return timeForNextTrigger;
|
return timeForNextTrigger;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nextCommand = Command::REFP2B;
|
nextCommand = Command::REFP2B;
|
||||||
currentRefreshPayload = &refreshPayloads[currentIterator->front()];
|
currentRefreshPayload = &refreshPayloads[currentIterator->front()];
|
||||||
for (auto it : *currentIterator)
|
for (auto* it : *currentIterator)
|
||||||
{
|
{
|
||||||
if (it->isActivated())
|
if (it->isActivated())
|
||||||
{
|
{
|
||||||
@@ -147,7 +146,7 @@ sc_time RefreshManagerPer2Bank::start()
|
|||||||
// TODO: banks should already be blocked for precharge and selection should be skipped
|
// TODO: banks should already be blocked for precharge and selection should be skipped
|
||||||
if (nextCommand == Command::REFP2B && forcedRefresh)
|
if (nextCommand == Command::REFP2B && forcedRefresh)
|
||||||
{
|
{
|
||||||
for (auto it : *currentIterator)
|
for (auto* it : *currentIterator)
|
||||||
it->block();
|
it->block();
|
||||||
skipSelection = true;
|
skipSelection = true;
|
||||||
}
|
}
|
||||||
@@ -164,7 +163,7 @@ sc_time RefreshManagerPer2Bank::start()
|
|||||||
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
||||||
{
|
{
|
||||||
bool pairIsBusy = false;
|
bool pairIsBusy = false;
|
||||||
for (auto pairIt : *bankIt)
|
for (const auto* pairIt : *bankIt)
|
||||||
{
|
{
|
||||||
if (!pairIt->isIdle())
|
if (!pairIt->isIdle())
|
||||||
{
|
{
|
||||||
@@ -183,14 +182,14 @@ sc_time RefreshManagerPer2Bank::start()
|
|||||||
if (allBankPairsBusy)
|
if (allBankPairsBusy)
|
||||||
{
|
{
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalP2B();
|
timeForNextTrigger += memSpec.getRefreshIntervalP2B();
|
||||||
return timeForNextTrigger;
|
return timeForNextTrigger;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nextCommand = Command::REFP2B;
|
nextCommand = Command::REFP2B;
|
||||||
currentRefreshPayload = &refreshPayloads[currentIterator->front()];
|
currentRefreshPayload = &refreshPayloads[currentIterator->front()];
|
||||||
for (auto it : *currentIterator)
|
for (auto* it : *currentIterator)
|
||||||
{
|
{
|
||||||
if (it->isActivated())
|
if (it->isActivated())
|
||||||
{
|
{
|
||||||
@@ -228,13 +227,13 @@ void RefreshManagerPer2Bank::updateState(Command command)
|
|||||||
if (flexibilityCounter == maxPulledin)
|
if (flexibilityCounter == maxPulledin)
|
||||||
{
|
{
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalP2B();
|
timeForNextTrigger += memSpec.getRefreshIntervalP2B();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Command::REFAB:
|
case Command::REFAB:
|
||||||
// Refresh command after SREFEX
|
// Refresh command after SREFEX
|
||||||
state = State::Regular; // TODO: check if this assignment is necessary
|
state = State::Regular; // TODO: check if this assignment is necessary
|
||||||
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalP2B();
|
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalP2B();
|
||||||
sleeping = false;
|
sleeping = false;
|
||||||
remainingBankMachines = allBankMachines;
|
remainingBankMachines = allBankMachines;
|
||||||
currentIterator = remainingBankMachines.begin();
|
currentIterator = remainingBankMachines.begin();
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "RefreshManagerIF.h"
|
#include "RefreshManagerIF.h"
|
||||||
#include "../checker/CheckerIF.h"
|
#include "../checker/CheckerIF.h"
|
||||||
#include "../../configuration/memspec/MemSpec.h"
|
#include "../../configuration/memspec/MemSpec.h"
|
||||||
|
#include "../../configuration/Configuration.h"
|
||||||
|
|
||||||
class BankMachine;
|
class BankMachine;
|
||||||
class PowerDownManagerIF;
|
class PowerDownManagerIF;
|
||||||
@@ -51,7 +52,7 @@ class PowerDownManagerIF;
|
|||||||
class RefreshManagerPer2Bank final : public RefreshManagerIF
|
class RefreshManagerPer2Bank final : public RefreshManagerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RefreshManagerPer2Bank(std::vector<BankMachine*>& bankMachinesOnRank,
|
RefreshManagerPer2Bank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
||||||
|
|
||||||
CommandTuple::Type getNextCommand() override;
|
CommandTuple::Type getNextCommand() override;
|
||||||
@@ -60,10 +61,10 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum class State {Regular, Pulledin} state = State::Regular;
|
enum class State {Regular, Pulledin} state = State::Regular;
|
||||||
const MemSpec *memSpec;
|
const MemSpec& memSpec;
|
||||||
PowerDownManagerIF& powerDownManager;
|
PowerDownManagerIF& powerDownManager;
|
||||||
std::unordered_map<BankMachine*, tlm::tlm_generic_payload> refreshPayloads;
|
std::unordered_map<BankMachine*, tlm::tlm_generic_payload> refreshPayloads;
|
||||||
tlm::tlm_generic_payload *currentRefreshPayload;
|
tlm::tlm_generic_payload* currentRefreshPayload;
|
||||||
sc_core::sc_time timeForNextTrigger = sc_core::sc_max_time();
|
sc_core::sc_time timeForNextTrigger = sc_core::sc_max_time();
|
||||||
sc_core::sc_time timeToSchedule = sc_core::sc_max_time();
|
sc_core::sc_time timeToSchedule = sc_core::sc_max_time();
|
||||||
const CheckerIF& checker;
|
const CheckerIF& checker;
|
||||||
|
|||||||
@@ -42,15 +42,13 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
RefreshManagerPerBank::RefreshManagerPerBank(std::vector<BankMachine*>& bankMachinesOnRank,
|
RefreshManagerPerBank::RefreshManagerPerBank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
||||||
: powerDownManager(powerDownManager), checker(checker)
|
: powerDownManager(powerDownManager), checker(checker), memSpec(*config.memSpec)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalPB(), rank,
|
||||||
memSpec = config.memSpec;
|
memSpec.ranksPerChannel);
|
||||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec->getRefreshIntervalPB(),
|
for (auto* it : bankMachinesOnRank)
|
||||||
rank, memSpec->ranksPerChannel);
|
|
||||||
for (auto it : bankMachinesOnRank)
|
|
||||||
{
|
{
|
||||||
setUpDummy(refreshPayloads[it], 0, rank, it->getBankGroup(), it->getBank());
|
setUpDummy(refreshPayloads[it], 0, rank, it->getBankGroup(), it->getBank());
|
||||||
allBankMachines.push_back(it);
|
allBankMachines.push_back(it);
|
||||||
@@ -59,8 +57,8 @@ RefreshManagerPerBank::RefreshManagerPerBank(std::vector<BankMachine*>& bankMach
|
|||||||
remainingBankMachines = allBankMachines;
|
remainingBankMachines = allBankMachines;
|
||||||
currentIterator = remainingBankMachines.begin();
|
currentIterator = remainingBankMachines.begin();
|
||||||
|
|
||||||
maxPostponed = static_cast<int>(config.refreshMaxPostponed * memSpec->banksPerRank);
|
maxPostponed = static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerRank);
|
||||||
maxPulledin = -static_cast<int>(config.refreshMaxPulledin * memSpec->banksPerRank);
|
maxPulledin = -static_cast<int>(config.refreshMaxPulledin * memSpec.banksPerRank);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandTuple::Type RefreshManagerPerBank::getNextCommand()
|
CommandTuple::Type RefreshManagerPerBank::getNextCommand()
|
||||||
@@ -79,9 +77,9 @@ sc_time RefreshManagerPerBank::start()
|
|||||||
if (sleeping)
|
if (sleeping)
|
||||||
return timeToSchedule;
|
return timeToSchedule;
|
||||||
|
|
||||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalPB())
|
if (sc_time_stamp() >= timeForNextTrigger + memSpec.getRefreshIntervalPB())
|
||||||
{
|
{
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
timeForNextTrigger += memSpec.getRefreshIntervalPB();
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +106,7 @@ sc_time RefreshManagerPerBank::start()
|
|||||||
if (allBanksBusy && !forcedRefresh)
|
if (allBanksBusy && !forcedRefresh)
|
||||||
{
|
{
|
||||||
flexibilityCounter++;
|
flexibilityCounter++;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
timeForNextTrigger += memSpec.getRefreshIntervalPB();
|
||||||
return timeForNextTrigger;
|
return timeForNextTrigger;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -148,7 +146,7 @@ sc_time RefreshManagerPerBank::start()
|
|||||||
if (allBanksBusy)
|
if (allBanksBusy)
|
||||||
{
|
{
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
timeForNextTrigger += memSpec.getRefreshIntervalPB();
|
||||||
return timeForNextTrigger;
|
return timeForNextTrigger;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -185,13 +183,13 @@ void RefreshManagerPerBank::updateState(Command command)
|
|||||||
if (flexibilityCounter == maxPulledin)
|
if (flexibilityCounter == maxPulledin)
|
||||||
{
|
{
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
timeForNextTrigger += memSpec.getRefreshIntervalPB();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Command::REFAB:
|
case Command::REFAB:
|
||||||
// Refresh command after SREFEX
|
// Refresh command after SREFEX
|
||||||
state = State::Regular; // TODO: check if this assignment is necessary
|
state = State::Regular; // TODO: check if this assignment is necessary
|
||||||
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalPB();
|
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalPB();
|
||||||
sleeping = false;
|
sleeping = false;
|
||||||
remainingBankMachines = allBankMachines;
|
remainingBankMachines = allBankMachines;
|
||||||
currentIterator = remainingBankMachines.begin();
|
currentIterator = remainingBankMachines.begin();
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "RefreshManagerIF.h"
|
#include "RefreshManagerIF.h"
|
||||||
#include "../checker/CheckerIF.h"
|
#include "../checker/CheckerIF.h"
|
||||||
#include "../../configuration/memspec/MemSpec.h"
|
#include "../../configuration/memspec/MemSpec.h"
|
||||||
|
#include "../../configuration/Configuration.h"
|
||||||
|
|
||||||
class BankMachine;
|
class BankMachine;
|
||||||
class PowerDownManagerIF;
|
class PowerDownManagerIF;
|
||||||
@@ -51,8 +52,8 @@ class PowerDownManagerIF;
|
|||||||
class RefreshManagerPerBank final : public RefreshManagerIF
|
class RefreshManagerPerBank final : public RefreshManagerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RefreshManagerPerBank(std::vector<BankMachine *>& bankMachinesOnRank, PowerDownManagerIF& powerDownManager,
|
RefreshManagerPerBank(const Configuration& config, std::vector<BankMachine *>& bankMachinesOnRank,
|
||||||
Rank rank, const CheckerIF& checker);
|
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
||||||
|
|
||||||
CommandTuple::Type getNextCommand() override;
|
CommandTuple::Type getNextCommand() override;
|
||||||
sc_core::sc_time start() override;
|
sc_core::sc_time start() override;
|
||||||
@@ -60,7 +61,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum class State {Regular, Pulledin} state = State::Regular;
|
enum class State {Regular, Pulledin} state = State::Regular;
|
||||||
const MemSpec *memSpec;
|
const MemSpec& memSpec;
|
||||||
PowerDownManagerIF& powerDownManager;
|
PowerDownManagerIF& powerDownManager;
|
||||||
std::unordered_map<BankMachine*, tlm::tlm_generic_payload> refreshPayloads;
|
std::unordered_map<BankMachine*, tlm::tlm_generic_payload> refreshPayloads;
|
||||||
sc_core::sc_time timeForNextTrigger = sc_core::sc_max_time();
|
sc_core::sc_time timeForNextTrigger = sc_core::sc_max_time();
|
||||||
@@ -68,9 +69,9 @@ private:
|
|||||||
const CheckerIF& checker;
|
const CheckerIF& checker;
|
||||||
Command nextCommand = Command::NOP;
|
Command nextCommand = Command::NOP;
|
||||||
|
|
||||||
std::list<BankMachine *> remainingBankMachines;
|
std::list<BankMachine*> remainingBankMachines;
|
||||||
std::list<BankMachine *> allBankMachines;
|
std::list<BankMachine*> allBankMachines;
|
||||||
std::list<BankMachine *>::iterator currentIterator;
|
std::list<BankMachine*>::iterator currentIterator;
|
||||||
|
|
||||||
int flexibilityCounter = 0;
|
int flexibilityCounter = 0;
|
||||||
int maxPostponed = 0;
|
int maxPostponed = 0;
|
||||||
|
|||||||
@@ -42,39 +42,39 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
RefreshManagerSameBank::RefreshManagerSameBank(std::vector<BankMachine*>& bankMachinesOnRank,
|
RefreshManagerSameBank::RefreshManagerSameBank(const Configuration& config,
|
||||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
std::vector<BankMachine*>& bankMachinesOnRank,
|
||||||
: powerDownManager(powerDownManager), checker(checker)
|
PowerDownManagerIF& powerDownManager, Rank rank,
|
||||||
|
const CheckerIF& checker)
|
||||||
|
: powerDownManager(powerDownManager), checker(checker), memSpec(*config.memSpec)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalSB(), rank,
|
||||||
memSpec = config.memSpec;
|
memSpec.ranksPerChannel);
|
||||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec->getRefreshIntervalSB(),
|
|
||||||
rank, memSpec->ranksPerChannel);
|
|
||||||
|
|
||||||
// each same-bank group has one payload (e.g. 0-4-8-12-16-20-24-28)
|
// each same-bank group has one payload (e.g. 0-4-8-12-16-20-24-28)
|
||||||
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->banksPerGroup);
|
refreshPayloads = std::vector<tlm_generic_payload>(memSpec.banksPerGroup);
|
||||||
for (unsigned bankID = 0; bankID < memSpec->banksPerGroup; bankID++)
|
for (unsigned bankID = 0; bankID < memSpec.banksPerGroup; bankID++)
|
||||||
{
|
{
|
||||||
// rank 0: bank group 0, bank 0 - 3; rank 1: bank group 8, bank 32 - 35
|
// rank 0: bank group 0, bank 0 - 3; rank 1: bank group 8, bank 32 - 35
|
||||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[bankID]->getBankGroup(),
|
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[bankID]->getBankGroup(),
|
||||||
bankMachinesOnRank[bankID]->getBank());
|
bankMachinesOnRank[bankID]->getBank());
|
||||||
allBankMachines.emplace_back(std::vector<BankMachine *>(memSpec->groupsPerRank));
|
allBankMachines.emplace_back(std::vector<BankMachine *>(memSpec.groupsPerRank));
|
||||||
}
|
}
|
||||||
|
|
||||||
// allBankMachines: ((0-4-8-12-16-20-24-28), (1-5-9-13-17-21-25-29), ...)
|
// allBankMachines: ((0-4-8-12-16-20-24-28), (1-5-9-13-17-21-25-29), ...)
|
||||||
std::list<std::vector<BankMachine *>>::iterator it = allBankMachines.begin();
|
std::list<std::vector<BankMachine *>>::iterator it = allBankMachines.begin();
|
||||||
for (unsigned bankID = 0; bankID < memSpec->banksPerGroup; bankID++)
|
for (unsigned bankID = 0; bankID < memSpec.banksPerGroup; bankID++)
|
||||||
{
|
{
|
||||||
for (unsigned groupID = 0; groupID < memSpec->groupsPerRank; groupID++)
|
for (unsigned groupID = 0; groupID < memSpec.groupsPerRank; groupID++)
|
||||||
(*it)[groupID] = bankMachinesOnRank[groupID * memSpec->banksPerGroup + bankID];
|
(*it)[groupID] = bankMachinesOnRank[groupID * memSpec.banksPerGroup + bankID];
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
remainingBankMachines = allBankMachines;
|
remainingBankMachines = allBankMachines;
|
||||||
currentIterator = remainingBankMachines.begin();
|
currentIterator = remainingBankMachines.begin();
|
||||||
|
|
||||||
maxPostponed = static_cast<int>(config.refreshMaxPostponed * memSpec->banksPerGroup);
|
maxPostponed = static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerGroup);
|
||||||
maxPulledin = -static_cast<int>(config.refreshMaxPulledin * memSpec->banksPerGroup);
|
maxPulledin = -static_cast<int>(config.refreshMaxPulledin * memSpec.banksPerGroup);
|
||||||
|
|
||||||
refreshManagement = config.refreshManagement;
|
refreshManagement = config.refreshManagement;
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ RefreshManagerSameBank::RefreshManagerSameBank(std::vector<BankMachine*>& bankMa
|
|||||||
CommandTuple::Type RefreshManagerSameBank::getNextCommand()
|
CommandTuple::Type RefreshManagerSameBank::getNextCommand()
|
||||||
{
|
{
|
||||||
return {nextCommand,
|
return {nextCommand,
|
||||||
&refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup],
|
&refreshPayloads[currentIterator->front()->getBank().ID() % memSpec.banksPerGroup],
|
||||||
std::max(timeToSchedule, sc_time_stamp())};
|
std::max(timeToSchedule, sc_time_stamp())};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,9 +97,9 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
if (sleeping)
|
if (sleeping)
|
||||||
return timeToSchedule;
|
return timeToSchedule;
|
||||||
|
|
||||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalSB())
|
if (sc_time_stamp() >= timeForNextTrigger + memSpec.getRefreshIntervalSB())
|
||||||
{
|
{
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalSB();
|
timeForNextTrigger += memSpec.getRefreshIntervalSB();
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
||||||
{
|
{
|
||||||
bool groupIsBusy = false;
|
bool groupIsBusy = false;
|
||||||
for (auto groupIt : *bankIt)
|
for (const auto* groupIt : *bankIt)
|
||||||
{
|
{
|
||||||
if (!groupIt->isIdle())
|
if (!groupIt->isIdle())
|
||||||
{
|
{
|
||||||
@@ -134,12 +134,12 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
if (allGroupsBusy && !forcedRefresh)
|
if (allGroupsBusy && !forcedRefresh)
|
||||||
{
|
{
|
||||||
flexibilityCounter++;
|
flexibilityCounter++;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalSB();
|
timeForNextTrigger += memSpec.getRefreshIntervalSB();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nextCommand = Command::REFSB;
|
nextCommand = Command::REFSB;
|
||||||
for (auto it : *currentIterator)
|
for (const auto* it : *currentIterator)
|
||||||
{
|
{
|
||||||
if (it->isActivated())
|
if (it->isActivated())
|
||||||
{
|
{
|
||||||
@@ -152,13 +152,13 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
// only check for forced refresh, also block for PRESB
|
// only check for forced refresh, also block for PRESB
|
||||||
if (nextCommand == Command::REFSB && forcedRefresh)
|
if (nextCommand == Command::REFSB && forcedRefresh)
|
||||||
{
|
{
|
||||||
for (auto it : *currentIterator)
|
for (auto* it : *currentIterator)
|
||||||
it->block();
|
it->block();
|
||||||
skipSelection = true;
|
skipSelection = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand,
|
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand,
|
||||||
refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]);
|
refreshPayloads[currentIterator->front()->getBank().ID() % memSpec.banksPerGroup]);
|
||||||
return timeToSchedule;
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,7 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
||||||
{
|
{
|
||||||
bool groupIsBusy = false;
|
bool groupIsBusy = false;
|
||||||
for (auto groupIt : *bankIt)
|
for (const auto* groupIt : *bankIt)
|
||||||
{
|
{
|
||||||
if (!groupIt->isIdle())
|
if (!groupIt->isIdle())
|
||||||
{
|
{
|
||||||
@@ -189,12 +189,12 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
if (allGroupsBusy)
|
if (allGroupsBusy)
|
||||||
{
|
{
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalSB();
|
timeForNextTrigger += memSpec.getRefreshIntervalSB();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nextCommand = Command::REFSB;
|
nextCommand = Command::REFSB;
|
||||||
for (auto it : *currentIterator)
|
for (const auto* it : *currentIterator)
|
||||||
{
|
{
|
||||||
if (it->isActivated())
|
if (it->isActivated())
|
||||||
{
|
{
|
||||||
@@ -204,7 +204,7 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand,
|
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand,
|
||||||
refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]);
|
refreshPayloads[currentIterator->front()->getBank().ID() % memSpec.banksPerGroup]);
|
||||||
return timeToSchedule;
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,15 +217,15 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
|
|
||||||
for (auto bankIt = allBankMachines.begin(); bankIt != allBankMachines.end(); bankIt++)
|
for (auto bankIt = allBankMachines.begin(); bankIt != allBankMachines.end(); bankIt++)
|
||||||
{
|
{
|
||||||
for (auto groupIt : *bankIt)
|
for (const auto* groupIt : *bankIt)
|
||||||
{
|
{
|
||||||
if (groupIt->getRefreshManagementCounter() >= memSpec->getRAAMMT())
|
if (groupIt->getRefreshManagementCounter() >= memSpec.getRAAMMT())
|
||||||
{
|
{
|
||||||
mmtReached = true;
|
mmtReached = true;
|
||||||
currentIterator = bankIt;
|
currentIterator = bankIt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (groupIt->getRefreshManagementCounter() >= memSpec->getRAAIMT())
|
else if (groupIt->getRefreshManagementCounter() >= memSpec.getRAAIMT())
|
||||||
{
|
{
|
||||||
imtCandidates.emplace_back(bankIt);
|
imtCandidates.emplace_back(bankIt);
|
||||||
}
|
}
|
||||||
@@ -235,14 +235,14 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
if (mmtReached)
|
if (mmtReached)
|
||||||
{
|
{
|
||||||
nextCommand = Command::RFMSB;
|
nextCommand = Command::RFMSB;
|
||||||
for (auto groupIt : *currentIterator)
|
for (auto* groupIt : *currentIterator)
|
||||||
{
|
{
|
||||||
groupIt->block();
|
groupIt->block();
|
||||||
if (groupIt->isActivated())
|
if (groupIt->isActivated())
|
||||||
nextCommand = Command::PRESB;
|
nextCommand = Command::PRESB;
|
||||||
}
|
}
|
||||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand,
|
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand,
|
||||||
refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]);
|
refreshPayloads[currentIterator->front()->getBank().ID() % memSpec.banksPerGroup]);
|
||||||
return timeToSchedule;
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
else if (!imtCandidates.empty())
|
else if (!imtCandidates.empty())
|
||||||
@@ -252,7 +252,7 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
for (auto candidateIt : imtCandidates)
|
for (auto candidateIt : imtCandidates)
|
||||||
{
|
{
|
||||||
bool groupIsBusy = false;
|
bool groupIsBusy = false;
|
||||||
for (auto groupIt : *candidateIt)
|
for (const auto* groupIt : *candidateIt)
|
||||||
{
|
{
|
||||||
if (!groupIt->isIdle())
|
if (!groupIt->isIdle())
|
||||||
{
|
{
|
||||||
@@ -270,7 +270,7 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
if (!allGroupsBusy)
|
if (!allGroupsBusy)
|
||||||
{
|
{
|
||||||
nextCommand = Command::RFMSB;
|
nextCommand = Command::RFMSB;
|
||||||
for (auto it : *currentIterator)
|
for (const auto* it : *currentIterator)
|
||||||
{
|
{
|
||||||
if (it->isActivated())
|
if (it->isActivated())
|
||||||
{
|
{
|
||||||
@@ -279,7 +279,7 @@ sc_time RefreshManagerSameBank::start()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand,
|
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand,
|
||||||
refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]);
|
refreshPayloads[currentIterator->front()->getBank().ID() % memSpec.banksPerGroup]);
|
||||||
return timeToSchedule;
|
return timeToSchedule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,13 +307,13 @@ void RefreshManagerSameBank::updateState(Command command)
|
|||||||
if (flexibilityCounter == maxPulledin)
|
if (flexibilityCounter == maxPulledin)
|
||||||
{
|
{
|
||||||
state = State::Regular;
|
state = State::Regular;
|
||||||
timeForNextTrigger += memSpec->getRefreshIntervalSB();
|
timeForNextTrigger += memSpec.getRefreshIntervalSB();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Command::REFAB:
|
case Command::REFAB:
|
||||||
// Refresh command after SREFEX
|
// Refresh command after SREFEX
|
||||||
state = State::Regular; // TODO: check if this assignment is necessary
|
state = State::Regular; // TODO: check if this assignment is necessary
|
||||||
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalSB();
|
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalSB();
|
||||||
sleeping = false;
|
sleeping = false;
|
||||||
remainingBankMachines = allBankMachines;
|
remainingBankMachines = allBankMachines;
|
||||||
currentIterator = remainingBankMachines.begin();
|
currentIterator = remainingBankMachines.begin();
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#include "RefreshManagerIF.h"
|
#include "RefreshManagerIF.h"
|
||||||
#include "../checker/CheckerIF.h"
|
#include "../checker/CheckerIF.h"
|
||||||
#include "../../configuration/memspec/MemSpec.h"
|
#include "../../configuration/memspec/MemSpec.h"
|
||||||
|
#include "../../configuration/Configuration.h"
|
||||||
|
|
||||||
class BankMachine;
|
class BankMachine;
|
||||||
class PowerDownManagerIF;
|
class PowerDownManagerIF;
|
||||||
@@ -50,8 +51,8 @@ class PowerDownManagerIF;
|
|||||||
class RefreshManagerSameBank final : public RefreshManagerIF
|
class RefreshManagerSameBank final : public RefreshManagerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RefreshManagerSameBank(std::vector<BankMachine *>& bankMachinesOnRank, PowerDownManagerIF& powerDownManager,
|
RefreshManagerSameBank(const Configuration& config, std::vector<BankMachine *>& bankMachinesOnRank,
|
||||||
Rank rank, const CheckerIF& checker);
|
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
||||||
|
|
||||||
CommandTuple::Type getNextCommand() override;
|
CommandTuple::Type getNextCommand() override;
|
||||||
sc_core::sc_time start() override;
|
sc_core::sc_time start() override;
|
||||||
@@ -59,7 +60,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum class State {Regular, Pulledin} state = State::Regular;
|
enum class State {Regular, Pulledin} state = State::Regular;
|
||||||
const MemSpec *memSpec;
|
const MemSpec& memSpec;
|
||||||
PowerDownManagerIF& powerDownManager;
|
PowerDownManagerIF& powerDownManager;
|
||||||
std::vector<tlm::tlm_generic_payload> refreshPayloads;
|
std::vector<tlm::tlm_generic_payload> refreshPayloads;
|
||||||
sc_core::sc_time timeForNextTrigger = sc_core::sc_max_time();
|
sc_core::sc_time timeForNextTrigger = sc_core::sc_max_time();
|
||||||
|
|||||||
@@ -40,9 +40,8 @@
|
|||||||
|
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
SchedulerFifo::SchedulerFifo()
|
SchedulerFifo::SchedulerFifo(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
|
||||||
buffer = std::vector<std::deque<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
buffer = std::vector<std::deque<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
||||||
|
|
||||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
class SchedulerFifo final : public SchedulerIF
|
class SchedulerFifo final : public SchedulerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SchedulerFifo();
|
explicit SchedulerFifo(const Configuration& config);
|
||||||
bool hasBufferSpace() const override;
|
bool hasBufferSpace() const override;
|
||||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||||
|
|||||||
@@ -40,9 +40,8 @@
|
|||||||
|
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
SchedulerFrFcfs::SchedulerFrFcfs()
|
SchedulerFrFcfs::SchedulerFrFcfs(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
|
||||||
buffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
buffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
||||||
|
|
||||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
class SchedulerFrFcfs final : public SchedulerIF
|
class SchedulerFrFcfs final : public SchedulerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SchedulerFrFcfs();
|
explicit SchedulerFrFcfs(const Configuration& config);
|
||||||
bool hasBufferSpace() const override;
|
bool hasBufferSpace() const override;
|
||||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||||
|
|||||||
@@ -40,9 +40,8 @@
|
|||||||
|
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
SchedulerFrFcfsGrp::SchedulerFrFcfsGrp()
|
SchedulerFrFcfsGrp::SchedulerFrFcfsGrp(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
|
||||||
buffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
buffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
||||||
|
|
||||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
class SchedulerFrFcfsGrp final : public SchedulerIF
|
class SchedulerFrFcfsGrp final : public SchedulerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SchedulerFrFcfsGrp();
|
explicit SchedulerFrFcfsGrp(const Configuration& config);
|
||||||
bool hasBufferSpace() const override;
|
bool hasBufferSpace() const override;
|
||||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||||
|
|||||||
@@ -40,9 +40,8 @@
|
|||||||
|
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
SchedulerGrpFrFcfs::SchedulerGrpFrFcfs()
|
SchedulerGrpFrFcfs::SchedulerGrpFrFcfs(const Configuration& config)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
|
||||||
readBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
readBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
||||||
writeBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
writeBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
class SchedulerGrpFrFcfs final : public SchedulerIF
|
class SchedulerGrpFrFcfs final : public SchedulerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SchedulerGrpFrFcfs();
|
explicit SchedulerGrpFrFcfs(const Configuration& config);
|
||||||
bool hasBufferSpace() const override;
|
bool hasBufferSpace() const override;
|
||||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||||
|
|||||||
@@ -40,9 +40,8 @@
|
|||||||
|
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
SchedulerGrpFrFcfsWm::SchedulerGrpFrFcfsWm() : lowWatermark(0), highWatermark(0)
|
SchedulerGrpFrFcfsWm::SchedulerGrpFrFcfsWm(const Configuration& config) : lowWatermark(0), highWatermark(0)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
|
||||||
readBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
readBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
||||||
writeBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
writeBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
||||||
|
|
||||||
@@ -55,6 +54,9 @@ SchedulerGrpFrFcfsWm::SchedulerGrpFrFcfsWm() : lowWatermark(0), highWatermark(0)
|
|||||||
|
|
||||||
lowWatermark = config.lowWatermark;
|
lowWatermark = config.lowWatermark;
|
||||||
highWatermark = config.highWatermark;
|
highWatermark = config.highWatermark;
|
||||||
|
|
||||||
|
if (lowWatermark == 0 || highWatermark == 0 || lowWatermark == highWatermark)
|
||||||
|
SC_REPORT_FATAL("SchedulerGrpFrFcfsWm", "Invalid watermark configuration.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SchedulerGrpFrFcfsWm::hasBufferSpace() const
|
bool SchedulerGrpFrFcfsWm::hasBufferSpace() const
|
||||||
@@ -136,7 +138,7 @@ bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command
|
|||||||
unsigned rowHitCounter = 0;
|
unsigned rowHitCounter = 0;
|
||||||
if (!writeMode)
|
if (!writeMode)
|
||||||
{
|
{
|
||||||
for (auto it : readBuffer[bank.ID()])
|
for (const auto* it : readBuffer[bank.ID()])
|
||||||
{
|
{
|
||||||
if (DramExtension::getRow(it) == row)
|
if (DramExtension::getRow(it) == row)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,11 +44,12 @@
|
|||||||
#include "../../common/dramExtensions.h"
|
#include "../../common/dramExtensions.h"
|
||||||
#include "../BankMachine.h"
|
#include "../BankMachine.h"
|
||||||
#include "BufferCounterIF.h"
|
#include "BufferCounterIF.h"
|
||||||
|
#include "../../configuration/Configuration.h"
|
||||||
|
|
||||||
class SchedulerGrpFrFcfsWm final : public SchedulerIF
|
class SchedulerGrpFrFcfsWm final : public SchedulerIF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SchedulerGrpFrFcfsWm();
|
explicit SchedulerGrpFrFcfsWm(const Configuration& config);
|
||||||
bool hasBufferSpace() const override;
|
bool hasBufferSpace() const override;
|
||||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||||
@@ -60,8 +61,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void evaluateWriteMode();
|
void evaluateWriteMode();
|
||||||
|
|
||||||
std::vector<std::list<tlm::tlm_generic_payload *>> readBuffer;
|
std::vector<std::list<tlm::tlm_generic_payload*>> readBuffer;
|
||||||
std::vector<std::list<tlm::tlm_generic_payload *>> writeBuffer;
|
std::vector<std::list<tlm::tlm_generic_payload*>> writeBuffer;
|
||||||
std::unique_ptr<BufferCounterIF> bufferCounter;
|
std::unique_ptr<BufferCounterIF> bufferCounter;
|
||||||
unsigned lowWatermark;
|
unsigned lowWatermark;
|
||||||
unsigned highWatermark;
|
unsigned highWatermark;
|
||||||
|
|||||||
@@ -48,19 +48,27 @@
|
|||||||
|
|
||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
|
|
||||||
void errorModel::init()
|
errorModel::errorModel(const sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController, libDRAMPower *dramPower)
|
||||||
|
: sc_module(name), memSpec(*config.memSpec), temperatureController(temperatureController)
|
||||||
{
|
{
|
||||||
powerAnalysis = Configuration::getInstance().powerAnalysis;
|
this->DRAMPower = dramPower;
|
||||||
thermalSim = Configuration::getInstance().thermalSimulation;
|
init(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void errorModel::init(const Configuration& config)
|
||||||
|
{
|
||||||
|
powerAnalysis = config.powerAnalysis;
|
||||||
|
thermalSim = config.thermalSimulation;
|
||||||
// Get Configuration parameters:
|
// Get Configuration parameters:
|
||||||
burstLenght = Configuration::getInstance().memSpec->defaultBurstLength;
|
burstLenght = config.memSpec->defaultBurstLength;
|
||||||
numberOfColumns = Configuration::getInstance().memSpec->columnsPerRow;
|
numberOfColumns = config.memSpec->columnsPerRow;
|
||||||
bytesPerColumn = std::log2(Configuration::getInstance().memSpec->dataBusWidth);
|
bytesPerColumn = std::log2(config.memSpec->dataBusWidth);
|
||||||
|
|
||||||
// Adjust number of bytes per column dynamically to the selected ecc controller
|
// Adjust number of bytes per column dynamically to the selected ecc controller
|
||||||
//TODO: bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC(bytesPerColumn);
|
//TODO: bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC(bytesPerColumn);
|
||||||
|
|
||||||
numberOfRows = Configuration::getInstance().memSpec->rowsPerBank;
|
numberOfRows = config.memSpec->rowsPerBank;
|
||||||
numberOfBitErrorEvents = 0;
|
numberOfBitErrorEvents = 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -73,7 +81,7 @@ void errorModel::init()
|
|||||||
contextStr = "";
|
contextStr = "";
|
||||||
|
|
||||||
// Parse data input:
|
// Parse data input:
|
||||||
parseInputData();
|
parseInputData(config);
|
||||||
prepareWeakCells();
|
prepareWeakCells();
|
||||||
|
|
||||||
// Initialize context variables:
|
// Initialize context variables:
|
||||||
@@ -117,17 +125,6 @@ void errorModel::init()
|
|||||||
markBitFlips();
|
markBitFlips();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorModel::errorModel(const sc_module_name &name, libDRAMPower *dp) : sc_module(name)
|
|
||||||
{
|
|
||||||
this->DRAMPower = dp;
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorModel::errorModel(const sc_module_name &name) : sc_module(name)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorModel::~errorModel()
|
errorModel::~errorModel()
|
||||||
{
|
{
|
||||||
// Remove all data from the dataMap:
|
// Remove all data from the dataMap:
|
||||||
@@ -262,7 +259,7 @@ void errorModel::markBitFlips()
|
|||||||
{
|
{
|
||||||
double temp = getTemperature();
|
double temp = getTemperature();
|
||||||
for (unsigned int row = 0;
|
for (unsigned int row = 0;
|
||||||
row < Configuration::getInstance().memSpec->rowsPerBank; row++) {
|
row < memSpec.rowsPerBank; row++) {
|
||||||
// If the row has never been accessed ignore it and go to the next one
|
// If the row has never been accessed ignore it and go to the next one
|
||||||
if (lastRowAccess[row] != SC_ZERO_TIME) {
|
if (lastRowAccess[row] != SC_ZERO_TIME) {
|
||||||
// Get the time interval between now and the last acivate/refresh
|
// Get the time interval between now and the last acivate/refresh
|
||||||
@@ -275,7 +272,7 @@ void errorModel::markBitFlips()
|
|||||||
// and temperature, if yes mark it as flipped:
|
// and temperature, if yes mark it as flipped:
|
||||||
for (unsigned int i = 0; i < n; i++) {
|
for (unsigned int i = 0; i < n; i++) {
|
||||||
// Check if Bit has marked as flipped yet, if yes mark it as flipped
|
// Check if Bit has marked as flipped yet, if yes mark it as flipped
|
||||||
if (weakCells[i].flipped == false && weakCells[i].row == row) {
|
if (!weakCells[i].flipped && weakCells[i].row == row) {
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "Maked weakCell[" << i << "] as flipped" << std::endl;
|
msg << "Maked weakCell[" << i << "] as flipped" << std::endl;
|
||||||
PRINTDEBUGMESSAGE(name(), msg.str());
|
PRINTDEBUGMESSAGE(name(), msg.str());
|
||||||
@@ -502,28 +499,27 @@ double errorModel::getTemperature()
|
|||||||
// requesting the temperature.
|
// requesting the temperature.
|
||||||
double temperature = 89;
|
double temperature = 89;
|
||||||
|
|
||||||
if (this->myChannel != -1) {
|
if (this->myChannel != -1)
|
||||||
if (thermalSim == true && powerAnalysis == true) {
|
{
|
||||||
|
if (thermalSim && powerAnalysis)
|
||||||
|
{
|
||||||
// TODO
|
// TODO
|
||||||
// check if this is best way to request information to DRAMPower.
|
// check if this is best way to request information to DRAMPower.
|
||||||
unsigned long long clk_cycles = sc_time_stamp() /
|
unsigned long long clk_cycles = sc_time_stamp() / memSpec.tCK;
|
||||||
Configuration::getInstance().memSpec->tCK;
|
|
||||||
DRAMPower->calcWindowEnergy(clk_cycles);
|
DRAMPower->calcWindowEnergy(clk_cycles);
|
||||||
float average_power = (float)DRAMPower->getPower().average_power;
|
float average_power = (float)DRAMPower->getPower().average_power;
|
||||||
temperature = TemperatureController::getInstance().getTemperature(
|
temperature = temperatureController.getTemperature(this->myChannel, average_power);
|
||||||
this->myChannel, average_power);
|
|
||||||
} else {
|
} else {
|
||||||
temperature = TemperatureController::getInstance().getTemperature(
|
temperature = temperatureController.getTemperature(this->myChannel, 0);
|
||||||
this->myChannel, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return temperature;
|
return temperature;
|
||||||
}
|
}
|
||||||
|
|
||||||
void errorModel::parseInputData()
|
void errorModel::parseInputData(const Configuration& config)
|
||||||
{
|
{
|
||||||
std::string fileName = Configuration::getInstance().errorCSVFile;
|
std::string fileName = config.errorCSVFile;
|
||||||
std::ifstream inputFile(fileName);
|
std::ifstream inputFile(fileName);
|
||||||
|
|
||||||
if (inputFile.is_open()) {
|
if (inputFile.is_open()) {
|
||||||
@@ -645,7 +641,7 @@ void errorModel::prepareWeakCells()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If a cell was already choosen as weak we have to roll the dice again:
|
// If a cell was already choosen as weak we have to roll the dice again:
|
||||||
if (found == true) {
|
if (found) {
|
||||||
i--;
|
i--;
|
||||||
} else {
|
} else {
|
||||||
weakCells[i].row = row; // Row in the bank
|
weakCells[i].row = row; // Row in the bank
|
||||||
@@ -663,7 +659,7 @@ void errorModel::prepareWeakCells()
|
|||||||
unsigned int r = (rand() % maxNumberOfWeakCells);
|
unsigned int r = (rand() % maxNumberOfWeakCells);
|
||||||
|
|
||||||
// If the dependent weak cell was choosen before roll the dice again:
|
// If the dependent weak cell was choosen before roll the dice again:
|
||||||
if (weakCells[r].dependent == true) {
|
if (weakCells[r].dependent) {
|
||||||
i--;
|
i--;
|
||||||
} else {
|
} else {
|
||||||
weakCells[r].dependent = true;
|
weakCells[r].dependent = true;
|
||||||
|
|||||||
@@ -42,12 +42,13 @@
|
|||||||
#include "../configuration/Configuration.h"
|
#include "../configuration/Configuration.h"
|
||||||
#include "../simulation/AddressDecoder.h"
|
#include "../simulation/AddressDecoder.h"
|
||||||
#include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
#include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||||
|
#include "../simulation/TemperatureController.h"
|
||||||
|
|
||||||
class errorModel : public sc_core::sc_module
|
class errorModel : public sc_core::sc_module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
errorModel(const sc_core::sc_module_name &, libDRAMPower *);
|
errorModel(const sc_core::sc_module_name& name, const Configuration& config,
|
||||||
explicit errorModel(const sc_core::sc_module_name &);
|
TemperatureController& temperatureController, libDRAMPower* dramPower = nullptr);
|
||||||
~errorModel() override;
|
~errorModel() override;
|
||||||
|
|
||||||
// Access Methods:
|
// Access Methods:
|
||||||
@@ -59,10 +60,12 @@ public:
|
|||||||
double getTemperature();
|
double getTemperature();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init(const Configuration& config);
|
||||||
bool powerAnalysis;
|
bool powerAnalysis;
|
||||||
libDRAMPower *DRAMPower;
|
libDRAMPower *DRAMPower;
|
||||||
bool thermalSim;
|
bool thermalSim;
|
||||||
|
TemperatureController& temperatureController;
|
||||||
|
const MemSpec& memSpec;
|
||||||
// Configuration Parameters:
|
// Configuration Parameters:
|
||||||
unsigned int burstLenght;
|
unsigned int burstLenght;
|
||||||
unsigned int numberOfColumns;
|
unsigned int numberOfColumns;
|
||||||
@@ -76,7 +79,7 @@ private:
|
|||||||
unsigned int numberOfBitErrorEvents;
|
unsigned int numberOfBitErrorEvents;
|
||||||
|
|
||||||
// Private Methods:
|
// Private Methods:
|
||||||
void parseInputData();
|
void parseInputData(const Configuration& config);
|
||||||
void prepareWeakCells();
|
void prepareWeakCells();
|
||||||
void markBitFlips();
|
void markBitFlips();
|
||||||
unsigned int getNumberOfFlips(double temp, sc_core::sc_time time);
|
unsigned int getNumberOfFlips(double temp, sc_core::sc_time time);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
#include "../common/utils.h"
|
#include "../common/utils.h"
|
||||||
#include "../configuration/Configuration.h"
|
#include "../configuration/Configuration.h"
|
||||||
|
|
||||||
AddressDecoder::AddressDecoder(const DRAMSysConfiguration::AddressMapping &addressMapping)
|
AddressDecoder::AddressDecoder(const Configuration& config, const DRAMSysConfiguration::AddressMapping &addressMapping)
|
||||||
{
|
{
|
||||||
if (const auto &channelBits = addressMapping.channelBits)
|
if (const auto &channelBits = addressMapping.channelBits)
|
||||||
{
|
{
|
||||||
@@ -107,14 +107,12 @@ AddressDecoder::AddressDecoder(const DRAMSysConfiguration::AddressMapping &addre
|
|||||||
banksPerGroup = banks;
|
banksPerGroup = banks;
|
||||||
banks = banksPerGroup * bankGroups;
|
banks = banksPerGroup * bankGroups;
|
||||||
|
|
||||||
|
const MemSpec& memSpec = *config.memSpec;
|
||||||
|
|
||||||
Configuration &config = Configuration::getInstance();
|
if (memSpec.numberOfChannels != channels || memSpec.ranksPerChannel != ranks
|
||||||
const MemSpec *memSpec = config.memSpec;
|
|| memSpec.bankGroupsPerChannel != bankGroups || memSpec.banksPerChannel != banks
|
||||||
|
|| memSpec.rowsPerBank != rows || memSpec.columnsPerRow != columns
|
||||||
if (memSpec->numberOfChannels != channels || memSpec->ranksPerChannel != ranks
|
|| memSpec.devicesPerRank * memSpec.bitWidth != bytes * 8)
|
||||||
|| memSpec->bankGroupsPerChannel != bankGroups || memSpec->banksPerChannel != banks
|
|
||||||
|| memSpec->rowsPerBank != rows || memSpec->columnsPerRow != columns
|
|
||||||
|| memSpec->devicesPerRank * memSpec->bitWidth != bytes * 8)
|
|
||||||
SC_REPORT_FATAL("AddressDecoder", "Memspec and address mapping do not match");
|
SC_REPORT_FATAL("AddressDecoder", "Memspec and address mapping do not match");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <Configuration.h>
|
#include <Configuration.h>
|
||||||
|
#include "../configuration/Configuration.h"
|
||||||
|
|
||||||
struct DecodedAddress
|
struct DecodedAddress
|
||||||
{
|
{
|
||||||
@@ -68,7 +69,7 @@ struct DecodedAddress
|
|||||||
class AddressDecoder
|
class AddressDecoder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit AddressDecoder(const DRAMSysConfiguration::AddressMapping &addressMapping);
|
AddressDecoder(const Configuration& config, const DRAMSysConfiguration::AddressMapping &addressMapping);
|
||||||
DecodedAddress decodeAddress(uint64_t addr);
|
DecodedAddress decodeAddress(uint64_t addr);
|
||||||
void print();
|
void print();
|
||||||
|
|
||||||
|
|||||||
@@ -46,37 +46,36 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
|
|
||||||
Arbiter::Arbiter(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
Arbiter::Arbiter(const sc_module_name &name, const Configuration& config,
|
||||||
sc_module(name), payloadEventQueue(this, &Arbiter::peqCallback),
|
const DRAMSysConfiguration::AddressMapping& addressMapping) :
|
||||||
tCK(Configuration::getInstance().memSpec->tCK),
|
sc_module(name), addressDecoder(config, addressMapping), payloadEventQueue(this, &Arbiter::peqCallback),
|
||||||
arbitrationDelayFw(Configuration::getInstance().arbitrationDelayFw),
|
tCK(config.memSpec->tCK),
|
||||||
arbitrationDelayBw(Configuration::getInstance().arbitrationDelayBw)
|
arbitrationDelayFw(config.arbitrationDelayFw),
|
||||||
|
arbitrationDelayBw(config.arbitrationDelayBw),
|
||||||
|
addressOffset(config.addressOffset)
|
||||||
{
|
{
|
||||||
iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw);
|
iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw);
|
||||||
tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw);
|
tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw);
|
||||||
tSocket.register_transport_dbg(this, &Arbiter::transport_dbg);
|
tSocket.register_transport_dbg(this, &Arbiter::transport_dbg);
|
||||||
|
|
||||||
addressDecoder = new AddressDecoder(addressMapping);
|
addressDecoder.print();
|
||||||
addressDecoder->print();
|
|
||||||
|
|
||||||
bytesPerBeat = Configuration::getInstance().memSpec->dataBusWidth / 8;
|
bytesPerBeat = config.memSpec->dataBusWidth / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArbiterSimple::ArbiterSimple(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
ArbiterSimple::ArbiterSimple(const sc_module_name& name, const Configuration& config,
|
||||||
Arbiter(name, addressMapping) {}
|
const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
||||||
|
Arbiter(name, config, addressMapping) {}
|
||||||
|
|
||||||
ArbiterFifo::ArbiterFifo(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
ArbiterFifo::ArbiterFifo(const sc_module_name &name, const Configuration& config,
|
||||||
Arbiter(name, addressMapping),
|
const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
||||||
maxActiveTransactions(Configuration::getInstance().maxActiveTransactions) {}
|
Arbiter(name, config, addressMapping),
|
||||||
|
maxActiveTransactions(config.maxActiveTransactions) {}
|
||||||
|
|
||||||
ArbiterReorder::ArbiterReorder(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
ArbiterReorder::ArbiterReorder(const sc_module_name &name, const Configuration& config,
|
||||||
Arbiter(name, addressMapping),
|
const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
||||||
maxActiveTransactions(Configuration::getInstance().maxActiveTransactions) {}
|
Arbiter(name, config, addressMapping),
|
||||||
|
maxActiveTransactions(config.maxActiveTransactions) {}
|
||||||
Arbiter::~Arbiter()
|
|
||||||
{
|
|
||||||
delete addressDecoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Arbiter::end_of_elaboration()
|
void Arbiter::end_of_elaboration()
|
||||||
{
|
{
|
||||||
@@ -139,10 +138,10 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload,
|
|||||||
{
|
{
|
||||||
// TODO: do not adjust address permanently
|
// TODO: do not adjust address permanently
|
||||||
// adjust address offset:
|
// adjust address offset:
|
||||||
uint64_t adjustedAddress = payload.get_address() - Configuration::getInstance().addressOffset;
|
uint64_t adjustedAddress = payload.get_address() - addressOffset;
|
||||||
payload.set_address(adjustedAddress);
|
payload.set_address(adjustedAddress);
|
||||||
|
|
||||||
DecodedAddress decodedAddress = addressDecoder->decodeAddress(adjustedAddress);
|
DecodedAddress decodedAddress = addressDecoder.decodeAddress(adjustedAddress);
|
||||||
DramExtension::setExtension(payload, Thread(static_cast<unsigned int>(id)), Channel(decodedAddress.channel),
|
DramExtension::setExtension(payload, Thread(static_cast<unsigned int>(id)), Channel(decodedAddress.channel),
|
||||||
Rank(decodedAddress.rank),
|
Rank(decodedAddress.rank),
|
||||||
BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank),
|
BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank),
|
||||||
@@ -168,10 +167,9 @@ tlm_sync_enum Arbiter::nb_transport_bw(int, tlm_generic_payload &payload,
|
|||||||
|
|
||||||
unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans)
|
unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans)
|
||||||
{
|
{
|
||||||
trans.set_address(trans.get_address() -
|
trans.set_address(trans.get_address() - addressOffset);
|
||||||
Configuration::getInstance().addressOffset);
|
|
||||||
|
|
||||||
DecodedAddress decodedAddress = addressDecoder->decodeAddress(trans.get_address());
|
DecodedAddress decodedAddress = addressDecoder.decodeAddress(trans.get_address());
|
||||||
return iSocket[static_cast<int>(decodedAddress.channel)]->transport_dbg(trans);
|
return iSocket[static_cast<int>(decodedAddress.channel)]->transport_dbg(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,15 +62,14 @@ public:
|
|||||||
tlm_utils::multi_passthrough_initiator_socket<Arbiter> iSocket;
|
tlm_utils::multi_passthrough_initiator_socket<Arbiter> iSocket;
|
||||||
tlm_utils::multi_passthrough_target_socket<Arbiter> tSocket;
|
tlm_utils::multi_passthrough_target_socket<Arbiter> tSocket;
|
||||||
|
|
||||||
~Arbiter() override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Arbiter(const sc_core::sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping);
|
Arbiter(const sc_core::sc_module_name &name, const Configuration& config,
|
||||||
|
const DRAMSysConfiguration::AddressMapping &addressMapping);
|
||||||
SC_HAS_PROCESS(Arbiter);
|
SC_HAS_PROCESS(Arbiter);
|
||||||
|
|
||||||
void end_of_elaboration() override;
|
void end_of_elaboration() override;
|
||||||
|
|
||||||
AddressDecoder *addressDecoder;
|
AddressDecoder addressDecoder;
|
||||||
|
|
||||||
tlm_utils::peq_with_cb_and_phase<Arbiter> payloadEventQueue;
|
tlm_utils::peq_with_cb_and_phase<Arbiter> payloadEventQueue;
|
||||||
virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) = 0;
|
virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) = 0;
|
||||||
@@ -94,12 +93,14 @@ protected:
|
|||||||
sc_core::sc_time arbitrationDelayBw;
|
sc_core::sc_time arbitrationDelayBw;
|
||||||
|
|
||||||
unsigned bytesPerBeat;
|
unsigned bytesPerBeat;
|
||||||
|
uint64_t addressOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArbiterSimple final : public Arbiter
|
class ArbiterSimple final : public Arbiter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ArbiterSimple(const sc_core::sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping);
|
ArbiterSimple(const sc_core::sc_module_name &name, const Configuration& config,
|
||||||
|
const DRAMSysConfiguration::AddressMapping &addressMapping);
|
||||||
SC_HAS_PROCESS(ArbiterSimple);
|
SC_HAS_PROCESS(ArbiterSimple);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -112,7 +113,8 @@ private:
|
|||||||
class ArbiterFifo final : public Arbiter
|
class ArbiterFifo final : public Arbiter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ArbiterFifo(const sc_core::sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping);
|
ArbiterFifo(const sc_core::sc_module_name &name, const Configuration& config,
|
||||||
|
const DRAMSysConfiguration::AddressMapping &addressMapping);
|
||||||
SC_HAS_PROCESS(ArbiterFifo);
|
SC_HAS_PROCESS(ArbiterFifo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -132,7 +134,8 @@ private:
|
|||||||
class ArbiterReorder final : public Arbiter
|
class ArbiterReorder final : public Arbiter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ArbiterReorder(const sc_core::sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping);
|
ArbiterReorder(const sc_core::sc_module_name &name, const Configuration& config,
|
||||||
|
const DRAMSysConfiguration::AddressMapping &addressMapping);
|
||||||
SC_HAS_PROCESS(ArbiterReorder);
|
SC_HAS_PROCESS(ArbiterReorder);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -64,42 +64,47 @@
|
|||||||
#include "../controller/Controller.h"
|
#include "../controller/Controller.h"
|
||||||
|
|
||||||
DRAMSys::DRAMSys(const sc_core::sc_module_name &name,
|
DRAMSys::DRAMSys(const sc_core::sc_module_name &name,
|
||||||
const DRAMSysConfiguration::Configuration &config)
|
const DRAMSysConfiguration::Configuration &configLib)
|
||||||
: DRAMSys(name, config, true)
|
: DRAMSys(name, configLib, true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
DRAMSys::DRAMSys(const sc_core::sc_module_name &name,
|
DRAMSys::DRAMSys(const sc_core::sc_module_name &name,
|
||||||
const DRAMSysConfiguration::Configuration &config,
|
const DRAMSysConfiguration::Configuration &configLib,
|
||||||
bool initAndBind)
|
bool initAndBind)
|
||||||
: sc_module(name), tSocket("DRAMSys_tSocket")
|
: sc_module(name), tSocket("DRAMSys_tSocket")
|
||||||
{
|
{
|
||||||
logo();
|
logo();
|
||||||
|
|
||||||
// Load config and initialize modules
|
// Load configLib and initialize modules
|
||||||
// Important: The memSpec needs to be the first configuration to be loaded!
|
// Important: The memSpec needs to be the first configuration to be loaded!
|
||||||
Configuration::loadMemSpec(Configuration::getInstance(), config.memSpec);
|
config.loadMemSpec(configLib.memSpec);
|
||||||
Configuration::loadMCConfig(Configuration::getInstance(), config.mcConfig);
|
config.loadMCConfig(configLib.mcConfig);
|
||||||
Configuration::loadSimConfig(Configuration::getInstance(), config.simConfig);
|
config.loadSimConfig(configLib.simConfig);
|
||||||
|
|
||||||
if (const auto &thermalConfig = config.thermalConfig)
|
if (const auto &thermalConfig = configLib.thermalConfig)
|
||||||
Configuration::loadTemperatureSimConfig(Configuration::getInstance(), *thermalConfig);
|
config.loadTemperatureSimConfig(*thermalConfig);
|
||||||
|
|
||||||
// Setup the debug manager:
|
// Setup the debug manager:
|
||||||
setupDebugManager(Configuration::getInstance().simulationName);
|
setupDebugManager(config.simulationName);
|
||||||
|
|
||||||
if (initAndBind)
|
if (initAndBind)
|
||||||
{
|
{
|
||||||
// Instantiate all internal DRAMSys modules:
|
// Instantiate all internal DRAMSys modules:
|
||||||
instantiateModules(config.addressMapping);
|
instantiateModules(configLib.addressMapping);
|
||||||
// Connect all internal DRAMSys modules:
|
// Connect all internal DRAMSys modules:
|
||||||
bindSockets();
|
bindSockets();
|
||||||
report(headline);
|
report(headline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Configuration& DRAMSys::getConfig()
|
||||||
|
{
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
void DRAMSys::end_of_simulation()
|
void DRAMSys::end_of_simulation()
|
||||||
{
|
{
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (config.powerAnalysis)
|
||||||
{
|
{
|
||||||
for (auto& dram : drams)
|
for (auto& dram : drams)
|
||||||
dram->reportPower();
|
dram->reportPower();
|
||||||
@@ -134,59 +139,70 @@ void DRAMSys::logo()
|
|||||||
void DRAMSys::setupDebugManager(NDEBUG_UNUSED(const std::string &traceName))
|
void DRAMSys::setupDebugManager(NDEBUG_UNUSED(const std::string &traceName))
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
auto &dbg = DebugManager::getInstance();
|
auto& dbg = DebugManager::getInstance();
|
||||||
dbg.writeToConsole = false;
|
bool debugEnabled = config.debug;
|
||||||
dbg.writeToFile = true;
|
bool writeToConsole = false;
|
||||||
if (dbg.writeToFile)
|
bool writeToFile = true;
|
||||||
|
dbg.setup(debugEnabled, writeToConsole, writeToFile);
|
||||||
|
if (writeToFile)
|
||||||
dbg.openDebugFile(traceName + ".txt");
|
dbg.openDebugFile(traceName + ".txt");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DRAMSys::instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping)
|
void DRAMSys::instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping)
|
||||||
{
|
{
|
||||||
// The first call to getInstance() creates the Temperature Controller.
|
temperatureController = std::make_unique<TemperatureController>("TemperatureController", config);
|
||||||
// The same instance will be accessed by all other modules.
|
|
||||||
TemperatureController::getInstance();
|
|
||||||
Configuration &config = Configuration::getInstance();
|
|
||||||
|
|
||||||
// Create arbiter
|
// Create arbiter
|
||||||
if (config.arbiter == Configuration::Arbiter::Simple)
|
if (config.arbiter == Configuration::Arbiter::Simple)
|
||||||
arbiter = std::make_unique<ArbiterSimple>("arbiter", addressMapping);
|
arbiter = std::make_unique<ArbiterSimple>("arbiter", config, addressMapping);
|
||||||
else if (config.arbiter == Configuration::Arbiter::Fifo)
|
else if (config.arbiter == Configuration::Arbiter::Fifo)
|
||||||
arbiter = std::make_unique<ArbiterFifo>("arbiter", addressMapping);
|
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, addressMapping);
|
||||||
else if (config.arbiter == Configuration::Arbiter::Reorder)
|
else if (config.arbiter == Configuration::Arbiter::Reorder)
|
||||||
arbiter = std::make_unique<ArbiterReorder>("arbiter", addressMapping);
|
arbiter = std::make_unique<ArbiterReorder>("arbiter", config, addressMapping);
|
||||||
|
|
||||||
// Create controllers and DRAMs
|
// Create controllers and DRAMs
|
||||||
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
|
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
|
||||||
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
|
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
|
||||||
{
|
{
|
||||||
controllers.emplace_back(std::make_unique<Controller>(("controller" + std::to_string(i)).c_str()));
|
controllers.emplace_back(std::make_unique<Controller>(("controller" + std::to_string(i)).c_str(), config));
|
||||||
|
|
||||||
if (memoryType == MemSpec::MemoryType::DDR3)
|
if (memoryType == MemSpec::MemoryType::DDR3)
|
||||||
drams.emplace_back(std::make_unique<DramDDR3>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramDDR3>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::DDR4)
|
else if (memoryType == MemSpec::MemoryType::DDR4)
|
||||||
drams.emplace_back(std::make_unique<DramDDR4>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramDDR4>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::DDR5)
|
else if (memoryType == MemSpec::MemoryType::DDR5)
|
||||||
drams.emplace_back(std::make_unique<DramDDR5>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramDDR5>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::WideIO)
|
else if (memoryType == MemSpec::MemoryType::WideIO)
|
||||||
drams.emplace_back(std::make_unique<DramWideIO>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramWideIO>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::LPDDR4)
|
else if (memoryType == MemSpec::MemoryType::LPDDR4)
|
||||||
drams.emplace_back(std::make_unique<DramLPDDR4>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramLPDDR4>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::LPDDR5)
|
else if (memoryType == MemSpec::MemoryType::LPDDR5)
|
||||||
drams.emplace_back(std::make_unique<DramLPDDR5>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramLPDDR5>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::WideIO2)
|
else if (memoryType == MemSpec::MemoryType::WideIO2)
|
||||||
drams.emplace_back(std::make_unique<DramWideIO2>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramWideIO2>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::HBM2)
|
else if (memoryType == MemSpec::MemoryType::HBM2)
|
||||||
drams.emplace_back(std::make_unique<DramHBM2>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramHBM2>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::GDDR5)
|
else if (memoryType == MemSpec::MemoryType::GDDR5)
|
||||||
drams.emplace_back(std::make_unique<DramGDDR5>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramGDDR5>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::GDDR5X)
|
else if (memoryType == MemSpec::MemoryType::GDDR5X)
|
||||||
drams.emplace_back(std::make_unique<DramGDDR5X>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramGDDR5X>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::GDDR6)
|
else if (memoryType == MemSpec::MemoryType::GDDR6)
|
||||||
drams.emplace_back(std::make_unique<DramGDDR6>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramGDDR6>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
else if (memoryType == MemSpec::MemoryType::STTMRAM)
|
else if (memoryType == MemSpec::MemoryType::STTMRAM)
|
||||||
drams.emplace_back(std::make_unique<DramSTTMRAM>(("dram" + std::to_string(i)).c_str()));
|
drams.emplace_back(std::make_unique<DramSTTMRAM>(("dram" + std::to_string(i)).c_str(), config,
|
||||||
|
*temperatureController));
|
||||||
|
|
||||||
if (config.checkTLM2Protocol)
|
if (config.checkTLM2Protocol)
|
||||||
controllersTlmCheckers.push_back(std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>
|
controllersTlmCheckers.push_back(std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>
|
||||||
@@ -196,8 +212,6 @@ void DRAMSys::instantiateModules(const DRAMSysConfiguration::AddressMapping &add
|
|||||||
|
|
||||||
void DRAMSys::bindSockets()
|
void DRAMSys::bindSockets()
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
|
||||||
|
|
||||||
tSocket.bind(arbiter->tSocket);
|
tSocket.bind(arbiter->tSocket);
|
||||||
|
|
||||||
for (unsigned i = 0; i < config.memSpec->numberOfChannels; i++)
|
for (unsigned i = 0; i < config.memSpec->numberOfChannels; i++)
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#include "../common/tlm2_base_protocol_checker.h"
|
#include "../common/tlm2_base_protocol_checker.h"
|
||||||
#include "../error/eccbaseclass.h"
|
#include "../error/eccbaseclass.h"
|
||||||
#include "../controller/ControllerIF.h"
|
#include "../controller/ControllerIF.h"
|
||||||
|
#include "TemperatureController.h"
|
||||||
|
|
||||||
#include <Configuration.h>
|
#include <Configuration.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -63,15 +64,21 @@ public:
|
|||||||
|
|
||||||
SC_HAS_PROCESS(DRAMSys);
|
SC_HAS_PROCESS(DRAMSys);
|
||||||
DRAMSys(const sc_core::sc_module_name &name,
|
DRAMSys(const sc_core::sc_module_name &name,
|
||||||
const DRAMSysConfiguration::Configuration &config);
|
const DRAMSysConfiguration::Configuration &configLib);
|
||||||
|
|
||||||
|
const Configuration& getConfig();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DRAMSys(const sc_core::sc_module_name &name,
|
DRAMSys(const sc_core::sc_module_name &name,
|
||||||
const DRAMSysConfiguration::Configuration &config,
|
const DRAMSysConfiguration::Configuration &configLib,
|
||||||
bool initAndBind);
|
bool initAndBind);
|
||||||
|
|
||||||
void end_of_simulation() override;
|
void end_of_simulation() override;
|
||||||
|
|
||||||
|
Configuration config;
|
||||||
|
|
||||||
|
std::unique_ptr<TemperatureController> temperatureController;
|
||||||
|
|
||||||
//TLM 2.0 Protocol Checkers
|
//TLM 2.0 Protocol Checkers
|
||||||
std::vector<std::unique_ptr<tlm_utils::tlm2_base_protocol_checker<>>> controllersTlmCheckers;
|
std::vector<std::unique_ptr<tlm_utils::tlm2_base_protocol_checker<>>> controllersTlmCheckers;
|
||||||
|
|
||||||
@@ -95,7 +102,7 @@ private:
|
|||||||
|
|
||||||
void instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping);
|
void instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping);
|
||||||
|
|
||||||
static void setupDebugManager(const std::string &traceName);
|
void setupDebugManager(const std::string &traceName);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DRAMSYS_H
|
#endif // DRAMSYS_H
|
||||||
|
|||||||
@@ -57,23 +57,22 @@
|
|||||||
|
|
||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
|
|
||||||
DRAMSysRecordable::DRAMSysRecordable(const sc_module_name &name,
|
DRAMSysRecordable::DRAMSysRecordable(const sc_module_name& name, const DRAMSysConfiguration::Configuration& configLib)
|
||||||
const DRAMSysConfiguration::Configuration &configuration)
|
: DRAMSys(name, configLib, false)
|
||||||
: DRAMSys(name, configuration, false)
|
|
||||||
{
|
{
|
||||||
// If a simulation file is passed as argument to DRAMSys the simulation ID
|
// If a simulation file is passed as argument to DRAMSys the simulation ID
|
||||||
// is prepended to the simulation name if found.
|
// is prepended to the simulation name if found.
|
||||||
std::string traceName;
|
std::string traceName;
|
||||||
|
|
||||||
if (!configuration.simulationId.empty())
|
if (!configLib.simulationId.empty())
|
||||||
{
|
{
|
||||||
std::string sid = configuration.simulationId;
|
std::string sid = configLib.simulationId;
|
||||||
traceName = sid + '_' + Configuration::getInstance().simulationName;
|
traceName = sid + '_' + config.simulationName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
traceName = Configuration::getInstance().simulationName;
|
traceName = config.simulationName;
|
||||||
|
|
||||||
instantiateModules(traceName, configuration);
|
instantiateModules(traceName, configLib);
|
||||||
bindSockets();
|
bindSockets();
|
||||||
report(headline);
|
report(headline);
|
||||||
}
|
}
|
||||||
@@ -81,7 +80,7 @@ DRAMSysRecordable::DRAMSysRecordable(const sc_module_name &name,
|
|||||||
void DRAMSysRecordable::end_of_simulation()
|
void DRAMSysRecordable::end_of_simulation()
|
||||||
{
|
{
|
||||||
// Report power before TLM recorders are finalized
|
// Report power before TLM recorders are finalized
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (config.powerAnalysis)
|
||||||
{
|
{
|
||||||
for (auto& dram : drams)
|
for (auto& dram : drams)
|
||||||
dram->reportPower();
|
dram->reportPower();
|
||||||
@@ -91,75 +90,84 @@ void DRAMSysRecordable::end_of_simulation()
|
|||||||
tlmRecorder.finalize();
|
tlmRecorder.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DRAMSysRecordable::setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configuration)
|
void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName, const DRAMSysConfiguration::Configuration& configLib)
|
||||||
{
|
{
|
||||||
// Create TLM Recorders, one per channel.
|
// Create TLM Recorders, one per channel.
|
||||||
for (std::size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++)
|
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
|
||||||
{
|
{
|
||||||
std::string dbName = traceName + std::string("_ch") + std::to_string(i) + ".tdb";
|
std::string dbName = traceName + std::string("_ch") + std::to_string(i) + ".tdb";
|
||||||
std::string recorderName = "tlmRecorder" + std::to_string(i);
|
std::string recorderName = "tlmRecorder" + std::to_string(i);
|
||||||
|
|
||||||
tlmRecorders.emplace_back(recorderName, dbName);
|
tlmRecorders.emplace_back(recorderName, config, dbName);
|
||||||
tlmRecorders.back().recordMcConfig(DRAMSysConfiguration::dump(configuration.mcConfig));
|
tlmRecorders.back().recordMcConfig(DRAMSysConfiguration::dump(configLib.mcConfig));
|
||||||
tlmRecorders.back().recordMemspec(DRAMSysConfiguration::dump(configuration.memSpec));
|
tlmRecorders.back().recordMemspec(DRAMSysConfiguration::dump(configLib.memSpec));
|
||||||
tlmRecorders.back().recordTraceNames(Configuration::getInstance().simulationName);
|
tlmRecorders.back().recordTraceNames(config.simulationName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DRAMSysRecordable::instantiateModules(const std::string &traceName,
|
void DRAMSysRecordable::instantiateModules(const std::string &traceName,
|
||||||
const DRAMSysConfiguration::Configuration &configuration)
|
const DRAMSysConfiguration::Configuration &configLib)
|
||||||
{
|
{
|
||||||
// The first call to getInstance() creates the Temperature Controller.
|
temperatureController = std::make_unique<TemperatureController>("TemperatureController", config);
|
||||||
// The same instance will be accessed by all other modules.
|
|
||||||
TemperatureController::getInstance();
|
|
||||||
|
|
||||||
Configuration &config = Configuration::getInstance();
|
|
||||||
|
|
||||||
// Create and properly initialize TLM recorders.
|
// Create and properly initialize TLM recorders.
|
||||||
// They need to be ready before creating some modules.
|
// They need to be ready before creating some modules.
|
||||||
setupTlmRecorders(traceName, configuration);
|
setupTlmRecorders(traceName, configLib);
|
||||||
|
|
||||||
// Create arbiter
|
// Create arbiter
|
||||||
if (config.arbiter == Configuration::Arbiter::Simple)
|
if (config.arbiter == Configuration::Arbiter::Simple)
|
||||||
arbiter = std::make_unique<ArbiterSimple>("arbiter", configuration.addressMapping);
|
arbiter = std::make_unique<ArbiterSimple>("arbiter", config, configLib.addressMapping);
|
||||||
else if (config.arbiter == Configuration::Arbiter::Fifo)
|
else if (config.arbiter == Configuration::Arbiter::Fifo)
|
||||||
arbiter = std::make_unique<ArbiterFifo>("arbiter", configuration.addressMapping);
|
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, configLib.addressMapping);
|
||||||
else if (config.arbiter == Configuration::Arbiter::Reorder)
|
else if (config.arbiter == Configuration::Arbiter::Reorder)
|
||||||
arbiter = std::make_unique<ArbiterReorder>("arbiter", configuration.addressMapping);
|
arbiter = std::make_unique<ArbiterReorder>("arbiter", config, configLib.addressMapping);
|
||||||
|
|
||||||
// Create controllers and DRAMs
|
// Create controllers and DRAMs
|
||||||
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
|
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
|
||||||
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
|
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
|
||||||
{
|
{
|
||||||
controllers.emplace_back(std::make_unique<ControllerRecordable>(("controller" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
controllers.emplace_back(std::make_unique<ControllerRecordable>(("controller" + std::to_string(i)).c_str(),
|
||||||
|
config, tlmRecorders[i]));
|
||||||
|
|
||||||
if (memoryType == MemSpec::MemoryType::DDR3)
|
if (memoryType == MemSpec::MemoryType::DDR3)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramDDR3>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramDDR3>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::DDR4)
|
else if (memoryType == MemSpec::MemoryType::DDR4)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramDDR4>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramDDR4>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::DDR5)
|
else if (memoryType == MemSpec::MemoryType::DDR5)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramDDR5>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramDDR5>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::WideIO)
|
else if (memoryType == MemSpec::MemoryType::WideIO)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramWideIO>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramWideIO>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::LPDDR4)
|
else if (memoryType == MemSpec::MemoryType::LPDDR4)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramLPDDR4>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramLPDDR4>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::LPDDR5)
|
else if (memoryType == MemSpec::MemoryType::LPDDR5)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramLPDDR5>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramLPDDR5>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::WideIO2)
|
else if (memoryType == MemSpec::MemoryType::WideIO2)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramWideIO2>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramWideIO2>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::HBM2)
|
else if (memoryType == MemSpec::MemoryType::HBM2)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramHBM2>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramHBM2>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::GDDR5)
|
else if (memoryType == MemSpec::MemoryType::GDDR5)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR5>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR5>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::GDDR5X)
|
else if (memoryType == MemSpec::MemoryType::GDDR5X)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR5X>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR5X>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::GDDR6)
|
else if (memoryType == MemSpec::MemoryType::GDDR6)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR6>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR6>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
else if (memoryType == MemSpec::MemoryType::STTMRAM)
|
else if (memoryType == MemSpec::MemoryType::STTMRAM)
|
||||||
drams.emplace_back(std::make_unique<DramRecordable<DramSTTMRAM>>(("dram" + std::to_string(i)).c_str(), tlmRecorders[i]));
|
drams.emplace_back(std::make_unique<DramRecordable<DramSTTMRAM>>(("dram" + std::to_string(i)).c_str(),
|
||||||
|
config, *temperatureController, tlmRecorders[i]));
|
||||||
|
|
||||||
if (config.checkTLM2Protocol)
|
if (config.checkTLM2Protocol)
|
||||||
controllersTlmCheckers.emplace_back(std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(("TLMCheckerController"
|
controllersTlmCheckers.emplace_back(std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>
|
||||||
+ std::to_string(i)).c_str()));
|
(("TLMCheckerController" + std::to_string(i)).c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,7 @@
|
|||||||
class DRAMSysRecordable : public DRAMSys
|
class DRAMSysRecordable : public DRAMSys
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DRAMSysRecordable(const sc_core::sc_module_name &name,
|
DRAMSysRecordable(const sc_core::sc_module_name &name, const DRAMSysConfiguration::Configuration &configLib);
|
||||||
const DRAMSysConfiguration::Configuration &configuration);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void end_of_simulation() override;
|
void end_of_simulation() override;
|
||||||
@@ -56,10 +55,8 @@ private:
|
|||||||
// They generate the output databases.
|
// They generate the output databases.
|
||||||
std::vector<TlmRecorder> tlmRecorders;
|
std::vector<TlmRecorder> tlmRecorders;
|
||||||
|
|
||||||
void setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configuration);
|
void setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configLib);
|
||||||
|
void instantiateModules(const std::string &traceName, const DRAMSysConfiguration::Configuration &configLib);
|
||||||
void instantiateModules(const std::string &traceName,
|
|
||||||
const DRAMSysConfiguration::Configuration &configuration);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,17 +58,19 @@ double TemperatureController::getTemperature(int deviceId, float currentPower)
|
|||||||
PRINTDEBUGMESSAGE(name(), "Temperature requested by device " + std::to_string(
|
PRINTDEBUGMESSAGE(name(), "Temperature requested by device " + std::to_string(
|
||||||
deviceId) + " current power is " + std::to_string(currentPower));
|
deviceId) + " current power is " + std::to_string(currentPower));
|
||||||
|
|
||||||
if (dynamicTempSimEnabled) {
|
if (dynamicTempSimEnabled)
|
||||||
|
{
|
||||||
currentPowerValues.at(deviceId) = currentPower;
|
currentPowerValues.at(deviceId) = currentPower;
|
||||||
checkPowerThreshold(deviceId);
|
checkPowerThreshold(deviceId);
|
||||||
|
|
||||||
// FIXME using the static temperature value until the vector of
|
// FIXME: using the static temperature value until the vector of temperatures is filled
|
||||||
// temperatures is filled
|
|
||||||
if (temperatureValues.empty())
|
if (temperatureValues.empty())
|
||||||
return temperatureConvert(staticTemperature + 273.15);
|
return temperatureConvert(staticTemperature + 273.15);
|
||||||
|
|
||||||
return temperatureConvert(temperatureValues.at(deviceId));
|
return temperatureConvert(temperatureValues.at(deviceId));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
PRINTDEBUGMESSAGE(name(), "Temperature is " + std::to_string(staticTemperature));
|
PRINTDEBUGMESSAGE(name(), "Temperature is " + std::to_string(staticTemperature));
|
||||||
return staticTemperature;
|
return staticTemperature;
|
||||||
}
|
}
|
||||||
@@ -138,13 +140,16 @@ double TemperatureController::adjustThermalSimPeriod()
|
|||||||
// again in steps of 'n/2' until it achieves the desired value given by
|
// again in steps of 'n/2' until it achieves the desired value given by
|
||||||
// configuration or the described in 1.1 occurs.
|
// configuration or the described in 1.1 occurs.
|
||||||
|
|
||||||
if (decreaseSimPeriod) {
|
if (decreaseSimPeriod)
|
||||||
|
{
|
||||||
period = period / periodAdjustFactor;
|
period = period / periodAdjustFactor;
|
||||||
cyclesSinceLastPeriodAdjust = 0;
|
cyclesSinceLastPeriodAdjust = 0;
|
||||||
decreaseSimPeriod = false;
|
decreaseSimPeriod = false;
|
||||||
PRINTDEBUGMESSAGE(name(), "Thermal Simulation period reduced to " + std::to_string(
|
PRINTDEBUGMESSAGE(name(), "Thermal Simulation period reduced to " + std::to_string(
|
||||||
period) + ". Target is " + std::to_string(targetPeriod));
|
period) + ". Target is " + std::to_string(targetPeriod));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (period != targetPeriod) {
|
if (period != targetPeriod) {
|
||||||
cyclesSinceLastPeriodAdjust++;
|
cyclesSinceLastPeriodAdjust++;
|
||||||
if (cyclesSinceLastPeriodAdjust >= nPowStableCyclesToIncreasePeriod) {
|
if (cyclesSinceLastPeriodAdjust >= nPowStableCyclesToIncreasePeriod) {
|
||||||
@@ -163,7 +168,8 @@ double TemperatureController::adjustThermalSimPeriod()
|
|||||||
|
|
||||||
void TemperatureController::temperatureThread()
|
void TemperatureController::temperatureThread()
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true)
|
||||||
|
{
|
||||||
updateTemperatures();
|
updateTemperatures();
|
||||||
double p = adjustThermalSimPeriod();
|
double p = adjustThermalSimPeriod();
|
||||||
|
|
||||||
|
|||||||
@@ -52,26 +52,23 @@
|
|||||||
class TemperatureController : sc_core::sc_module
|
class TemperatureController : sc_core::sc_module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static inline TemperatureController &getInstance() {
|
TemperatureController(const TemperatureController&) = delete;
|
||||||
static TemperatureController temperaturectrl("TemperatureController");
|
TemperatureController& operator=(const TemperatureController&) = delete;
|
||||||
return temperaturectrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
SC_HAS_PROCESS(TemperatureController);
|
SC_HAS_PROCESS(TemperatureController);
|
||||||
explicit TemperatureController(const sc_core::sc_module_name &name) : sc_core::sc_module(name)
|
TemperatureController() = default;
|
||||||
|
TemperatureController(const sc_core::sc_module_name& name, const Configuration& config) : sc_core::sc_module(name)
|
||||||
{
|
{
|
||||||
temperatureScale = Configuration::getInstance().temperatureSim.temperatureScale;
|
temperatureScale = config.temperatureSim.temperatureScale;
|
||||||
|
dynamicTempSimEnabled = config.thermalSimulation;
|
||||||
|
staticTemperature = config.temperatureSim.staticTemperatureDefaultValue;
|
||||||
|
|
||||||
dynamicTempSimEnabled = Configuration::getInstance().thermalSimulation;
|
if (dynamicTempSimEnabled)
|
||||||
|
{
|
||||||
staticTemperature =
|
|
||||||
Configuration::getInstance().temperatureSim.staticTemperatureDefaultValue;
|
|
||||||
|
|
||||||
if (dynamicTempSimEnabled) {
|
|
||||||
#ifdef THERMALSIM
|
#ifdef THERMALSIM
|
||||||
// Connect to the server
|
// Connect to the server
|
||||||
std::string ip = Configuration::getInstance().temperatureSim.iceServerIp;
|
std::string ip = config.temperatureSim.iceServerIp;
|
||||||
unsigned int port = Configuration::getInstance().temperatureSim.iceServerPort;
|
unsigned int port = config.temperatureSim.iceServerPort;
|
||||||
thermalSimulation = new IceWrapper(ip, port);
|
thermalSimulation = new IceWrapper(ip, port);
|
||||||
PRINTDEBUGMESSAGE(name(), "Dynamic temperature simulation. Server @ "
|
PRINTDEBUGMESSAGE(name(), "Dynamic temperature simulation. Server @ "
|
||||||
+ ip + ":" + std::to_string(port));
|
+ ip + ":" + std::to_string(port));
|
||||||
@@ -80,34 +77,33 @@ public:
|
|||||||
"DRAMSys was build without support to dynamic temperature simulation. Check the README file for further details.");
|
"DRAMSys was build without support to dynamic temperature simulation. Check the README file for further details.");
|
||||||
#endif
|
#endif
|
||||||
// Initial power dissipation values (got from config)
|
// Initial power dissipation values (got from config)
|
||||||
currentPowerValues =
|
currentPowerValues = config.temperatureSim.powerInitialValues;
|
||||||
Configuration::getInstance().temperatureSim.powerInitialValues;
|
|
||||||
lastPowerValues = currentPowerValues;
|
lastPowerValues = currentPowerValues;
|
||||||
|
|
||||||
// Substantial changes in power will trigger adjustments in the simulaiton period. Get the thresholds from config.
|
// Substantial changes in power will trigger adjustments in the simulaiton period. Get the thresholds from config.
|
||||||
powerThresholds = Configuration::getInstance().temperatureSim.powerThresholds;
|
powerThresholds = config.temperatureSim.powerThresholds;
|
||||||
decreaseSimPeriod = false;
|
decreaseSimPeriod = false;
|
||||||
periodAdjustFactor =
|
periodAdjustFactor = config.temperatureSim.simPeriodAdjustFactor;
|
||||||
Configuration::getInstance().temperatureSim.simPeriodAdjustFactor;
|
nPowStableCyclesToIncreasePeriod = config.temperatureSim.nPowStableCyclesToIncreasePeriod;
|
||||||
nPowStableCyclesToIncreasePeriod =
|
|
||||||
Configuration::getInstance().temperatureSim.nPowStableCyclesToIncreasePeriod;
|
|
||||||
cyclesSinceLastPeriodAdjust = 0;
|
cyclesSinceLastPeriodAdjust = 0;
|
||||||
|
|
||||||
// Get the target period for the thermal simulation from config.
|
// Get the target period for the thermal simulation from config.
|
||||||
targetPeriod = Configuration::getInstance().temperatureSim.thermalSimPeriod;
|
targetPeriod = config.temperatureSim.thermalSimPeriod;
|
||||||
period = targetPeriod;
|
period = targetPeriod;
|
||||||
t_unit = Configuration::getInstance().temperatureSim.thermalSimUnit;
|
t_unit = config.temperatureSim.thermalSimUnit;
|
||||||
|
|
||||||
genTempMap = Configuration::getInstance().temperatureSim.generateTemperatureMap;
|
genTempMap = config.temperatureSim.generateTemperatureMap;
|
||||||
temperatureMapFile = "temperature_map";
|
temperatureMapFile = "temperature_map";
|
||||||
std::system("rm -f temperature_map*");
|
std::system("rm -f temperature_map*");
|
||||||
|
|
||||||
genPowerMap = Configuration::getInstance().temperatureSim.generatePowerMap;
|
genPowerMap = config.temperatureSim.generatePowerMap;
|
||||||
powerMapFile = "power_map";
|
powerMapFile = "power_map";
|
||||||
std::system("rm -f power_map*");
|
std::system("rm -f power_map*");
|
||||||
|
|
||||||
SC_THREAD(temperatureThread);
|
SC_THREAD(temperatureThread);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
PRINTDEBUGMESSAGE(sc_module::name(), "Static temperature simulation. Temperature set to " +
|
PRINTDEBUGMESSAGE(sc_module::name(), "Static temperature simulation. Temperature set to " +
|
||||||
std::to_string(staticTemperature));
|
std::to_string(staticTemperature));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,16 +62,14 @@ using namespace sc_core;
|
|||||||
using namespace tlm;
|
using namespace tlm;
|
||||||
using namespace DRAMPower;
|
using namespace DRAMPower;
|
||||||
|
|
||||||
Dram::Dram(const sc_module_name &name) : sc_module(name), tSocket("socket")
|
Dram::Dram(const sc_module_name& name, const Configuration& config)
|
||||||
|
: sc_module(name), memSpec(*config.memSpec), tSocket("socket"), storeMode(config.storeMode),
|
||||||
|
powerAnalysis(config.powerAnalysis), useMalloc(config.useMalloc)
|
||||||
{
|
{
|
||||||
Configuration &config = Configuration::getInstance();
|
uint64_t channelSize = memSpec.getSimMemSizeInBytes() / memSpec.numberOfChannels;
|
||||||
|
|
||||||
storeMode = config.storeMode;
|
|
||||||
|
|
||||||
uint64_t channelSize = config.memSpec->getSimMemSizeInBytes() / config.memSpec->numberOfChannels;
|
|
||||||
if (storeMode == Configuration::StoreMode::Store)
|
if (storeMode == Configuration::StoreMode::Store)
|
||||||
{
|
{
|
||||||
if (config.useMalloc)
|
if (useMalloc)
|
||||||
{
|
{
|
||||||
memory = (unsigned char *)malloc(channelSize);
|
memory = (unsigned char *)malloc(channelSize);
|
||||||
if (!memory)
|
if (!memory)
|
||||||
@@ -95,7 +93,7 @@ Dram::Dram(const sc_module_name &name) : sc_module(name), tSocket("socket")
|
|||||||
|
|
||||||
Dram::~Dram()
|
Dram::~Dram()
|
||||||
{
|
{
|
||||||
if (Configuration::getInstance().useMalloc)
|
if (useMalloc)
|
||||||
free(memory);
|
free(memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,14 +106,14 @@ void Dram::reportPower()
|
|||||||
std::cout << name() << std::string(" Total Energy: ")
|
std::cout << name() << std::string(" Total Energy: ")
|
||||||
<< std::fixed << std::setprecision( 2 )
|
<< std::fixed << std::setprecision( 2 )
|
||||||
<< DRAMPower->getEnergy().total_energy
|
<< DRAMPower->getEnergy().total_energy
|
||||||
* Configuration::getInstance().memSpec->devicesPerRank
|
* memSpec.devicesPerRank
|
||||||
<< std::string(" pJ")
|
<< std::string(" pJ")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
std::cout << name() << std::string(" Average Power: ")
|
std::cout << name() << std::string(" Average Power: ")
|
||||||
<< std::fixed << std::setprecision( 2 )
|
<< std::fixed << std::setprecision( 2 )
|
||||||
<< DRAMPower->getPower().average_power
|
<< DRAMPower->getPower().average_power
|
||||||
* Configuration::getInstance().memSpec->devicesPerRank
|
* memSpec.devicesPerRank
|
||||||
<< std::string(" mW") << std::endl;
|
<< std::string(" mW") << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,10 +122,10 @@ tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload,
|
|||||||
{
|
{
|
||||||
assert(phase >= BEGIN_RD && phase <= END_SREF);
|
assert(phase >= BEGIN_RD && phase <= END_SREF);
|
||||||
|
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (powerAnalysis)
|
||||||
{
|
{
|
||||||
int bank = static_cast<int>(DramExtension::getExtension(payload).getBank().ID());
|
int bank = static_cast<int>(DramExtension::getExtension(payload).getBank().ID());
|
||||||
int64_t cycle = std::lround((sc_time_stamp() + delay) / memSpec->tCK);
|
int64_t cycle = std::lround((sc_time_stamp() + delay) / memSpec.tCK);
|
||||||
DRAMPower->doCommand(phaseToDRAMPowerCommand(phase), bank, cycle);
|
DRAMPower->doCommand(phaseToDRAMPowerCommand(phase), bank, cycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,15 +52,16 @@
|
|||||||
class Dram : public sc_core::sc_module
|
class Dram : public sc_core::sc_module
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
explicit Dram(const sc_core::sc_module_name &name);
|
Dram(const sc_core::sc_module_name &name, const Configuration& config);
|
||||||
SC_HAS_PROCESS(Dram);
|
SC_HAS_PROCESS(Dram);
|
||||||
|
|
||||||
const MemSpec *memSpec = Configuration::getInstance().memSpec;
|
const MemSpec& memSpec;
|
||||||
|
|
||||||
// Data Storage:
|
// Data Storage:
|
||||||
Configuration::StoreMode storeMode;
|
Configuration::StoreMode storeMode;
|
||||||
|
bool powerAnalysis;
|
||||||
unsigned char *memory;
|
unsigned char *memory;
|
||||||
|
bool useMalloc;
|
||||||
|
|
||||||
std::unique_ptr<libDRAMPower> DRAMPower;
|
std::unique_ptr<libDRAMPower> DRAMPower;
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "DramDDR3.h"
|
#include "DramDDR3.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "../../configuration/Configuration.h"
|
#include "../../configuration/Configuration.h"
|
||||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||||
#include "../../configuration/memspec/MemSpecDDR3.h"
|
#include "../../configuration/memspec/MemSpecDDR3.h"
|
||||||
@@ -41,103 +43,105 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace DRAMPower;
|
using namespace DRAMPower;
|
||||||
|
|
||||||
DramDDR3::DramDDR3(const sc_module_name &name) : Dram(name)
|
DramDDR3::DramDDR3(const sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController)
|
||||||
|
: Dram(name, config)
|
||||||
{
|
{
|
||||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||||
SC_REPORT_FATAL("DramDDR3", "Error Model not supported for DDR3");
|
SC_REPORT_FATAL("DramDDR3", "Error Model not supported for DDR3");
|
||||||
|
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (powerAnalysis)
|
||||||
{
|
{
|
||||||
const auto *memSpec = dynamic_cast<const MemSpecDDR3 *>(this->memSpec);
|
const auto *memSpecDDR3 = dynamic_cast<const MemSpecDDR3*>(config.memSpec.get());
|
||||||
if (memSpec == nullptr)
|
if (memSpecDDR3 == nullptr)
|
||||||
SC_REPORT_FATAL("DramDDR3", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("DramDDR3", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
MemArchitectureSpec memArchSpec;
|
MemArchitectureSpec memArchSpec;
|
||||||
memArchSpec.burstLength = memSpec->defaultBurstLength;
|
memArchSpec.burstLength = memSpecDDR3->defaultBurstLength;
|
||||||
memArchSpec.dataRate = memSpec->dataRate;
|
memArchSpec.dataRate = memSpecDDR3->dataRate;
|
||||||
memArchSpec.nbrOfRows = memSpec->rowsPerBank;
|
memArchSpec.nbrOfRows = memSpecDDR3->rowsPerBank;
|
||||||
memArchSpec.nbrOfBanks = memSpec->banksPerChannel;
|
memArchSpec.nbrOfBanks = memSpecDDR3->banksPerChannel;
|
||||||
memArchSpec.nbrOfColumns = memSpec->columnsPerRow;
|
memArchSpec.nbrOfColumns = memSpecDDR3->columnsPerRow;
|
||||||
memArchSpec.nbrOfRanks = memSpec->ranksPerChannel;
|
memArchSpec.nbrOfRanks = memSpecDDR3->ranksPerChannel;
|
||||||
memArchSpec.width = memSpec->bitWidth;
|
memArchSpec.width = memSpecDDR3->bitWidth;
|
||||||
memArchSpec.nbrOfBankGroups = memSpec->bankGroupsPerChannel;
|
memArchSpec.nbrOfBankGroups = memSpecDDR3->bankGroupsPerChannel;
|
||||||
memArchSpec.twoVoltageDomains = false;
|
memArchSpec.twoVoltageDomains = false;
|
||||||
memArchSpec.dll = true;
|
memArchSpec.dll = true;
|
||||||
|
|
||||||
MemTimingSpec memTimingSpec;
|
MemTimingSpec memTimingSpec;
|
||||||
//FIXME: memTimingSpec.FAWB = memSpec->tFAW / memSpec->tCK;
|
//FIXME: memTimingSpec.FAWB = memSpecDDR3->tFAW / memSpecDDR3->tCK;
|
||||||
//FIXME: memTimingSpec.RASB = memSpec->tRAS / memSpec->tCK;
|
//FIXME: memTimingSpec.RASB = memSpecDDR3->tRAS / memSpecDDR3->tCK;
|
||||||
//FIXME: memTimingSpec.RCB = memSpec->tRC / memSpec->tCK;
|
//FIXME: memTimingSpec.RCB = memSpecDDR3->tRC / memSpecDDR3->tCK;
|
||||||
//FIXME: memTimingSpec.RPB = memSpec->tRP / memSpec->tCK;
|
//FIXME: memTimingSpec.RPB = memSpecDDR3->tRP / memSpecDDR3->tCK;
|
||||||
//FIXME: memTimingSpec.RRDB = memSpec->tRRD / memSpec->tCK;
|
//FIXME: memTimingSpec.RRDB = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||||
//FIXME: memTimingSpec.RRDB_L = memSpec->tRRD / memSpec->tCK;
|
//FIXME: memTimingSpec.RRDB_L = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||||
//FIXME: memTimingSpec.RRDB_S = memSpec->tRRD / memSpec->tCK;
|
//FIXME: memTimingSpec.RRDB_S = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||||
memTimingSpec.AL = memSpec->tAL / memSpec->tCK;
|
memTimingSpec.AL = memSpecDDR3->tAL / memSpecDDR3->tCK;
|
||||||
memTimingSpec.CCD = memSpec->tCCD / memSpec->tCK;
|
memTimingSpec.CCD = memSpecDDR3->tCCD / memSpecDDR3->tCK;
|
||||||
memTimingSpec.CCD_L = memSpec->tCCD / memSpec->tCK;
|
memTimingSpec.CCD_L = memSpecDDR3->tCCD / memSpecDDR3->tCK;
|
||||||
memTimingSpec.CCD_S = memSpec->tCCD / memSpec->tCK;
|
memTimingSpec.CCD_S = memSpecDDR3->tCCD / memSpecDDR3->tCK;
|
||||||
memTimingSpec.CKE = memSpec->tCKE / memSpec->tCK;
|
memTimingSpec.CKE = memSpecDDR3->tCKE / memSpecDDR3->tCK;
|
||||||
memTimingSpec.CKESR = memSpec->tCKESR / memSpec->tCK;
|
memTimingSpec.CKESR = memSpecDDR3->tCKESR / memSpecDDR3->tCK;
|
||||||
memTimingSpec.clkMhz = memSpec->fCKMHz;
|
memTimingSpec.clkMhz = memSpecDDR3->fCKMHz;
|
||||||
// See also MemTimingSpec.cc in DRAMPower
|
// See also MemTimingSpec.cc in DRAMPower
|
||||||
memTimingSpec.clkPeriod = 1000.0 / memSpec->fCKMHz;
|
memTimingSpec.clkPeriod = 1000.0 / memSpecDDR3->fCKMHz;
|
||||||
memTimingSpec.DQSCK = memSpec->tDQSCK / memSpec->tCK;
|
memTimingSpec.DQSCK = memSpecDDR3->tDQSCK / memSpecDDR3->tCK;
|
||||||
memTimingSpec.FAW = memSpec->tFAW / memSpec->tCK;
|
memTimingSpec.FAW = memSpecDDR3->tFAW / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RAS = memSpec->tRAS / memSpec->tCK;
|
memTimingSpec.RAS = memSpecDDR3->tRAS / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RC = memSpec->tRC / memSpec->tCK;
|
memTimingSpec.RC = memSpecDDR3->tRC / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RCD = memSpec->tRCD / memSpec->tCK;
|
memTimingSpec.RCD = memSpecDDR3->tRCD / memSpecDDR3->tCK;
|
||||||
memTimingSpec.REFI = memSpec->tREFI / memSpec->tCK;
|
memTimingSpec.REFI = memSpecDDR3->tREFI / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RFC = memSpec->tRFC / memSpec->tCK;
|
memTimingSpec.RFC = memSpecDDR3->tRFC / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RL = memSpec->tRL / memSpec->tCK;
|
memTimingSpec.RL = memSpecDDR3->tRL / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RP = memSpec->tRP / memSpec->tCK;
|
memTimingSpec.RP = memSpecDDR3->tRP / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RRD = memSpec->tRRD / memSpec->tCK;
|
memTimingSpec.RRD = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RRD_L = memSpec->tRRD / memSpec->tCK;
|
memTimingSpec.RRD_L = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RRD_S = memSpec->tRRD / memSpec->tCK;
|
memTimingSpec.RRD_S = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||||
memTimingSpec.RTP = memSpec->tRTP / memSpec->tCK;
|
memTimingSpec.RTP = memSpecDDR3->tRTP / memSpecDDR3->tCK;
|
||||||
memTimingSpec.TAW = memSpec->tFAW / memSpec->tCK;
|
memTimingSpec.TAW = memSpecDDR3->tFAW / memSpecDDR3->tCK;
|
||||||
memTimingSpec.WL = memSpec->tWL / memSpec->tCK;
|
memTimingSpec.WL = memSpecDDR3->tWL / memSpecDDR3->tCK;
|
||||||
memTimingSpec.WR = memSpec->tWR / memSpec->tCK;
|
memTimingSpec.WR = memSpecDDR3->tWR / memSpecDDR3->tCK;
|
||||||
memTimingSpec.WTR = memSpec->tWTR / memSpec->tCK;
|
memTimingSpec.WTR = memSpecDDR3->tWTR / memSpecDDR3->tCK;
|
||||||
memTimingSpec.WTR_L = memSpec->tWTR / memSpec->tCK;
|
memTimingSpec.WTR_L = memSpecDDR3->tWTR / memSpecDDR3->tCK;
|
||||||
memTimingSpec.WTR_S = memSpec->tWTR / memSpec->tCK;
|
memTimingSpec.WTR_S = memSpecDDR3->tWTR / memSpecDDR3->tCK;
|
||||||
memTimingSpec.XP = memSpec->tXP / memSpec->tCK;
|
memTimingSpec.XP = memSpecDDR3->tXP / memSpecDDR3->tCK;
|
||||||
memTimingSpec.XPDLL = memSpec->tXPDLL / memSpec->tCK;
|
memTimingSpec.XPDLL = memSpecDDR3->tXPDLL / memSpecDDR3->tCK;
|
||||||
memTimingSpec.XS = memSpec->tXS / memSpec->tCK;
|
memTimingSpec.XS = memSpecDDR3->tXS / memSpecDDR3->tCK;
|
||||||
memTimingSpec.XSDLL = memSpec->tXSDLL / memSpec->tCK;
|
memTimingSpec.XSDLL = memSpecDDR3->tXSDLL / memSpecDDR3->tCK;
|
||||||
|
|
||||||
MemPowerSpec memPowerSpec;
|
MemPowerSpec memPowerSpec;
|
||||||
memPowerSpec.idd0 = memSpec->iDD0;
|
memPowerSpec.idd0 = memSpecDDR3->iDD0;
|
||||||
memPowerSpec.idd02 = 0;
|
memPowerSpec.idd02 = 0;
|
||||||
memPowerSpec.idd2p0 = memSpec->iDD2P0;
|
memPowerSpec.idd2p0 = memSpecDDR3->iDD2P0;
|
||||||
memPowerSpec.idd2p02 = 0;
|
memPowerSpec.idd2p02 = 0;
|
||||||
memPowerSpec.idd2p1 = memSpec->iDD2P1;
|
memPowerSpec.idd2p1 = memSpecDDR3->iDD2P1;
|
||||||
memPowerSpec.idd2p12 = 0;
|
memPowerSpec.idd2p12 = 0;
|
||||||
memPowerSpec.idd2n = memSpec->iDD2N;
|
memPowerSpec.idd2n = memSpecDDR3->iDD2N;
|
||||||
memPowerSpec.idd2n2 = 0;
|
memPowerSpec.idd2n2 = 0;
|
||||||
memPowerSpec.idd3p0 = memSpec->iDD3P0;
|
memPowerSpec.idd3p0 = memSpecDDR3->iDD3P0;
|
||||||
memPowerSpec.idd3p02 = 0;
|
memPowerSpec.idd3p02 = 0;
|
||||||
memPowerSpec.idd3p1 = memSpec->iDD3P1;
|
memPowerSpec.idd3p1 = memSpecDDR3->iDD3P1;
|
||||||
memPowerSpec.idd3p12 = 0;
|
memPowerSpec.idd3p12 = 0;
|
||||||
memPowerSpec.idd3n = memSpec->iDD3N;
|
memPowerSpec.idd3n = memSpecDDR3->iDD3N;
|
||||||
memPowerSpec.idd3n2 = 0;
|
memPowerSpec.idd3n2 = 0;
|
||||||
memPowerSpec.idd4r = memSpec->iDD4R;
|
memPowerSpec.idd4r = memSpecDDR3->iDD4R;
|
||||||
memPowerSpec.idd4r2 = 0;
|
memPowerSpec.idd4r2 = 0;
|
||||||
memPowerSpec.idd4w = memSpec->iDD4W;
|
memPowerSpec.idd4w = memSpecDDR3->iDD4W;
|
||||||
memPowerSpec.idd4w2 = 0;
|
memPowerSpec.idd4w2 = 0;
|
||||||
memPowerSpec.idd5 = memSpec->iDD5;
|
memPowerSpec.idd5 = memSpecDDR3->iDD5;
|
||||||
memPowerSpec.idd52 = 0;
|
memPowerSpec.idd52 = 0;
|
||||||
memPowerSpec.idd6 = memSpec->iDD6;
|
memPowerSpec.idd6 = memSpecDDR3->iDD6;
|
||||||
memPowerSpec.idd62 = 0;
|
memPowerSpec.idd62 = 0;
|
||||||
memPowerSpec.vdd = memSpec->vDD;
|
memPowerSpec.vdd = memSpecDDR3->vDD;
|
||||||
memPowerSpec.vdd2 = 0;
|
memPowerSpec.vdd2 = 0;
|
||||||
|
|
||||||
MemorySpecification powerSpec;
|
MemorySpecification powerSpec;
|
||||||
powerSpec.id = memSpec->memoryId;
|
powerSpec.id = memSpecDDR3->memoryId;
|
||||||
powerSpec.memoryType = MemoryType::DDR3;
|
powerSpec.memoryType = MemoryType::DDR3;
|
||||||
powerSpec.memTimingSpec = memTimingSpec;
|
powerSpec.memTimingSpec = memTimingSpec;
|
||||||
powerSpec.memPowerSpec = memPowerSpec;
|
powerSpec.memPowerSpec = memPowerSpec;
|
||||||
powerSpec.memArchSpec = memArchSpec;
|
powerSpec.memArchSpec = memArchSpec;
|
||||||
|
|
||||||
DRAMPower = std::unique_ptr<libDRAMPower>(new libDRAMPower(powerSpec, false));
|
DRAMPower = std::make_unique<libDRAMPower>(powerSpec, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,15 @@
|
|||||||
#define DRAMDDR3_H
|
#define DRAMDDR3_H
|
||||||
|
|
||||||
#include <systemc>
|
#include <systemc>
|
||||||
|
|
||||||
#include "Dram.h"
|
#include "Dram.h"
|
||||||
|
#include "../TemperatureController.h"
|
||||||
|
|
||||||
class DramDDR3 : public Dram
|
class DramDDR3 : public Dram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DramDDR3(const sc_core::sc_module_name&);
|
DramDDR3(const sc_core::sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController);
|
||||||
SC_HAS_PROCESS(DramDDR3);
|
SC_HAS_PROCESS(DramDDR3);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "DramDDR4.h"
|
#include "DramDDR4.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "../../configuration/Configuration.h"
|
#include "../../configuration/Configuration.h"
|
||||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||||
#include "../../configuration/memspec/MemSpecDDR4.h"
|
#include "../../configuration/memspec/MemSpecDDR4.h"
|
||||||
@@ -41,103 +43,105 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace DRAMPower;
|
using namespace DRAMPower;
|
||||||
|
|
||||||
DramDDR4::DramDDR4(const sc_module_name &name) : Dram(name)
|
DramDDR4::DramDDR4(const sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController)
|
||||||
|
: Dram(name, config)
|
||||||
{
|
{
|
||||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||||
SC_REPORT_FATAL("DramDDR4", "Error Model not supported for DDR4");
|
SC_REPORT_FATAL("DramDDR4", "Error Model not supported for DDR4");
|
||||||
|
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (powerAnalysis)
|
||||||
{
|
{
|
||||||
const auto *memSpec = dynamic_cast<const MemSpecDDR4 *>(this->memSpec);
|
const auto *memSpecDDR4 = dynamic_cast<const MemSpecDDR4*>(config.memSpec.get());
|
||||||
if (memSpec == nullptr)
|
if (memSpecDDR4 == nullptr)
|
||||||
SC_REPORT_FATAL("DramDDR4", "Wrong MemSpec chosen");
|
SC_REPORT_FATAL("DramDDR4", "Wrong MemSpec chosen");
|
||||||
|
|
||||||
MemArchitectureSpec memArchSpec;
|
MemArchitectureSpec memArchSpec;
|
||||||
memArchSpec.burstLength = memSpec->defaultBurstLength;
|
memArchSpec.burstLength = memSpecDDR4->defaultBurstLength;
|
||||||
memArchSpec.dataRate = memSpec->dataRate;
|
memArchSpec.dataRate = memSpecDDR4->dataRate;
|
||||||
memArchSpec.nbrOfRows = memSpec->rowsPerBank;
|
memArchSpec.nbrOfRows = memSpecDDR4->rowsPerBank;
|
||||||
memArchSpec.nbrOfBanks = memSpec->banksPerChannel;
|
memArchSpec.nbrOfBanks = memSpecDDR4->banksPerChannel;
|
||||||
memArchSpec.nbrOfColumns = memSpec->columnsPerRow;
|
memArchSpec.nbrOfColumns = memSpecDDR4->columnsPerRow;
|
||||||
memArchSpec.nbrOfRanks = memSpec->ranksPerChannel;
|
memArchSpec.nbrOfRanks = memSpecDDR4->ranksPerChannel;
|
||||||
memArchSpec.width = memSpec->bitWidth;
|
memArchSpec.width = memSpecDDR4->bitWidth;
|
||||||
memArchSpec.nbrOfBankGroups = memSpec->bankGroupsPerChannel;
|
memArchSpec.nbrOfBankGroups = memSpecDDR4->bankGroupsPerChannel;
|
||||||
memArchSpec.twoVoltageDomains = true;
|
memArchSpec.twoVoltageDomains = true;
|
||||||
memArchSpec.dll = true;
|
memArchSpec.dll = true;
|
||||||
|
|
||||||
MemTimingSpec memTimingSpec;
|
MemTimingSpec memTimingSpec;
|
||||||
//FIXME: memTimingSpec.FAWB = memSpec->tFAW / memSpec->tCK;
|
//FIXME: memTimingSpec.FAWB = memSpecDDR4->tFAW / memSpecDDR4->tCK;
|
||||||
//FIXME: memTimingSpec.RASB = memSpec->tRAS / memSpec->tCK;
|
//FIXME: memTimingSpec.RASB = memSpecDDR4->tRAS / memSpecDDR4->tCK;
|
||||||
//FIXME: memTimingSpec.RCB = memSpec->tRC / memSpec->tCK;
|
//FIXME: memTimingSpec.RCB = memSpecDDR4->tRC / memSpecDDR4->tCK;
|
||||||
//FIXME: memTimingSpec.RPB = memSpec->tRP / memSpec->tCK;
|
//FIXME: memTimingSpec.RPB = memSpecDDR4->tRP / memSpecDDR4->tCK;
|
||||||
//FIXME: memTimingSpec.RRDB = memSpec->tRRD_S / memSpec->tCK;
|
//FIXME: memTimingSpec.RRDB = memSpecDDR4->tRRD_S / memSpecDDR4->tCK;
|
||||||
//FIXME: memTimingSpec.RRDB_L = memSpec->tRRD_L / memSpec->tCK;
|
//FIXME: memTimingSpec.RRDB_L = memSpecDDR4->tRRD_L / memSpecDDR4->tCK;
|
||||||
//FIXME: memTimingSpec.RRDB_S = memSpec->tRRD_S / memSpec->tCK;
|
//FIXME: memTimingSpec.RRDB_S = memSpecDDR4->tRRD_S / memSpecDDR4->tCK;
|
||||||
memTimingSpec.AL = memSpec->tAL / memSpec->tCK;
|
memTimingSpec.AL = memSpecDDR4->tAL / memSpecDDR4->tCK;
|
||||||
memTimingSpec.CCD = memSpec->tCCD_S / memSpec->tCK;
|
memTimingSpec.CCD = memSpecDDR4->tCCD_S / memSpecDDR4->tCK;
|
||||||
memTimingSpec.CCD_L = memSpec->tCCD_L / memSpec->tCK;
|
memTimingSpec.CCD_L = memSpecDDR4->tCCD_L / memSpecDDR4->tCK;
|
||||||
memTimingSpec.CCD_S = memSpec->tCCD_S / memSpec->tCK;
|
memTimingSpec.CCD_S = memSpecDDR4->tCCD_S / memSpecDDR4->tCK;
|
||||||
memTimingSpec.CKE = memSpec->tCKE / memSpec->tCK;
|
memTimingSpec.CKE = memSpecDDR4->tCKE / memSpecDDR4->tCK;
|
||||||
memTimingSpec.CKESR = memSpec->tCKESR / memSpec->tCK;
|
memTimingSpec.CKESR = memSpecDDR4->tCKESR / memSpecDDR4->tCK;
|
||||||
memTimingSpec.clkMhz = memSpec->fCKMHz;
|
memTimingSpec.clkMhz = memSpecDDR4->fCKMHz;
|
||||||
// See also MemTimingSpec.cc in DRAMPower
|
// See also MemTimingSpec.cc in DRAMPower
|
||||||
memTimingSpec.clkPeriod = 1000.0 / memSpec->fCKMHz;
|
memTimingSpec.clkPeriod = 1000.0 / memSpecDDR4->fCKMHz;
|
||||||
memTimingSpec.DQSCK = memSpec->tDQSCK / memSpec->tCK;
|
memTimingSpec.DQSCK = memSpecDDR4->tDQSCK / memSpecDDR4->tCK;
|
||||||
memTimingSpec.FAW = memSpec->tFAW / memSpec->tCK;
|
memTimingSpec.FAW = memSpecDDR4->tFAW / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RAS = memSpec->tRAS / memSpec->tCK;
|
memTimingSpec.RAS = memSpecDDR4->tRAS / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RC = memSpec->tRC / memSpec->tCK;
|
memTimingSpec.RC = memSpecDDR4->tRC / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RCD = memSpec->tRCD / memSpec->tCK;
|
memTimingSpec.RCD = memSpecDDR4->tRCD / memSpecDDR4->tCK;
|
||||||
memTimingSpec.REFI = memSpec->tREFI / memSpec->tCK;
|
memTimingSpec.REFI = memSpecDDR4->tREFI / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RFC = memSpec->tRFC / memSpec->tCK;
|
memTimingSpec.RFC = memSpecDDR4->tRFC / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RL = memSpec->tRL / memSpec->tCK;
|
memTimingSpec.RL = memSpecDDR4->tRL / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RP = memSpec->tRP / memSpec->tCK;
|
memTimingSpec.RP = memSpecDDR4->tRP / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RRD = memSpec->tRRD_S / memSpec->tCK;
|
memTimingSpec.RRD = memSpecDDR4->tRRD_S / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RRD_L = memSpec->tRRD_L / memSpec->tCK;
|
memTimingSpec.RRD_L = memSpecDDR4->tRRD_L / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RRD_S = memSpec->tRRD_S / memSpec->tCK;
|
memTimingSpec.RRD_S = memSpecDDR4->tRRD_S / memSpecDDR4->tCK;
|
||||||
memTimingSpec.RTP = memSpec->tRTP / memSpec->tCK;
|
memTimingSpec.RTP = memSpecDDR4->tRTP / memSpecDDR4->tCK;
|
||||||
memTimingSpec.TAW = memSpec->tFAW / memSpec->tCK;
|
memTimingSpec.TAW = memSpecDDR4->tFAW / memSpecDDR4->tCK;
|
||||||
memTimingSpec.WL = memSpec->tWL / memSpec->tCK;
|
memTimingSpec.WL = memSpecDDR4->tWL / memSpecDDR4->tCK;
|
||||||
memTimingSpec.WR = memSpec->tWR / memSpec->tCK;
|
memTimingSpec.WR = memSpecDDR4->tWR / memSpecDDR4->tCK;
|
||||||
memTimingSpec.WTR = memSpec->tWTR_S / memSpec->tCK;
|
memTimingSpec.WTR = memSpecDDR4->tWTR_S / memSpecDDR4->tCK;
|
||||||
memTimingSpec.WTR_L = memSpec->tWTR_L / memSpec->tCK;
|
memTimingSpec.WTR_L = memSpecDDR4->tWTR_L / memSpecDDR4->tCK;
|
||||||
memTimingSpec.WTR_S = memSpec->tWTR_S / memSpec->tCK;
|
memTimingSpec.WTR_S = memSpecDDR4->tWTR_S / memSpecDDR4->tCK;
|
||||||
memTimingSpec.XP = memSpec->tXP / memSpec->tCK;
|
memTimingSpec.XP = memSpecDDR4->tXP / memSpecDDR4->tCK;
|
||||||
memTimingSpec.XPDLL = memSpec->tXPDLL / memSpec->tCK;
|
memTimingSpec.XPDLL = memSpecDDR4->tXPDLL / memSpecDDR4->tCK;
|
||||||
memTimingSpec.XS = memSpec->tXS / memSpec->tCK;
|
memTimingSpec.XS = memSpecDDR4->tXS / memSpecDDR4->tCK;
|
||||||
memTimingSpec.XSDLL = memSpec->tXSDLL / memSpec->tCK;
|
memTimingSpec.XSDLL = memSpecDDR4->tXSDLL / memSpecDDR4->tCK;
|
||||||
|
|
||||||
MemPowerSpec memPowerSpec;
|
MemPowerSpec memPowerSpec;
|
||||||
memPowerSpec.idd0 = memSpec->iDD0;
|
memPowerSpec.idd0 = memSpecDDR4->iDD0;
|
||||||
memPowerSpec.idd02 = memSpec->iDD02;
|
memPowerSpec.idd02 = memSpecDDR4->iDD02;
|
||||||
memPowerSpec.idd2p0 = memSpec->iDD2P0;
|
memPowerSpec.idd2p0 = memSpecDDR4->iDD2P0;
|
||||||
memPowerSpec.idd2p02 = 0;
|
memPowerSpec.idd2p02 = 0;
|
||||||
memPowerSpec.idd2p1 = memSpec->iDD2P1;
|
memPowerSpec.idd2p1 = memSpecDDR4->iDD2P1;
|
||||||
memPowerSpec.idd2p12 = 0;
|
memPowerSpec.idd2p12 = 0;
|
||||||
memPowerSpec.idd2n = memSpec->iDD2N;
|
memPowerSpec.idd2n = memSpecDDR4->iDD2N;
|
||||||
memPowerSpec.idd2n2 = 0;
|
memPowerSpec.idd2n2 = 0;
|
||||||
memPowerSpec.idd3p0 = memSpec->iDD3P0;
|
memPowerSpec.idd3p0 = memSpecDDR4->iDD3P0;
|
||||||
memPowerSpec.idd3p02 = 0;
|
memPowerSpec.idd3p02 = 0;
|
||||||
memPowerSpec.idd3p1 = memSpec->iDD3P1;
|
memPowerSpec.idd3p1 = memSpecDDR4->iDD3P1;
|
||||||
memPowerSpec.idd3p12 = 0;
|
memPowerSpec.idd3p12 = 0;
|
||||||
memPowerSpec.idd3n = memSpec->iDD3N;
|
memPowerSpec.idd3n = memSpecDDR4->iDD3N;
|
||||||
memPowerSpec.idd3n2 = 0;
|
memPowerSpec.idd3n2 = 0;
|
||||||
memPowerSpec.idd4r = memSpec->iDD4R;
|
memPowerSpec.idd4r = memSpecDDR4->iDD4R;
|
||||||
memPowerSpec.idd4r2 = 0;
|
memPowerSpec.idd4r2 = 0;
|
||||||
memPowerSpec.idd4w = memSpec->iDD4W;
|
memPowerSpec.idd4w = memSpecDDR4->iDD4W;
|
||||||
memPowerSpec.idd4w2 = 0;
|
memPowerSpec.idd4w2 = 0;
|
||||||
memPowerSpec.idd5 = memSpec->iDD5;
|
memPowerSpec.idd5 = memSpecDDR4->iDD5;
|
||||||
memPowerSpec.idd52 = 0;
|
memPowerSpec.idd52 = 0;
|
||||||
memPowerSpec.idd6 = memSpec->iDD6;
|
memPowerSpec.idd6 = memSpecDDR4->iDD6;
|
||||||
memPowerSpec.idd62 = memSpec->iDD62;
|
memPowerSpec.idd62 = memSpecDDR4->iDD62;
|
||||||
memPowerSpec.vdd = memSpec->vDD;
|
memPowerSpec.vdd = memSpecDDR4->vDD;
|
||||||
memPowerSpec.vdd2 = memSpec->vDD2;
|
memPowerSpec.vdd2 = memSpecDDR4->vDD2;
|
||||||
|
|
||||||
MemorySpecification powerSpec;
|
MemorySpecification powerSpec;
|
||||||
powerSpec.id = memSpec->memoryId;
|
powerSpec.id = memSpecDDR4->memoryId;
|
||||||
powerSpec.memoryType = MemoryType::DDR4;
|
powerSpec.memoryType = MemoryType::DDR4;
|
||||||
powerSpec.memTimingSpec = memTimingSpec;
|
powerSpec.memTimingSpec = memTimingSpec;
|
||||||
powerSpec.memPowerSpec = memPowerSpec;
|
powerSpec.memPowerSpec = memPowerSpec;
|
||||||
powerSpec.memArchSpec = memArchSpec;
|
powerSpec.memArchSpec = memArchSpec;
|
||||||
|
|
||||||
DRAMPower = std::unique_ptr<libDRAMPower>(new libDRAMPower(powerSpec, false));
|
DRAMPower = std::make_unique<libDRAMPower>(powerSpec, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,15 @@
|
|||||||
#define DRAMDDR4_H
|
#define DRAMDDR4_H
|
||||||
|
|
||||||
#include <systemc>
|
#include <systemc>
|
||||||
|
|
||||||
#include "Dram.h"
|
#include "Dram.h"
|
||||||
|
#include "../TemperatureController.h"
|
||||||
|
|
||||||
class DramDDR4 : public Dram
|
class DramDDR4 : public Dram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DramDDR4(const sc_core::sc_module_name &name);
|
DramDDR4(const sc_core::sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController);
|
||||||
SC_HAS_PROCESS(DramDDR4);
|
SC_HAS_PROCESS(DramDDR4);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,11 +41,13 @@
|
|||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
using namespace DRAMPower;
|
using namespace DRAMPower;
|
||||||
|
|
||||||
DramDDR5::DramDDR5(const sc_module_name &name) : Dram(name)
|
DramDDR5::DramDDR5(const sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController)
|
||||||
|
: Dram(name, config)
|
||||||
{
|
{
|
||||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||||
SC_REPORT_FATAL("DramDDR5", "Error Model not supported for DDR5");
|
SC_REPORT_FATAL("DramDDR5", "Error Model not supported for DDR5");
|
||||||
|
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (powerAnalysis)
|
||||||
SC_REPORT_FATAL("DramDDR5", "DRAMPower does not support DDR5");
|
SC_REPORT_FATAL("DramDDR5", "DRAMPower does not support DDR5");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,15 @@
|
|||||||
#define DRAMDDR5_H
|
#define DRAMDDR5_H
|
||||||
|
|
||||||
#include <systemc>
|
#include <systemc>
|
||||||
|
|
||||||
#include "Dram.h"
|
#include "Dram.h"
|
||||||
|
#include "../TemperatureController.h"
|
||||||
|
|
||||||
class DramDDR5 : public Dram
|
class DramDDR5 : public Dram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DramDDR5(const sc_core::sc_module_name &name);
|
DramDDR5(const sc_core::sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController);
|
||||||
SC_HAS_PROCESS(DramDDR5);
|
SC_HAS_PROCESS(DramDDR5);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,11 +40,13 @@
|
|||||||
|
|
||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
|
|
||||||
DramGDDR5::DramGDDR5(const sc_module_name &name) : Dram(name)
|
DramGDDR5::DramGDDR5(const sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController)
|
||||||
|
: Dram(name, config)
|
||||||
{
|
{
|
||||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||||
SC_REPORT_FATAL("DramGDDR5", "Error Model not supported for GDDR5");
|
SC_REPORT_FATAL("DramGDDR5", "Error Model not supported for GDDR5");
|
||||||
|
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (powerAnalysis)
|
||||||
SC_REPORT_FATAL("DramGDDR5", "DRAMPower does not support GDDR5");
|
SC_REPORT_FATAL("DramGDDR5", "DRAMPower does not support GDDR5");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,15 @@
|
|||||||
#define DRAMGDDR5_H
|
#define DRAMGDDR5_H
|
||||||
|
|
||||||
#include <systemc>
|
#include <systemc>
|
||||||
|
|
||||||
#include "Dram.h"
|
#include "Dram.h"
|
||||||
|
#include "../TemperatureController.h"
|
||||||
|
|
||||||
class DramGDDR5 : public Dram
|
class DramGDDR5 : public Dram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DramGDDR5(const sc_core::sc_module_name &name);
|
DramGDDR5(const sc_core::sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController);
|
||||||
SC_HAS_PROCESS(DramGDDR5);
|
SC_HAS_PROCESS(DramGDDR5);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,11 +40,13 @@
|
|||||||
|
|
||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
|
|
||||||
DramGDDR5X::DramGDDR5X(const sc_module_name &name) : Dram(name)
|
DramGDDR5X::DramGDDR5X(const sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController)
|
||||||
|
: Dram(name, config)
|
||||||
{
|
{
|
||||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||||
SC_REPORT_FATAL("DramGDDR5X", "Error Model not supported for GDDR5X");
|
SC_REPORT_FATAL("DramGDDR5X", "Error Model not supported for GDDR5X");
|
||||||
|
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (powerAnalysis)
|
||||||
SC_REPORT_FATAL("DramGDDR5X", "DRAMPower does not support GDDR5X");
|
SC_REPORT_FATAL("DramGDDR5X", "DRAMPower does not support GDDR5X");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,15 @@
|
|||||||
#define DRAMGDDR5X_H
|
#define DRAMGDDR5X_H
|
||||||
|
|
||||||
#include <systemc>
|
#include <systemc>
|
||||||
|
|
||||||
#include "Dram.h"
|
#include "Dram.h"
|
||||||
|
#include "../TemperatureController.h"
|
||||||
|
|
||||||
class DramGDDR5X : public Dram
|
class DramGDDR5X : public Dram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DramGDDR5X(const sc_core::sc_module_name &name);
|
DramGDDR5X(const sc_core::sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController);
|
||||||
SC_HAS_PROCESS(DramGDDR5X);
|
SC_HAS_PROCESS(DramGDDR5X);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,11 +40,13 @@
|
|||||||
|
|
||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
|
|
||||||
DramGDDR6::DramGDDR6(const sc_module_name &name) : Dram(name)
|
DramGDDR6::DramGDDR6(const sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController)
|
||||||
|
: Dram(name, config)
|
||||||
{
|
{
|
||||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||||
SC_REPORT_FATAL("DramGDDR6", "Error Model not supported for GDDR6");
|
SC_REPORT_FATAL("DramGDDR6", "Error Model not supported for GDDR6");
|
||||||
|
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (powerAnalysis)
|
||||||
SC_REPORT_FATAL("DramGDDR6", "DRAMPower does not support GDDR6");
|
SC_REPORT_FATAL("DramGDDR6", "DRAMPower does not support GDDR6");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,15 @@
|
|||||||
#define DRAMGDDR6_H
|
#define DRAMGDDR6_H
|
||||||
|
|
||||||
#include <systemc>
|
#include <systemc>
|
||||||
|
|
||||||
#include "Dram.h"
|
#include "Dram.h"
|
||||||
|
#include "../TemperatureController.h"
|
||||||
|
|
||||||
class DramGDDR6 : public Dram
|
class DramGDDR6 : public Dram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DramGDDR6(const sc_core::sc_module_name &name);
|
DramGDDR6(const sc_core::sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController);
|
||||||
SC_HAS_PROCESS(DramGDDR6);
|
SC_HAS_PROCESS(DramGDDR6);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,11 +40,13 @@
|
|||||||
|
|
||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
|
|
||||||
DramHBM2::DramHBM2(const sc_module_name &name) : Dram(name)
|
DramHBM2::DramHBM2(const sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController)
|
||||||
|
: Dram(name, config)
|
||||||
{
|
{
|
||||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||||
SC_REPORT_FATAL("DramHBM2", "Error Model not supported for HBM2");
|
SC_REPORT_FATAL("DramHBM2", "Error Model not supported for HBM2");
|
||||||
|
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (powerAnalysis)
|
||||||
SC_REPORT_FATAL("DramHBM2", "DRAMPower does not support HBM2");
|
SC_REPORT_FATAL("DramHBM2", "DRAMPower does not support HBM2");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,15 @@
|
|||||||
#define DRAMHBM2_H
|
#define DRAMHBM2_H
|
||||||
|
|
||||||
#include <systemc>
|
#include <systemc>
|
||||||
|
|
||||||
#include "Dram.h"
|
#include "Dram.h"
|
||||||
|
#include "../TemperatureController.h"
|
||||||
|
|
||||||
class DramHBM2 : public Dram
|
class DramHBM2 : public Dram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DramHBM2(const sc_core::sc_module_name &name);
|
DramHBM2(const sc_core::sc_module_name &name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController);
|
||||||
SC_HAS_PROCESS(DramHBM2);
|
SC_HAS_PROCESS(DramHBM2);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,11 +40,13 @@
|
|||||||
|
|
||||||
using namespace sc_core;
|
using namespace sc_core;
|
||||||
|
|
||||||
DramLPDDR4::DramLPDDR4(const sc_module_name &name) : Dram(name)
|
DramLPDDR4::DramLPDDR4(const sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController)
|
||||||
|
: Dram(name, config)
|
||||||
{
|
{
|
||||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||||
SC_REPORT_FATAL("DramLPDDR4", "Error Model not supported for LPDDR4");
|
SC_REPORT_FATAL("DramLPDDR4", "Error Model not supported for LPDDR4");
|
||||||
|
|
||||||
if (Configuration::getInstance().powerAnalysis)
|
if (powerAnalysis)
|
||||||
SC_REPORT_FATAL("DramLPDDR4", "DRAMPower does not support LPDDR4");
|
SC_REPORT_FATAL("DramLPDDR4", "DRAMPower does not support LPDDR4");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,15 @@
|
|||||||
#define DRAMLPDDR4_H
|
#define DRAMLPDDR4_H
|
||||||
|
|
||||||
#include <systemc>
|
#include <systemc>
|
||||||
|
|
||||||
#include "Dram.h"
|
#include "Dram.h"
|
||||||
|
#include "../TemperatureController.h"
|
||||||
|
|
||||||
class DramLPDDR4 : public Dram
|
class DramLPDDR4 : public Dram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DramLPDDR4(const sc_core::sc_module_name &name);
|
DramLPDDR4(const sc_core::sc_module_name& name, const Configuration& config,
|
||||||
|
TemperatureController& temperatureController);
|
||||||
SC_HAS_PROCESS(DramLPDDR4);
|
SC_HAS_PROCESS(DramLPDDR4);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user