Remove config singleton.
This commit is contained in:
@@ -44,7 +44,7 @@ using namespace sc_core;
|
||||
|
||||
void DebugManager::printDebugMessage(const std::string &sender, const std::string &message)
|
||||
{
|
||||
if (Configuration::getInstance().debug)
|
||||
if (debugEnabled)
|
||||
{
|
||||
if (writeToConsole)
|
||||
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)
|
||||
{
|
||||
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()
|
||||
: writeToConsole(false), writeToFile(false)
|
||||
: debugEnabled(false), writeToConsole(false), writeToFile(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -69,14 +69,17 @@ private:
|
||||
DebugManager & operator = (const DebugManager &);
|
||||
|
||||
public:
|
||||
bool writeToConsole;
|
||||
bool writeToFile;
|
||||
void setup(bool _debugEnabled, bool _writeToConsole, bool _writeToFile);
|
||||
|
||||
void printDebugMessage(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);
|
||||
|
||||
private:
|
||||
bool debugEnabled;
|
||||
bool writeToConsole;
|
||||
bool writeToFile;
|
||||
|
||||
std::ofstream debugFile;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
TlmRecorder::TlmRecorder(const std::string &name, const std::string &dbName) :
|
||||
name(name), totalNumTransactions(0), simulationTimeCoveredByRecording(SC_ZERO_TIME)
|
||||
TlmRecorder::TlmRecorder(const std::string& name, const Configuration& config, const std::string& dbName) :
|
||||
name(name), config(config), totalNumTransactions(0), simulationTimeCoveredByRecording(SC_ZERO_TIME)
|
||||
{
|
||||
currentDataBuffer = &recordingDataBuffer[0];
|
||||
storageDataBuffer = &recordingDataBuffer[1];
|
||||
@@ -345,29 +345,28 @@ void TlmRecorder::insertGeneralInfo()
|
||||
{
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 1, static_cast<int64_t>(totalNumTransactions));
|
||||
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, 4, static_cast<int>(Configuration::getInstance().memSpec->bankGroupsPerChannel));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 5, static_cast<int>(Configuration::getInstance().memSpec->banksPerChannel));
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 6, static_cast<int64_t>(Configuration::getInstance().memSpec->tCK.value()));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 3, static_cast<int>(config.memSpec->ranksPerChannel));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 4, static_cast<int>(config.memSpec->bankGroupsPerChannel));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 5, static_cast<int>(config.memSpec->banksPerChannel));
|
||||
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, 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, 10, traces.c_str(), static_cast<int>(traces.length()), nullptr);
|
||||
if (Configuration::getInstance().enableWindowing)
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 11, static_cast<int64_t>((Configuration::getInstance().memSpec->tCK
|
||||
* Configuration::getInstance().windowSize).value()));
|
||||
if (config.enableWindowing)
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 11, static_cast<int64_t>((config.memSpec->tCK
|
||||
* config.windowSize).value()));
|
||||
else
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 11, 0);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, static_cast<int>(Configuration::getInstance().refreshMaxPostponed));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(Configuration::getInstance().refreshMaxPulledin));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, static_cast<int>(config.refreshMaxPostponed));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(config.refreshMaxPulledin));
|
||||
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, 16,
|
||||
static_cast<int>(Configuration::getInstance().memSpec->getPer2BankOffset()));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast<int>(config.requestBufferSize));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 16, static_cast<int>(config.memSpec->getPer2BankOffset()));
|
||||
|
||||
const auto memSpec = Configuration::getInstance().memSpec;
|
||||
const auto memoryType = memSpec->memoryType;
|
||||
const MemSpec& memSpec = *config.memSpec;
|
||||
const auto memoryType = memSpec.memoryType;
|
||||
bool rowColumnCommandBus = [memoryType]() -> bool {
|
||||
if (memoryType == MemSpec::MemoryType::HBM2)
|
||||
return true;
|
||||
@@ -375,11 +374,11 @@ void TlmRecorder::insertGeneralInfo()
|
||||
return false;
|
||||
}();
|
||||
|
||||
bool pseudoChannelMode = [memSpec, memoryType]() -> bool {
|
||||
bool pseudoChannelMode = [&memSpec, memoryType]() -> bool {
|
||||
if (memoryType != MemSpec::MemoryType::HBM2)
|
||||
return false;
|
||||
|
||||
if (memSpec->pseudoChannelsPerChannel != 1)
|
||||
if (memSpec.pseudoChannelsPerChannel != 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -392,14 +391,14 @@ void TlmRecorder::insertGeneralInfo()
|
||||
|
||||
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();
|
||||
|
||||
sqlite3_bind_text(insertCommandLengthsStatement, 1, commandName.c_str(), commandName.length(), nullptr);
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -51,11 +51,12 @@
|
||||
#include "sqlite3.h"
|
||||
#include "dramExtensions.h"
|
||||
#include "utils.h"
|
||||
#include "../configuration/Configuration.h"
|
||||
|
||||
class TlmRecorder
|
||||
{
|
||||
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(TlmRecorder&&) = default;
|
||||
|
||||
@@ -84,6 +85,8 @@ public:
|
||||
void finalize();
|
||||
|
||||
private:
|
||||
const Configuration& config;
|
||||
|
||||
struct Transaction
|
||||
{
|
||||
Transaction() = default;
|
||||
@@ -143,11 +146,11 @@ private:
|
||||
sc_core::sc_time simulationTimeCoveredByRecording;
|
||||
|
||||
sqlite3 *db = nullptr;
|
||||
sqlite3_stmt *insertTransactionStatement, *insertRangeStatement,
|
||||
*updateRangeStatement, *insertPhaseStatement, *updatePhaseStatement,
|
||||
*insertGeneralInfoStatement, *insertCommandLengthsStatement,
|
||||
*insertDebugMessageStatement, *updateDataStrobeStatement,
|
||||
*insertPowerStatement, *insertBufferDepthStatement, *insertBandwidthStatement;
|
||||
sqlite3_stmt *insertTransactionStatement = nullptr, *insertRangeStatement = nullptr,
|
||||
*updateRangeStatement = nullptr, *insertPhaseStatement = nullptr, *updatePhaseStatement = nullptr,
|
||||
*insertGeneralInfoStatement = nullptr, *insertCommandLengthsStatement = nullptr,
|
||||
*insertDebugMessageStatement = nullptr, *updateDataStrobeStatement = nullptr,
|
||||
*insertPowerStatement = nullptr, *insertBufferDepthStatement = nullptr, *insertBandwidthStatement = nullptr;
|
||||
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString,
|
||||
updatePhaseString, insertGeneralInfoString, insertCommandLengthsString,
|
||||
insertDebugMessageString, updateDataStrobeString, insertPowerString,
|
||||
|
||||
@@ -292,11 +292,6 @@ uint64_t DramExtension::getChannelPayloadID() const
|
||||
return channelPayloadID;
|
||||
}
|
||||
|
||||
void DramExtension::incrementRow()
|
||||
{
|
||||
++row;
|
||||
}
|
||||
|
||||
tlm_extension_base *GenerationExtension::clone() const
|
||||
{
|
||||
return new GenerationExtension(timeOfGeneration);
|
||||
@@ -433,12 +428,6 @@ bool operator !=(const Row &lhs, const Row &rhs)
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
Row Row::operator ++()
|
||||
{
|
||||
id = (id + 1) % Configuration::getInstance().memSpec->rowsPerBank;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//COLUMN
|
||||
bool operator ==(const Column &lhs, const Column &rhs)
|
||||
|
||||
@@ -218,7 +218,6 @@ public:
|
||||
unsigned int getBurstLength() const;
|
||||
uint64_t getThreadPayloadID() const;
|
||||
uint64_t getChannelPayloadID() const;
|
||||
void incrementRow();
|
||||
|
||||
private:
|
||||
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)
|
||||
config.addressOffset = *addressOffset;
|
||||
if (const auto& _addressOffset = simConfig.addressOffset)
|
||||
addressOffset = *_addressOffset;
|
||||
|
||||
if (const auto &checkTLM2Protocol = simConfig.checkTLM2Protocol)
|
||||
config.checkTLM2Protocol = *checkTLM2Protocol;
|
||||
if (const auto& _checkTLM2Protocol = simConfig.checkTLM2Protocol)
|
||||
checkTLM2Protocol = *_checkTLM2Protocol;
|
||||
|
||||
if (const auto &databaseRecording = simConfig.databaseRecording)
|
||||
config.databaseRecording = *databaseRecording;
|
||||
if (const auto& _databaseRecording = simConfig.databaseRecording)
|
||||
databaseRecording = *_databaseRecording;
|
||||
|
||||
if (const auto &debug = simConfig.debug)
|
||||
config.debug = *debug;
|
||||
if (const auto& _debug = simConfig.debug)
|
||||
debug = *_debug;
|
||||
|
||||
if (const auto &enableWindowing = simConfig.enableWindowing)
|
||||
config.enableWindowing = *enableWindowing;
|
||||
if (const auto& _enableWindowing = simConfig.enableWindowing)
|
||||
enableWindowing = *_enableWindowing;
|
||||
|
||||
if (const auto &powerAnalysis = simConfig.powerAnalysis)
|
||||
config.powerAnalysis = *powerAnalysis;
|
||||
if (const auto& _powerAnalysis = simConfig.powerAnalysis)
|
||||
powerAnalysis = *_powerAnalysis;
|
||||
|
||||
if (const auto &simulationName = simConfig.simulationName)
|
||||
config.simulationName = *simulationName;
|
||||
if (const auto& _simulationName = simConfig.simulationName)
|
||||
simulationName = *_simulationName;
|
||||
|
||||
if (const auto &simulationProgressBar = simConfig.simulationProgressBar)
|
||||
config.simulationProgressBar = *simulationProgressBar;
|
||||
if (const auto& _simulationProgressBar = simConfig.simulationProgressBar)
|
||||
simulationProgressBar = *_simulationProgressBar;
|
||||
|
||||
if (const auto &thermalSimulation = simConfig.thermalSimulation)
|
||||
config.thermalSimulation = *thermalSimulation;
|
||||
if (const auto& _thermalSimulation = simConfig.thermalSimulation)
|
||||
thermalSimulation = *_thermalSimulation;
|
||||
|
||||
if (const auto &useMalloc = simConfig.useMalloc)
|
||||
config.useMalloc = *useMalloc;
|
||||
if (const auto& _useMalloc = simConfig.useMalloc)
|
||||
useMalloc = *_useMalloc;
|
||||
|
||||
if (const auto &windowSize = simConfig.windowSize)
|
||||
config.windowSize = *windowSize;
|
||||
if (const auto& _windowSize = simConfig.windowSize)
|
||||
windowSize = *_windowSize;
|
||||
|
||||
if (config.windowSize == 0)
|
||||
if (windowSize == 0)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum window size is 1");
|
||||
|
||||
if (const auto &errorCsvFile = simConfig.errorCsvFile)
|
||||
config.errorCSVFile = *errorCsvFile;
|
||||
if (const auto& _errorCsvFile = simConfig.errorCsvFile)
|
||||
errorCSVFile = *_errorCsvFile;
|
||||
|
||||
if (const auto &errorChipSeed = simConfig.errorChipSeed)
|
||||
config.errorChipSeed = *errorChipSeed;
|
||||
if (const auto& _errorChipSeed = simConfig.errorChipSeed)
|
||||
errorChipSeed = *_errorChipSeed;
|
||||
|
||||
if (const auto &storeMode = simConfig.storeMode)
|
||||
config.storeMode = [=] {
|
||||
if (storeMode == DRAMSysConfiguration::StoreMode::NoStorage)
|
||||
if (const auto& _storeMode = simConfig.storeMode)
|
||||
storeMode = [=] {
|
||||
if (_storeMode == DRAMSysConfiguration::StoreMode::NoStorage)
|
||||
return StoreMode::NoStorage;
|
||||
else if (storeMode == DRAMSysConfiguration::StoreMode::Store)
|
||||
else if (_storeMode == DRAMSysConfiguration::StoreMode::Store)
|
||||
return StoreMode::Store;
|
||||
else
|
||||
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)
|
||||
return TemperatureSimConfig::TemperatureScale::Celsius;
|
||||
else if (thermalConfig.temperatureScale == DRAMSysConfiguration::TemperatureScale::Fahrenheit)
|
||||
@@ -142,10 +142,10 @@ void Configuration::loadTemperatureSimConfig(Configuration &config, const DRAMSy
|
||||
return TemperatureSimConfig::TemperatureScale::Kelvin;
|
||||
}();
|
||||
|
||||
config.temperatureSim.staticTemperatureDefaultValue = thermalConfig.staticTemperatureDefaultValue;
|
||||
config.temperatureSim.thermalSimPeriod = thermalConfig.thermalSimPeriod;
|
||||
temperatureSim.staticTemperatureDefaultValue = thermalConfig.staticTemperatureDefaultValue;
|
||||
temperatureSim.thermalSimPeriod = thermalConfig.thermalSimPeriod;
|
||||
|
||||
config.temperatureSim.thermalSimUnit = [=] {
|
||||
temperatureSim.thermalSimUnit = [=] {
|
||||
if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Seconds)
|
||||
return sc_core::SC_SEC;
|
||||
else if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Milliseconds)
|
||||
@@ -162,189 +162,189 @@ void Configuration::loadTemperatureSimConfig(Configuration &config, const DRAMSy
|
||||
|
||||
for (const auto &channel : thermalConfig.powerInfo.channels)
|
||||
{
|
||||
config.temperatureSim.powerInitialValues.push_back(channel.init_pow);
|
||||
config.temperatureSim.powerThresholds.push_back(channel.threshold);
|
||||
temperatureSim.powerInitialValues.push_back(channel.init_pow);
|
||||
temperatureSim.powerThresholds.push_back(channel.threshold);
|
||||
}
|
||||
|
||||
config.temperatureSim.iceServerIp = thermalConfig.iceServerIp;
|
||||
config.temperatureSim.iceServerPort = thermalConfig.iceServerPort;
|
||||
config.temperatureSim.simPeriodAdjustFactor = thermalConfig.simPeriodAdjustFactor;
|
||||
config.temperatureSim.nPowStableCyclesToIncreasePeriod = thermalConfig.nPowStableCyclesToIncreasePeriod;
|
||||
config.temperatureSim.generateTemperatureMap = thermalConfig.generateTemperatureMap;
|
||||
config.temperatureSim.generatePowerMap = thermalConfig.generatePowerMap;
|
||||
temperatureSim.iceServerIp = thermalConfig.iceServerIp;
|
||||
temperatureSim.iceServerPort = thermalConfig.iceServerPort;
|
||||
temperatureSim.simPeriodAdjustFactor = thermalConfig.simPeriodAdjustFactor;
|
||||
temperatureSim.nPowStableCyclesToIncreasePeriod = thermalConfig.nPowStableCyclesToIncreasePeriod;
|
||||
temperatureSim.generateTemperatureMap = thermalConfig.generateTemperatureMap;
|
||||
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)
|
||||
config.pagePolicy = [=] {
|
||||
if (pagePolicy == DRAMSysConfiguration::PagePolicy::Open)
|
||||
if (const auto& _pagePolicy = mcConfig.pagePolicy)
|
||||
pagePolicy = [=] {
|
||||
if (_pagePolicy == DRAMSysConfiguration::PagePolicy::Open)
|
||||
return PagePolicy::Open;
|
||||
else if (pagePolicy == DRAMSysConfiguration::PagePolicy::OpenAdaptive)
|
||||
else if (_pagePolicy == DRAMSysConfiguration::PagePolicy::OpenAdaptive)
|
||||
return PagePolicy::OpenAdaptive;
|
||||
else if (pagePolicy == DRAMSysConfiguration::PagePolicy::Closed)
|
||||
else if (_pagePolicy == DRAMSysConfiguration::PagePolicy::Closed)
|
||||
return PagePolicy::Closed;
|
||||
else
|
||||
return PagePolicy::ClosedAdaptive;
|
||||
}();
|
||||
|
||||
if (const auto &scheduler = mcConfig.scheduler)
|
||||
config.scheduler = [=] {
|
||||
if (scheduler == DRAMSysConfiguration::Scheduler::Fifo)
|
||||
if (const auto& _scheduler = mcConfig.scheduler)
|
||||
scheduler = [=] {
|
||||
if (_scheduler == DRAMSysConfiguration::Scheduler::Fifo)
|
||||
return Scheduler::Fifo;
|
||||
else if (scheduler == DRAMSysConfiguration::Scheduler::FrFcfs)
|
||||
else if (_scheduler == DRAMSysConfiguration::Scheduler::FrFcfs)
|
||||
return Scheduler::FrFcfs;
|
||||
else if (scheduler == DRAMSysConfiguration::Scheduler::FrFcfsGrp)
|
||||
else if (_scheduler == DRAMSysConfiguration::Scheduler::FrFcfsGrp)
|
||||
return Scheduler::FrFcfsGrp;
|
||||
else if (scheduler == DRAMSysConfiguration::Scheduler::GrpFrFcfs)
|
||||
else if (_scheduler == DRAMSysConfiguration::Scheduler::GrpFrFcfs)
|
||||
return Scheduler::GrpFrFcfs;
|
||||
else
|
||||
return Scheduler::GrpFrFcfsWm;
|
||||
}();
|
||||
|
||||
if (const auto &highWatermark = mcConfig.highWatermark)
|
||||
config.highWatermark = *mcConfig.highWatermark;
|
||||
if (const auto& _highWatermark = mcConfig.highWatermark)
|
||||
highWatermark = *mcConfig.highWatermark;
|
||||
|
||||
if (const auto &lowWatermark = mcConfig.lowWatermark)
|
||||
config.lowWatermark = *mcConfig.lowWatermark;
|
||||
if (const auto& _lowWatermark = mcConfig.lowWatermark)
|
||||
lowWatermark = *mcConfig.lowWatermark;
|
||||
|
||||
if (const auto &schedulerBuffer = mcConfig.schedulerBuffer)
|
||||
config.schedulerBuffer = [=] {
|
||||
if (schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::Bankwise)
|
||||
if (const auto& _schedulerBuffer = mcConfig.schedulerBuffer)
|
||||
schedulerBuffer = [=] {
|
||||
if (_schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::Bankwise)
|
||||
return SchedulerBuffer::Bankwise;
|
||||
else if (schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::ReadWrite)
|
||||
else if (_schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::ReadWrite)
|
||||
return SchedulerBuffer::ReadWrite;
|
||||
else
|
||||
return SchedulerBuffer::Shared;
|
||||
}();
|
||||
|
||||
if (const auto &requestBufferSize = mcConfig.requestBufferSize)
|
||||
config.requestBufferSize = *mcConfig.requestBufferSize;
|
||||
if (const auto& _requestBufferSize = mcConfig.requestBufferSize)
|
||||
requestBufferSize = *mcConfig.requestBufferSize;
|
||||
|
||||
if (config.requestBufferSize == 0)
|
||||
if (requestBufferSize == 0)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||
|
||||
if (const auto &cmdMux = mcConfig.cmdMux)
|
||||
config.cmdMux = [=] {
|
||||
if (cmdMux == DRAMSysConfiguration::CmdMux::Oldest)
|
||||
if (const auto& _cmdMux = mcConfig.cmdMux)
|
||||
cmdMux = [=] {
|
||||
if (_cmdMux == DRAMSysConfiguration::CmdMux::Oldest)
|
||||
return CmdMux::Oldest;
|
||||
else
|
||||
return CmdMux::Strict;
|
||||
}();
|
||||
|
||||
if (const auto &respQueue = mcConfig.respQueue)
|
||||
config.respQueue = [=] {
|
||||
if (respQueue == DRAMSysConfiguration::RespQueue::Fifo)
|
||||
if (const auto& _respQueue = mcConfig.respQueue)
|
||||
respQueue = [=] {
|
||||
if (_respQueue == DRAMSysConfiguration::RespQueue::Fifo)
|
||||
return RespQueue::Fifo;
|
||||
else
|
||||
return RespQueue::Reorder;
|
||||
}();
|
||||
|
||||
if (const auto &refreshPolicy = mcConfig.refreshPolicy)
|
||||
config.refreshPolicy = [=] {
|
||||
if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::NoRefresh)
|
||||
if (const auto& _refreshPolicy = mcConfig.refreshPolicy)
|
||||
refreshPolicy = [=] {
|
||||
if (_refreshPolicy == DRAMSysConfiguration::RefreshPolicy::NoRefresh)
|
||||
return RefreshPolicy::NoRefresh;
|
||||
else if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::AllBank)
|
||||
else if (_refreshPolicy == DRAMSysConfiguration::RefreshPolicy::AllBank)
|
||||
return RefreshPolicy::AllBank;
|
||||
else if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::PerBank)
|
||||
else if (_refreshPolicy == DRAMSysConfiguration::RefreshPolicy::PerBank)
|
||||
return RefreshPolicy::PerBank;
|
||||
else if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::Per2Bank)
|
||||
else if (_refreshPolicy == DRAMSysConfiguration::RefreshPolicy::Per2Bank)
|
||||
return RefreshPolicy::Per2Bank;
|
||||
else // if (policy == DRAMSysConfiguration::RefreshPolicy::SameBank)
|
||||
return RefreshPolicy::SameBank;
|
||||
}();
|
||||
|
||||
if (const auto &refreshMaxPostponed = mcConfig.refreshMaxPostponed)
|
||||
config.refreshMaxPostponed = *refreshMaxPostponed;
|
||||
if (const auto& _refreshMaxPostponed = mcConfig.refreshMaxPostponed)
|
||||
refreshMaxPostponed = *_refreshMaxPostponed;
|
||||
|
||||
if (const auto &refreshMaxPulledin = mcConfig.refreshMaxPulledin)
|
||||
config.refreshMaxPulledin = *refreshMaxPulledin;
|
||||
if (const auto& _refreshMaxPulledin = mcConfig.refreshMaxPulledin)
|
||||
refreshMaxPulledin = *_refreshMaxPulledin;
|
||||
|
||||
if (const auto &powerDownPolicy = mcConfig.powerDownPolicy)
|
||||
config.powerDownPolicy = [=] {
|
||||
if (powerDownPolicy == DRAMSysConfiguration::PowerDownPolicy::NoPowerDown)
|
||||
if (const auto& _powerDownPolicy = mcConfig.powerDownPolicy)
|
||||
powerDownPolicy = [=] {
|
||||
if (_powerDownPolicy == DRAMSysConfiguration::PowerDownPolicy::NoPowerDown)
|
||||
return PowerDownPolicy::NoPowerDown;
|
||||
else
|
||||
return PowerDownPolicy::Staggered;
|
||||
}();
|
||||
|
||||
if (const auto &arbiter = mcConfig.arbiter)
|
||||
config.arbiter = [=] {
|
||||
if (arbiter == DRAMSysConfiguration::Arbiter::Simple)
|
||||
if (const auto& _arbiter = mcConfig.arbiter)
|
||||
arbiter = [=] {
|
||||
if (_arbiter == DRAMSysConfiguration::Arbiter::Simple)
|
||||
return Arbiter::Simple;
|
||||
else if (arbiter == DRAMSysConfiguration::Arbiter::Fifo)
|
||||
else if (_arbiter == DRAMSysConfiguration::Arbiter::Fifo)
|
||||
return Arbiter::Fifo;
|
||||
else
|
||||
return Arbiter::Reorder;
|
||||
}();
|
||||
|
||||
if (const auto &maxActiveTransactions = mcConfig.maxActiveTransactions)
|
||||
config.maxActiveTransactions = *maxActiveTransactions;
|
||||
if (const auto& _maxActiveTransactions = mcConfig.maxActiveTransactions)
|
||||
maxActiveTransactions = *_maxActiveTransactions;
|
||||
|
||||
if (const auto &refreshManagement = mcConfig.refreshManagement)
|
||||
config.refreshManagement = *refreshManagement;
|
||||
if (const auto& _refreshManagement = mcConfig.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;
|
||||
|
||||
if (memoryType == "DDR3")
|
||||
config.memSpec = new MemSpecDDR3(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecDDR3>(memSpecConfig);
|
||||
else if (memoryType == "DDR4")
|
||||
config.memSpec = new MemSpecDDR4(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecDDR4>(memSpecConfig);
|
||||
else if (memoryType == "DDR5")
|
||||
config.memSpec = new MemSpecDDR5(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecDDR5>(memSpecConfig);
|
||||
else if (memoryType == "LPDDR4")
|
||||
config.memSpec = new MemSpecLPDDR4(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecLPDDR4>(memSpecConfig);
|
||||
else if (memoryType == "LPDDR5")
|
||||
config.memSpec = new MemSpecLPDDR5(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecLPDDR5>(memSpecConfig);
|
||||
else if (memoryType == "WIDEIO_SDR")
|
||||
config.memSpec = new MemSpecWideIO(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecWideIO>(memSpecConfig);
|
||||
else if (memoryType == "WIDEIO2")
|
||||
config.memSpec = new MemSpecWideIO2(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecWideIO2>(memSpecConfig);
|
||||
else if (memoryType == "HBM2")
|
||||
config.memSpec = new MemSpecHBM2(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecHBM2>(memSpecConfig);
|
||||
else if (memoryType == "GDDR5")
|
||||
config.memSpec = new MemSpecGDDR5(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecGDDR5>(memSpecConfig);
|
||||
else if (memoryType == "GDDR5X")
|
||||
config.memSpec = new MemSpecGDDR5X(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecGDDR5X>(memSpecConfig);
|
||||
else if (memoryType == "GDDR6")
|
||||
config.memSpec = new MemSpecGDDR6(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecGDDR6>(memSpecConfig);
|
||||
else if (memoryType == "STT-MRAM")
|
||||
config.memSpec = new MemSpecSTTMRAM(memSpecConfig);
|
||||
memSpec = std::make_unique<const MemSpecSTTMRAM>(memSpecConfig);
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported DRAM type");
|
||||
}
|
||||
|
||||
@@ -51,15 +51,9 @@
|
||||
class Configuration
|
||||
{
|
||||
public:
|
||||
static Configuration &getInstance()
|
||||
{
|
||||
static Configuration _instance;
|
||||
return _instance;
|
||||
}
|
||||
private:
|
||||
Configuration() = default;
|
||||
Configuration(const Configuration &);
|
||||
Configuration &operator = (const Configuration &);
|
||||
Configuration(const Configuration&) = delete;
|
||||
Configuration& operator=(const Configuration &) = delete;
|
||||
|
||||
public:
|
||||
// MCConfig:
|
||||
@@ -105,15 +99,15 @@ public:
|
||||
enum class StoreMode {NoStorage, Store, ErrorModel} storeMode = StoreMode::NoStorage;
|
||||
|
||||
// MemSpec (from DRAM-Power)
|
||||
const MemSpec *memSpec = nullptr;
|
||||
std::unique_ptr<const MemSpec> memSpec;
|
||||
|
||||
// Temperature Simulation related
|
||||
TemperatureSimConfig temperatureSim;
|
||||
|
||||
static void loadMCConfig(Configuration &config, const DRAMSysConfiguration::McConfig &mcConfig);
|
||||
static void loadSimConfig(Configuration &config, const DRAMSysConfiguration::SimConfig &simConfig);
|
||||
static void loadMemSpec(Configuration &config, const DRAMSysConfiguration::MemSpec &memSpec);
|
||||
static void loadTemperatureSimConfig(Configuration &config, const DRAMSysConfiguration::ThermalConfig &thermalConfig);
|
||||
void loadMCConfig(const DRAMSysConfiguration::McConfig& mcConfig);
|
||||
void loadSimConfig(const DRAMSysConfiguration::SimConfig& simConfig);
|
||||
void loadMemSpec(const DRAMSysConfiguration::MemSpec& memSpec);
|
||||
void loadTemperatureSimConfig(const DRAMSysConfiguration::ThermalConfig& thermalConfig);
|
||||
};
|
||||
|
||||
#endif // CONFIGURATION_H
|
||||
|
||||
@@ -40,13 +40,12 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
BankMachine::BankMachine(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||
: scheduler(scheduler), checker(checker), bank(bank)
|
||||
BankMachine::BankMachine(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||
: scheduler(scheduler), checker(checker), bank(bank), memSpec(*config.memSpec)
|
||||
{
|
||||
memSpec = Configuration::getInstance().memSpec;
|
||||
rank = Rank(bank.ID() / memSpec->banksPerRank);
|
||||
bankgroup = BankGroup(bank.ID() / memSpec->banksPerGroup);
|
||||
refreshManagement = Configuration::getInstance().refreshManagement;
|
||||
rank = Rank(bank.ID() / memSpec.banksPerRank);
|
||||
bankgroup = BankGroup(bank.ID() / memSpec.banksPerGroup);
|
||||
refreshManagement = config.refreshManagement;
|
||||
}
|
||||
|
||||
CommandTuple::Type BankMachine::getNextCommand()
|
||||
@@ -87,8 +86,8 @@ void BankMachine::updateState(Command command)
|
||||
|
||||
if (refreshManagement)
|
||||
{
|
||||
if (refreshManagementCounter > memSpec->getRAACDR())
|
||||
refreshManagementCounter -= memSpec->getRAACDR();
|
||||
if (refreshManagementCounter > memSpec.getRAACDR())
|
||||
refreshManagementCounter -= memSpec.getRAACDR();
|
||||
else
|
||||
refreshManagementCounter = 0;
|
||||
}
|
||||
@@ -100,8 +99,8 @@ void BankMachine::updateState(Command command)
|
||||
|
||||
if (refreshManagement)
|
||||
{
|
||||
if (refreshManagementCounter > memSpec->getRAAIMT())
|
||||
refreshManagementCounter -= memSpec->getRAAIMT();
|
||||
if (refreshManagementCounter > memSpec.getRAAIMT())
|
||||
refreshManagementCounter -= memSpec.getRAAIMT();
|
||||
else
|
||||
refreshManagementCounter = 0;
|
||||
}
|
||||
@@ -162,8 +161,9 @@ bool BankMachine::isPrecharged() const
|
||||
return state == State::Precharged;
|
||||
}
|
||||
|
||||
BankMachineOpen::BankMachineOpen(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||
: BankMachine(scheduler, checker, bank) {}
|
||||
BankMachineOpen::BankMachineOpen(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker,
|
||||
Bank bank)
|
||||
: BankMachine(config, scheduler, checker, bank) {}
|
||||
|
||||
sc_time BankMachineOpen::start()
|
||||
{
|
||||
@@ -213,8 +213,9 @@ sc_time BankMachineOpen::start()
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineClosed::BankMachineClosed(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||
: BankMachine(scheduler, checker, bank) {}
|
||||
BankMachineClosed::BankMachineClosed(const Configuration& config, const SchedulerIF& scheduler,
|
||||
const CheckerIF& checker, Bank bank)
|
||||
: BankMachine(config, scheduler, checker, bank) {}
|
||||
|
||||
sc_time BankMachineClosed::start()
|
||||
{
|
||||
@@ -259,8 +260,9 @@ sc_time BankMachineClosed::start()
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineOpenAdaptive::BankMachineOpenAdaptive(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||
: BankMachine(scheduler, checker, bank) {}
|
||||
BankMachineOpenAdaptive::BankMachineOpenAdaptive(const Configuration& config, const SchedulerIF& scheduler,
|
||||
const CheckerIF& checker, Bank bank)
|
||||
: BankMachine(config, scheduler, checker, bank) {}
|
||||
|
||||
sc_time BankMachineOpenAdaptive::start()
|
||||
{
|
||||
@@ -322,8 +324,9 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineClosedAdaptive::BankMachineClosedAdaptive(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||
: BankMachine(scheduler, checker, bank) {}
|
||||
BankMachineClosedAdaptive::BankMachineClosedAdaptive(const Configuration& config, const SchedulerIF& scheduler,
|
||||
const CheckerIF& checker, Bank bank)
|
||||
: BankMachine(config, scheduler, checker, bank) {}
|
||||
|
||||
sc_time BankMachineClosedAdaptive::start()
|
||||
{
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "scheduler/SchedulerIF.h"
|
||||
#include "checker/CheckerIF.h"
|
||||
#include "../configuration/memspec/MemSpec.h"
|
||||
#include "../configuration/Configuration.h"
|
||||
|
||||
class BankMachine
|
||||
{
|
||||
@@ -63,8 +64,8 @@ public:
|
||||
|
||||
protected:
|
||||
enum class State {Precharged, Activated} state = State::Precharged;
|
||||
BankMachine(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
||||
const MemSpec* memSpec;
|
||||
BankMachine(const Configuration& config, const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank);
|
||||
const MemSpec& memSpec;
|
||||
tlm::tlm_generic_payload *currentPayload = nullptr;
|
||||
const SchedulerIF& scheduler;
|
||||
const CheckerIF& checker;
|
||||
@@ -84,28 +85,30 @@ protected:
|
||||
class BankMachineOpen final : public BankMachine
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
class BankMachineClosed final : public BankMachine
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
class BankMachineOpenAdaptive final : public BankMachine
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
class BankMachineClosedAdaptive final : public BankMachine
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -69,15 +69,13 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
Controller::Controller(const sc_module_name &name) :
|
||||
ControllerIF(name)
|
||||
Controller::Controller(const sc_module_name& name, const Configuration& config) :
|
||||
ControllerIF(name, config)
|
||||
{
|
||||
SC_METHOD(controllerMethod);
|
||||
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
|
||||
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
ranksNumberOfPayloads = std::vector<unsigned>(memSpec->ranksPerChannel);
|
||||
|
||||
ranksNumberOfPayloads = std::vector<unsigned>(memSpec.ranksPerChannel);
|
||||
|
||||
thinkDelayFw = config.thinkDelayFw;
|
||||
thinkDelayBw = config.thinkDelayBw;
|
||||
@@ -85,59 +83,59 @@ Controller::Controller(const sc_module_name &name) :
|
||||
phyDelayBw = config.phyDelayBw;
|
||||
|
||||
// reserve buffer for command tuples
|
||||
readyCommands.reserve(memSpec->banksPerChannel);
|
||||
readyCommands.reserve(memSpec.banksPerChannel);
|
||||
|
||||
// instantiate timing checker
|
||||
if (memSpec->memoryType == MemSpec::MemoryType::DDR3)
|
||||
checker = std::make_unique<CheckerDDR3>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::DDR4)
|
||||
checker = std::make_unique<CheckerDDR4>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::DDR5)
|
||||
checker = std::make_unique<CheckerDDR5>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::WideIO)
|
||||
checker = std::make_unique<CheckerWideIO>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::LPDDR4)
|
||||
checker = std::make_unique<CheckerLPDDR4>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::LPDDR5)
|
||||
checker = std::make_unique<CheckerLPDDR5>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::WideIO2)
|
||||
checker = std::make_unique<CheckerWideIO2>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::HBM2)
|
||||
checker = std::make_unique<CheckerHBM2>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5)
|
||||
checker = std::make_unique<CheckerGDDR5>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5X)
|
||||
checker = std::make_unique<CheckerGDDR5X>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR6)
|
||||
checker = std::make_unique<CheckerGDDR6>();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::STTMRAM)
|
||||
checker = std::make_unique<CheckerSTTMRAM>();
|
||||
if (memSpec.memoryType == MemSpec::MemoryType::DDR3)
|
||||
checker = std::make_unique<CheckerDDR3>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::DDR4)
|
||||
checker = std::make_unique<CheckerDDR4>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::DDR5)
|
||||
checker = std::make_unique<CheckerDDR5>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::WideIO)
|
||||
checker = std::make_unique<CheckerWideIO>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::LPDDR4)
|
||||
checker = std::make_unique<CheckerLPDDR4>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::LPDDR5)
|
||||
checker = std::make_unique<CheckerLPDDR5>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::WideIO2)
|
||||
checker = std::make_unique<CheckerWideIO2>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::HBM2)
|
||||
checker = std::make_unique<CheckerHBM2>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::GDDR5)
|
||||
checker = std::make_unique<CheckerGDDR5>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::GDDR5X)
|
||||
checker = std::make_unique<CheckerGDDR5X>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::GDDR6)
|
||||
checker = std::make_unique<CheckerGDDR6>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::STTMRAM)
|
||||
checker = std::make_unique<CheckerSTTMRAM>(config);
|
||||
|
||||
// instantiate scheduler and command mux
|
||||
if (config.scheduler == Configuration::Scheduler::Fifo)
|
||||
scheduler = std::make_unique<SchedulerFifo>();
|
||||
scheduler = std::make_unique<SchedulerFifo>(config);
|
||||
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)
|
||||
scheduler = std::make_unique<SchedulerFrFcfsGrp>();
|
||||
scheduler = std::make_unique<SchedulerFrFcfsGrp>(config);
|
||||
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)
|
||||
scheduler = std::make_unique<SchedulerGrpFrFcfsWm>();
|
||||
scheduler = std::make_unique<SchedulerGrpFrFcfsWm>(config);
|
||||
|
||||
if (config.cmdMux == Configuration::CmdMux::Oldest)
|
||||
{
|
||||
if (memSpec->hasRasAndCasBus())
|
||||
cmdMux = std::make_unique<CmdMuxOldestRasCas>();
|
||||
if (memSpec.hasRasAndCasBus())
|
||||
cmdMux = std::make_unique<CmdMuxOldestRasCas>(config);
|
||||
else
|
||||
cmdMux = std::make_unique<CmdMuxOldest>();
|
||||
cmdMux = std::make_unique<CmdMuxOldest>(config);
|
||||
}
|
||||
else if (config.cmdMux == Configuration::CmdMux::Strict)
|
||||
{
|
||||
if (memSpec->hasRasAndCasBus())
|
||||
cmdMux = std::make_unique<CmdMuxStrictRasCas>();
|
||||
if (memSpec.hasRasAndCasBus())
|
||||
cmdMux = std::make_unique<CmdMuxStrictRasCas>(config);
|
||||
else
|
||||
cmdMux = std::make_unique<CmdMuxStrict>();
|
||||
cmdMux = std::make_unique<CmdMuxStrict>(config);
|
||||
}
|
||||
|
||||
if (config.respQueue == Configuration::RespQueue::Fifo)
|
||||
@@ -148,42 +146,46 @@ Controller::Controller(const sc_module_name &name) :
|
||||
// instantiate bank machines (one per bank)
|
||||
if (config.pagePolicy == Configuration::PagePolicy::Open)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineOpen>(*scheduler, *checker, Bank(bankID)));
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineOpen>
|
||||
(config, *scheduler, *checker, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::OpenAdaptive)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineOpenAdaptive>(*scheduler, *checker, Bank(bankID)));
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineOpenAdaptive>
|
||||
(config, *scheduler, *checker, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::Closed)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineClosed>(*scheduler, *checker, Bank(bankID)));
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineClosed>
|
||||
(config, *scheduler, *checker, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::ClosedAdaptive)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineClosedAdaptive>(*scheduler, *checker, Bank(bankID)));
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineClosedAdaptive>
|
||||
(config, *scheduler, *checker, Bank(bankID)));
|
||||
}
|
||||
|
||||
bankMachinesOnRank = std::vector<std::vector<BankMachine*>>(memSpec->ranksPerChannel,
|
||||
std::vector<BankMachine*>(memSpec->banksPerRank));
|
||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
||||
bankMachinesOnRank = std::vector<std::vector<BankMachine*>>(memSpec.ranksPerChannel,
|
||||
std::vector<BankMachine*>(memSpec.banksPerRank));
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++)
|
||||
bankMachinesOnRank[rankID][bankID] = bankMachines[rankID * memSpec->banksPerRank + bankID].get();
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerRank; bankID++)
|
||||
bankMachinesOnRank[rankID][bankID] = bankMachines[rankID * memSpec.banksPerRank + bankID].get();
|
||||
}
|
||||
|
||||
// instantiate power-down managers (one per rank)
|
||||
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>());
|
||||
}
|
||||
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],
|
||||
Rank(rankID), *checker));
|
||||
@@ -193,41 +195,41 @@ Controller::Controller(const sc_module_name &name) :
|
||||
// instantiate refresh managers (one per rank)
|
||||
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>());
|
||||
}
|
||||
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>
|
||||
(bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID), *checker));
|
||||
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID), *checker));
|
||||
}
|
||||
}
|
||||
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>
|
||||
(bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID), *checker));
|
||||
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID), *checker));
|
||||
}
|
||||
}
|
||||
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
|
||||
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)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->ranksPerChannel; rankID++)
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
// TODO: remove bankMachines in constructor
|
||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerPer2Bank>
|
||||
(bankMachinesOnRank[rankID], *powerDownManagers[rankID], Rank(rankID), *checker));
|
||||
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID], Rank(rankID), *checker));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -260,7 +262,7 @@ void Controller::controllerMethod()
|
||||
// clear command buffer
|
||||
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)
|
||||
commandTuple = powerDownManagers[rankID]->getNextCommand();
|
||||
@@ -302,14 +304,14 @@ void Controller::controllerMethod()
|
||||
}
|
||||
else if (command.isGroupCommand())
|
||||
{
|
||||
for (unsigned bankID = (bank.ID() % memSpec->banksPerGroup);
|
||||
bankID < memSpec->banksPerRank; bankID += memSpec->banksPerGroup)
|
||||
for (unsigned bankID = (bank.ID() % memSpec.banksPerGroup);
|
||||
bankID < memSpec.banksPerRank; bankID += memSpec.banksPerGroup)
|
||||
bankMachinesOnRank[rank.ID()][bankID]->updateState(command);
|
||||
}
|
||||
else if (command.is2BankCommand())
|
||||
{
|
||||
bankMachines[bank.ID()]->updateState(command);
|
||||
bankMachines[bank.ID() + memSpec->getPer2BankOffset()]->updateState(command);
|
||||
bankMachines[bank.ID() + memSpec.getPer2BankOffset()]->updateState(command);
|
||||
}
|
||||
else // if (isBankCommand(command))
|
||||
bankMachines[bank.ID()]->updateState(command);
|
||||
@@ -324,7 +326,7 @@ void Controller::controllerMethod()
|
||||
manageRequests(thinkDelayFw);
|
||||
respQueue->insertPayload(payload, sc_time_stamp()
|
||||
+ thinkDelayFw + phyDelayFw
|
||||
+ memSpec->getIntervalOnDataStrobe(command, *payload).end
|
||||
+ memSpec.getIntervalOnDataStrobe(command, *payload).end
|
||||
+ phyDelayBw + thinkDelayBw);
|
||||
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
@@ -469,7 +471,7 @@ void Controller::manageResponses()
|
||||
{
|
||||
// last payload was released in this cycle
|
||||
tlm_phase bwPhase = BEGIN_RESP;
|
||||
sc_time bwDelay = memSpec->tCK;
|
||||
sc_time bwDelay = memSpec.tCK;
|
||||
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
|
||||
transToRelease.time = sc_max_time();
|
||||
}
|
||||
@@ -491,7 +493,7 @@ void Controller::manageResponses()
|
||||
tlm_phase bwPhase = BEGIN_RESP;
|
||||
sc_time bwDelay;
|
||||
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
|
||||
bwDelay = memSpec->tCK;
|
||||
bwDelay = memSpec.tCK;
|
||||
else
|
||||
bwDelay = SC_ZERO_TIME;
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
class Controller : public ControllerIF
|
||||
{
|
||||
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);
|
||||
|
||||
protected:
|
||||
@@ -70,7 +70,6 @@ protected:
|
||||
virtual void controllerMethod();
|
||||
|
||||
std::unique_ptr<SchedulerIF> scheduler;
|
||||
const MemSpec *memSpec;
|
||||
|
||||
sc_core::sc_time thinkDelayFw;
|
||||
sc_core::sc_time thinkDelayBw;
|
||||
|
||||
@@ -54,56 +54,57 @@ public:
|
||||
tlm_utils::simple_target_socket<ControllerIF> tSocket; // Arbiter side
|
||||
tlm_utils::simple_initiator_socket<ControllerIF> iSocket; // DRAM side
|
||||
|
||||
// Destructor
|
||||
~ControllerIF() override
|
||||
void end_of_simulation() override
|
||||
{
|
||||
sc_core::sc_time activeTime = static_cast<double>(numberOfBeatsServed)
|
||||
/ Configuration::getInstance().memSpec->dataRate
|
||||
* Configuration::getInstance().memSpec->tCK
|
||||
/ Configuration::getInstance().memSpec->pseudoChannelsPerChannel;
|
||||
/ memSpec.dataRate
|
||||
* memSpec.tCK
|
||||
/ memSpec.pseudoChannelsPerChannel;
|
||||
|
||||
double bandwidth = activeTime / sc_core::sc_time_stamp();
|
||||
double bandwidthWoIdle = activeTime / (sc_core::sc_time_stamp() - idleTimeCollector.getIdleTime());
|
||||
|
||||
double maxBandwidth = (
|
||||
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
|
||||
(1000 / Configuration::getInstance().memSpec->tCK.to_double())
|
||||
// DataRate e.g. 2
|
||||
* Configuration::getInstance().memSpec->dataRate
|
||||
// BusWidth e.g. 8 or 64
|
||||
* Configuration::getInstance().memSpec->bitWidth
|
||||
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
|
||||
* Configuration::getInstance().memSpec->devicesPerRank
|
||||
// HBM specific, one or two pseudo channels per channel
|
||||
* Configuration::getInstance().memSpec->pseudoChannelsPerChannel);
|
||||
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
|
||||
(1000 / memSpec.tCK.to_double())
|
||||
// DataRate e.g. 2
|
||||
* memSpec.dataRate
|
||||
// BusWidth e.g. 8 or 64
|
||||
* memSpec.bitWidth
|
||||
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
|
||||
* memSpec.devicesPerRank
|
||||
// HBM specific, one or two pseudo channels per channel
|
||||
* memSpec.pseudoChannelsPerChannel);
|
||||
|
||||
std::cout << name() << std::string(" Total Time: ")
|
||||
<< sc_core::sc_time_stamp().to_string()
|
||||
<< std::endl;
|
||||
<< sc_core::sc_time_stamp().to_string()
|
||||
<< std::endl;
|
||||
std::cout << name() << std::string(" AVG BW: ")
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< std::setw(6) << (bandwidth * maxBandwidth) << " Gb/s | "
|
||||
<< std::setw(6) << (bandwidth * maxBandwidth / 8) << " GB/s | "
|
||||
<< std::setw(6) << (bandwidth * 100) << " %"
|
||||
<< std::endl;
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< std::setw(6) << (bandwidth * maxBandwidth) << " Gb/s | "
|
||||
<< std::setw(6) << (bandwidth * maxBandwidth / 8) << " GB/s | "
|
||||
<< std::setw(6) << (bandwidth * 100) << " %"
|
||||
<< std::endl;
|
||||
std::cout << name() << std::string(" AVG BW\\IDLE: ")
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth) << " Gb/s | "
|
||||
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth / 8) << " GB/s | "
|
||||
<< std::setw(6) << (bandwidthWoIdle * 100) << " %"
|
||||
<< std::endl;
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth) << " Gb/s | "
|
||||
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth / 8) << " GB/s | "
|
||||
<< std::setw(6) << (bandwidthWoIdle * 100) << " %"
|
||||
<< std::endl;
|
||||
std::cout << name() << std::string(" MAX BW: ")
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< std::setw(6) << maxBandwidth << " Gb/s | "
|
||||
<< std::setw(6) << maxBandwidth / 8 << " GB/s | "
|
||||
<< std::setw(6) << 100.0 << " %"
|
||||
<< std::endl;
|
||||
<< std::fixed << std::setprecision(2)
|
||||
<< std::setw(6) << maxBandwidth << " Gb/s | "
|
||||
<< std::setw(6) << maxBandwidth / 8 << " GB/s | "
|
||||
<< std::setw(6) << 100.0 << " %"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
protected:
|
||||
const MemSpec& memSpec;
|
||||
|
||||
// Bind sockets with virtual functions
|
||||
explicit ControllerIF(const sc_core::sc_module_name& name)
|
||||
: sc_core::sc_module(name), tSocket("tSocket"), iSocket("iSocket")
|
||||
ControllerIF(const sc_core::sc_module_name& name, const Configuration& config)
|
||||
: sc_core::sc_module(name), tSocket("tSocket"), iSocket("iSocket"), memSpec(*config.memSpec)
|
||||
{
|
||||
tSocket.register_nb_transport_fw(this, &ControllerIF::nb_transport_fw);
|
||||
tSocket.register_transport_dbg(this, &ControllerIF::transport_dbg);
|
||||
|
||||
@@ -39,13 +39,15 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
ControllerRecordable::ControllerRecordable(const sc_module_name &name, TlmRecorder& tlmRecorder)
|
||||
: Controller(name), tlmRecorder(tlmRecorder)
|
||||
ControllerRecordable::ControllerRecordable(const sc_module_name &name, const Configuration& config,
|
||||
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;
|
||||
windowSizeTime = Configuration::getInstance().windowSize * memSpec->tCK;
|
||||
windowSizeTime = config.windowSize * memSpec.tCK;
|
||||
slidingAverageBufferDepth = std::vector<sc_time>(scheduler->getBufferDepth().size());
|
||||
windowAverageBufferDepth = std::vector<double>(scheduler->getBufferDepth().size());
|
||||
windowEvent.notify(windowSizeTime);
|
||||
@@ -77,7 +79,7 @@ void ControllerRecordable::sendToDram(Command command, tlm_generic_payload& payl
|
||||
{
|
||||
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,
|
||||
sc_time_stamp() + delay + dataStrobe.end, payload);
|
||||
}
|
||||
@@ -108,7 +110,7 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, const tlm_pha
|
||||
|
||||
void ControllerRecordable::controllerMethod()
|
||||
{
|
||||
if (Configuration::getInstance().enableWindowing)
|
||||
if (enableWindowing)
|
||||
{
|
||||
sc_time timeDiff = sc_time_stamp() - lastTimeCalled;
|
||||
lastTimeCalled = sc_time_stamp();
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
class ControllerRecordable final : public Controller
|
||||
{
|
||||
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;
|
||||
|
||||
protected:
|
||||
@@ -69,8 +69,8 @@ private:
|
||||
sc_core::sc_time lastTimeCalled = sc_core::SC_ZERO_TIME;
|
||||
|
||||
uint64_t lastNumberOfBeatsServed = 0;
|
||||
sc_core::sc_time activeTimeMultiplier = Configuration::getInstance().memSpec->tCK
|
||||
/ Configuration::getInstance().memSpec->dataRate;
|
||||
sc_core::sc_time activeTimeMultiplier;
|
||||
bool enableWindowing;
|
||||
};
|
||||
|
||||
#endif // CONTROLLERRECORDABLE_H
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerDDR3::CheckerDDR3()
|
||||
CheckerDDR3::CheckerDDR3(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecDDR3 *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecDDR3 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerDDR3 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR3();
|
||||
explicit CheckerDDR3(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerDDR4::CheckerDDR4()
|
||||
CheckerDDR4::CheckerDDR4(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecDDR4 *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecDDR4 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR4();
|
||||
explicit CheckerDDR4(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerDDR5::CheckerDDR5()
|
||||
CheckerDDR5::CheckerDDR5(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecDDR5 *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecDDR5 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
class CheckerDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR5();
|
||||
explicit CheckerDDR5(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerGDDR5::CheckerGDDR5()
|
||||
CheckerGDDR5::CheckerGDDR5(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecGDDR5 *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecGDDR5 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR5", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerGDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5();
|
||||
explicit CheckerGDDR5(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerGDDR5X::CheckerGDDR5X()
|
||||
CheckerGDDR5X::CheckerGDDR5X(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecGDDR5X *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecGDDR5X *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR5X", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerGDDR5X final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5X();
|
||||
explicit CheckerGDDR5X(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerGDDR6::CheckerGDDR6()
|
||||
CheckerGDDR6::CheckerGDDR6(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecGDDR6 *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecGDDR6 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR6", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerGDDR6 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR6();
|
||||
explicit CheckerGDDR6(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerHBM2::CheckerHBM2()
|
||||
CheckerHBM2::CheckerHBM2(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecHBM2 *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecHBM2 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerHBM2", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerHBM2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerHBM2();
|
||||
explicit CheckerHBM2(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#define CHECKERIF_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "../Command.h"
|
||||
|
||||
class CheckerIF
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerLPDDR4::CheckerLPDDR4()
|
||||
CheckerLPDDR4::CheckerLPDDR4(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecLPDDR4 *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecLPDDR4 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerLPDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerLPDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerLPDDR4();
|
||||
explicit CheckerLPDDR4(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerLPDDR5::CheckerLPDDR5()
|
||||
CheckerLPDDR5::CheckerLPDDR5(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecLPDDR5 *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecLPDDR5 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerLPDDR5", "Wrong MemSpec chosen");
|
||||
else
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
class CheckerLPDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerLPDDR5();
|
||||
explicit CheckerLPDDR5(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerSTTMRAM::CheckerSTTMRAM()
|
||||
CheckerSTTMRAM::CheckerSTTMRAM(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecSTTMRAM *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecSTTMRAM *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerSTTMRAM final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerSTTMRAM();
|
||||
explicit CheckerSTTMRAM(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerWideIO::CheckerWideIO()
|
||||
CheckerWideIO::CheckerWideIO(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecWideIO *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecWideIO *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerWideIO", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerWideIO final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerWideIO();
|
||||
explicit CheckerWideIO(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -39,10 +39,9 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerWideIO2::CheckerWideIO2()
|
||||
CheckerWideIO2::CheckerWideIO2(const Configuration& config)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecWideIO2 *>(config.memSpec);
|
||||
memSpec = dynamic_cast<const MemSpecWideIO2 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerWideIO2", "Wrong MemSpec chosen");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
class CheckerWideIO2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerWideIO2();
|
||||
explicit CheckerWideIO2(const Configuration& config);
|
||||
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;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -51,7 +51,7 @@ CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommand
|
||||
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); 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));
|
||||
|
||||
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);
|
||||
readyCasCommands.reserve(memSpec->banksPerChannel);
|
||||
readyRasCommands.reserve(memSpec.banksPerChannel);
|
||||
readyCasCommands.reserve(memSpec.banksPerChannel);
|
||||
readyRasCasCommands.reserve(2);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
|
||||
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); 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));
|
||||
|
||||
if (newTimestamp < lastTimestamp)
|
||||
@@ -129,7 +129,7 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
|
||||
for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); 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));
|
||||
|
||||
if (newTimestamp < lastTimestamp)
|
||||
|
||||
@@ -41,22 +41,22 @@
|
||||
class CmdMuxOldest : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
CmdMuxOldest();
|
||||
explicit CmdMuxOldest(const Configuration& config);
|
||||
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
||||
|
||||
private:
|
||||
const MemSpec *memSpec;
|
||||
const MemSpec& memSpec;
|
||||
};
|
||||
|
||||
|
||||
class CmdMuxOldestRasCas : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
CmdMuxOldestRasCas();
|
||||
explicit CmdMuxOldestRasCas(const Configuration& config);
|
||||
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
||||
|
||||
private:
|
||||
const MemSpec *memSpec;
|
||||
const MemSpec& memSpec;
|
||||
ReadyCommands readyRasCommands;
|
||||
ReadyCommands readyCasCommands;
|
||||
ReadyCommands readyRasCasCommands;
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -51,7 +51,7 @@ CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommand
|
||||
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); 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));
|
||||
|
||||
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);
|
||||
readyCasCommands.reserve(memSpec->banksPerChannel);
|
||||
readyRasCommands.reserve(memSpec.banksPerChannel);
|
||||
readyCasCommands.reserve(memSpec.banksPerChannel);
|
||||
readyRasCasCommands.reserve(2);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyC
|
||||
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); 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));
|
||||
|
||||
if (newTimestamp < lastTimestamp)
|
||||
|
||||
@@ -41,23 +41,23 @@
|
||||
class CmdMuxStrict : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
CmdMuxStrict();
|
||||
explicit CmdMuxStrict(const Configuration& config);
|
||||
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
||||
|
||||
private:
|
||||
uint64_t nextPayloadID = 1;
|
||||
const MemSpec *memSpec;
|
||||
const MemSpec& memSpec;
|
||||
};
|
||||
|
||||
class CmdMuxStrictRasCas : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
CmdMuxStrictRasCas();
|
||||
explicit CmdMuxStrictRasCas(const Configuration& config);
|
||||
CommandTuple::Type selectCommand(const ReadyCommands &) override;
|
||||
|
||||
private:
|
||||
uint64_t nextPayloadID = 1;
|
||||
const MemSpec *memSpec;
|
||||
const MemSpec& memSpec;
|
||||
ReadyCommands readyRasCommands;
|
||||
ReadyCommands readyCasCommands;
|
||||
ReadyCommands readyRasCasCommands;
|
||||
|
||||
@@ -43,16 +43,15 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerAllBank::RefreshManagerAllBank(std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
||||
RefreshManagerAllBank::RefreshManagerAllBank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
||||
: bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), checker(checker),
|
||||
memSpec(*Configuration::getInstance().memSpec)
|
||||
memSpec(*config.memSpec)
|
||||
{
|
||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec.getRefreshIntervalAB(),
|
||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalAB(),
|
||||
rank, memSpec.ranksPerChannel);
|
||||
setUpDummy(refreshPayload, 0, rank);
|
||||
|
||||
const Configuration &config = Configuration::getInstance();
|
||||
maxPostponed = static_cast<int>(config.refreshMaxPostponed);
|
||||
maxPulledin = -static_cast<int>(config.refreshMaxPulledin);
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <tlm>
|
||||
#include "RefreshManagerIF.h"
|
||||
#include "../checker/CheckerIF.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../configuration/memspec/MemSpec.h"
|
||||
|
||||
class BankMachine;
|
||||
@@ -49,7 +50,7 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerAllBank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerAllBank(std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
RefreshManagerAllBank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
||||
|
||||
CommandTuple::Type getNextCommand() override;
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
virtual void updateState(Command) = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
// Calculate bit-reversal rank ID
|
||||
@@ -74,7 +74,6 @@ protected:
|
||||
|
||||
// Use bit-reversal order for refreshes on ranks
|
||||
sc_core::sc_time timeForFirstTrigger = refreshInterval - reverseRankID * (refreshInterval / numberOfRanks);
|
||||
sc_core::sc_time tCK = Configuration::getInstance().memSpec->tCK;
|
||||
timeForFirstTrigger = std::ceil(timeForFirstTrigger / tCK) * tCK;
|
||||
|
||||
return timeForFirstTrigger;
|
||||
|
||||
@@ -42,14 +42,14 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerPer2Bank::RefreshManagerPer2Bank(std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
RefreshManagerPer2Bank::RefreshManagerPer2Bank(const Configuration& config,
|
||||
std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank,
|
||||
const CheckerIF& checker)
|
||||
: powerDownManager(powerDownManager), checker(checker), memSpec(*Configuration::getInstance().memSpec)
|
||||
: powerDownManager(powerDownManager), checker(checker), memSpec(*config.memSpec)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec.getRefreshIntervalP2B(),
|
||||
rank, memSpec.ranksPerChannel);
|
||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalP2B(), rank,
|
||||
memSpec.ranksPerChannel);
|
||||
|
||||
// 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))
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "RefreshManagerIF.h"
|
||||
#include "../checker/CheckerIF.h"
|
||||
#include "../../configuration/memspec/MemSpec.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class BankMachine;
|
||||
class PowerDownManagerIF;
|
||||
@@ -51,7 +52,7 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerPer2Bank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerPer2Bank(std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
RefreshManagerPer2Bank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
||||
|
||||
CommandTuple::Type getNextCommand() override;
|
||||
|
||||
@@ -42,13 +42,12 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerPerBank::RefreshManagerPerBank(std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
||||
: powerDownManager(powerDownManager), checker(checker), memSpec(*Configuration::getInstance().memSpec)
|
||||
RefreshManagerPerBank::RefreshManagerPerBank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
||||
: powerDownManager(powerDownManager), checker(checker), memSpec(*config.memSpec)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec.getRefreshIntervalPB(),
|
||||
rank, memSpec.ranksPerChannel);
|
||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalPB(), rank,
|
||||
memSpec.ranksPerChannel);
|
||||
for (auto* it : bankMachinesOnRank)
|
||||
{
|
||||
setUpDummy(refreshPayloads[it], 0, rank, it->getBankGroup(), it->getBank());
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "RefreshManagerIF.h"
|
||||
#include "../checker/CheckerIF.h"
|
||||
#include "../../configuration/memspec/MemSpec.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class BankMachine;
|
||||
class PowerDownManagerIF;
|
||||
@@ -51,8 +52,8 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerPerBank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerPerBank(std::vector<BankMachine *>& bankMachinesOnRank, PowerDownManagerIF& powerDownManager,
|
||||
Rank rank, const CheckerIF& checker);
|
||||
RefreshManagerPerBank(const Configuration& config, std::vector<BankMachine *>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
||||
|
||||
CommandTuple::Type getNextCommand() override;
|
||||
sc_core::sc_time start() override;
|
||||
|
||||
@@ -42,13 +42,14 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerSameBank::RefreshManagerSameBank(std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker)
|
||||
: powerDownManager(powerDownManager), checker(checker), memSpec(*Configuration::getInstance().memSpec)
|
||||
RefreshManagerSameBank::RefreshManagerSameBank(const Configuration& config,
|
||||
std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank,
|
||||
const CheckerIF& checker)
|
||||
: powerDownManager(powerDownManager), checker(checker), memSpec(*config.memSpec)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec.getRefreshIntervalSB(),
|
||||
rank, memSpec.ranksPerChannel);
|
||||
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalSB(), rank,
|
||||
memSpec.ranksPerChannel);
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "RefreshManagerIF.h"
|
||||
#include "../checker/CheckerIF.h"
|
||||
#include "../../configuration/memspec/MemSpec.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class BankMachine;
|
||||
class PowerDownManagerIF;
|
||||
@@ -50,8 +51,8 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerSameBank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerSameBank(std::vector<BankMachine *>& bankMachinesOnRank, PowerDownManagerIF& powerDownManager,
|
||||
Rank rank, const CheckerIF& checker);
|
||||
RefreshManagerSameBank(const Configuration& config, std::vector<BankMachine *>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank, const CheckerIF& checker);
|
||||
|
||||
CommandTuple::Type getNextCommand() override;
|
||||
sc_core::sc_time start() override;
|
||||
|
||||
@@ -40,9 +40,8 @@
|
||||
|
||||
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);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
class SchedulerFifo final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
SchedulerFifo();
|
||||
explicit SchedulerFifo(const Configuration& config);
|
||||
bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||
|
||||
@@ -40,9 +40,8 @@
|
||||
|
||||
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);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
class SchedulerFrFcfs final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
SchedulerFrFcfs();
|
||||
explicit SchedulerFrFcfs(const Configuration& config);
|
||||
bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||
|
||||
@@ -40,9 +40,8 @@
|
||||
|
||||
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);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
class SchedulerFrFcfsGrp final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
SchedulerFrFcfsGrp();
|
||||
explicit SchedulerFrFcfsGrp(const Configuration& config);
|
||||
bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||
|
||||
@@ -40,9 +40,8 @@
|
||||
|
||||
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);
|
||||
writeBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
class SchedulerGrpFrFcfs final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
SchedulerGrpFrFcfs();
|
||||
explicit SchedulerGrpFrFcfs(const Configuration& config);
|
||||
bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||
|
||||
@@ -40,9 +40,8 @@
|
||||
|
||||
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);
|
||||
writeBuffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->banksPerChannel);
|
||||
|
||||
|
||||
@@ -44,11 +44,12 @@
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../BankMachine.h"
|
||||
#include "BufferCounterIF.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class SchedulerGrpFrFcfsWm final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
SchedulerGrpFrFcfsWm();
|
||||
explicit SchedulerGrpFrFcfsWm(const Configuration& config);
|
||||
bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload&) override;
|
||||
void removeRequest(tlm::tlm_generic_payload&) override;
|
||||
|
||||
@@ -48,19 +48,27 @@
|
||||
|
||||
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;
|
||||
thermalSim = Configuration::getInstance().thermalSimulation;
|
||||
this->DRAMPower = dramPower;
|
||||
init(config);
|
||||
}
|
||||
|
||||
void errorModel::init(const Configuration& config)
|
||||
{
|
||||
powerAnalysis = config.powerAnalysis;
|
||||
thermalSim = config.thermalSimulation;
|
||||
// Get Configuration parameters:
|
||||
burstLenght = Configuration::getInstance().memSpec->defaultBurstLength;
|
||||
numberOfColumns = Configuration::getInstance().memSpec->columnsPerRow;
|
||||
bytesPerColumn = std::log2(Configuration::getInstance().memSpec->dataBusWidth);
|
||||
burstLenght = config.memSpec->defaultBurstLength;
|
||||
numberOfColumns = config.memSpec->columnsPerRow;
|
||||
bytesPerColumn = std::log2(config.memSpec->dataBusWidth);
|
||||
|
||||
// Adjust number of bytes per column dynamically to the selected ecc controller
|
||||
//TODO: bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC(bytesPerColumn);
|
||||
|
||||
numberOfRows = Configuration::getInstance().memSpec->rowsPerBank;
|
||||
numberOfRows = config.memSpec->rowsPerBank;
|
||||
numberOfBitErrorEvents = 0;
|
||||
|
||||
|
||||
@@ -73,7 +81,7 @@ void errorModel::init()
|
||||
contextStr = "";
|
||||
|
||||
// Parse data input:
|
||||
parseInputData();
|
||||
parseInputData(config);
|
||||
prepareWeakCells();
|
||||
|
||||
// Initialize context variables:
|
||||
@@ -117,17 +125,6 @@ void errorModel::init()
|
||||
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()
|
||||
{
|
||||
// Remove all data from the dataMap:
|
||||
@@ -262,7 +259,7 @@ void errorModel::markBitFlips()
|
||||
{
|
||||
double temp = getTemperature();
|
||||
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 (lastRowAccess[row] != SC_ZERO_TIME) {
|
||||
// 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:
|
||||
for (unsigned int i = 0; i < n; i++) {
|
||||
// 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;
|
||||
msg << "Maked weakCell[" << i << "] as flipped" << std::endl;
|
||||
PRINTDEBUGMESSAGE(name(), msg.str());
|
||||
@@ -502,28 +499,27 @@ double errorModel::getTemperature()
|
||||
// requesting the temperature.
|
||||
double temperature = 89;
|
||||
|
||||
if (this->myChannel != -1) {
|
||||
if (thermalSim == true && powerAnalysis == true) {
|
||||
if (this->myChannel != -1)
|
||||
{
|
||||
if (thermalSim && powerAnalysis)
|
||||
{
|
||||
// TODO
|
||||
// check if this is best way to request information to DRAMPower.
|
||||
unsigned long long clk_cycles = sc_time_stamp() /
|
||||
Configuration::getInstance().memSpec->tCK;
|
||||
unsigned long long clk_cycles = sc_time_stamp() / memSpec.tCK;
|
||||
DRAMPower->calcWindowEnergy(clk_cycles);
|
||||
float average_power = (float)DRAMPower->getPower().average_power;
|
||||
temperature = TemperatureController::getInstance().getTemperature(
|
||||
this->myChannel, average_power);
|
||||
temperature = temperatureController.getTemperature(this->myChannel, average_power);
|
||||
} else {
|
||||
temperature = TemperatureController::getInstance().getTemperature(
|
||||
this->myChannel, 0);
|
||||
temperature = temperatureController.getTemperature(this->myChannel, 0);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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 (found == true) {
|
||||
if (found) {
|
||||
i--;
|
||||
} else {
|
||||
weakCells[i].row = row; // Row in the bank
|
||||
@@ -663,7 +659,7 @@ void errorModel::prepareWeakCells()
|
||||
unsigned int r = (rand() % maxNumberOfWeakCells);
|
||||
|
||||
// If the dependent weak cell was choosen before roll the dice again:
|
||||
if (weakCells[r].dependent == true) {
|
||||
if (weakCells[r].dependent) {
|
||||
i--;
|
||||
} else {
|
||||
weakCells[r].dependent = true;
|
||||
|
||||
@@ -42,12 +42,13 @@
|
||||
#include "../configuration/Configuration.h"
|
||||
#include "../simulation/AddressDecoder.h"
|
||||
#include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../simulation/TemperatureController.h"
|
||||
|
||||
class errorModel : public sc_core::sc_module
|
||||
{
|
||||
public:
|
||||
errorModel(const sc_core::sc_module_name &, libDRAMPower *);
|
||||
explicit errorModel(const sc_core::sc_module_name &);
|
||||
errorModel(const sc_core::sc_module_name& name, const Configuration& config,
|
||||
TemperatureController& temperatureController, libDRAMPower* dramPower = nullptr);
|
||||
~errorModel() override;
|
||||
|
||||
// Access Methods:
|
||||
@@ -59,10 +60,12 @@ public:
|
||||
double getTemperature();
|
||||
|
||||
private:
|
||||
void init();
|
||||
void init(const Configuration& config);
|
||||
bool powerAnalysis;
|
||||
libDRAMPower *DRAMPower;
|
||||
bool thermalSim;
|
||||
TemperatureController& temperatureController;
|
||||
const MemSpec& memSpec;
|
||||
// Configuration Parameters:
|
||||
unsigned int burstLenght;
|
||||
unsigned int numberOfColumns;
|
||||
@@ -76,7 +79,7 @@ private:
|
||||
unsigned int numberOfBitErrorEvents;
|
||||
|
||||
// Private Methods:
|
||||
void parseInputData();
|
||||
void parseInputData(const Configuration& config);
|
||||
void prepareWeakCells();
|
||||
void markBitFlips();
|
||||
unsigned int getNumberOfFlips(double temp, sc_core::sc_time time);
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#include "../common/utils.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)
|
||||
{
|
||||
@@ -107,14 +107,12 @@ AddressDecoder::AddressDecoder(const DRAMSysConfiguration::AddressMapping &addre
|
||||
banksPerGroup = banks;
|
||||
banks = banksPerGroup * bankGroups;
|
||||
|
||||
const MemSpec& memSpec = *config.memSpec;
|
||||
|
||||
Configuration &config = Configuration::getInstance();
|
||||
const MemSpec *memSpec = config.memSpec;
|
||||
|
||||
if (memSpec->numberOfChannels != channels || memSpec->ranksPerChannel != ranks
|
||||
|| memSpec->bankGroupsPerChannel != bankGroups || memSpec->banksPerChannel != banks
|
||||
|| memSpec->rowsPerBank != rows || memSpec->columnsPerRow != columns
|
||||
|| memSpec->devicesPerRank * memSpec->bitWidth != bytes * 8)
|
||||
if (memSpec.numberOfChannels != channels || memSpec.ranksPerChannel != ranks
|
||||
|| 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");
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <Configuration.h>
|
||||
#include "../configuration/Configuration.h"
|
||||
|
||||
struct DecodedAddress
|
||||
{
|
||||
@@ -68,7 +69,7 @@ struct DecodedAddress
|
||||
class AddressDecoder
|
||||
{
|
||||
public:
|
||||
explicit AddressDecoder(const DRAMSysConfiguration::AddressMapping &addressMapping);
|
||||
AddressDecoder(const Configuration& config, const DRAMSysConfiguration::AddressMapping &addressMapping);
|
||||
DecodedAddress decodeAddress(uint64_t addr);
|
||||
void print();
|
||||
|
||||
|
||||
@@ -46,37 +46,36 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
Arbiter::Arbiter(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
||||
sc_module(name), payloadEventQueue(this, &Arbiter::peqCallback),
|
||||
tCK(Configuration::getInstance().memSpec->tCK),
|
||||
arbitrationDelayFw(Configuration::getInstance().arbitrationDelayFw),
|
||||
arbitrationDelayBw(Configuration::getInstance().arbitrationDelayBw)
|
||||
Arbiter::Arbiter(const sc_module_name &name, const Configuration& config,
|
||||
const DRAMSysConfiguration::AddressMapping& addressMapping) :
|
||||
sc_module(name), addressDecoder(config, addressMapping), payloadEventQueue(this, &Arbiter::peqCallback),
|
||||
tCK(config.memSpec->tCK),
|
||||
arbitrationDelayFw(config.arbitrationDelayFw),
|
||||
arbitrationDelayBw(config.arbitrationDelayBw),
|
||||
addressOffset(config.addressOffset)
|
||||
{
|
||||
iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw);
|
||||
tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw);
|
||||
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) :
|
||||
Arbiter(name, addressMapping) {}
|
||||
ArbiterSimple::ArbiterSimple(const sc_module_name& name, const Configuration& config,
|
||||
const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
||||
Arbiter(name, config, addressMapping) {}
|
||||
|
||||
ArbiterFifo::ArbiterFifo(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
||||
Arbiter(name, addressMapping),
|
||||
maxActiveTransactions(Configuration::getInstance().maxActiveTransactions) {}
|
||||
ArbiterFifo::ArbiterFifo(const sc_module_name &name, const Configuration& config,
|
||||
const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
||||
Arbiter(name, config, addressMapping),
|
||||
maxActiveTransactions(config.maxActiveTransactions) {}
|
||||
|
||||
ArbiterReorder::ArbiterReorder(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
||||
Arbiter(name, addressMapping),
|
||||
maxActiveTransactions(Configuration::getInstance().maxActiveTransactions) {}
|
||||
|
||||
Arbiter::~Arbiter()
|
||||
{
|
||||
delete addressDecoder;
|
||||
}
|
||||
ArbiterReorder::ArbiterReorder(const sc_module_name &name, const Configuration& config,
|
||||
const DRAMSysConfiguration::AddressMapping &addressMapping) :
|
||||
Arbiter(name, config, addressMapping),
|
||||
maxActiveTransactions(config.maxActiveTransactions) {}
|
||||
|
||||
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
|
||||
// adjust address offset:
|
||||
uint64_t adjustedAddress = payload.get_address() - Configuration::getInstance().addressOffset;
|
||||
uint64_t adjustedAddress = payload.get_address() - addressOffset;
|
||||
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),
|
||||
Rank(decodedAddress.rank),
|
||||
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)
|
||||
{
|
||||
trans.set_address(trans.get_address() -
|
||||
Configuration::getInstance().addressOffset);
|
||||
trans.set_address(trans.get_address() - 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,15 +62,14 @@ public:
|
||||
tlm_utils::multi_passthrough_initiator_socket<Arbiter> iSocket;
|
||||
tlm_utils::multi_passthrough_target_socket<Arbiter> tSocket;
|
||||
|
||||
~Arbiter() override;
|
||||
|
||||
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);
|
||||
|
||||
void end_of_elaboration() override;
|
||||
|
||||
AddressDecoder *addressDecoder;
|
||||
AddressDecoder addressDecoder;
|
||||
|
||||
tlm_utils::peq_with_cb_and_phase<Arbiter> payloadEventQueue;
|
||||
virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) = 0;
|
||||
@@ -94,12 +93,14 @@ protected:
|
||||
sc_core::sc_time arbitrationDelayBw;
|
||||
|
||||
unsigned bytesPerBeat;
|
||||
uint64_t addressOffset;
|
||||
};
|
||||
|
||||
class ArbiterSimple final : public Arbiter
|
||||
{
|
||||
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);
|
||||
|
||||
private:
|
||||
@@ -112,7 +113,8 @@ private:
|
||||
class ArbiterFifo final : public Arbiter
|
||||
{
|
||||
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);
|
||||
|
||||
private:
|
||||
@@ -132,7 +134,8 @@ private:
|
||||
class ArbiterReorder final : public Arbiter
|
||||
{
|
||||
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);
|
||||
|
||||
private:
|
||||
|
||||
@@ -64,42 +64,47 @@
|
||||
#include "../controller/Controller.h"
|
||||
|
||||
DRAMSys::DRAMSys(const sc_core::sc_module_name &name,
|
||||
const DRAMSysConfiguration::Configuration &config)
|
||||
: DRAMSys(name, config, true)
|
||||
const DRAMSysConfiguration::Configuration &configLib)
|
||||
: DRAMSys(name, configLib, true)
|
||||
{}
|
||||
|
||||
DRAMSys::DRAMSys(const sc_core::sc_module_name &name,
|
||||
const DRAMSysConfiguration::Configuration &config,
|
||||
const DRAMSysConfiguration::Configuration &configLib,
|
||||
bool initAndBind)
|
||||
: sc_module(name), tSocket("DRAMSys_tSocket")
|
||||
{
|
||||
logo();
|
||||
|
||||
// Load config and initialize modules
|
||||
// Load configLib and initialize modules
|
||||
// Important: The memSpec needs to be the first configuration to be loaded!
|
||||
Configuration::loadMemSpec(Configuration::getInstance(), config.memSpec);
|
||||
Configuration::loadMCConfig(Configuration::getInstance(), config.mcConfig);
|
||||
Configuration::loadSimConfig(Configuration::getInstance(), config.simConfig);
|
||||
config.loadMemSpec(configLib.memSpec);
|
||||
config.loadMCConfig(configLib.mcConfig);
|
||||
config.loadSimConfig(configLib.simConfig);
|
||||
|
||||
if (const auto &thermalConfig = config.thermalConfig)
|
||||
Configuration::loadTemperatureSimConfig(Configuration::getInstance(), *thermalConfig);
|
||||
if (const auto &thermalConfig = configLib.thermalConfig)
|
||||
config.loadTemperatureSimConfig(*thermalConfig);
|
||||
|
||||
// Setup the debug manager:
|
||||
setupDebugManager(Configuration::getInstance().simulationName);
|
||||
setupDebugManager(config.simulationName);
|
||||
|
||||
if (initAndBind)
|
||||
{
|
||||
// Instantiate all internal DRAMSys modules:
|
||||
instantiateModules(config.addressMapping);
|
||||
instantiateModules(configLib.addressMapping);
|
||||
// Connect all internal DRAMSys modules:
|
||||
bindSockets();
|
||||
report(headline);
|
||||
}
|
||||
}
|
||||
|
||||
const Configuration& DRAMSys::getConfig()
|
||||
{
|
||||
return config;
|
||||
}
|
||||
|
||||
void DRAMSys::end_of_simulation()
|
||||
{
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
if (config.powerAnalysis)
|
||||
{
|
||||
for (auto& dram : drams)
|
||||
dram->reportPower();
|
||||
@@ -134,59 +139,70 @@ void DRAMSys::logo()
|
||||
void DRAMSys::setupDebugManager(NDEBUG_UNUSED(const std::string &traceName))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
auto &dbg = DebugManager::getInstance();
|
||||
dbg.writeToConsole = false;
|
||||
dbg.writeToFile = true;
|
||||
if (dbg.writeToFile)
|
||||
auto& dbg = DebugManager::getInstance();
|
||||
bool debugEnabled = config.debug;
|
||||
bool writeToConsole = false;
|
||||
bool writeToFile = true;
|
||||
dbg.setup(debugEnabled, writeToConsole, writeToFile);
|
||||
if (writeToFile)
|
||||
dbg.openDebugFile(traceName + ".txt");
|
||||
#endif
|
||||
}
|
||||
|
||||
void DRAMSys::instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping)
|
||||
{
|
||||
// The first call to getInstance() creates the Temperature Controller.
|
||||
// The same instance will be accessed by all other modules.
|
||||
TemperatureController::getInstance();
|
||||
Configuration &config = Configuration::getInstance();
|
||||
temperatureController = std::make_unique<TemperatureController>("TemperatureController", config);
|
||||
|
||||
// Create arbiter
|
||||
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)
|
||||
arbiter = std::make_unique<ArbiterFifo>("arbiter", addressMapping);
|
||||
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, addressMapping);
|
||||
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
|
||||
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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()
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
|
||||
tSocket.bind(arbiter->tSocket);
|
||||
|
||||
for (unsigned i = 0; i < config.memSpec->numberOfChannels; i++)
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "../common/tlm2_base_protocol_checker.h"
|
||||
#include "../error/eccbaseclass.h"
|
||||
#include "../controller/ControllerIF.h"
|
||||
#include "TemperatureController.h"
|
||||
|
||||
#include <Configuration.h>
|
||||
#include <string>
|
||||
@@ -63,15 +64,21 @@ public:
|
||||
|
||||
SC_HAS_PROCESS(DRAMSys);
|
||||
DRAMSys(const sc_core::sc_module_name &name,
|
||||
const DRAMSysConfiguration::Configuration &config);
|
||||
const DRAMSysConfiguration::Configuration &configLib);
|
||||
|
||||
const Configuration& getConfig();
|
||||
|
||||
protected:
|
||||
DRAMSys(const sc_core::sc_module_name &name,
|
||||
const DRAMSysConfiguration::Configuration &config,
|
||||
const DRAMSysConfiguration::Configuration &configLib,
|
||||
bool initAndBind);
|
||||
|
||||
void end_of_simulation() override;
|
||||
|
||||
Configuration config;
|
||||
|
||||
std::unique_ptr<TemperatureController> temperatureController;
|
||||
|
||||
//TLM 2.0 Protocol Checkers
|
||||
std::vector<std::unique_ptr<tlm_utils::tlm2_base_protocol_checker<>>> controllersTlmCheckers;
|
||||
|
||||
@@ -95,7 +102,7 @@ private:
|
||||
|
||||
void instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping);
|
||||
|
||||
static void setupDebugManager(const std::string &traceName);
|
||||
void setupDebugManager(const std::string &traceName);
|
||||
};
|
||||
|
||||
#endif // DRAMSYS_H
|
||||
|
||||
@@ -57,23 +57,22 @@
|
||||
|
||||
using namespace sc_core;
|
||||
|
||||
DRAMSysRecordable::DRAMSysRecordable(const sc_module_name &name,
|
||||
const DRAMSysConfiguration::Configuration &configuration)
|
||||
: DRAMSys(name, configuration, false)
|
||||
DRAMSysRecordable::DRAMSysRecordable(const sc_module_name& name, const DRAMSysConfiguration::Configuration& configLib)
|
||||
: DRAMSys(name, configLib, false)
|
||||
{
|
||||
// If a simulation file is passed as argument to DRAMSys the simulation ID
|
||||
// is prepended to the simulation name if found.
|
||||
std::string traceName;
|
||||
|
||||
if (!configuration.simulationId.empty())
|
||||
if (!configLib.simulationId.empty())
|
||||
{
|
||||
std::string sid = configuration.simulationId;
|
||||
traceName = sid + '_' + Configuration::getInstance().simulationName;
|
||||
std::string sid = configLib.simulationId;
|
||||
traceName = sid + '_' + config.simulationName;
|
||||
}
|
||||
else
|
||||
traceName = Configuration::getInstance().simulationName;
|
||||
traceName = config.simulationName;
|
||||
|
||||
instantiateModules(traceName, configuration);
|
||||
instantiateModules(traceName, configLib);
|
||||
bindSockets();
|
||||
report(headline);
|
||||
}
|
||||
@@ -81,7 +80,7 @@ DRAMSysRecordable::DRAMSysRecordable(const sc_module_name &name,
|
||||
void DRAMSysRecordable::end_of_simulation()
|
||||
{
|
||||
// Report power before TLM recorders are finalized
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
if (config.powerAnalysis)
|
||||
{
|
||||
for (auto& dram : drams)
|
||||
dram->reportPower();
|
||||
@@ -91,75 +90,84 @@ void DRAMSysRecordable::end_of_simulation()
|
||||
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.
|
||||
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 recorderName = "tlmRecorder" + std::to_string(i);
|
||||
|
||||
tlmRecorders.emplace_back(recorderName, dbName);
|
||||
tlmRecorders.back().recordMcConfig(DRAMSysConfiguration::dump(configuration.mcConfig));
|
||||
tlmRecorders.back().recordMemspec(DRAMSysConfiguration::dump(configuration.memSpec));
|
||||
tlmRecorders.back().recordTraceNames(Configuration::getInstance().simulationName);
|
||||
tlmRecorders.emplace_back(recorderName, config, dbName);
|
||||
tlmRecorders.back().recordMcConfig(DRAMSysConfiguration::dump(configLib.mcConfig));
|
||||
tlmRecorders.back().recordMemspec(DRAMSysConfiguration::dump(configLib.memSpec));
|
||||
tlmRecorders.back().recordTraceNames(config.simulationName);
|
||||
}
|
||||
}
|
||||
|
||||
void DRAMSysRecordable::instantiateModules(const std::string &traceName,
|
||||
const DRAMSysConfiguration::Configuration &configuration)
|
||||
const DRAMSysConfiguration::Configuration &configLib)
|
||||
{
|
||||
// The first call to getInstance() creates the Temperature Controller.
|
||||
// The same instance will be accessed by all other modules.
|
||||
TemperatureController::getInstance();
|
||||
|
||||
Configuration &config = Configuration::getInstance();
|
||||
temperatureController = std::make_unique<TemperatureController>("TemperatureController", config);
|
||||
|
||||
// Create and properly initialize TLM recorders.
|
||||
// They need to be ready before creating some modules.
|
||||
setupTlmRecorders(traceName, configuration);
|
||||
setupTlmRecorders(traceName, configLib);
|
||||
|
||||
// Create arbiter
|
||||
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)
|
||||
arbiter = std::make_unique<ArbiterFifo>("arbiter", configuration.addressMapping);
|
||||
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, configLib.addressMapping);
|
||||
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
|
||||
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
controllersTlmCheckers.emplace_back(std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(("TLMCheckerController"
|
||||
+ std::to_string(i)).c_str()));
|
||||
controllersTlmCheckers.emplace_back(std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>
|
||||
(("TLMCheckerController" + std::to_string(i)).c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,7 @@
|
||||
class DRAMSysRecordable : public DRAMSys
|
||||
{
|
||||
public:
|
||||
DRAMSysRecordable(const sc_core::sc_module_name &name,
|
||||
const DRAMSysConfiguration::Configuration &configuration);
|
||||
DRAMSysRecordable(const sc_core::sc_module_name &name, const DRAMSysConfiguration::Configuration &configLib);
|
||||
|
||||
protected:
|
||||
void end_of_simulation() override;
|
||||
@@ -56,10 +55,8 @@ private:
|
||||
// They generate the output databases.
|
||||
std::vector<TlmRecorder> tlmRecorders;
|
||||
|
||||
void setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configuration);
|
||||
|
||||
void instantiateModules(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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -58,17 +58,19 @@ double TemperatureController::getTemperature(int deviceId, float currentPower)
|
||||
PRINTDEBUGMESSAGE(name(), "Temperature requested by device " + std::to_string(
|
||||
deviceId) + " current power is " + std::to_string(currentPower));
|
||||
|
||||
if (dynamicTempSimEnabled) {
|
||||
if (dynamicTempSimEnabled)
|
||||
{
|
||||
currentPowerValues.at(deviceId) = currentPower;
|
||||
checkPowerThreshold(deviceId);
|
||||
|
||||
// FIXME using the static temperature value until the vector of
|
||||
// temperatures is filled
|
||||
// FIXME: using the static temperature value until the vector of temperatures is filled
|
||||
if (temperatureValues.empty())
|
||||
return temperatureConvert(staticTemperature + 273.15);
|
||||
|
||||
return temperatureConvert(temperatureValues.at(deviceId));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTDEBUGMESSAGE(name(), "Temperature is " + std::to_string(staticTemperature));
|
||||
return staticTemperature;
|
||||
}
|
||||
@@ -138,13 +140,16 @@ double TemperatureController::adjustThermalSimPeriod()
|
||||
// again in steps of 'n/2' until it achieves the desired value given by
|
||||
// configuration or the described in 1.1 occurs.
|
||||
|
||||
if (decreaseSimPeriod) {
|
||||
if (decreaseSimPeriod)
|
||||
{
|
||||
period = period / periodAdjustFactor;
|
||||
cyclesSinceLastPeriodAdjust = 0;
|
||||
decreaseSimPeriod = false;
|
||||
PRINTDEBUGMESSAGE(name(), "Thermal Simulation period reduced to " + std::to_string(
|
||||
period) + ". Target is " + std::to_string(targetPeriod));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (period != targetPeriod) {
|
||||
cyclesSinceLastPeriodAdjust++;
|
||||
if (cyclesSinceLastPeriodAdjust >= nPowStableCyclesToIncreasePeriod) {
|
||||
@@ -163,7 +168,8 @@ double TemperatureController::adjustThermalSimPeriod()
|
||||
|
||||
void TemperatureController::temperatureThread()
|
||||
{
|
||||
while (true) {
|
||||
while (true)
|
||||
{
|
||||
updateTemperatures();
|
||||
double p = adjustThermalSimPeriod();
|
||||
|
||||
|
||||
@@ -52,26 +52,23 @@
|
||||
class TemperatureController : sc_core::sc_module
|
||||
{
|
||||
public:
|
||||
static inline TemperatureController &getInstance() {
|
||||
static TemperatureController temperaturectrl("TemperatureController");
|
||||
return temperaturectrl;
|
||||
}
|
||||
TemperatureController(const TemperatureController&) = delete;
|
||||
TemperatureController& operator=(const TemperatureController&) = delete;
|
||||
|
||||
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;
|
||||
|
||||
staticTemperature =
|
||||
Configuration::getInstance().temperatureSim.staticTemperatureDefaultValue;
|
||||
|
||||
if (dynamicTempSimEnabled) {
|
||||
if (dynamicTempSimEnabled)
|
||||
{
|
||||
#ifdef THERMALSIM
|
||||
// Connect to the server
|
||||
std::string ip = Configuration::getInstance().temperatureSim.iceServerIp;
|
||||
unsigned int port = Configuration::getInstance().temperatureSim.iceServerPort;
|
||||
std::string ip = config.temperatureSim.iceServerIp;
|
||||
unsigned int port = config.temperatureSim.iceServerPort;
|
||||
thermalSimulation = new IceWrapper(ip, port);
|
||||
PRINTDEBUGMESSAGE(name(), "Dynamic temperature simulation. Server @ "
|
||||
+ 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.");
|
||||
#endif
|
||||
// Initial power dissipation values (got from config)
|
||||
currentPowerValues =
|
||||
Configuration::getInstance().temperatureSim.powerInitialValues;
|
||||
currentPowerValues = config.temperatureSim.powerInitialValues;
|
||||
lastPowerValues = currentPowerValues;
|
||||
|
||||
// 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;
|
||||
periodAdjustFactor =
|
||||
Configuration::getInstance().temperatureSim.simPeriodAdjustFactor;
|
||||
nPowStableCyclesToIncreasePeriod =
|
||||
Configuration::getInstance().temperatureSim.nPowStableCyclesToIncreasePeriod;
|
||||
periodAdjustFactor = config.temperatureSim.simPeriodAdjustFactor;
|
||||
nPowStableCyclesToIncreasePeriod = config.temperatureSim.nPowStableCyclesToIncreasePeriod;
|
||||
cyclesSinceLastPeriodAdjust = 0;
|
||||
|
||||
// Get the target period for the thermal simulation from config.
|
||||
targetPeriod = Configuration::getInstance().temperatureSim.thermalSimPeriod;
|
||||
targetPeriod = config.temperatureSim.thermalSimPeriod;
|
||||
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";
|
||||
std::system("rm -f temperature_map*");
|
||||
|
||||
genPowerMap = Configuration::getInstance().temperatureSim.generatePowerMap;
|
||||
genPowerMap = config.temperatureSim.generatePowerMap;
|
||||
powerMapFile = "power_map";
|
||||
std::system("rm -f power_map*");
|
||||
|
||||
SC_THREAD(temperatureThread);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTDEBUGMESSAGE(sc_module::name(), "Static temperature simulation. Temperature set to " +
|
||||
std::to_string(staticTemperature));
|
||||
}
|
||||
|
||||
@@ -62,16 +62,14 @@ using namespace sc_core;
|
||||
using namespace tlm;
|
||||
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();
|
||||
|
||||
storeMode = config.storeMode;
|
||||
|
||||
uint64_t channelSize = config.memSpec->getSimMemSizeInBytes() / config.memSpec->numberOfChannels;
|
||||
uint64_t channelSize = memSpec.getSimMemSizeInBytes() / memSpec.numberOfChannels;
|
||||
if (storeMode == Configuration::StoreMode::Store)
|
||||
{
|
||||
if (config.useMalloc)
|
||||
if (useMalloc)
|
||||
{
|
||||
memory = (unsigned char *)malloc(channelSize);
|
||||
if (!memory)
|
||||
@@ -95,7 +93,7 @@ Dram::Dram(const sc_module_name &name) : sc_module(name), tSocket("socket")
|
||||
|
||||
Dram::~Dram()
|
||||
{
|
||||
if (Configuration::getInstance().useMalloc)
|
||||
if (useMalloc)
|
||||
free(memory);
|
||||
}
|
||||
|
||||
@@ -108,14 +106,14 @@ void Dram::reportPower()
|
||||
std::cout << name() << std::string(" Total Energy: ")
|
||||
<< std::fixed << std::setprecision( 2 )
|
||||
<< DRAMPower->getEnergy().total_energy
|
||||
* Configuration::getInstance().memSpec->devicesPerRank
|
||||
* memSpec.devicesPerRank
|
||||
<< std::string(" pJ")
|
||||
<< std::endl;
|
||||
|
||||
std::cout << name() << std::string(" Average Power: ")
|
||||
<< std::fixed << std::setprecision( 2 )
|
||||
<< DRAMPower->getPower().average_power
|
||||
* Configuration::getInstance().memSpec->devicesPerRank
|
||||
* memSpec.devicesPerRank
|
||||
<< 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);
|
||||
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
if (powerAnalysis)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,15 +52,16 @@
|
||||
class Dram : public sc_core::sc_module
|
||||
{
|
||||
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);
|
||||
|
||||
const MemSpec *memSpec = Configuration::getInstance().memSpec;
|
||||
const MemSpec& memSpec;
|
||||
|
||||
// Data Storage:
|
||||
Configuration::StoreMode storeMode;
|
||||
|
||||
bool powerAnalysis;
|
||||
unsigned char *memory;
|
||||
bool useMalloc;
|
||||
|
||||
std::unique_ptr<libDRAMPower> DRAMPower;
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
#include "DramDDR3.h"
|
||||
|
||||
#include <memory>
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../../configuration/memspec/MemSpecDDR3.h"
|
||||
@@ -41,103 +43,105 @@
|
||||
using namespace sc_core;
|
||||
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)
|
||||
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);
|
||||
if (memSpec == nullptr)
|
||||
const auto *memSpecDDR3 = dynamic_cast<const MemSpecDDR3*>(config.memSpec.get());
|
||||
if (memSpecDDR3 == nullptr)
|
||||
SC_REPORT_FATAL("DramDDR3", "Wrong MemSpec chosen");
|
||||
|
||||
MemArchitectureSpec memArchSpec;
|
||||
memArchSpec.burstLength = memSpec->defaultBurstLength;
|
||||
memArchSpec.dataRate = memSpec->dataRate;
|
||||
memArchSpec.nbrOfRows = memSpec->rowsPerBank;
|
||||
memArchSpec.nbrOfBanks = memSpec->banksPerChannel;
|
||||
memArchSpec.nbrOfColumns = memSpec->columnsPerRow;
|
||||
memArchSpec.nbrOfRanks = memSpec->ranksPerChannel;
|
||||
memArchSpec.width = memSpec->bitWidth;
|
||||
memArchSpec.nbrOfBankGroups = memSpec->bankGroupsPerChannel;
|
||||
memArchSpec.burstLength = memSpecDDR3->defaultBurstLength;
|
||||
memArchSpec.dataRate = memSpecDDR3->dataRate;
|
||||
memArchSpec.nbrOfRows = memSpecDDR3->rowsPerBank;
|
||||
memArchSpec.nbrOfBanks = memSpecDDR3->banksPerChannel;
|
||||
memArchSpec.nbrOfColumns = memSpecDDR3->columnsPerRow;
|
||||
memArchSpec.nbrOfRanks = memSpecDDR3->ranksPerChannel;
|
||||
memArchSpec.width = memSpecDDR3->bitWidth;
|
||||
memArchSpec.nbrOfBankGroups = memSpecDDR3->bankGroupsPerChannel;
|
||||
memArchSpec.twoVoltageDomains = false;
|
||||
memArchSpec.dll = true;
|
||||
|
||||
MemTimingSpec memTimingSpec;
|
||||
//FIXME: memTimingSpec.FAWB = memSpec->tFAW / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RASB = memSpec->tRAS / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RCB = memSpec->tRC / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RPB = memSpec->tRP / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RRDB = memSpec->tRRD / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_L = memSpec->tRRD / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_S = memSpec->tRRD / memSpec->tCK;
|
||||
memTimingSpec.AL = memSpec->tAL / memSpec->tCK;
|
||||
memTimingSpec.CCD = memSpec->tCCD / memSpec->tCK;
|
||||
memTimingSpec.CCD_L = memSpec->tCCD / memSpec->tCK;
|
||||
memTimingSpec.CCD_S = memSpec->tCCD / memSpec->tCK;
|
||||
memTimingSpec.CKE = memSpec->tCKE / memSpec->tCK;
|
||||
memTimingSpec.CKESR = memSpec->tCKESR / memSpec->tCK;
|
||||
memTimingSpec.clkMhz = memSpec->fCKMHz;
|
||||
//FIXME: memTimingSpec.FAWB = memSpecDDR3->tFAW / memSpecDDR3->tCK;
|
||||
//FIXME: memTimingSpec.RASB = memSpecDDR3->tRAS / memSpecDDR3->tCK;
|
||||
//FIXME: memTimingSpec.RCB = memSpecDDR3->tRC / memSpecDDR3->tCK;
|
||||
//FIXME: memTimingSpec.RPB = memSpecDDR3->tRP / memSpecDDR3->tCK;
|
||||
//FIXME: memTimingSpec.RRDB = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_L = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_S = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||
memTimingSpec.AL = memSpecDDR3->tAL / memSpecDDR3->tCK;
|
||||
memTimingSpec.CCD = memSpecDDR3->tCCD / memSpecDDR3->tCK;
|
||||
memTimingSpec.CCD_L = memSpecDDR3->tCCD / memSpecDDR3->tCK;
|
||||
memTimingSpec.CCD_S = memSpecDDR3->tCCD / memSpecDDR3->tCK;
|
||||
memTimingSpec.CKE = memSpecDDR3->tCKE / memSpecDDR3->tCK;
|
||||
memTimingSpec.CKESR = memSpecDDR3->tCKESR / memSpecDDR3->tCK;
|
||||
memTimingSpec.clkMhz = memSpecDDR3->fCKMHz;
|
||||
// See also MemTimingSpec.cc in DRAMPower
|
||||
memTimingSpec.clkPeriod = 1000.0 / memSpec->fCKMHz;
|
||||
memTimingSpec.DQSCK = memSpec->tDQSCK / memSpec->tCK;
|
||||
memTimingSpec.FAW = memSpec->tFAW / memSpec->tCK;
|
||||
memTimingSpec.RAS = memSpec->tRAS / memSpec->tCK;
|
||||
memTimingSpec.RC = memSpec->tRC / memSpec->tCK;
|
||||
memTimingSpec.RCD = memSpec->tRCD / memSpec->tCK;
|
||||
memTimingSpec.REFI = memSpec->tREFI / memSpec->tCK;
|
||||
memTimingSpec.RFC = memSpec->tRFC / memSpec->tCK;
|
||||
memTimingSpec.RL = memSpec->tRL / memSpec->tCK;
|
||||
memTimingSpec.RP = memSpec->tRP / memSpec->tCK;
|
||||
memTimingSpec.RRD = memSpec->tRRD / memSpec->tCK;
|
||||
memTimingSpec.RRD_L = memSpec->tRRD / memSpec->tCK;
|
||||
memTimingSpec.RRD_S = memSpec->tRRD / memSpec->tCK;
|
||||
memTimingSpec.RTP = memSpec->tRTP / memSpec->tCK;
|
||||
memTimingSpec.TAW = memSpec->tFAW / memSpec->tCK;
|
||||
memTimingSpec.WL = memSpec->tWL / memSpec->tCK;
|
||||
memTimingSpec.WR = memSpec->tWR / memSpec->tCK;
|
||||
memTimingSpec.WTR = memSpec->tWTR / memSpec->tCK;
|
||||
memTimingSpec.WTR_L = memSpec->tWTR / memSpec->tCK;
|
||||
memTimingSpec.WTR_S = memSpec->tWTR / memSpec->tCK;
|
||||
memTimingSpec.XP = memSpec->tXP / memSpec->tCK;
|
||||
memTimingSpec.XPDLL = memSpec->tXPDLL / memSpec->tCK;
|
||||
memTimingSpec.XS = memSpec->tXS / memSpec->tCK;
|
||||
memTimingSpec.XSDLL = memSpec->tXSDLL / memSpec->tCK;
|
||||
memTimingSpec.clkPeriod = 1000.0 / memSpecDDR3->fCKMHz;
|
||||
memTimingSpec.DQSCK = memSpecDDR3->tDQSCK / memSpecDDR3->tCK;
|
||||
memTimingSpec.FAW = memSpecDDR3->tFAW / memSpecDDR3->tCK;
|
||||
memTimingSpec.RAS = memSpecDDR3->tRAS / memSpecDDR3->tCK;
|
||||
memTimingSpec.RC = memSpecDDR3->tRC / memSpecDDR3->tCK;
|
||||
memTimingSpec.RCD = memSpecDDR3->tRCD / memSpecDDR3->tCK;
|
||||
memTimingSpec.REFI = memSpecDDR3->tREFI / memSpecDDR3->tCK;
|
||||
memTimingSpec.RFC = memSpecDDR3->tRFC / memSpecDDR3->tCK;
|
||||
memTimingSpec.RL = memSpecDDR3->tRL / memSpecDDR3->tCK;
|
||||
memTimingSpec.RP = memSpecDDR3->tRP / memSpecDDR3->tCK;
|
||||
memTimingSpec.RRD = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||
memTimingSpec.RRD_L = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||
memTimingSpec.RRD_S = memSpecDDR3->tRRD / memSpecDDR3->tCK;
|
||||
memTimingSpec.RTP = memSpecDDR3->tRTP / memSpecDDR3->tCK;
|
||||
memTimingSpec.TAW = memSpecDDR3->tFAW / memSpecDDR3->tCK;
|
||||
memTimingSpec.WL = memSpecDDR3->tWL / memSpecDDR3->tCK;
|
||||
memTimingSpec.WR = memSpecDDR3->tWR / memSpecDDR3->tCK;
|
||||
memTimingSpec.WTR = memSpecDDR3->tWTR / memSpecDDR3->tCK;
|
||||
memTimingSpec.WTR_L = memSpecDDR3->tWTR / memSpecDDR3->tCK;
|
||||
memTimingSpec.WTR_S = memSpecDDR3->tWTR / memSpecDDR3->tCK;
|
||||
memTimingSpec.XP = memSpecDDR3->tXP / memSpecDDR3->tCK;
|
||||
memTimingSpec.XPDLL = memSpecDDR3->tXPDLL / memSpecDDR3->tCK;
|
||||
memTimingSpec.XS = memSpecDDR3->tXS / memSpecDDR3->tCK;
|
||||
memTimingSpec.XSDLL = memSpecDDR3->tXSDLL / memSpecDDR3->tCK;
|
||||
|
||||
MemPowerSpec memPowerSpec;
|
||||
memPowerSpec.idd0 = memSpec->iDD0;
|
||||
memPowerSpec.idd0 = memSpecDDR3->iDD0;
|
||||
memPowerSpec.idd02 = 0;
|
||||
memPowerSpec.idd2p0 = memSpec->iDD2P0;
|
||||
memPowerSpec.idd2p0 = memSpecDDR3->iDD2P0;
|
||||
memPowerSpec.idd2p02 = 0;
|
||||
memPowerSpec.idd2p1 = memSpec->iDD2P1;
|
||||
memPowerSpec.idd2p1 = memSpecDDR3->iDD2P1;
|
||||
memPowerSpec.idd2p12 = 0;
|
||||
memPowerSpec.idd2n = memSpec->iDD2N;
|
||||
memPowerSpec.idd2n = memSpecDDR3->iDD2N;
|
||||
memPowerSpec.idd2n2 = 0;
|
||||
memPowerSpec.idd3p0 = memSpec->iDD3P0;
|
||||
memPowerSpec.idd3p0 = memSpecDDR3->iDD3P0;
|
||||
memPowerSpec.idd3p02 = 0;
|
||||
memPowerSpec.idd3p1 = memSpec->iDD3P1;
|
||||
memPowerSpec.idd3p1 = memSpecDDR3->iDD3P1;
|
||||
memPowerSpec.idd3p12 = 0;
|
||||
memPowerSpec.idd3n = memSpec->iDD3N;
|
||||
memPowerSpec.idd3n = memSpecDDR3->iDD3N;
|
||||
memPowerSpec.idd3n2 = 0;
|
||||
memPowerSpec.idd4r = memSpec->iDD4R;
|
||||
memPowerSpec.idd4r = memSpecDDR3->iDD4R;
|
||||
memPowerSpec.idd4r2 = 0;
|
||||
memPowerSpec.idd4w = memSpec->iDD4W;
|
||||
memPowerSpec.idd4w = memSpecDDR3->iDD4W;
|
||||
memPowerSpec.idd4w2 = 0;
|
||||
memPowerSpec.idd5 = memSpec->iDD5;
|
||||
memPowerSpec.idd5 = memSpecDDR3->iDD5;
|
||||
memPowerSpec.idd52 = 0;
|
||||
memPowerSpec.idd6 = memSpec->iDD6;
|
||||
memPowerSpec.idd6 = memSpecDDR3->iDD6;
|
||||
memPowerSpec.idd62 = 0;
|
||||
memPowerSpec.vdd = memSpec->vDD;
|
||||
memPowerSpec.vdd = memSpecDDR3->vDD;
|
||||
memPowerSpec.vdd2 = 0;
|
||||
|
||||
MemorySpecification powerSpec;
|
||||
powerSpec.id = memSpec->memoryId;
|
||||
powerSpec.id = memSpecDDR3->memoryId;
|
||||
powerSpec.memoryType = MemoryType::DDR3;
|
||||
powerSpec.memTimingSpec = memTimingSpec;
|
||||
powerSpec.memPowerSpec = memPowerSpec;
|
||||
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
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramDDR3 : public Dram
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
#include "DramDDR4.h"
|
||||
|
||||
#include <memory>
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../../configuration/memspec/MemSpecDDR4.h"
|
||||
@@ -41,103 +43,105 @@
|
||||
using namespace sc_core;
|
||||
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)
|
||||
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);
|
||||
if (memSpec == nullptr)
|
||||
const auto *memSpecDDR4 = dynamic_cast<const MemSpecDDR4*>(config.memSpec.get());
|
||||
if (memSpecDDR4 == nullptr)
|
||||
SC_REPORT_FATAL("DramDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
MemArchitectureSpec memArchSpec;
|
||||
memArchSpec.burstLength = memSpec->defaultBurstLength;
|
||||
memArchSpec.dataRate = memSpec->dataRate;
|
||||
memArchSpec.nbrOfRows = memSpec->rowsPerBank;
|
||||
memArchSpec.nbrOfBanks = memSpec->banksPerChannel;
|
||||
memArchSpec.nbrOfColumns = memSpec->columnsPerRow;
|
||||
memArchSpec.nbrOfRanks = memSpec->ranksPerChannel;
|
||||
memArchSpec.width = memSpec->bitWidth;
|
||||
memArchSpec.nbrOfBankGroups = memSpec->bankGroupsPerChannel;
|
||||
memArchSpec.burstLength = memSpecDDR4->defaultBurstLength;
|
||||
memArchSpec.dataRate = memSpecDDR4->dataRate;
|
||||
memArchSpec.nbrOfRows = memSpecDDR4->rowsPerBank;
|
||||
memArchSpec.nbrOfBanks = memSpecDDR4->banksPerChannel;
|
||||
memArchSpec.nbrOfColumns = memSpecDDR4->columnsPerRow;
|
||||
memArchSpec.nbrOfRanks = memSpecDDR4->ranksPerChannel;
|
||||
memArchSpec.width = memSpecDDR4->bitWidth;
|
||||
memArchSpec.nbrOfBankGroups = memSpecDDR4->bankGroupsPerChannel;
|
||||
memArchSpec.twoVoltageDomains = true;
|
||||
memArchSpec.dll = true;
|
||||
|
||||
MemTimingSpec memTimingSpec;
|
||||
//FIXME: memTimingSpec.FAWB = memSpec->tFAW / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RASB = memSpec->tRAS / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RCB = memSpec->tRC / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RPB = memSpec->tRP / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RRDB = memSpec->tRRD_S / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_L = memSpec->tRRD_L / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_S = memSpec->tRRD_S / memSpec->tCK;
|
||||
memTimingSpec.AL = memSpec->tAL / memSpec->tCK;
|
||||
memTimingSpec.CCD = memSpec->tCCD_S / memSpec->tCK;
|
||||
memTimingSpec.CCD_L = memSpec->tCCD_L / memSpec->tCK;
|
||||
memTimingSpec.CCD_S = memSpec->tCCD_S / memSpec->tCK;
|
||||
memTimingSpec.CKE = memSpec->tCKE / memSpec->tCK;
|
||||
memTimingSpec.CKESR = memSpec->tCKESR / memSpec->tCK;
|
||||
memTimingSpec.clkMhz = memSpec->fCKMHz;
|
||||
//FIXME: memTimingSpec.FAWB = memSpecDDR4->tFAW / memSpecDDR4->tCK;
|
||||
//FIXME: memTimingSpec.RASB = memSpecDDR4->tRAS / memSpecDDR4->tCK;
|
||||
//FIXME: memTimingSpec.RCB = memSpecDDR4->tRC / memSpecDDR4->tCK;
|
||||
//FIXME: memTimingSpec.RPB = memSpecDDR4->tRP / memSpecDDR4->tCK;
|
||||
//FIXME: memTimingSpec.RRDB = memSpecDDR4->tRRD_S / memSpecDDR4->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_L = memSpecDDR4->tRRD_L / memSpecDDR4->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_S = memSpecDDR4->tRRD_S / memSpecDDR4->tCK;
|
||||
memTimingSpec.AL = memSpecDDR4->tAL / memSpecDDR4->tCK;
|
||||
memTimingSpec.CCD = memSpecDDR4->tCCD_S / memSpecDDR4->tCK;
|
||||
memTimingSpec.CCD_L = memSpecDDR4->tCCD_L / memSpecDDR4->tCK;
|
||||
memTimingSpec.CCD_S = memSpecDDR4->tCCD_S / memSpecDDR4->tCK;
|
||||
memTimingSpec.CKE = memSpecDDR4->tCKE / memSpecDDR4->tCK;
|
||||
memTimingSpec.CKESR = memSpecDDR4->tCKESR / memSpecDDR4->tCK;
|
||||
memTimingSpec.clkMhz = memSpecDDR4->fCKMHz;
|
||||
// See also MemTimingSpec.cc in DRAMPower
|
||||
memTimingSpec.clkPeriod = 1000.0 / memSpec->fCKMHz;
|
||||
memTimingSpec.DQSCK = memSpec->tDQSCK / memSpec->tCK;
|
||||
memTimingSpec.FAW = memSpec->tFAW / memSpec->tCK;
|
||||
memTimingSpec.RAS = memSpec->tRAS / memSpec->tCK;
|
||||
memTimingSpec.RC = memSpec->tRC / memSpec->tCK;
|
||||
memTimingSpec.RCD = memSpec->tRCD / memSpec->tCK;
|
||||
memTimingSpec.REFI = memSpec->tREFI / memSpec->tCK;
|
||||
memTimingSpec.RFC = memSpec->tRFC / memSpec->tCK;
|
||||
memTimingSpec.RL = memSpec->tRL / memSpec->tCK;
|
||||
memTimingSpec.RP = memSpec->tRP / memSpec->tCK;
|
||||
memTimingSpec.RRD = memSpec->tRRD_S / memSpec->tCK;
|
||||
memTimingSpec.RRD_L = memSpec->tRRD_L / memSpec->tCK;
|
||||
memTimingSpec.RRD_S = memSpec->tRRD_S / memSpec->tCK;
|
||||
memTimingSpec.RTP = memSpec->tRTP / memSpec->tCK;
|
||||
memTimingSpec.TAW = memSpec->tFAW / memSpec->tCK;
|
||||
memTimingSpec.WL = memSpec->tWL / memSpec->tCK;
|
||||
memTimingSpec.WR = memSpec->tWR / memSpec->tCK;
|
||||
memTimingSpec.WTR = memSpec->tWTR_S / memSpec->tCK;
|
||||
memTimingSpec.WTR_L = memSpec->tWTR_L / memSpec->tCK;
|
||||
memTimingSpec.WTR_S = memSpec->tWTR_S / memSpec->tCK;
|
||||
memTimingSpec.XP = memSpec->tXP / memSpec->tCK;
|
||||
memTimingSpec.XPDLL = memSpec->tXPDLL / memSpec->tCK;
|
||||
memTimingSpec.XS = memSpec->tXS / memSpec->tCK;
|
||||
memTimingSpec.XSDLL = memSpec->tXSDLL / memSpec->tCK;
|
||||
memTimingSpec.clkPeriod = 1000.0 / memSpecDDR4->fCKMHz;
|
||||
memTimingSpec.DQSCK = memSpecDDR4->tDQSCK / memSpecDDR4->tCK;
|
||||
memTimingSpec.FAW = memSpecDDR4->tFAW / memSpecDDR4->tCK;
|
||||
memTimingSpec.RAS = memSpecDDR4->tRAS / memSpecDDR4->tCK;
|
||||
memTimingSpec.RC = memSpecDDR4->tRC / memSpecDDR4->tCK;
|
||||
memTimingSpec.RCD = memSpecDDR4->tRCD / memSpecDDR4->tCK;
|
||||
memTimingSpec.REFI = memSpecDDR4->tREFI / memSpecDDR4->tCK;
|
||||
memTimingSpec.RFC = memSpecDDR4->tRFC / memSpecDDR4->tCK;
|
||||
memTimingSpec.RL = memSpecDDR4->tRL / memSpecDDR4->tCK;
|
||||
memTimingSpec.RP = memSpecDDR4->tRP / memSpecDDR4->tCK;
|
||||
memTimingSpec.RRD = memSpecDDR4->tRRD_S / memSpecDDR4->tCK;
|
||||
memTimingSpec.RRD_L = memSpecDDR4->tRRD_L / memSpecDDR4->tCK;
|
||||
memTimingSpec.RRD_S = memSpecDDR4->tRRD_S / memSpecDDR4->tCK;
|
||||
memTimingSpec.RTP = memSpecDDR4->tRTP / memSpecDDR4->tCK;
|
||||
memTimingSpec.TAW = memSpecDDR4->tFAW / memSpecDDR4->tCK;
|
||||
memTimingSpec.WL = memSpecDDR4->tWL / memSpecDDR4->tCK;
|
||||
memTimingSpec.WR = memSpecDDR4->tWR / memSpecDDR4->tCK;
|
||||
memTimingSpec.WTR = memSpecDDR4->tWTR_S / memSpecDDR4->tCK;
|
||||
memTimingSpec.WTR_L = memSpecDDR4->tWTR_L / memSpecDDR4->tCK;
|
||||
memTimingSpec.WTR_S = memSpecDDR4->tWTR_S / memSpecDDR4->tCK;
|
||||
memTimingSpec.XP = memSpecDDR4->tXP / memSpecDDR4->tCK;
|
||||
memTimingSpec.XPDLL = memSpecDDR4->tXPDLL / memSpecDDR4->tCK;
|
||||
memTimingSpec.XS = memSpecDDR4->tXS / memSpecDDR4->tCK;
|
||||
memTimingSpec.XSDLL = memSpecDDR4->tXSDLL / memSpecDDR4->tCK;
|
||||
|
||||
MemPowerSpec memPowerSpec;
|
||||
memPowerSpec.idd0 = memSpec->iDD0;
|
||||
memPowerSpec.idd02 = memSpec->iDD02;
|
||||
memPowerSpec.idd2p0 = memSpec->iDD2P0;
|
||||
memPowerSpec.idd0 = memSpecDDR4->iDD0;
|
||||
memPowerSpec.idd02 = memSpecDDR4->iDD02;
|
||||
memPowerSpec.idd2p0 = memSpecDDR4->iDD2P0;
|
||||
memPowerSpec.idd2p02 = 0;
|
||||
memPowerSpec.idd2p1 = memSpec->iDD2P1;
|
||||
memPowerSpec.idd2p1 = memSpecDDR4->iDD2P1;
|
||||
memPowerSpec.idd2p12 = 0;
|
||||
memPowerSpec.idd2n = memSpec->iDD2N;
|
||||
memPowerSpec.idd2n = memSpecDDR4->iDD2N;
|
||||
memPowerSpec.idd2n2 = 0;
|
||||
memPowerSpec.idd3p0 = memSpec->iDD3P0;
|
||||
memPowerSpec.idd3p0 = memSpecDDR4->iDD3P0;
|
||||
memPowerSpec.idd3p02 = 0;
|
||||
memPowerSpec.idd3p1 = memSpec->iDD3P1;
|
||||
memPowerSpec.idd3p1 = memSpecDDR4->iDD3P1;
|
||||
memPowerSpec.idd3p12 = 0;
|
||||
memPowerSpec.idd3n = memSpec->iDD3N;
|
||||
memPowerSpec.idd3n = memSpecDDR4->iDD3N;
|
||||
memPowerSpec.idd3n2 = 0;
|
||||
memPowerSpec.idd4r = memSpec->iDD4R;
|
||||
memPowerSpec.idd4r = memSpecDDR4->iDD4R;
|
||||
memPowerSpec.idd4r2 = 0;
|
||||
memPowerSpec.idd4w = memSpec->iDD4W;
|
||||
memPowerSpec.idd4w = memSpecDDR4->iDD4W;
|
||||
memPowerSpec.idd4w2 = 0;
|
||||
memPowerSpec.idd5 = memSpec->iDD5;
|
||||
memPowerSpec.idd5 = memSpecDDR4->iDD5;
|
||||
memPowerSpec.idd52 = 0;
|
||||
memPowerSpec.idd6 = memSpec->iDD6;
|
||||
memPowerSpec.idd62 = memSpec->iDD62;
|
||||
memPowerSpec.vdd = memSpec->vDD;
|
||||
memPowerSpec.vdd2 = memSpec->vDD2;
|
||||
memPowerSpec.idd6 = memSpecDDR4->iDD6;
|
||||
memPowerSpec.idd62 = memSpecDDR4->iDD62;
|
||||
memPowerSpec.vdd = memSpecDDR4->vDD;
|
||||
memPowerSpec.vdd2 = memSpecDDR4->vDD2;
|
||||
|
||||
MemorySpecification powerSpec;
|
||||
powerSpec.id = memSpec->memoryId;
|
||||
powerSpec.id = memSpecDDR4->memoryId;
|
||||
powerSpec.memoryType = MemoryType::DDR4;
|
||||
powerSpec.memTimingSpec = memTimingSpec;
|
||||
powerSpec.memPowerSpec = memPowerSpec;
|
||||
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
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramDDR4 : public Dram
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -41,11 +41,13 @@
|
||||
using namespace sc_core;
|
||||
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)
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#define DRAMDDR5_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramDDR5 : public Dram
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -40,11 +40,13 @@
|
||||
|
||||
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)
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#define DRAMGDDR5_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramGDDR5 : public Dram
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -40,11 +40,13 @@
|
||||
|
||||
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)
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#define DRAMGDDR5X_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramGDDR5X : public Dram
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -40,11 +40,13 @@
|
||||
|
||||
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)
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#define DRAMGDDR6_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramGDDR6 : public Dram
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -40,11 +40,13 @@
|
||||
|
||||
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)
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#define DRAMHBM2_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramHBM2 : public Dram
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -40,11 +40,13 @@
|
||||
|
||||
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)
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#define DRAMLPDDR4_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramLPDDR4 : public Dram
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -40,11 +40,15 @@
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../../configuration/memspec/MemSpecLPDDR5.h"
|
||||
|
||||
DramLPDDR5::DramLPDDR5(const sc_module_name &name) : Dram(name)
|
||||
using namespace sc_core;
|
||||
|
||||
DramLPDDR5::DramLPDDR5(const sc_module_name& name, const Configuration& config,
|
||||
TemperatureController& temperatureController)
|
||||
: Dram(name, config)
|
||||
{
|
||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||
SC_REPORT_FATAL("DramLPDDR5", "Error Model not supported for LPDDR5");
|
||||
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
if (powerAnalysis)
|
||||
SC_REPORT_FATAL("DramLPDDR5", "DRAMPower does not support LPDDR5");
|
||||
}
|
||||
|
||||
@@ -36,13 +36,16 @@
|
||||
#ifndef DRAMLPDDR5_H
|
||||
#define DRAMLPDDR5_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramLPDDR5 : public Dram
|
||||
{
|
||||
public:
|
||||
explicit DramLPDDR5(const sc_module_name &name);
|
||||
DramLPDDR5(const sc_core::sc_module_name& name, const Configuration& config,
|
||||
TemperatureController& temperatureController);
|
||||
SC_HAS_PROCESS(DramLPDDR5);
|
||||
};
|
||||
|
||||
|
||||
@@ -55,12 +55,14 @@ using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
template<class BaseDram>
|
||||
DramRecordable<BaseDram>::DramRecordable(const sc_module_name &name, TlmRecorder& tlmRecorder)
|
||||
: BaseDram(name), tlmRecorder(tlmRecorder)
|
||||
DramRecordable<BaseDram>::DramRecordable(const sc_module_name& name, const Configuration& config,
|
||||
TemperatureController& temperatureController, TlmRecorder& tlmRecorder)
|
||||
: BaseDram(name, config, temperatureController), tlmRecorder(tlmRecorder),
|
||||
powerWindowSize(config.memSpec->tCK * config.windowSize)
|
||||
{
|
||||
// Create a thread that is triggered every $powerWindowSize
|
||||
// to generate a Power over Time plot in the Trace analyzer:
|
||||
if (Configuration::getInstance().powerAnalysis && Configuration::getInstance().enableWindowing)
|
||||
if (config.powerAnalysis && config.enableWindowing)
|
||||
SC_THREAD(powerWindow);
|
||||
}
|
||||
|
||||
@@ -70,7 +72,7 @@ void DramRecordable<BaseDram>::reportPower()
|
||||
BaseDram::reportPower();
|
||||
tlmRecorder.recordPower(sc_time_stamp().to_seconds(),
|
||||
this->DRAMPower->getPower().window_average_power
|
||||
* Configuration::getInstance().memSpec->devicesPerRank);
|
||||
* this->memSpec.devicesPerRank);
|
||||
}
|
||||
|
||||
template<class BaseDram>
|
||||
@@ -89,7 +91,7 @@ void DramRecordable<BaseDram>::recordPhase(tlm_generic_payload &trans, const tlm
|
||||
// These are terminating phases recorded by the DRAM. The execution
|
||||
// time of the related command must be taken into consideration.
|
||||
if (phase == END_PDNA || phase == END_PDNP || phase == END_SREF)
|
||||
recTime += this->memSpec->getCommandLength(Command(phase));
|
||||
recTime += this->memSpec.getCommandLength(Command(phase));
|
||||
|
||||
NDEBUG_UNUSED(unsigned thr) = DramExtension::getExtension(trans).getThread().ID();
|
||||
NDEBUG_UNUSED(unsigned ch) = DramExtension::getExtension(trans).getChannel().ID();
|
||||
@@ -107,7 +109,7 @@ void DramRecordable<BaseDram>::recordPhase(tlm_generic_payload &trans, const tlm
|
||||
|
||||
if (phaseNeedsEnd(phase))
|
||||
{
|
||||
recTime += this->memSpec->getExecutionTime(Command(phase), trans);
|
||||
recTime += this->memSpec.getExecutionTime(Command(phase), trans);
|
||||
tlmRecorder.recordPhase(trans, getEndPhase(phase), recTime);
|
||||
}
|
||||
|
||||
@@ -126,7 +128,7 @@ void DramRecordable<BaseDram>::powerWindow()
|
||||
// At the very beginning (zero clock cycles) the energy is 0, so we wait first
|
||||
sc_module::wait(powerWindowSize);
|
||||
|
||||
clkCycles = std::lround(sc_time_stamp() / this->memSpec->tCK);
|
||||
clkCycles = std::lround(sc_time_stamp() / this->memSpec.tCK);
|
||||
|
||||
this->DRAMPower->calcWindowEnergy(clkCycles);
|
||||
|
||||
@@ -136,15 +138,15 @@ void DramRecordable<BaseDram>::powerWindow()
|
||||
// Store the time (in seconds) and the current average power (in mW) into the database
|
||||
tlmRecorder.recordPower(sc_time_stamp().to_seconds(),
|
||||
this->DRAMPower->getPower().window_average_power
|
||||
* Configuration::getInstance().memSpec->devicesPerRank);
|
||||
* this->memSpec.devicesPerRank);
|
||||
|
||||
// Here considering that DRAMPower provides the energy in pJ and the power in mW
|
||||
PRINTDEBUGMESSAGE(this->name(), std::string("\tWindow Energy: \t") + std::to_string(
|
||||
this->DRAMPower->getEnergy().window_energy *
|
||||
Configuration::getInstance().memSpec->devicesPerRank) + std::string("\t[pJ]"));
|
||||
this->memSpec.devicesPerRank) + std::string("\t[pJ]"));
|
||||
PRINTDEBUGMESSAGE(this->name(), std::string("\tWindow Average Power: \t") + std::to_string(
|
||||
this->DRAMPower->getPower().window_average_power *
|
||||
Configuration::getInstance().memSpec->devicesPerRank) + std::string("\t[mW]"));
|
||||
this->memSpec.devicesPerRank) + std::string("\t[mW]"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,12 +41,14 @@
|
||||
#include "../../common/TlmRecorder.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
template<class BaseDram>
|
||||
class DramRecordable final : public BaseDram
|
||||
{
|
||||
public:
|
||||
DramRecordable(const sc_core::sc_module_name &name, TlmRecorder& tlmRecorder);
|
||||
DramRecordable(const sc_core::sc_module_name& name, const Configuration& config,
|
||||
TemperatureController& temperatureController, TlmRecorder& tlmRecorder);
|
||||
SC_HAS_PROCESS(DramRecordable);
|
||||
|
||||
void reportPower() override;
|
||||
@@ -59,8 +61,7 @@ private:
|
||||
|
||||
TlmRecorder& tlmRecorder;
|
||||
|
||||
sc_core::sc_time powerWindowSize = Configuration::getInstance().memSpec->tCK *
|
||||
Configuration::getInstance().windowSize;
|
||||
sc_core::sc_time powerWindowSize;
|
||||
|
||||
// When working with floats, we have to decide ourselves what is an
|
||||
// acceptable definition for "equal". Here the number is compared with a
|
||||
|
||||
@@ -41,11 +41,13 @@
|
||||
using namespace sc_core;
|
||||
using namespace DRAMPower;
|
||||
|
||||
DramSTTMRAM::DramSTTMRAM(const sc_module_name &name) : Dram(name)
|
||||
DramSTTMRAM::DramSTTMRAM(const sc_module_name& name, const Configuration& config,
|
||||
TemperatureController& temperatureController)
|
||||
: Dram(name, config)
|
||||
{
|
||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||
SC_REPORT_FATAL("DramSTTMRAM", "Error Model not supported for STT-MRAM");
|
||||
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
if (powerAnalysis)
|
||||
SC_REPORT_FATAL("DramSTTMRAM", "DRAMPower does not support STT-MRAM");
|
||||
}
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#define DRAMSTTMRAM_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramSTTMRAM : public Dram
|
||||
{
|
||||
public:
|
||||
explicit DramSTTMRAM(const sc_core::sc_module_name &name);
|
||||
DramSTTMRAM(const sc_core::sc_module_name& name, const Configuration& config,
|
||||
TemperatureController& temperatureController);
|
||||
SC_HAS_PROCESS(DramSTTMRAM);
|
||||
};
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
|
||||
#include "DramWideIO.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
@@ -45,111 +46,112 @@ using namespace sc_core;
|
||||
using namespace tlm;
|
||||
using namespace DRAMPower;
|
||||
|
||||
DramWideIO::DramWideIO(const sc_module_name &name) : Dram(name)
|
||||
DramWideIO::DramWideIO(const sc_module_name& name, const Configuration& config,
|
||||
TemperatureController& temperatureController)
|
||||
: Dram(name, config)
|
||||
{
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
if (powerAnalysis)
|
||||
{
|
||||
const auto *memSpec = dynamic_cast<const MemSpecWideIO *>(this->memSpec);
|
||||
if (memSpec == nullptr)
|
||||
const auto* memSpecWideIO = dynamic_cast<const MemSpecWideIO *>(config.memSpec.get());
|
||||
if (memSpecWideIO == nullptr)
|
||||
SC_REPORT_FATAL("DramWideIO", "Wrong MemSpec chosen");
|
||||
|
||||
MemArchitectureSpec memArchSpec;
|
||||
memArchSpec.burstLength = memSpec->defaultBurstLength;
|
||||
memArchSpec.dataRate = memSpec->dataRate;
|
||||
memArchSpec.nbrOfRows = memSpec->rowsPerBank;
|
||||
memArchSpec.nbrOfBanks = memSpec->banksPerChannel;
|
||||
memArchSpec.nbrOfColumns = memSpec->columnsPerRow;
|
||||
memArchSpec.nbrOfRanks = memSpec->ranksPerChannel;
|
||||
memArchSpec.width = memSpec->bitWidth;
|
||||
memArchSpec.nbrOfBankGroups = memSpec->bankGroupsPerChannel;
|
||||
memArchSpec.burstLength = memSpecWideIO->defaultBurstLength;
|
||||
memArchSpec.dataRate = memSpecWideIO->dataRate;
|
||||
memArchSpec.nbrOfRows = memSpecWideIO->rowsPerBank;
|
||||
memArchSpec.nbrOfBanks = memSpecWideIO->banksPerChannel;
|
||||
memArchSpec.nbrOfColumns = memSpecWideIO->columnsPerRow;
|
||||
memArchSpec.nbrOfRanks = memSpecWideIO->ranksPerChannel;
|
||||
memArchSpec.width = memSpecWideIO->bitWidth;
|
||||
memArchSpec.nbrOfBankGroups = memSpecWideIO->bankGroupsPerChannel;
|
||||
memArchSpec.twoVoltageDomains = true;
|
||||
memArchSpec.dll = false;
|
||||
|
||||
MemTimingSpec memTimingSpec;
|
||||
//FIXME: memTimingSpec.FAWB = memSpec->tTAW / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RASB = memSpec->tRAS / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RCB = memSpec->tRC / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RPB = memSpec->tRP / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RRDB = memSpec->tRRD / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_L = memSpec->tRRD / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_S = memSpec->tRRD / memSpec->tCK;
|
||||
//FIXME: memTimingSpec.FAWB = memSpecWideIO->tTAW / memSpecWideIO->tCK;
|
||||
//FIXME: memTimingSpec.RASB = memSpecWideIO->tRAS / memSpecWideIO->tCK;
|
||||
//FIXME: memTimingSpec.RCB = memSpecWideIO->tRC / memSpecWideIO->tCK;
|
||||
//FIXME: memTimingSpec.RPB = memSpecWideIO->tRP / memSpecWideIO->tCK;
|
||||
//FIXME: memTimingSpec.RRDB = memSpecWideIO->tRRD / memSpecWideIO->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_L = memSpecWideIO->tRRD / memSpecWideIO->tCK;
|
||||
//FIXME: memTimingSpec.RRDB_S = memSpecWideIO->tRRD / memSpecWideIO->tCK;
|
||||
memTimingSpec.AL = 0;
|
||||
memTimingSpec.CCD = memSpec->defaultBurstLength;
|
||||
memTimingSpec.CCD_L = memSpec->defaultBurstLength;
|
||||
memTimingSpec.CCD_S = memSpec->defaultBurstLength;
|
||||
memTimingSpec.CKE = memSpec->tCKE / memSpec->tCK;
|
||||
memTimingSpec.CKESR = memSpec->tCKESR / memSpec->tCK;
|
||||
memTimingSpec.clkMhz = memSpec->fCKMHz;
|
||||
memTimingSpec.CCD = memSpecWideIO->defaultBurstLength;
|
||||
memTimingSpec.CCD_L = memSpecWideIO->defaultBurstLength;
|
||||
memTimingSpec.CCD_S = memSpecWideIO->defaultBurstLength;
|
||||
memTimingSpec.CKE = memSpecWideIO->tCKE / memSpecWideIO->tCK;
|
||||
memTimingSpec.CKESR = memSpecWideIO->tCKESR / memSpecWideIO->tCK;
|
||||
memTimingSpec.clkMhz = memSpecWideIO->fCKMHz;
|
||||
// See also MemTimingSpec.cc in DRAMPower
|
||||
memTimingSpec.clkPeriod = 1000.0 / memSpec->fCKMHz;
|
||||
memTimingSpec.DQSCK = memSpec->tDQSCK / memSpec->tCK;
|
||||
memTimingSpec.FAW = memSpec->tTAW / memSpec->tCK;
|
||||
memTimingSpec.RAS = memSpec->tRAS / memSpec->tCK;
|
||||
memTimingSpec.RC = memSpec->tRC / memSpec->tCK;
|
||||
memTimingSpec.RCD = memSpec->tRCD / memSpec->tCK;
|
||||
memTimingSpec.REFI = memSpec->tREFI / memSpec->tCK;
|
||||
memTimingSpec.RFC = memSpec->tRFC / memSpec->tCK;
|
||||
memTimingSpec.RL = memSpec->tRL / memSpec->tCK;
|
||||
memTimingSpec.RP = memSpec->tRP / memSpec->tCK;
|
||||
memTimingSpec.RRD = memSpec->tRRD / memSpec->tCK;
|
||||
memTimingSpec.RRD_L = memSpec->tRRD / memSpec->tCK;
|
||||
memTimingSpec.RRD_S = memSpec->tRRD / memSpec->tCK;
|
||||
memTimingSpec.RTP = memSpec->defaultBurstLength;
|
||||
memTimingSpec.TAW = memSpec->tTAW / memSpec->tCK;
|
||||
memTimingSpec.WL = memSpec->tWL / memSpec->tCK;
|
||||
memTimingSpec.WR = memSpec->tWR / memSpec->tCK;
|
||||
memTimingSpec.WTR = memSpec->tWTR / memSpec->tCK;
|
||||
memTimingSpec.WTR_L = memSpec->tWTR / memSpec->tCK;
|
||||
memTimingSpec.WTR_S = memSpec->tWTR / memSpec->tCK;
|
||||
memTimingSpec.XP = memSpec->tXP / memSpec->tCK;
|
||||
memTimingSpec.XPDLL = memSpec->tXP / memSpec->tCK;
|
||||
memTimingSpec.XS = memSpec->tXSR / memSpec->tCK;
|
||||
memTimingSpec.XSDLL = memSpec->tXSR / memSpec->tCK;
|
||||
memTimingSpec.clkPeriod = 1000.0 / memSpecWideIO->fCKMHz;
|
||||
memTimingSpec.DQSCK = memSpecWideIO->tDQSCK / memSpecWideIO->tCK;
|
||||
memTimingSpec.FAW = memSpecWideIO->tTAW / memSpecWideIO->tCK;
|
||||
memTimingSpec.RAS = memSpecWideIO->tRAS / memSpecWideIO->tCK;
|
||||
memTimingSpec.RC = memSpecWideIO->tRC / memSpecWideIO->tCK;
|
||||
memTimingSpec.RCD = memSpecWideIO->tRCD / memSpecWideIO->tCK;
|
||||
memTimingSpec.REFI = memSpecWideIO->tREFI / memSpecWideIO->tCK;
|
||||
memTimingSpec.RFC = memSpecWideIO->tRFC / memSpecWideIO->tCK;
|
||||
memTimingSpec.RL = memSpecWideIO->tRL / memSpecWideIO->tCK;
|
||||
memTimingSpec.RP = memSpecWideIO->tRP / memSpecWideIO->tCK;
|
||||
memTimingSpec.RRD = memSpecWideIO->tRRD / memSpecWideIO->tCK;
|
||||
memTimingSpec.RRD_L = memSpecWideIO->tRRD / memSpecWideIO->tCK;
|
||||
memTimingSpec.RRD_S = memSpecWideIO->tRRD / memSpecWideIO->tCK;
|
||||
memTimingSpec.RTP = memSpecWideIO->defaultBurstLength;
|
||||
memTimingSpec.TAW = memSpecWideIO->tTAW / memSpecWideIO->tCK;
|
||||
memTimingSpec.WL = memSpecWideIO->tWL / memSpecWideIO->tCK;
|
||||
memTimingSpec.WR = memSpecWideIO->tWR / memSpecWideIO->tCK;
|
||||
memTimingSpec.WTR = memSpecWideIO->tWTR / memSpecWideIO->tCK;
|
||||
memTimingSpec.WTR_L = memSpecWideIO->tWTR / memSpecWideIO->tCK;
|
||||
memTimingSpec.WTR_S = memSpecWideIO->tWTR / memSpecWideIO->tCK;
|
||||
memTimingSpec.XP = memSpecWideIO->tXP / memSpecWideIO->tCK;
|
||||
memTimingSpec.XPDLL = memSpecWideIO->tXP / memSpecWideIO->tCK;
|
||||
memTimingSpec.XS = memSpecWideIO->tXSR / memSpecWideIO->tCK;
|
||||
memTimingSpec.XSDLL = memSpecWideIO->tXSR / memSpecWideIO->tCK;
|
||||
|
||||
MemPowerSpec memPowerSpec;
|
||||
memPowerSpec.idd0 = memSpec->iDD0;
|
||||
memPowerSpec.idd02 = memSpec->iDD02;
|
||||
memPowerSpec.idd2p0 = memSpec->iDD2P0;
|
||||
memPowerSpec.idd2p02 = memSpec->iDD2P02;
|
||||
memPowerSpec.idd2p1 = memSpec->iDD2P1;
|
||||
memPowerSpec.idd2p12 = memSpec->iDD2P12;
|
||||
memPowerSpec.idd2n = memSpec->iDD2N;
|
||||
memPowerSpec.idd2n2 = memSpec->iDD2N2;
|
||||
memPowerSpec.idd3p0 = memSpec->iDD3P0;
|
||||
memPowerSpec.idd3p02 = memSpec->iDD3P02;
|
||||
memPowerSpec.idd3p1 = memSpec->iDD3P1;
|
||||
memPowerSpec.idd3p12 = memSpec->iDD3P12;
|
||||
memPowerSpec.idd3n = memSpec->iDD3N;
|
||||
memPowerSpec.idd3n2 = memSpec->iDD3N2;
|
||||
memPowerSpec.idd4r = memSpec->iDD4R;
|
||||
memPowerSpec.idd4r2 = memSpec->iDD4R2;
|
||||
memPowerSpec.idd4w = memSpec->iDD4W;
|
||||
memPowerSpec.idd4w2 = memSpec->iDD4W2;
|
||||
memPowerSpec.idd5 = memSpec->iDD5;
|
||||
memPowerSpec.idd52 = memSpec->iDD52;
|
||||
memPowerSpec.idd6 = memSpec->iDD6;
|
||||
memPowerSpec.idd62 = memSpec->iDD62;
|
||||
memPowerSpec.vdd = memSpec->vDD;
|
||||
memPowerSpec.vdd2 = memSpec->vDD2;
|
||||
memPowerSpec.idd0 = memSpecWideIO->iDD0;
|
||||
memPowerSpec.idd02 = memSpecWideIO->iDD02;
|
||||
memPowerSpec.idd2p0 = memSpecWideIO->iDD2P0;
|
||||
memPowerSpec.idd2p02 = memSpecWideIO->iDD2P02;
|
||||
memPowerSpec.idd2p1 = memSpecWideIO->iDD2P1;
|
||||
memPowerSpec.idd2p12 = memSpecWideIO->iDD2P12;
|
||||
memPowerSpec.idd2n = memSpecWideIO->iDD2N;
|
||||
memPowerSpec.idd2n2 = memSpecWideIO->iDD2N2;
|
||||
memPowerSpec.idd3p0 = memSpecWideIO->iDD3P0;
|
||||
memPowerSpec.idd3p02 = memSpecWideIO->iDD3P02;
|
||||
memPowerSpec.idd3p1 = memSpecWideIO->iDD3P1;
|
||||
memPowerSpec.idd3p12 = memSpecWideIO->iDD3P12;
|
||||
memPowerSpec.idd3n = memSpecWideIO->iDD3N;
|
||||
memPowerSpec.idd3n2 = memSpecWideIO->iDD3N2;
|
||||
memPowerSpec.idd4r = memSpecWideIO->iDD4R;
|
||||
memPowerSpec.idd4r2 = memSpecWideIO->iDD4R2;
|
||||
memPowerSpec.idd4w = memSpecWideIO->iDD4W;
|
||||
memPowerSpec.idd4w2 = memSpecWideIO->iDD4W2;
|
||||
memPowerSpec.idd5 = memSpecWideIO->iDD5;
|
||||
memPowerSpec.idd52 = memSpecWideIO->iDD52;
|
||||
memPowerSpec.idd6 = memSpecWideIO->iDD6;
|
||||
memPowerSpec.idd62 = memSpecWideIO->iDD62;
|
||||
memPowerSpec.vdd = memSpecWideIO->vDD;
|
||||
memPowerSpec.vdd2 = memSpecWideIO->vDD2;
|
||||
|
||||
MemorySpecification powerSpec;
|
||||
powerSpec.id = memSpec->memoryId;
|
||||
powerSpec.id = memSpecWideIO->memoryId;
|
||||
powerSpec.memoryType = MemoryType::WIDEIO_SDR;
|
||||
powerSpec.memTimingSpec = memTimingSpec;
|
||||
powerSpec.memPowerSpec = memPowerSpec;
|
||||
powerSpec.memArchSpec = memArchSpec;
|
||||
|
||||
DRAMPower = std::unique_ptr<libDRAMPower>(new libDRAMPower(powerSpec, false));
|
||||
DRAMPower = std::make_unique<libDRAMPower>(powerSpec, false);
|
||||
|
||||
// For each bank in a channel a error Model is created:
|
||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||
{
|
||||
for (unsigned i = 0; i < memSpec->banksPerChannel; i++)
|
||||
for (unsigned i = 0; i < memSpec.banksPerChannel; i++)
|
||||
{
|
||||
errorModel *em;
|
||||
std::string errorModelStr = "errorModel_bank" + std::to_string(i);
|
||||
em = new errorModel(errorModelStr.c_str(), DRAMPower.get());
|
||||
ememory.push_back(em);
|
||||
ememory.emplace_back(std::make_unique<errorModel>(errorModelStr.c_str(), config,
|
||||
temperatureController, DRAMPower.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,33 +159,25 @@ DramWideIO::DramWideIO(const sc_module_name &name) : Dram(name)
|
||||
{
|
||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||
{
|
||||
for (unsigned i = 0; i < memSpec->banksPerChannel; i++)
|
||||
for (unsigned i = 0; i < memSpec.banksPerChannel; i++)
|
||||
{
|
||||
errorModel *em;
|
||||
std::string errorModelStr = "errorModel_bank" + std::to_string(i);
|
||||
em = new errorModel(errorModelStr.c_str());
|
||||
ememory.push_back(em);
|
||||
ememory.emplace_back(std::make_unique<errorModel>(errorModelStr.c_str(), config,
|
||||
temperatureController));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DramWideIO::~DramWideIO()
|
||||
{
|
||||
// Clean up:
|
||||
for (auto e : ememory)
|
||||
delete e;
|
||||
}
|
||||
|
||||
tlm_sync_enum DramWideIO::nb_transport_fw(tlm_generic_payload &payload,
|
||||
tlm_phase &phase, sc_time &delay)
|
||||
{
|
||||
assert(phase >= 5 && phase <= 19);
|
||||
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
if (powerAnalysis)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user